1import { with_opacity } from "../theme/color"
2import { background, border, foreground, text } from "./components"
3import { interactive, toggleable } from "../element"
4import { useTheme } from "../theme"
5import { text_button } from "../component/text_button"
6
7const search_results = () => {
8 const theme = useTheme()
9
10 return {
11 // TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
12 match_background: with_opacity(
13 foreground(theme.highest, "accent"),
14 0.4
15 ),
16 }
17}
18
19export default function search(): any {
20 const theme = useTheme()
21 const SEARCH_ROW_SPACING = 12
22
23 // Search input
24 const editor = {
25 background: background(theme.highest),
26 corner_radius: 8,
27 min_width: 200,
28 max_width: 500,
29 placeholder_text: text(theme.highest, "mono", "disabled"),
30 selection: theme.players[0],
31 text: text(theme.highest, "mono", "default"),
32 border: border(theme.highest),
33 margin: {
34 right: 9,
35 },
36 padding: {
37 top: 4,
38 bottom: 4,
39 left: 10,
40 right: 4,
41 },
42 }
43
44 const include_exclude_editor = {
45 ...editor,
46 min_width: 100,
47 max_width: 250,
48 }
49
50 return {
51 padding: { top: 4, bottom: 4 },
52
53 option_button: toggleable({
54 base: interactive({
55 base: {
56 icon_width: 14,
57 button_width: 32,
58 color: foreground(theme.highest, "variant"),
59 background: background(theme.highest, "on"),
60 corner_radius: 2,
61 margin: { right: 2 },
62 border: {
63 width: 1., color: background(theme.highest, "on")
64 },
65 padding: {
66 left: 4,
67 right: 4,
68 top: 4,
69 bottom: 4,
70 },
71 },
72 state: {
73 hovered: {
74 ...text(theme.highest, "mono", "variant", "hovered"),
75 background: background(theme.highest, "on", "hovered"),
76 border: {
77 width: 1., color: background(theme.highest, "on", "hovered")
78 },
79 },
80 clicked: {
81 ...text(theme.highest, "mono", "variant", "pressed"),
82 background: background(theme.highest, "on", "pressed"),
83 border: {
84 width: 1., color: background(theme.highest, "on", "pressed")
85 },
86 },
87 },
88 }),
89 state: {
90 active: {
91 default: {
92 icon_width: 14,
93 button_width: 32,
94 color: foreground(theme.highest, "variant"),
95 background: background(theme.highest, "accent"),
96 border: border(theme.highest, "accent"),
97 },
98 hovered: {
99 background: background(theme.highest, "accent", "hovered"),
100 border: border(theme.highest, "accent", "hovered"),
101 },
102 clicked: {
103 background: background(theme.highest, "accent", "pressed"),
104 border: border(theme.highest, "accent", "pressed"),
105 },
106 },
107 },
108 }),
109 option_button_component: toggleable({
110 base: interactive({
111 base: {
112 icon_size: 14,
113 color: foreground(theme.highest, "variant"),
114
115 button_width: 32,
116 background: background(theme.highest, "on"),
117 corner_radius: 2,
118 margin: { right: 2 },
119 border: {
120 width: 1., color: background(theme.highest, "on")
121 },
122 padding: {
123 left: 4,
124 right: 4,
125 top: 4,
126 bottom: 4,
127 },
128 },
129 state: {
130 hovered: {
131 ...text(theme.highest, "mono", "variant", "hovered"),
132 background: background(theme.highest, "on", "hovered"),
133 border: {
134 width: 1., color: background(theme.highest, "on", "hovered")
135 },
136 },
137 clicked: {
138 ...text(theme.highest, "mono", "variant", "pressed"),
139 background: background(theme.highest, "on", "pressed"),
140 border: {
141 width: 1., color: background(theme.highest, "on", "pressed")
142 },
143 },
144 },
145 }),
146 state: {
147 active: {
148 default: {
149 icon_size: 14,
150 button_width: 32,
151 color: foreground(theme.highest, "variant"),
152 background: background(theme.highest, "accent"),
153 border: border(theme.highest, "accent"),
154 },
155 hovered: {
156 background: background(theme.highest, "accent", "hovered"),
157 border: border(theme.highest, "accent", "hovered"),
158 },
159 clicked: {
160 background: background(theme.highest, "accent", "pressed"),
161 border: border(theme.highest, "accent", "pressed"),
162 },
163 },
164 },
165 }),
166 // Search tool buttons
167 // HACK: This is not how disabled elements should be created
168 // Disabled elements should use a disabled state of an interactive element, not a toggleable element with the inactive state being disabled
169 action_button: toggleable({
170 state: {
171 inactive: text_button({ variant: "ghost", layer: theme.highest, disabled: true, margin: { right: SEARCH_ROW_SPACING }, text_properties: { size: "sm" } }),
172 active: text_button({ variant: "ghost", layer: theme.highest, margin: { right: SEARCH_ROW_SPACING }, text_properties: { size: "sm" } })
173 }
174 }),
175 editor,
176 invalid_editor: {
177 ...editor,
178 border: border(theme.highest, "negative"),
179 },
180 include_exclude_editor,
181 invalid_include_exclude_editor: {
182 ...include_exclude_editor,
183 border: border(theme.highest, "negative"),
184 },
185 match_index: {
186 ...text(theme.highest, "mono", { size: "sm" }),
187 padding: {
188 right: SEARCH_ROW_SPACING,
189 },
190 },
191 option_button_group: {
192 padding: {
193 left: SEARCH_ROW_SPACING,
194 right: SEARCH_ROW_SPACING,
195 },
196 },
197 include_exclude_inputs: {
198 ...text(theme.highest, "mono", "variant"),
199 padding: {
200 right: 6,
201 },
202 },
203 major_results_status: {
204 ...text(theme.highest, "mono", "on"),
205 size: 15,
206 },
207 minor_results_status: {
208 ...text(theme.highest, "mono", "variant"),
209 size: 13,
210 },
211 // Input Icon
212 editor_icon: {
213 icon: {
214 color: foreground(theme.highest, "disabled"),
215 asset: "icons/magnifying_glass.svg",
216 dimensions: {
217 width: 14,
218 height: 14,
219 }
220 },
221 container: {
222 margin: { right: 4 },
223 padding: { left: 1, right: 1 },
224 }
225 },
226 // Toggle group buttons - Text | Regex | Semantic
227 mode_button: toggleable({
228 base: interactive({
229 base: {
230 ...text(theme.highest, "mono", "variant", { size: "sm" }),
231 background: background(theme.highest, "variant"),
232
233 border: {
234 ...border(theme.highest, "on"),
235 left: false,
236 right: false
237 },
238 margin: {
239 top: 1,
240 bottom: 1,
241 },
242 padding: {
243 left: 12,
244 right: 12,
245 },
246 corner_radius: 6,
247 },
248 state: {
249 hovered: {
250 ...text(theme.highest, "mono", "variant", "hovered", { size: "sm" }),
251 background: background(theme.highest, "variant", "hovered"),
252 border: border(theme.highest, "on", "hovered"),
253 },
254 clicked: {
255 ...text(theme.highest, "mono", "variant", "pressed", { size: "sm" }),
256 background: background(theme.highest, "variant", "pressed"),
257 border: border(theme.highest, "on", "pressed"),
258 },
259 },
260 }),
261 state: {
262 active: {
263 default: {
264 ...text(theme.highest, "mono", "on", { size: "sm" }),
265 background: background(theme.highest, "on")
266 },
267 hovered: {
268 ...text(theme.highest, "mono", "on", "hovered", { size: "sm" }),
269 background: background(theme.highest, "on", "hovered")
270 },
271 clicked: {
272 ...text(theme.highest, "mono", "on", "pressed", { size: "sm" }),
273 background: background(theme.highest, "on", "pressed")
274 },
275 },
276 },
277 }),
278 // Next/Previous Match buttons
279 // HACK: This is not how disabled elements should be created
280 // Disabled elements should use a disabled state of an interactive element, not a toggleable element with the inactive state being disabled
281 nav_button: toggleable({
282 state: {
283 inactive: interactive({
284 base: {
285 background: background(theme.highest, "disabled"),
286 text: text(theme.highest, "mono", "disabled"),
287 corner_radius: 6,
288 border: {
289 ...border(theme.highest, "disabled"),
290 left: false,
291 right: false,
292 },
293 margin: {
294 top: 1,
295 bottom: 1,
296 },
297 padding: {
298 left: 10,
299 right: 10,
300 },
301 },
302 state: {
303 hovered: {}
304 }
305 }),
306 active: interactive({
307 base: {
308 text: text(theme.highest, "mono", "on"),
309 background: background(theme.highest, "on"),
310 corner_radius: 6,
311 border: {
312 ...border(theme.highest, "on"),
313 left: false,
314 right: false,
315 },
316 margin: {
317 top: 1,
318 bottom: 1,
319 },
320 padding: {
321 left: 10,
322 right: 10,
323 },
324 },
325 state: {
326 hovered: {
327 ...text(theme.highest, "mono", "on", "hovered"),
328 background: background(theme.highest, "on", "hovered"),
329 border: border(theme.highest, "on", "hovered"),
330 },
331 clicked: {
332 ...text(theme.highest, "mono", "on", "pressed"),
333 background: background(theme.highest, "on", "pressed"),
334 border: border(theme.highest, "on", "pressed"),
335 },
336 },
337 })
338 }
339 }),
340 search_bar_row_height: 34,
341 search_row_spacing: 8,
342 option_button_height: 22,
343 modes_container: {},
344 ...search_results()
345 }
346}