1use crate::{
2 self as gpui3, hsla, point, px, relative, rems, AlignItems, DefiniteLength, Display, Fill,
3 FlexDirection, Hsla, JustifyContent, Length, Position, Rems, SharedString, StyleRefinement,
4};
5use crate::{BoxShadow, TextStyleRefinement};
6use smallvec::smallvec;
7
8pub trait Styled {
9 fn style(&mut self) -> &mut StyleRefinement;
10
11 gpui3_macros::style_helpers!();
12
13 /// Sets the size of the element to the full width and height.
14 fn full(mut self) -> Self
15 where
16 Self: Sized,
17 {
18 self.style().size.width = Some(relative(1.).into());
19 self.style().size.height = Some(relative(1.).into());
20 self
21 }
22
23 /// Sets the position of the element to `relative`.
24 /// [Docs](https://tailwindcss.com/docs/position)
25 fn relative(mut self) -> Self
26 where
27 Self: Sized,
28 {
29 self.style().position = Some(Position::Relative);
30 self
31 }
32
33 /// Sets the position of the element to `absolute`.
34 /// [Docs](https://tailwindcss.com/docs/position)
35 fn absolute(mut self) -> Self
36 where
37 Self: Sized,
38 {
39 self.style().position = Some(Position::Absolute);
40 self
41 }
42
43 /// Sets the display type of the element to `block`.
44 /// [Docs](https://tailwindcss.com/docs/display)
45 fn block(mut self) -> Self
46 where
47 Self: Sized,
48 {
49 self.style().display = Some(Display::Block);
50 self
51 }
52
53 /// Sets the display type of the element to `flex`.
54 /// [Docs](https://tailwindcss.com/docs/display)
55 fn flex(mut self) -> Self
56 where
57 Self: Sized,
58 {
59 self.style().display = Some(Display::Flex);
60 self
61 }
62
63 /// Sets the flex direction of the element to `column`.
64 /// [Docs](https://tailwindcss.com/docs/flex-direction#column)
65 fn flex_col(mut self) -> Self
66 where
67 Self: Sized,
68 {
69 self.style().flex_direction = Some(FlexDirection::Column);
70 self
71 }
72
73 /// Sets the flex direction of the element to `row`.
74 /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
75 fn flex_row(mut self) -> Self
76 where
77 Self: Sized,
78 {
79 self.style().flex_direction = Some(FlexDirection::Row);
80 self
81 }
82
83 /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
84 /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
85 fn flex_1(mut self) -> Self
86 where
87 Self: Sized,
88 {
89 self.style().flex_grow = Some(1.);
90 self.style().flex_shrink = Some(1.);
91 self.style().flex_basis = Some(relative(0.).into());
92 self
93 }
94
95 /// Sets the element to allow a flex item to grow and shrink, taking into account its initial size.
96 /// [Docs](https://tailwindcss.com/docs/flex#auto)
97 fn flex_auto(mut self) -> Self
98 where
99 Self: Sized,
100 {
101 self.style().flex_grow = Some(1.);
102 self.style().flex_shrink = Some(1.);
103 self.style().flex_basis = Some(Length::Auto);
104 self
105 }
106
107 /// Sets the element to allow a flex item to shrink but not grow, taking into account its initial size.
108 /// [Docs](https://tailwindcss.com/docs/flex#initial)
109 fn flex_initial(mut self) -> Self
110 where
111 Self: Sized,
112 {
113 self.style().flex_grow = Some(0.);
114 self.style().flex_shrink = Some(1.);
115 self.style().flex_basis = Some(Length::Auto);
116 self
117 }
118
119 /// Sets the element to prevent a flex item from growing or shrinking.
120 /// [Docs](https://tailwindcss.com/docs/flex#none)
121 fn flex_none(mut self) -> Self
122 where
123 Self: Sized,
124 {
125 self.style().flex_grow = Some(0.);
126 self.style().flex_shrink = Some(0.);
127 self
128 }
129
130 /// Sets the element to allow a flex item to grow to fill any available space.
131 /// [Docs](https://tailwindcss.com/docs/flex-grow)
132 fn grow(mut self) -> Self
133 where
134 Self: Sized,
135 {
136 self.style().flex_grow = Some(1.);
137 self
138 }
139
140 fn items_start(mut self) -> Self
141 where
142 Self: Sized,
143 {
144 self.style().align_items = Some(AlignItems::FlexStart);
145 self
146 }
147
148 fn items_end(mut self) -> Self
149 where
150 Self: Sized,
151 {
152 self.style().align_items = Some(AlignItems::FlexEnd);
153 self
154 }
155
156 fn items_center(mut self) -> Self
157 where
158 Self: Sized,
159 {
160 self.style().align_items = Some(AlignItems::Center);
161 self
162 }
163
164 fn justify_between(mut self) -> Self
165 where
166 Self: Sized,
167 {
168 self.style().justify_content = Some(JustifyContent::SpaceBetween);
169 self
170 }
171
172 fn justify_center(mut self) -> Self
173 where
174 Self: Sized,
175 {
176 self.style().justify_content = Some(JustifyContent::Center);
177 self
178 }
179
180 fn justify_start(mut self) -> Self
181 where
182 Self: Sized,
183 {
184 self.style().justify_content = Some(JustifyContent::Start);
185 self
186 }
187
188 fn justify_end(mut self) -> Self
189 where
190 Self: Sized,
191 {
192 self.style().justify_content = Some(JustifyContent::End);
193 self
194 }
195
196 fn justify_around(mut self) -> Self
197 where
198 Self: Sized,
199 {
200 self.style().justify_content = Some(JustifyContent::SpaceAround);
201 self
202 }
203
204 fn bg<F>(mut self, fill: F) -> Self
205 where
206 F: Into<Fill>,
207 Self: Sized,
208 {
209 self.style().background = Some(fill.into());
210 self
211 }
212
213 fn border_color<C>(mut self, border_color: C) -> Self
214 where
215 C: Into<Hsla>,
216 Self: Sized,
217 {
218 self.style().border_color = Some(border_color.into());
219 self
220 }
221
222 fn shadow(mut self) -> Self
223 where
224 Self: Sized,
225 {
226 self.style().box_shadow = Some(smallvec![
227 BoxShadow {
228 color: hsla(0., 0., 0., 0.1),
229 offset: point(px(0.), px(1.)),
230 blur_radius: px(3.),
231 spread_radius: px(0.),
232 },
233 BoxShadow {
234 color: hsla(0., 0., 0., 0.1),
235 offset: point(px(0.), px(1.)),
236 blur_radius: px(2.),
237 spread_radius: px(-1.),
238 }
239 ]);
240 self
241 }
242
243 fn shadow_none(mut self) -> Self
244 where
245 Self: Sized,
246 {
247 self.style().box_shadow = Some(Default::default());
248 self
249 }
250
251 fn shadow_sm(mut self) -> Self
252 where
253 Self: Sized,
254 {
255 self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
256 color: hsla(0., 0., 0., 0.05),
257 offset: point(px(0.), px(1.)),
258 blur_radius: px(2.),
259 spread_radius: px(0.),
260 }]);
261 self
262 }
263
264 fn shadow_md(mut self) -> Self
265 where
266 Self: Sized,
267 {
268 self.style().box_shadow = Some(smallvec![
269 BoxShadow {
270 color: hsla(0.5, 0., 0., 0.1),
271 offset: point(px(0.), px(4.)),
272 blur_radius: px(6.),
273 spread_radius: px(-1.),
274 },
275 BoxShadow {
276 color: hsla(0., 0., 0., 0.1),
277 offset: point(px(0.), px(2.)),
278 blur_radius: px(4.),
279 spread_radius: px(-2.),
280 }
281 ]);
282 self
283 }
284
285 fn shadow_lg(mut self) -> Self
286 where
287 Self: Sized,
288 {
289 self.style().box_shadow = Some(smallvec![
290 BoxShadow {
291 color: hsla(0., 0., 0., 0.1),
292 offset: point(px(0.), px(10.)),
293 blur_radius: px(15.),
294 spread_radius: px(-3.),
295 },
296 BoxShadow {
297 color: hsla(0., 0., 0., 0.1),
298 offset: point(px(0.), px(4.)),
299 blur_radius: px(6.),
300 spread_radius: px(-4.),
301 }
302 ]);
303 self
304 }
305
306 fn shadow_xl(mut self) -> Self
307 where
308 Self: Sized,
309 {
310 self.style().box_shadow = Some(smallvec![
311 BoxShadow {
312 color: hsla(0., 0., 0., 0.1),
313 offset: point(px(0.), px(20.)),
314 blur_radius: px(25.),
315 spread_radius: px(-5.),
316 },
317 BoxShadow {
318 color: hsla(0., 0., 0., 0.1),
319 offset: point(px(0.), px(8.)),
320 blur_radius: px(10.),
321 spread_radius: px(-6.),
322 }
323 ]);
324 self
325 }
326
327 fn shadow_2xl(mut self) -> Self
328 where
329 Self: Sized,
330 {
331 self.style().box_shadow = Some(smallvec![BoxShadow {
332 color: hsla(0., 0., 0., 0.25),
333 offset: point(px(0.), px(25.)),
334 blur_radius: px(50.),
335 spread_radius: px(-12.),
336 }]);
337 self
338 }
339
340 fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
341 let style: &mut StyleRefinement = self.style();
342 &mut style.text
343 }
344
345 fn text_color(mut self, color: impl Into<Hsla>) -> Self
346 where
347 Self: Sized,
348 {
349 self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
350 self
351 }
352
353 fn text_size(mut self, size: impl Into<Rems>) -> Self
354 where
355 Self: Sized,
356 {
357 self.text_style()
358 .get_or_insert_with(Default::default)
359 .font_size = Some(size.into());
360 self
361 }
362
363 fn text_xs(mut self) -> Self
364 where
365 Self: Sized,
366 {
367 self.text_style()
368 .get_or_insert_with(Default::default)
369 .font_size = Some(rems(0.75));
370 self
371 }
372
373 fn text_sm(mut self) -> Self
374 where
375 Self: Sized,
376 {
377 self.text_style()
378 .get_or_insert_with(Default::default)
379 .font_size = Some(rems(0.875));
380 self
381 }
382
383 fn text_base(mut self) -> Self
384 where
385 Self: Sized,
386 {
387 self.text_style()
388 .get_or_insert_with(Default::default)
389 .font_size = Some(rems(1.0));
390 self
391 }
392
393 fn text_lg(mut self) -> Self
394 where
395 Self: Sized,
396 {
397 self.text_style()
398 .get_or_insert_with(Default::default)
399 .font_size = Some(rems(1.125));
400 self
401 }
402
403 fn text_xl(mut self) -> Self
404 where
405 Self: Sized,
406 {
407 self.text_style()
408 .get_or_insert_with(Default::default)
409 .font_size = Some(rems(1.25));
410 self
411 }
412
413 fn text_2xl(mut self) -> Self
414 where
415 Self: Sized,
416 {
417 self.text_style()
418 .get_or_insert_with(Default::default)
419 .font_size = Some(rems(1.5));
420 self
421 }
422
423 fn text_3xl(mut self) -> Self
424 where
425 Self: Sized,
426 {
427 self.text_style()
428 .get_or_insert_with(Default::default)
429 .font_size = Some(rems(1.875));
430 self
431 }
432
433 fn text_decoration_none(mut self) -> Self
434 where
435 Self: Sized,
436 {
437 self.text_style()
438 .get_or_insert_with(Default::default)
439 .underline = None;
440 self
441 }
442
443 fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self
444 where
445 Self: Sized,
446 {
447 let style = self.text_style().get_or_insert_with(Default::default);
448 let underline = style.underline.get_or_insert_with(Default::default);
449 underline.color = Some(color.into());
450 self
451 }
452
453 fn text_decoration_solid(mut self) -> Self
454 where
455 Self: Sized,
456 {
457 let style = self.text_style().get_or_insert_with(Default::default);
458 let underline = style.underline.get_or_insert_with(Default::default);
459 underline.wavy = false;
460 self
461 }
462
463 fn text_decoration_wavy(mut self) -> Self
464 where
465 Self: Sized,
466 {
467 let style = self.text_style().get_or_insert_with(Default::default);
468 let underline = style.underline.get_or_insert_with(Default::default);
469 underline.wavy = true;
470 self
471 }
472
473 fn text_decoration_0(mut self) -> Self
474 where
475 Self: Sized,
476 {
477 let style = self.text_style().get_or_insert_with(Default::default);
478 let underline = style.underline.get_or_insert_with(Default::default);
479 underline.thickness = px(0.);
480 self
481 }
482
483 fn text_decoration_1(mut self) -> Self
484 where
485 Self: Sized,
486 {
487 let style = self.text_style().get_or_insert_with(Default::default);
488 let underline = style.underline.get_or_insert_with(Default::default);
489 underline.thickness = px(1.);
490 self
491 }
492
493 fn text_decoration_2(mut self) -> Self
494 where
495 Self: Sized,
496 {
497 let style = self.text_style().get_or_insert_with(Default::default);
498 let underline = style.underline.get_or_insert_with(Default::default);
499 underline.thickness = px(2.);
500 self
501 }
502
503 fn text_decoration_4(mut self) -> Self
504 where
505 Self: Sized,
506 {
507 let style = self.text_style().get_or_insert_with(Default::default);
508 let underline = style.underline.get_or_insert_with(Default::default);
509 underline.thickness = px(4.);
510 self
511 }
512
513 fn text_decoration_8(mut self) -> Self
514 where
515 Self: Sized,
516 {
517 let style = self.text_style().get_or_insert_with(Default::default);
518 let underline = style.underline.get_or_insert_with(Default::default);
519 underline.thickness = px(8.);
520 self
521 }
522
523 fn font(mut self, family_name: impl Into<SharedString>) -> Self
524 where
525 Self: Sized,
526 {
527 self.text_style()
528 .get_or_insert_with(Default::default)
529 .font_family = Some(family_name.into());
530 self
531 }
532
533 fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self
534 where
535 Self: Sized,
536 {
537 self.text_style()
538 .get_or_insert_with(Default::default)
539 .line_height = Some(line_height.into());
540 self
541 }
542}