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