styled.rs

  1use crate::{
  2    self as gpui, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, CursorStyle,
  3    DefiniteLength, Fill, FlexDirection, FontWeight, Hsla, JustifyContent, Length, Position,
  4    SharedString, StyleRefinement, Visibility, WhiteSpace,
  5};
  6use crate::{BoxShadow, TextStyleRefinement};
  7use smallvec::{smallvec, SmallVec};
  8use taffy::style::{Display, Overflow};
  9
 10pub trait Styled: Sized {
 11    fn style(&mut self) -> &mut StyleRefinement;
 12
 13    gpui_macros::style_helpers!();
 14
 15    fn z_index(mut self, z_index: u16) -> Self {
 16        self.style().z_index = Some(z_index);
 17        self
 18    }
 19
 20    /// Sets the size of the element to the full width and height.
 21    fn full(mut self) -> Self {
 22        self.style().size.width = Some(relative(1.).into());
 23        self.style().size.height = Some(relative(1.).into());
 24        self
 25    }
 26
 27    /// Sets the position of the element to `relative`.
 28    /// [Docs](https://tailwindcss.com/docs/position)
 29    fn relative(mut self) -> Self {
 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        self.style().position = Some(Position::Absolute);
 38        self
 39    }
 40
 41    /// Sets the display type of the element to `block`.
 42    /// [Docs](https://tailwindcss.com/docs/display)
 43    fn block(mut self) -> Self {
 44        self.style().display = Some(Display::Block);
 45        self
 46    }
 47
 48    /// Sets the display type of the element to `flex`.
 49    /// [Docs](https://tailwindcss.com/docs/display)
 50    fn flex(mut self) -> Self {
 51        self.style().display = Some(Display::Flex);
 52        self
 53    }
 54
 55    /// Sets the visibility of the element to `visible`.
 56    /// [Docs](https://tailwindcss.com/docs/visibility)
 57    fn visible(mut self) -> Self {
 58        self.style().visibility = Some(Visibility::Visible);
 59        self
 60    }
 61
 62    /// Sets the visibility of the element to `hidden`.
 63    /// [Docs](https://tailwindcss.com/docs/visibility)
 64    fn invisible(mut self) -> Self {
 65        self.style().visibility = Some(Visibility::Hidden);
 66        self
 67    }
 68
 69    /// Sets the behavior of content that overflows the container to be hidden.
 70    /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 71    fn overflow_hidden(mut self) -> Self {
 72        self.style().overflow.x = Some(Overflow::Hidden);
 73        self.style().overflow.y = Some(Overflow::Hidden);
 74        self
 75    }
 76
 77    /// Sets the behavior of content that overflows the container on the X axis to be hidden.
 78    /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 79    fn overflow_x_hidden(mut self) -> Self {
 80        self.style().overflow.x = Some(Overflow::Hidden);
 81        self
 82    }
 83
 84    /// Sets the behavior of content that overflows the container on the Y axis to be hidden.
 85    /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 86    fn overflow_y_hidden(mut self) -> Self {
 87        self.style().overflow.y = Some(Overflow::Hidden);
 88        self
 89    }
 90
 91    fn cursor(mut self, cursor: CursorStyle) -> Self {
 92        self.style().mouse_cursor = Some(cursor);
 93        self
 94    }
 95
 96    /// Sets the cursor style when hovering an element to `default`.
 97    /// [Docs](https://tailwindcss.com/docs/cursor)
 98    fn cursor_default(mut self) -> Self {
 99        self.style().mouse_cursor = Some(CursorStyle::Arrow);
100        self
101    }
102
103    /// Sets the cursor style when hovering an element to `pointer`.
104    /// [Docs](https://tailwindcss.com/docs/cursor)
105    fn cursor_pointer(mut self) -> Self {
106        self.style().mouse_cursor = Some(CursorStyle::PointingHand);
107        self
108    }
109
110    /// Sets cursor style when hovering over an element to `text`.
111    /// [Docs](https://tailwindcss.com/docs/cursor)
112    fn cursor_text(mut self) -> Self {
113        self.style().mouse_cursor = Some(CursorStyle::IBeam);
114        self
115    }
116
117    /// Sets cursor style when hovering over an element to `move`.
118    /// [Docs](https://tailwindcss.com/docs/cursor)
119    fn cursor_move(mut self) -> Self {
120        self.style().mouse_cursor = Some(CursorStyle::ClosedHand);
121        self
122    }
123
124    /// Sets cursor style when hovering over an element to `not-allowed`.
125    /// [Docs](https://tailwindcss.com/docs/cursor)
126    fn cursor_not_allowed(mut self) -> Self {
127        self.style().mouse_cursor = Some(CursorStyle::OperationNotAllowed);
128        self
129    }
130
131    /// Sets cursor style when hovering over an element to `context-menu`.
132    /// [Docs](https://tailwindcss.com/docs/cursor)
133    fn cursor_context_menu(mut self) -> Self {
134        self.style().mouse_cursor = Some(CursorStyle::ContextualMenu);
135        self
136    }
137
138    /// Sets cursor style when hovering over an element to `crosshair`.
139    /// [Docs](https://tailwindcss.com/docs/cursor)
140    fn cursor_crosshair(mut self) -> Self {
141        self.style().mouse_cursor = Some(CursorStyle::Crosshair);
142        self
143    }
144
145    /// Sets cursor style when hovering over an element to `vertical-text`.
146    /// [Docs](https://tailwindcss.com/docs/cursor)
147    fn cursor_vertical_text(mut self) -> Self {
148        self.style().mouse_cursor = Some(CursorStyle::IBeamCursorForVerticalLayout);
149        self
150    }
151
152    /// Sets cursor style when hovering over an element to `alias`.
153    /// [Docs](https://tailwindcss.com/docs/cursor)
154    fn cursor_alias(mut self) -> Self {
155        self.style().mouse_cursor = Some(CursorStyle::DragLink);
156        self
157    }
158
159    /// Sets cursor style when hovering over an element to `copy`.
160    /// [Docs](https://tailwindcss.com/docs/cursor)
161    fn cursor_copy(mut self) -> Self {
162        self.style().mouse_cursor = Some(CursorStyle::DragCopy);
163        self
164    }
165
166    /// Sets cursor style when hovering over an element to `no-drop`.
167    /// [Docs](https://tailwindcss.com/docs/cursor)
168    fn cursor_no_drop(mut self) -> Self {
169        self.style().mouse_cursor = Some(CursorStyle::OperationNotAllowed);
170        self
171    }
172
173    /// Sets cursor style when hovering over an element to `grab`.
174    /// [Docs](https://tailwindcss.com/docs/cursor)
175    fn cursor_grab(mut self) -> Self {
176        self.style().mouse_cursor = Some(CursorStyle::OpenHand);
177        self
178    }
179
180    /// Sets cursor style when hovering over an element to `grabbing`.
181    /// [Docs](https://tailwindcss.com/docs/cursor)
182    fn cursor_grabbing(mut self) -> Self {
183        self.style().mouse_cursor = Some(CursorStyle::ClosedHand);
184        self
185    }
186
187    /// Sets cursor style when hovering over an element to `col-resize`.
188    /// [Docs](https://tailwindcss.com/docs/cursor)
189    fn cursor_col_resize(mut self) -> Self {
190        self.style().mouse_cursor = Some(CursorStyle::ResizeLeftRight);
191        self
192    }
193
194    /// Sets cursor style when hovering over an element to `row-resize`.
195    /// [Docs](https://tailwindcss.com/docs/cursor)
196    fn cursor_row_resize(mut self) -> Self {
197        self.style().mouse_cursor = Some(CursorStyle::ResizeUpDown);
198        self
199    }
200
201    /// Sets cursor style when hovering over an element to `n-resize`.
202    /// [Docs](https://tailwindcss.com/docs/cursor)
203    fn cursor_n_resize(mut self) -> Self {
204        self.style().mouse_cursor = Some(CursorStyle::ResizeUp);
205        self
206    }
207
208    /// Sets cursor style when hovering over an element to `e-resize`.
209    /// [Docs](https://tailwindcss.com/docs/cursor)
210    fn cursor_e_resize(mut self) -> Self {
211        self.style().mouse_cursor = Some(CursorStyle::ResizeRight);
212        self
213    }
214
215    /// Sets cursor style when hovering over an element to `s-resize`.
216    /// [Docs](https://tailwindcss.com/docs/cursor)
217    fn cursor_s_resize(mut self) -> Self {
218        self.style().mouse_cursor = Some(CursorStyle::ResizeDown);
219        self
220    }
221
222    /// Sets cursor style when hovering over an element to `w-resize`.
223    /// [Docs](https://tailwindcss.com/docs/cursor)
224    fn cursor_w_resize(mut self) -> Self {
225        self.style().mouse_cursor = Some(CursorStyle::ResizeLeft);
226        self
227    }
228
229    /// Sets the whitespace of the element to `normal`.
230    /// [Docs](https://tailwindcss.com/docs/whitespace#normal)
231    fn whitespace_normal(mut self) -> Self {
232        self.text_style()
233            .get_or_insert_with(Default::default)
234            .white_space = Some(WhiteSpace::Normal);
235        self
236    }
237
238    /// Sets the whitespace of the element to `nowrap`.
239    /// [Docs](https://tailwindcss.com/docs/whitespace#nowrap)
240    fn whitespace_nowrap(mut self) -> Self {
241        self.text_style()
242            .get_or_insert_with(Default::default)
243            .white_space = Some(WhiteSpace::Nowrap);
244        self
245    }
246
247    /// Sets the flex direction of the element to `column`.
248    /// [Docs](https://tailwindcss.com/docs/flex-direction#column)
249    fn flex_col(mut self) -> Self {
250        self.style().flex_direction = Some(FlexDirection::Column);
251        self
252    }
253
254    /// Sets the flex direction of the element to `column-reverse`.
255    /// [Docs](https://tailwindcss.com/docs/flex-direction#column-reverse)
256    fn flex_col_reverse(mut self) -> Self {
257        self.style().flex_direction = Some(FlexDirection::ColumnReverse);
258        self
259    }
260
261    /// Sets the flex direction of the element to `row`.
262    /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
263    fn flex_row(mut self) -> Self {
264        self.style().flex_direction = Some(FlexDirection::Row);
265        self
266    }
267
268    /// Sets the flex direction of the element to `row-reverse`.
269    /// [Docs](https://tailwindcss.com/docs/flex-direction#row-reverse)
270    fn flex_row_reverse(mut self) -> Self {
271        self.style().flex_direction = Some(FlexDirection::RowReverse);
272        self
273    }
274
275    /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
276    /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
277    fn flex_1(mut self) -> Self {
278        self.style().flex_grow = Some(1.);
279        self.style().flex_shrink = Some(1.);
280        self.style().flex_basis = Some(relative(0.).into());
281        self
282    }
283
284    /// Sets the element to allow a flex item to grow and shrink, taking into account its initial size.
285    /// [Docs](https://tailwindcss.com/docs/flex#auto)
286    fn flex_auto(mut self) -> Self {
287        self.style().flex_grow = Some(1.);
288        self.style().flex_shrink = Some(1.);
289        self.style().flex_basis = Some(Length::Auto);
290        self
291    }
292
293    /// Sets the element to allow a flex item to shrink but not grow, taking into account its initial size.
294    /// [Docs](https://tailwindcss.com/docs/flex#initial)
295    fn flex_initial(mut self) -> Self {
296        self.style().flex_grow = Some(0.);
297        self.style().flex_shrink = Some(1.);
298        self.style().flex_basis = Some(Length::Auto);
299        self
300    }
301
302    /// Sets the element to prevent a flex item from growing or shrinking.
303    /// [Docs](https://tailwindcss.com/docs/flex#none)
304    fn flex_none(mut self) -> Self {
305        self.style().flex_grow = Some(0.);
306        self.style().flex_shrink = Some(0.);
307        self
308    }
309
310    /// Sets the initial size of flex items for this element.
311    /// [Docs](https://tailwindcss.com/docs/flex-basis)
312    fn flex_basis(mut self, basis: impl Into<Length>) -> Self {
313        self.style().flex_basis = Some(basis.into());
314        self
315    }
316
317    /// Sets the element to allow a flex item to grow to fill any available space.
318    /// [Docs](https://tailwindcss.com/docs/flex-grow)
319    fn flex_grow(mut self) -> Self {
320        self.style().flex_grow = Some(1.);
321        self
322    }
323
324    /// Sets the element to allow a flex item to shrink if needed.
325    /// [Docs](https://tailwindcss.com/docs/flex-shrink)
326    fn flex_shrink(mut self) -> Self {
327        self.style().flex_shrink = Some(1.);
328        self
329    }
330
331    /// Sets the element to prevent a flex item from shrinking.
332    /// [Docs](https://tailwindcss.com/docs/flex-shrink#dont-shrink)
333    fn flex_shrink_0(mut self) -> Self {
334        self.style().flex_shrink = Some(0.);
335        self
336    }
337
338    /// Sets the element to align flex items to the start of the container's cross axis.
339    /// [Docs](https://tailwindcss.com/docs/align-items#start)
340    fn items_start(mut self) -> Self {
341        self.style().align_items = Some(AlignItems::FlexStart);
342        self
343    }
344
345    /// Sets the element to align flex items to the end of the container's cross axis.
346    /// [Docs](https://tailwindcss.com/docs/align-items#end)
347    fn items_end(mut self) -> Self {
348        self.style().align_items = Some(AlignItems::FlexEnd);
349        self
350    }
351
352    /// Sets the element to align flex items along the center of the container's cross axis.
353    /// [Docs](https://tailwindcss.com/docs/align-items#center)
354    fn items_center(mut self) -> Self {
355        self.style().align_items = Some(AlignItems::Center);
356        self
357    }
358
359    /// Sets the element to justify flex items along the container's main axis
360    /// such that there is an equal amount of space between each item.
361    /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
362    fn justify_between(mut self) -> Self {
363        self.style().justify_content = Some(JustifyContent::SpaceBetween);
364        self
365    }
366
367    /// Sets the element to justify flex items along the center of the container's main axis.
368    /// [Docs](https://tailwindcss.com/docs/justify-content#center)
369    fn justify_center(mut self) -> Self {
370        self.style().justify_content = Some(JustifyContent::Center);
371        self
372    }
373
374    /// Sets the element to justify flex items against the start of the container's main axis.
375    /// [Docs](https://tailwindcss.com/docs/justify-content#start)
376    fn justify_start(mut self) -> Self {
377        self.style().justify_content = Some(JustifyContent::Start);
378        self
379    }
380
381    /// Sets the element to justify flex items against the end of the container's main axis.
382    /// [Docs](https://tailwindcss.com/docs/justify-content#end)
383    fn justify_end(mut self) -> Self {
384        self.style().justify_content = Some(JustifyContent::End);
385        self
386    }
387
388    /// Sets the element to justify items along the container's main axis such
389    /// that there is an equal amount of space on each side of each item.
390    /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
391    fn justify_around(mut self) -> Self {
392        self.style().justify_content = Some(JustifyContent::SpaceAround);
393        self
394    }
395
396    /// Sets the background color of the element.
397    fn bg<F>(mut self, fill: F) -> Self
398    where
399        F: Into<Fill>,
400        Self: Sized,
401    {
402        self.style().background = Some(fill.into());
403        self
404    }
405
406    /// Sets the border color of the element.
407    fn border_color<C>(mut self, border_color: C) -> Self
408    where
409        C: Into<Hsla>,
410        Self: Sized,
411    {
412        self.style().border_color = Some(border_color.into());
413        self
414    }
415
416    /// Sets the box shadow of the element.
417    /// [Docs](https://tailwindcss.com/docs/box-shadow)
418    fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self {
419        self.style().box_shadow = Some(shadows);
420        self
421    }
422
423    /// Clears the box shadow of the element.
424    /// [Docs](https://tailwindcss.com/docs/box-shadow)
425    fn shadow_none(mut self) -> Self {
426        self.style().box_shadow = Some(Default::default());
427        self
428    }
429
430    /// Sets the box shadow of the element.
431    /// [Docs](https://tailwindcss.com/docs/box-shadow)
432    fn shadow_sm(mut self) -> Self {
433        self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
434            color: hsla(0., 0., 0., 0.05),
435            offset: point(px(0.), px(1.)),
436            blur_radius: px(2.),
437            spread_radius: px(0.),
438        }]);
439        self
440    }
441
442    /// Sets the box shadow of the element.
443    /// [Docs](https://tailwindcss.com/docs/box-shadow)
444    fn shadow_md(mut self) -> Self {
445        self.style().box_shadow = Some(smallvec![
446            BoxShadow {
447                color: hsla(0.5, 0., 0., 0.1),
448                offset: point(px(0.), px(4.)),
449                blur_radius: px(6.),
450                spread_radius: px(-1.),
451            },
452            BoxShadow {
453                color: hsla(0., 0., 0., 0.1),
454                offset: point(px(0.), px(2.)),
455                blur_radius: px(4.),
456                spread_radius: px(-2.),
457            }
458        ]);
459        self
460    }
461
462    /// Sets the box shadow of the element.
463    /// [Docs](https://tailwindcss.com/docs/box-shadow)
464    fn shadow_lg(mut self) -> Self {
465        self.style().box_shadow = Some(smallvec![
466            BoxShadow {
467                color: hsla(0., 0., 0., 0.1),
468                offset: point(px(0.), px(10.)),
469                blur_radius: px(15.),
470                spread_radius: px(-3.),
471            },
472            BoxShadow {
473                color: hsla(0., 0., 0., 0.1),
474                offset: point(px(0.), px(4.)),
475                blur_radius: px(6.),
476                spread_radius: px(-4.),
477            }
478        ]);
479        self
480    }
481
482    /// Sets the box shadow of the element.
483    /// [Docs](https://tailwindcss.com/docs/box-shadow)
484    fn shadow_xl(mut self) -> Self {
485        self.style().box_shadow = Some(smallvec![
486            BoxShadow {
487                color: hsla(0., 0., 0., 0.1),
488                offset: point(px(0.), px(20.)),
489                blur_radius: px(25.),
490                spread_radius: px(-5.),
491            },
492            BoxShadow {
493                color: hsla(0., 0., 0., 0.1),
494                offset: point(px(0.), px(8.)),
495                blur_radius: px(10.),
496                spread_radius: px(-6.),
497            }
498        ]);
499        self
500    }
501
502    /// Sets the box shadow of the element.
503    /// [Docs](https://tailwindcss.com/docs/box-shadow)
504    fn shadow_2xl(mut self) -> Self {
505        self.style().box_shadow = Some(smallvec![BoxShadow {
506            color: hsla(0., 0., 0., 0.25),
507            offset: point(px(0.), px(25.)),
508            blur_radius: px(50.),
509            spread_radius: px(-12.),
510        }]);
511        self
512    }
513
514    fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
515        let style: &mut StyleRefinement = self.style();
516        &mut style.text
517    }
518
519    fn text_color(mut self, color: impl Into<Hsla>) -> Self {
520        self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
521        self
522    }
523
524    fn font_weight(mut self, weight: FontWeight) -> Self {
525        self.text_style()
526            .get_or_insert_with(Default::default)
527            .font_weight = Some(weight);
528        self
529    }
530
531    fn text_bg(mut self, bg: impl Into<Hsla>) -> Self {
532        self.text_style()
533            .get_or_insert_with(Default::default)
534            .background_color = Some(bg.into());
535        self
536    }
537
538    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
539        self.text_style()
540            .get_or_insert_with(Default::default)
541            .font_size = Some(size.into());
542        self
543    }
544
545    fn text_xs(mut self) -> Self {
546        self.text_style()
547            .get_or_insert_with(Default::default)
548            .font_size = Some(rems(0.75).into());
549        self
550    }
551
552    fn text_sm(mut self) -> Self {
553        self.text_style()
554            .get_or_insert_with(Default::default)
555            .font_size = Some(rems(0.875).into());
556        self
557    }
558
559    fn text_base(mut self) -> Self {
560        self.text_style()
561            .get_or_insert_with(Default::default)
562            .font_size = Some(rems(1.0).into());
563        self
564    }
565
566    fn text_lg(mut self) -> Self {
567        self.text_style()
568            .get_or_insert_with(Default::default)
569            .font_size = Some(rems(1.125).into());
570        self
571    }
572
573    fn text_xl(mut self) -> Self {
574        self.text_style()
575            .get_or_insert_with(Default::default)
576            .font_size = Some(rems(1.25).into());
577        self
578    }
579
580    fn text_2xl(mut self) -> Self {
581        self.text_style()
582            .get_or_insert_with(Default::default)
583            .font_size = Some(rems(1.5).into());
584        self
585    }
586
587    fn text_3xl(mut self) -> Self {
588        self.text_style()
589            .get_or_insert_with(Default::default)
590            .font_size = Some(rems(1.875).into());
591        self
592    }
593
594    fn text_decoration_none(mut self) -> Self {
595        self.text_style()
596            .get_or_insert_with(Default::default)
597            .underline = None;
598        self
599    }
600
601    fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self {
602        let style = self.text_style().get_or_insert_with(Default::default);
603        let underline = style.underline.get_or_insert_with(Default::default);
604        underline.color = Some(color.into());
605        self
606    }
607
608    fn text_decoration_solid(mut self) -> Self {
609        let style = self.text_style().get_or_insert_with(Default::default);
610        let underline = style.underline.get_or_insert_with(Default::default);
611        underline.wavy = false;
612        self
613    }
614
615    fn text_decoration_wavy(mut self) -> Self {
616        let style = self.text_style().get_or_insert_with(Default::default);
617        let underline = style.underline.get_or_insert_with(Default::default);
618        underline.wavy = true;
619        self
620    }
621
622    fn text_decoration_0(mut self) -> Self {
623        let style = self.text_style().get_or_insert_with(Default::default);
624        let underline = style.underline.get_or_insert_with(Default::default);
625        underline.thickness = px(0.);
626        self
627    }
628
629    fn text_decoration_1(mut self) -> Self {
630        let style = self.text_style().get_or_insert_with(Default::default);
631        let underline = style.underline.get_or_insert_with(Default::default);
632        underline.thickness = px(1.);
633        self
634    }
635
636    fn text_decoration_2(mut self) -> Self {
637        let style = self.text_style().get_or_insert_with(Default::default);
638        let underline = style.underline.get_or_insert_with(Default::default);
639        underline.thickness = px(2.);
640        self
641    }
642
643    fn text_decoration_4(mut self) -> Self {
644        let style = self.text_style().get_or_insert_with(Default::default);
645        let underline = style.underline.get_or_insert_with(Default::default);
646        underline.thickness = px(4.);
647        self
648    }
649
650    fn text_decoration_8(mut self) -> Self {
651        let style = self.text_style().get_or_insert_with(Default::default);
652        let underline = style.underline.get_or_insert_with(Default::default);
653        underline.thickness = px(8.);
654        self
655    }
656
657    fn font(mut self, family_name: impl Into<SharedString>) -> Self {
658        self.text_style()
659            .get_or_insert_with(Default::default)
660            .font_family = Some(family_name.into());
661        self
662    }
663
664    fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self {
665        self.text_style()
666            .get_or_insert_with(Default::default)
667            .line_height = Some(line_height.into());
668        self
669    }
670
671    #[cfg(debug_assertions)]
672    fn debug(mut self) -> Self {
673        self.style().debug = Some(true);
674        self
675    }
676
677    #[cfg(debug_assertions)]
678    fn debug_below(mut self) -> Self {
679        self.style().debug_below = Some(true);
680        self
681    }
682}