styled.rs

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