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