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