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