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 = (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 background: background(theme.highest),
64 margin: { top: 3, bottom: 3 },
65 border: border(theme.lowest, "on", {
66 top: true,
67 bottom: true,
68 overlay: true,
69 }),
70 editor: {
71 text: text(theme.highest, "mono", "default", { size: "sm" }),
72 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
73 selection: theme.players[0],
74 },
75 disabled_editor: {
76 text: text(theme.highest, "mono", "disabled", { size: "sm" }),
77 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
78 selection: {
79 cursor: text(theme.highest, "mono", "disabled").color,
80 selection: theme.players[0].selection,
81 },
82 },
83 pending_edit_background: background(theme.highest, "positive"),
84 include_conversation: toggleable({
85 base: interactive({
86 base: {
87 icon_size: 12,
88 color: foreground(theme.highest, "variant"),
89
90 button_width: 12,
91 background: background(theme.highest, "on"),
92 corner_radius: 2,
93 border: {
94 width: 1., color: background(theme.highest, "on")
95 },
96 padding: {
97 left: 4,
98 right: 4,
99 top: 4,
100 bottom: 4,
101 },
102 },
103 state: {
104 hovered: {
105 ...text(theme.highest, "mono", "variant", "hovered"),
106 background: background(theme.highest, "on", "hovered"),
107 border: {
108 width: 1., color: background(theme.highest, "on", "hovered")
109 },
110 },
111 clicked: {
112 ...text(theme.highest, "mono", "variant", "pressed"),
113 background: background(theme.highest, "on", "pressed"),
114 border: {
115 width: 1., color: background(theme.highest, "on", "pressed")
116 },
117 },
118 },
119 }),
120 state: {
121 active: {
122 default: {
123 icon_size: 12,
124 button_width: 12,
125 color: foreground(theme.highest, "variant"),
126 background: background(theme.highest, "accent"),
127 border: border(theme.highest, "accent"),
128 },
129 hovered: {
130 background: background(theme.highest, "accent", "hovered"),
131 border: border(theme.highest, "accent", "hovered"),
132 },
133 clicked: {
134 background: background(theme.highest, "accent", "pressed"),
135 border: border(theme.highest, "accent", "pressed"),
136 },
137 },
138 },
139 }),
140 },
141 message_header: {
142 margin: { bottom: 4, top: 4 },
143 background: background(theme.highest),
144 },
145 hamburger_button: tab_bar_button(theme, {
146 icon: "icons/hamburger_15.svg",
147 }),
148
149 split_button: tab_bar_button(theme, {
150 icon: "icons/split_message_15.svg",
151 }),
152 quote_button: tab_bar_button(theme, {
153 icon: "icons/radix/quote.svg",
154 }),
155 assist_button: tab_bar_button(theme, {
156 icon: "icons/radix/magic-wand.svg",
157 }),
158 zoom_in_button: tab_bar_button(theme, {
159 icon: "icons/radix/maximize.svg",
160 }),
161 zoom_out_button: tab_bar_button(theme, {
162 icon: "icons/radix/minimize.svg",
163 }),
164 plus_button: tab_bar_button(theme, {
165 icon: "icons/radix/plus.svg",
166 }),
167 title: {
168 ...text(theme.highest, "sans", "default", { size: "xs" }),
169 },
170 saved_conversation: {
171 container: interactive({
172 base: {
173 background: background(theme.middle),
174 padding: { top: 4, bottom: 4 },
175 border: border(theme.middle, "default", { top: true, overlay: true }),
176 },
177 state: {
178 hovered: {
179 background: background(theme.middle, "hovered"),
180 },
181 clicked: {
182 background: background(theme.middle, "pressed"),
183 }
184 },
185 }),
186 saved_at: {
187 margin: { left: 8 },
188 ...text(theme.highest, "sans", "variant", { size: "xs" }),
189 },
190 title: {
191 margin: { left: 12 },
192 ...text(theme.highest, "sans", "default", {
193 size: "sm",
194 weight: "bold",
195 }),
196 },
197 },
198 user_sender: interactive_role("base"),
199 assistant_sender: interactive_role("accent"),
200 system_sender: interactive_role("warning"),
201 sent_at: {
202 margin: { top: 2, left: 8 },
203 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
204 },
205 model: interactive({
206 base: {
207 background: background(theme.highest),
208 margin: { left: 12, right: 4, top: 12 },
209 padding: { right: 4, left: 4, top: 1, bottom: 1 },
210 corner_radius: 4,
211 ...text(theme.highest, "sans", "default", { size: "xs" }),
212 },
213 state: {
214 hovered: {
215 background: background(theme.highest, "on", "hovered"),
216 border: border(theme.highest, "on", { overlay: true }),
217 },
218 },
219 }),
220 remaining_tokens: tokens_remaining("positive"),
221 low_remaining_tokens: tokens_remaining("warning"),
222 no_remaining_tokens: tokens_remaining("negative"),
223 error_icon: {
224 margin: { left: 8 },
225 color: foreground(theme.highest, "negative"),
226 width: 12,
227 },
228 api_key_editor: {
229 background: background(theme.highest, "on"),
230 corner_radius: 4,
231 text: text(theme.highest, "mono", "on"),
232 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
233 size: "xs",
234 }),
235 selection: theme.players[0],
236 border: border(theme.highest, "on"),
237 padding: {
238 bottom: 4,
239 left: 8,
240 right: 8,
241 top: 4,
242 },
243 },
244 api_key_prompt: {
245 padding: 10,
246 ...text(theme.highest, "sans", "default", { size: "xs" }),
247 },
248 }
249}