1import { text, border, background, foreground, TextStyle } from "./components"
2import { Interactive, interactive, toggleable } 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 = (
26 color: StyleSets
27 ): Interactive<RoleCycleButton> => {
28 return interactive({
29 base: {
30 ...text(theme.highest, "sans", color, { size: "sm" }),
31 },
32 state: {
33 hovered: {
34 ...text(theme.highest, "sans", color, { size: "sm" }),
35 background: background(theme.highest, color, "hovered"),
36 },
37 clicked: {
38 ...text(theme.highest, "sans", color, { size: "sm" }),
39 background: background(theme.highest, color, "pressed"),
40 },
41 },
42 })
43 }
44
45 const tokens_remaining = (color: StyleSets): RemainingTokens => {
46 return {
47 ...text(theme.highest, "mono", color, { size: "xs" }),
48 background: background(theme.highest, "on", "default"),
49 margin: { top: 12, right: 20 },
50 padding: { right: 4, left: 4, top: 1, bottom: 1 },
51 corner_radius: 6,
52 }
53 }
54
55 return {
56 container: {
57 background: background(theme.highest),
58 padding: { left: 12 },
59 },
60 inline: {
61 background: background(theme.highest),
62 margin: { top: 3, bottom: 3 },
63 border: border(theme.lowest, "on", {
64 top: true,
65 bottom: true,
66 overlay: true,
67 }),
68 editor: {
69 text: text(theme.highest, "mono", "default", { size: "sm" }),
70 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
71 selection: theme.players[0],
72 },
73 disabled_editor: {
74 text: text(theme.highest, "mono", "disabled", { size: "sm" }),
75 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
76 selection: {
77 cursor: text(theme.highest, "mono", "disabled").color,
78 selection: theme.players[0].selection,
79 },
80 },
81 pending_edit_background: background(theme.highest, "positive"),
82 context_status: {
83 ...text(theme.highest, "mono", "disabled", { size: "sm" }),
84 },
85 retrieve_context: toggleable({
86 base: interactive({
87 base: {
88 icon_size: 12,
89 color: foreground(theme.highest, "variant"),
90
91 button_width: 12,
92 background: background(theme.highest, "on"),
93 corner_radius: 2,
94 border: {
95 width: 1., color: background(theme.highest, "on")
96 },
97 padding: {
98 left: 4,
99 right: 4,
100 top: 4,
101 bottom: 4,
102 },
103 },
104 state: {
105 hovered: {
106 ...text(theme.highest, "mono", "variant", "hovered"),
107 background: background(theme.highest, "on", "hovered"),
108 border: {
109 width: 1., color: background(theme.highest, "on", "hovered")
110 },
111 },
112 clicked: {
113 ...text(theme.highest, "mono", "variant", "pressed"),
114 background: background(theme.highest, "on", "pressed"),
115 border: {
116 width: 1., color: background(theme.highest, "on", "pressed")
117 },
118 },
119 },
120 }),
121 state: {
122 active: {
123 default: {
124 icon_size: 12,
125 button_width: 12,
126 color: foreground(theme.highest, "variant"),
127 background: background(theme.highest, "accent"),
128 border: border(theme.highest, "accent"),
129 },
130 hovered: {
131 background: background(theme.highest, "accent", "hovered"),
132 border: border(theme.highest, "accent", "hovered"),
133 },
134 clicked: {
135 background: background(theme.highest, "accent", "pressed"),
136 border: border(theme.highest, "accent", "pressed"),
137 },
138 },
139 },
140 }),
141 include_conversation: toggleable({
142 base: interactive({
143 base: {
144 icon_size: 12,
145 color: foreground(theme.highest, "variant"),
146
147 button_width: 12,
148 background: background(theme.highest, "on"),
149 corner_radius: 2,
150 border: {
151 width: 1., color: background(theme.highest, "on")
152 },
153 padding: {
154 left: 4,
155 right: 4,
156 top: 4,
157 bottom: 4,
158 },
159 },
160 state: {
161 hovered: {
162 ...text(theme.highest, "mono", "variant", "hovered"),
163 background: background(theme.highest, "on", "hovered"),
164 border: {
165 width: 1., color: background(theme.highest, "on", "hovered")
166 },
167 },
168 clicked: {
169 ...text(theme.highest, "mono", "variant", "pressed"),
170 background: background(theme.highest, "on", "pressed"),
171 border: {
172 width: 1., color: background(theme.highest, "on", "pressed")
173 },
174 },
175 },
176 }),
177 state: {
178 active: {
179 default: {
180 icon_size: 12,
181 button_width: 12,
182 color: foreground(theme.highest, "variant"),
183 background: background(theme.highest, "accent"),
184 border: border(theme.highest, "accent"),
185 },
186 hovered: {
187 background: background(theme.highest, "accent", "hovered"),
188 border: border(theme.highest, "accent", "hovered"),
189 },
190 clicked: {
191 background: background(theme.highest, "accent", "pressed"),
192 border: border(theme.highest, "accent", "pressed"),
193 },
194 },
195 },
196 }),
197 },
198 message_header: {
199 margin: { bottom: 4, top: 4 },
200 background: background(theme.highest),
201 },
202 hamburger_button: tab_bar_button(theme, {
203 icon: "icons/menu.svg",
204 }),
205
206 split_button: tab_bar_button(theme, {
207 icon: "icons/split_message.svg",
208 }),
209 quote_button: tab_bar_button(theme, {
210 icon: "icons/quote.svg",
211 }),
212 assist_button: tab_bar_button(theme, {
213 icon: "icons/magic-wand.svg",
214 }),
215 zoom_in_button: tab_bar_button(theme, {
216 icon: "icons/maximize.svg",
217 }),
218 zoom_out_button: tab_bar_button(theme, {
219 icon: "icons/minimize.svg",
220 }),
221 plus_button: tab_bar_button(theme, {
222 icon: "icons/plus.svg",
223 }),
224 title: {
225 ...text(theme.highest, "sans", "default", { size: "xs" }),
226 },
227 saved_conversation: {
228 container: interactive({
229 base: {
230 background: background(theme.middle),
231 padding: { top: 4, bottom: 4 },
232 border: border(theme.middle, "default", {
233 top: true,
234 overlay: true,
235 }),
236 },
237 state: {
238 hovered: {
239 background: background(theme.middle, "hovered"),
240 },
241 clicked: {
242 background: background(theme.middle, "pressed"),
243 },
244 },
245 }),
246 saved_at: {
247 margin: { left: 8 },
248 ...text(theme.highest, "sans", "variant", { size: "xs" }),
249 },
250 title: {
251 margin: { left: 12 },
252 ...text(theme.highest, "sans", "default", {
253 size: "sm",
254 weight: "bold",
255 }),
256 },
257 },
258 user_sender: interactive_role("base"),
259 assistant_sender: interactive_role("accent"),
260 system_sender: interactive_role("warning"),
261 sent_at: {
262 margin: { top: 2, left: 8 },
263 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
264 },
265 model: interactive({
266 base: {
267 background: background(theme.highest),
268 margin: { left: 12, right: 4, top: 12 },
269 padding: { right: 4, left: 4, top: 1, bottom: 1 },
270 corner_radius: 4,
271 ...text(theme.highest, "sans", "default", { size: "xs" }),
272 },
273 state: {
274 hovered: {
275 background: background(theme.highest, "on", "hovered"),
276 border: border(theme.highest, "on", { overlay: true }),
277 },
278 },
279 }),
280 remaining_tokens: tokens_remaining("positive"),
281 low_remaining_tokens: tokens_remaining("warning"),
282 no_remaining_tokens: tokens_remaining("negative"),
283 error_icon: {
284 margin: { left: 8 },
285 color: foreground(theme.highest, "negative"),
286 width: 12,
287 },
288 api_key_editor: {
289 background: background(theme.highest, "on"),
290 corner_radius: 4,
291 text: text(theme.highest, "mono", "on"),
292 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
293 size: "xs",
294 }),
295 selection: theme.players[0],
296 border: border(theme.highest, "on"),
297 padding: {
298 bottom: 4,
299 left: 8,
300 right: 8,
301 top: 4,
302 },
303 },
304 api_key_prompt: {
305 padding: 10,
306 ...text(theme.highest, "sans", "default", { size: "xs" }),
307 },
308 }
309}