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