styled.rs

  1use crate::{
  2    self as gpui, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, CursorStyle,
  3    DefiniteLength, Display, Fill, FlexDirection, FontWeight, Hsla, JustifyContent, Length,
  4    Position, 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    /// 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 element to allow a flex item to grow to fill any available space.
311    /// [Docs](https://tailwindcss.com/docs/flex-grow)
312    fn flex_grow(mut self) -> Self {
313        self.style().flex_grow = Some(1.);
314        self
315    }
316
317    /// Sets the element to align flex items to the start of the container's cross axis.
318    /// [Docs](https://tailwindcss.com/docs/align-items#start)
319    fn items_start(mut self) -> Self {
320        self.style().align_items = Some(AlignItems::FlexStart);
321        self
322    }
323
324    /// Sets the element to align flex items to the end of the container's cross axis.
325    /// [Docs](https://tailwindcss.com/docs/align-items#end)
326    fn items_end(mut self) -> Self {
327        self.style().align_items = Some(AlignItems::FlexEnd);
328        self
329    }
330
331    /// Sets the element to align flex items along the center of the container's cross axis.
332    /// [Docs](https://tailwindcss.com/docs/align-items#center)
333    fn items_center(mut self) -> Self {
334        self.style().align_items = Some(AlignItems::Center);
335        self
336    }
337
338    /// Sets the element to justify flex items along the container's main axis
339    /// such that there is an equal amount of space between each item.
340    /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
341    fn justify_between(mut self) -> Self {
342        self.style().justify_content = Some(JustifyContent::SpaceBetween);
343        self
344    }
345
346    /// Sets the element to justify flex items along the center of the container's main axis.
347    /// [Docs](https://tailwindcss.com/docs/justify-content#center)
348    fn justify_center(mut self) -> Self {
349        self.style().justify_content = Some(JustifyContent::Center);
350        self
351    }
352
353    /// Sets the element to justify flex items against the start of the container's main axis.
354    /// [Docs](https://tailwindcss.com/docs/justify-content#start)
355    fn justify_start(mut self) -> Self {
356        self.style().justify_content = Some(JustifyContent::Start);
357        self
358    }
359
360    /// Sets the element to justify flex items against the end of the container's main axis.
361    /// [Docs](https://tailwindcss.com/docs/justify-content#end)
362    fn justify_end(mut self) -> Self {
363        self.style().justify_content = Some(JustifyContent::End);
364        self
365    }
366
367    /// Sets the element to justify items along the container's main axis such
368    /// that there is an equal amount of space on each side of each item.
369    /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
370    fn justify_around(mut self) -> Self {
371        self.style().justify_content = Some(JustifyContent::SpaceAround);
372        self
373    }
374
375    /// Sets the background color of the element.
376    fn bg<F>(mut self, fill: F) -> Self
377    where
378        F: Into<Fill>,
379        Self: Sized,
380    {
381        self.style().background = Some(fill.into());
382        self
383    }
384
385    /// Sets the border color of the element.
386    fn border_color<C>(mut self, border_color: C) -> Self
387    where
388        C: Into<Hsla>,
389        Self: Sized,
390    {
391        self.style().border_color = Some(border_color.into());
392        self
393    }
394
395    /// Sets the box shadow of the element.
396    /// [Docs](https://tailwindcss.com/docs/box-shadow)
397    fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self {
398        self.style().box_shadow = Some(shadows);
399        self
400    }
401
402    /// Clears the box shadow of the element.
403    /// [Docs](https://tailwindcss.com/docs/box-shadow)
404    fn shadow_none(mut self) -> Self {
405        self.style().box_shadow = Some(Default::default());
406        self
407    }
408
409    /// Sets the box shadow of the element.
410    /// [Docs](https://tailwindcss.com/docs/box-shadow)
411    fn shadow_sm(mut self) -> Self {
412        self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
413            color: hsla(0., 0., 0., 0.05),
414            offset: point(px(0.), px(1.)),
415            blur_radius: px(2.),
416            spread_radius: px(0.),
417        }]);
418        self
419    }
420
421    /// Sets the box shadow of the element.
422    /// [Docs](https://tailwindcss.com/docs/box-shadow)
423    fn shadow_md(mut self) -> Self {
424        self.style().box_shadow = Some(smallvec![
425            BoxShadow {
426                color: hsla(0.5, 0., 0., 0.1),
427                offset: point(px(0.), px(4.)),
428                blur_radius: px(6.),
429                spread_radius: px(-1.),
430            },
431            BoxShadow {
432                color: hsla(0., 0., 0., 0.1),
433                offset: point(px(0.), px(2.)),
434                blur_radius: px(4.),
435                spread_radius: px(-2.),
436            }
437        ]);
438        self
439    }
440
441    /// Sets the box shadow of the element.
442    /// [Docs](https://tailwindcss.com/docs/box-shadow)
443    fn shadow_lg(mut self) -> Self {
444        self.style().box_shadow = Some(smallvec![
445            BoxShadow {
446                color: hsla(0., 0., 0., 0.1),
447                offset: point(px(0.), px(10.)),
448                blur_radius: px(15.),
449                spread_radius: px(-3.),
450            },
451            BoxShadow {
452                color: hsla(0., 0., 0., 0.1),
453                offset: point(px(0.), px(4.)),
454                blur_radius: px(6.),
455                spread_radius: px(-4.),
456            }
457        ]);
458        self
459    }
460
461    /// Sets the box shadow of the element.
462    /// [Docs](https://tailwindcss.com/docs/box-shadow)
463    fn shadow_xl(mut self) -> Self {
464        self.style().box_shadow = Some(smallvec![
465            BoxShadow {
466                color: hsla(0., 0., 0., 0.1),
467                offset: point(px(0.), px(20.)),
468                blur_radius: px(25.),
469                spread_radius: px(-5.),
470            },
471            BoxShadow {
472                color: hsla(0., 0., 0., 0.1),
473                offset: point(px(0.), px(8.)),
474                blur_radius: px(10.),
475                spread_radius: px(-6.),
476            }
477        ]);
478        self
479    }
480
481    /// Sets the box shadow of the element.
482    /// [Docs](https://tailwindcss.com/docs/box-shadow)
483    fn shadow_2xl(mut self) -> Self {
484        self.style().box_shadow = Some(smallvec![BoxShadow {
485            color: hsla(0., 0., 0., 0.25),
486            offset: point(px(0.), px(25.)),
487            blur_radius: px(50.),
488            spread_radius: px(-12.),
489        }]);
490        self
491    }
492
493    fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
494        let style: &mut StyleRefinement = self.style();
495        &mut style.text
496    }
497
498    fn text_color(mut self, color: impl Into<Hsla>) -> Self {
499        self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
500        self
501    }
502
503    fn font_weight(mut self, weight: FontWeight) -> Self {
504        self.text_style()
505            .get_or_insert_with(Default::default)
506            .font_weight = Some(weight);
507        self
508    }
509
510    fn text_bg(mut self, bg: impl Into<Hsla>) -> Self {
511        self.text_style()
512            .get_or_insert_with(Default::default)
513            .background_color = Some(bg.into());
514        self
515    }
516
517    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
518        self.text_style()
519            .get_or_insert_with(Default::default)
520            .font_size = Some(size.into());
521        self
522    }
523
524    fn text_xs(mut self) -> Self {
525        self.text_style()
526            .get_or_insert_with(Default::default)
527            .font_size = Some(rems(0.75).into());
528        self
529    }
530
531    fn text_sm(mut self) -> Self {
532        self.text_style()
533            .get_or_insert_with(Default::default)
534            .font_size = Some(rems(0.875).into());
535        self
536    }
537
538    fn text_base(mut self) -> Self {
539        self.text_style()
540            .get_or_insert_with(Default::default)
541            .font_size = Some(rems(1.0).into());
542        self
543    }
544
545    fn text_lg(mut self) -> Self {
546        self.text_style()
547            .get_or_insert_with(Default::default)
548            .font_size = Some(rems(1.125).into());
549        self
550    }
551
552    fn text_xl(mut self) -> Self {
553        self.text_style()
554            .get_or_insert_with(Default::default)
555            .font_size = Some(rems(1.25).into());
556        self
557    }
558
559    fn text_2xl(mut self) -> Self {
560        self.text_style()
561            .get_or_insert_with(Default::default)
562            .font_size = Some(rems(1.5).into());
563        self
564    }
565
566    fn text_3xl(mut self) -> Self {
567        self.text_style()
568            .get_or_insert_with(Default::default)
569            .font_size = Some(rems(1.875).into());
570        self
571    }
572
573    fn text_decoration_none(mut self) -> Self {
574        self.text_style()
575            .get_or_insert_with(Default::default)
576            .underline = None;
577        self
578    }
579
580    fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self {
581        let style = self.text_style().get_or_insert_with(Default::default);
582        let underline = style.underline.get_or_insert_with(Default::default);
583        underline.color = Some(color.into());
584        self
585    }
586
587    fn text_decoration_solid(mut self) -> Self {
588        let style = self.text_style().get_or_insert_with(Default::default);
589        let underline = style.underline.get_or_insert_with(Default::default);
590        underline.wavy = false;
591        self
592    }
593
594    fn text_decoration_wavy(mut self) -> Self {
595        let style = self.text_style().get_or_insert_with(Default::default);
596        let underline = style.underline.get_or_insert_with(Default::default);
597        underline.wavy = true;
598        self
599    }
600
601    fn text_decoration_0(mut self) -> 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.thickness = px(0.);
605        self
606    }
607
608    fn text_decoration_1(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.thickness = px(1.);
612        self
613    }
614
615    fn text_decoration_2(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.thickness = px(2.);
619        self
620    }
621
622    fn text_decoration_4(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(4.);
626        self
627    }
628
629    fn text_decoration_8(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(8.);
633        self
634    }
635
636    fn font(mut self, family_name: impl Into<SharedString>) -> Self {
637        self.text_style()
638            .get_or_insert_with(Default::default)
639            .font_family = Some(family_name.into());
640        self
641    }
642
643    fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self {
644        self.text_style()
645            .get_or_insert_with(Default::default)
646            .line_height = Some(line_height.into());
647        self
648    }
649
650    #[cfg(debug_assertions)]
651    fn debug(mut self) -> Self {
652        self.style().debug = Some(true);
653        self
654    }
655
656    #[cfg(debug_assertions)]
657    fn debug_below(mut self) -> Self {
658        self.style().debug_below = Some(true);
659        self
660    }
661}