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 include_conversation: 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 },
139 message_header: {
140 margin: { bottom: 4, top: 4 },
141 background: background(theme.highest),
142 },
143 hamburger_button: tab_bar_button(theme, {
144 icon: "icons/menu.svg",
145 }),
146
147 split_button: tab_bar_button(theme, {
148 icon: "icons/split_message.svg",
149 }),
150 quote_button: tab_bar_button(theme, {
151 icon: "icons/quote.svg",
152 }),
153 assist_button: tab_bar_button(theme, {
154 icon: "icons/magic-wand.svg",
155 }),
156 zoom_in_button: tab_bar_button(theme, {
157 icon: "icons/maximize.svg",
158 }),
159 zoom_out_button: tab_bar_button(theme, {
160 icon: "icons/minimize.svg",
161 }),
162 plus_button: tab_bar_button(theme, {
163 icon: "icons/plus.svg",
164 }),
165 title: {
166 ...text(theme.highest, "sans", "default", { size: "xs" }),
167 },
168 saved_conversation: {
169 container: interactive({
170 base: {
171 background: background(theme.middle),
172 padding: { top: 4, bottom: 4 },
173 border: border(theme.middle, "default", {
174 top: true,
175 overlay: true,
176 }),
177 },
178 state: {
179 hovered: {
180 background: background(theme.middle, "hovered"),
181 },
182 clicked: {
183 background: background(theme.middle, "pressed"),
184 },
185 },
186 }),
187 saved_at: {
188 margin: { left: 8 },
189 ...text(theme.highest, "sans", "variant", { size: "xs" }),
190 },
191 title: {
192 margin: { left: 12 },
193 ...text(theme.highest, "sans", "default", {
194 size: "sm",
195 weight: "bold",
196 }),
197 },
198 },
199 user_sender: interactive_role("base"),
200 assistant_sender: interactive_role("accent"),
201 system_sender: interactive_role("warning"),
202 sent_at: {
203 margin: { top: 2, left: 8 },
204 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
205 },
206 model: interactive({
207 base: {
208 background: background(theme.highest),
209 margin: { left: 12, right: 4, top: 12 },
210 padding: { right: 4, left: 4, top: 1, bottom: 1 },
211 corner_radius: 4,
212 ...text(theme.highest, "sans", "default", { size: "xs" }),
213 },
214 state: {
215 hovered: {
216 background: background(theme.highest, "on", "hovered"),
217 border: border(theme.highest, "on", { overlay: true }),
218 },
219 },
220 }),
221 remaining_tokens: tokens_remaining("positive"),
222 low_remaining_tokens: tokens_remaining("warning"),
223 no_remaining_tokens: tokens_remaining("negative"),
224 error_icon: {
225 margin: { left: 8 },
226 color: foreground(theme.highest, "negative"),
227 width: 12,
228 },
229 api_key_editor: {
230 background: background(theme.highest, "on"),
231 corner_radius: 4,
232 text: text(theme.highest, "mono", "on"),
233 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
234 size: "xs",
235 }),
236 selection: theme.players[0],
237 border: border(theme.highest, "on"),
238 padding: {
239 bottom: 4,
240 left: 8,
241 right: 8,
242 top: 4,
243 },
244 },
245 api_key_prompt: {
246 padding: 10,
247 ...text(theme.highest, "sans", "default", { size: "xs" }),
248 },
249 }
250}