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.lowest, "sans", "on", "disabled"),
72 selection: theme.players[0],
73 },
74 pending_edit_background: background(theme.highest, "positive"),
75 },
76 message_header: {
77 margin: { bottom: 4, top: 4 },
78 background: background(theme.highest),
79 },
80 hamburger_button: tab_bar_button(theme, {
81 icon: "icons/hamburger_15.svg",
82 }),
83
84 split_button: tab_bar_button(theme, {
85 icon: "icons/split_message_15.svg",
86 }),
87 quote_button: tab_bar_button(theme, {
88 icon: "icons/radix/quote.svg",
89 }),
90 assist_button: tab_bar_button(theme, {
91 icon: "icons/radix/magic-wand.svg",
92 }),
93 zoom_in_button: tab_bar_button(theme, {
94 icon: "icons/radix/maximize.svg",
95 }),
96 zoom_out_button: tab_bar_button(theme, {
97 icon: "icons/radix/minimize.svg",
98 }),
99 plus_button: tab_bar_button(theme, {
100 icon: "icons/radix/plus.svg",
101 }),
102 title: {
103 ...text(theme.highest, "sans", "default", { size: "xs" }),
104 },
105 saved_conversation: {
106 container: interactive({
107 base: {
108 background: background(theme.middle),
109 padding: { top: 4, bottom: 4 },
110 border: border(theme.middle, "default", { top: true, overlay: true }),
111 },
112 state: {
113 hovered: {
114 background: background(theme.middle, "hovered"),
115 },
116 clicked: {
117 background: background(theme.middle, "pressed"),
118 }
119 },
120 }),
121 saved_at: {
122 margin: { left: 8 },
123 ...text(theme.highest, "sans", "variant", { size: "xs" }),
124 },
125 title: {
126 margin: { left: 12 },
127 ...text(theme.highest, "sans", "default", {
128 size: "sm",
129 weight: "bold",
130 }),
131 },
132 },
133 user_sender: interactive_role("base"),
134 assistant_sender: interactive_role("accent"),
135 system_sender: interactive_role("warning"),
136 sent_at: {
137 margin: { top: 2, left: 8 },
138 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
139 },
140 model: interactive({
141 base: {
142 background: background(theme.highest),
143 margin: { left: 12, right: 4, top: 12 },
144 padding: { right: 4, left: 4, top: 1, bottom: 1 },
145 corner_radius: 4,
146 ...text(theme.highest, "sans", "default", { size: "xs" }),
147 },
148 state: {
149 hovered: {
150 background: background(theme.highest, "on", "hovered"),
151 border: border(theme.highest, "on", { overlay: true }),
152 },
153 },
154 }),
155 remaining_tokens: tokens_remaining("positive"),
156 low_remaining_tokens: tokens_remaining("warning"),
157 no_remaining_tokens: tokens_remaining("negative"),
158 error_icon: {
159 margin: { left: 8 },
160 color: foreground(theme.highest, "negative"),
161 width: 12,
162 },
163 api_key_editor: {
164 background: background(theme.highest, "on"),
165 corner_radius: 4,
166 text: text(theme.highest, "mono", "on"),
167 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
168 size: "xs",
169 }),
170 selection: theme.players[0],
171 border: border(theme.highest, "on"),
172 padding: {
173 bottom: 4,
174 left: 8,
175 right: 8,
176 top: 4,
177 },
178 },
179 api_key_prompt: {
180 padding: 10,
181 ...text(theme.highest, "sans", "default", { size: "xs" }),
182 },
183 }
184}