1import { text, border, background, foreground, TextStyle } from "./components"
2import { Interactive, interactive } from "../element"
3import { tab_bar_button } from "../component/tab_bar_button"
4import { StyleSets, useTheme } from "../theme"
5
6type RoleCycleButton = TextStyle & {
7 background?: string
8}
9// TODO: Replace these with zed types
10type RemainingTokens = TextStyle & {
11 background: string,
12 margin: { top: number, right: number },
13 padding: {
14 right: number,
15 left: number,
16 top: number,
17 bottom: number,
18 },
19 corner_radius: number,
20}
21
22export default function assistant(): any {
23 const theme = useTheme()
24
25 const interactive_role = (color: StyleSets): Interactive<RoleCycleButton> => {
26 return (
27 interactive({
28 base: {
29 ...text(theme.highest, "sans", color, { size: "sm" }),
30 },
31 state: {
32 hovered: {
33 ...text(theme.highest, "sans", color, { size: "sm" }),
34 background: background(theme.highest, color, "hovered"),
35 },
36 clicked: {
37 ...text(theme.highest, "sans", color, { size: "sm" }),
38 background: background(theme.highest, color, "pressed"),
39 }
40 },
41 })
42 )
43 }
44
45 const tokens_remaining = (color: StyleSets): RemainingTokens => {
46 return (
47 {
48 ...text(theme.highest, "mono", color, { size: "xs" }),
49 background: background(theme.highest, "on", "default"),
50 margin: { top: 12, right: 20 },
51 padding: { right: 4, left: 4, top: 1, bottom: 1 },
52 corner_radius: 6,
53 }
54 )
55 }
56
57 return {
58 container: {
59 background: background(theme.highest),
60 padding: { left: 12 },
61 },
62 inline: {
63 margin: { top: 3, bottom: 3 },
64 border: border(theme.lowest, "on", {
65 top: true,
66 bottom: true,
67 overlay: true,
68 }),
69 editor: {
70 text: text(theme.highest, "mono", "default", { size: "sm" }),
71 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
72 selection: theme.players[0],
73 },
74 disabled_editor: {
75 text: text(theme.highest, "mono", "disabled", { size: "sm" }),
76 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
77 selection: {
78 cursor: text(theme.highest, "mono", "disabled").color,
79 selection: theme.players[0].selection,
80 },
81 },
82 pending_edit_background: background(theme.highest, "positive"),
83 },
84 message_header: {
85 margin: { bottom: 4, top: 4 },
86 background: background(theme.highest),
87 },
88 hamburger_button: tab_bar_button(theme, {
89 icon: "icons/hamburger_15.svg",
90 }),
91
92 split_button: tab_bar_button(theme, {
93 icon: "icons/split_message_15.svg",
94 }),
95 quote_button: tab_bar_button(theme, {
96 icon: "icons/radix/quote.svg",
97 }),
98 assist_button: tab_bar_button(theme, {
99 icon: "icons/radix/magic-wand.svg",
100 }),
101 zoom_in_button: tab_bar_button(theme, {
102 icon: "icons/radix/maximize.svg",
103 }),
104 zoom_out_button: tab_bar_button(theme, {
105 icon: "icons/radix/minimize.svg",
106 }),
107 plus_button: tab_bar_button(theme, {
108 icon: "icons/radix/plus.svg",
109 }),
110 title: {
111 ...text(theme.highest, "sans", "default", { size: "xs" }),
112 },
113 saved_conversation: {
114 container: interactive({
115 base: {
116 background: background(theme.middle),
117 padding: { top: 4, bottom: 4 },
118 border: border(theme.middle, "default", { top: true, overlay: true }),
119 },
120 state: {
121 hovered: {
122 background: background(theme.middle, "hovered"),
123 },
124 clicked: {
125 background: background(theme.middle, "pressed"),
126 }
127 },
128 }),
129 saved_at: {
130 margin: { left: 8 },
131 ...text(theme.highest, "sans", "variant", { size: "xs" }),
132 },
133 title: {
134 margin: { left: 12 },
135 ...text(theme.highest, "sans", "default", {
136 size: "sm",
137 weight: "bold",
138 }),
139 },
140 },
141 user_sender: interactive_role("base"),
142 assistant_sender: interactive_role("accent"),
143 system_sender: interactive_role("warning"),
144 sent_at: {
145 margin: { top: 2, left: 8 },
146 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
147 },
148 model: interactive({
149 base: {
150 background: background(theme.highest),
151 margin: { left: 12, right: 4, top: 12 },
152 padding: { right: 4, left: 4, top: 1, bottom: 1 },
153 corner_radius: 4,
154 ...text(theme.highest, "sans", "default", { size: "xs" }),
155 },
156 state: {
157 hovered: {
158 background: background(theme.highest, "on", "hovered"),
159 border: border(theme.highest, "on", { overlay: true }),
160 },
161 },
162 }),
163 remaining_tokens: tokens_remaining("positive"),
164 low_remaining_tokens: tokens_remaining("warning"),
165 no_remaining_tokens: tokens_remaining("negative"),
166 error_icon: {
167 margin: { left: 8 },
168 color: foreground(theme.highest, "negative"),
169 width: 12,
170 },
171 api_key_editor: {
172 background: background(theme.highest, "on"),
173 corner_radius: 4,
174 text: text(theme.highest, "mono", "on"),
175 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
176 size: "xs",
177 }),
178 selection: theme.players[0],
179 border: border(theme.highest, "on"),
180 padding: {
181 bottom: 4,
182 left: 8,
183 right: 8,
184 top: 4,
185 },
186 },
187 api_key_prompt: {
188 padding: 10,
189 ...text(theme.highest, "sans", "default", { size: "xs" }),
190 },
191 }
192}