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    gpui2_macros::style_helpers!();
 14
 15    fn z_index(mut self, z_index: u32) -> 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 `row`.
249    /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
250    fn flex_row(mut self) -> Self {
251        self.style().flex_direction = Some(FlexDirection::Row);
252        self
253    }
254
255    /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
256    /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
257    fn flex_1(mut self) -> Self {
258        self.style().flex_grow = Some(1.);
259        self.style().flex_shrink = Some(1.);
260        self.style().flex_basis = Some(relative(0.).into());
261        self
262    }
263
264    /// Sets the element to allow a flex item to grow and shrink, taking into account its initial size.
265    /// [Docs](https://tailwindcss.com/docs/flex#auto)
266    fn flex_auto(mut self) -> Self {
267        self.style().flex_grow = Some(1.);
268        self.style().flex_shrink = Some(1.);
269        self.style().flex_basis = Some(Length::Auto);
270        self
271    }
272
273    /// Sets the element to allow a flex item to shrink but not grow, taking into account its initial size.
274    /// [Docs](https://tailwindcss.com/docs/flex#initial)
275    fn flex_initial(mut self) -> Self {
276        self.style().flex_grow = Some(0.);
277        self.style().flex_shrink = Some(1.);
278        self.style().flex_basis = Some(Length::Auto);
279        self
280    }
281
282    /// Sets the element to prevent a flex item from growing or shrinking.
283    /// [Docs](https://tailwindcss.com/docs/flex#none)
284    fn flex_none(mut self) -> Self {
285        self.style().flex_grow = Some(0.);
286        self.style().flex_shrink = Some(0.);
287        self
288    }
289
290    /// Sets the element to allow a flex item to grow to fill any available space.
291    /// [Docs](https://tailwindcss.com/docs/flex-grow)
292    fn grow(mut self) -> Self {
293        self.style().flex_grow = Some(1.);
294        self
295    }
296
297    /// Sets the element to align flex items to the start of the container's cross axis.
298    /// [Docs](https://tailwindcss.com/docs/align-items#start)
299    fn items_start(mut self) -> Self {
300        self.style().align_items = Some(AlignItems::FlexStart);
301        self
302    }
303
304    /// Sets the element to align flex items to the end of the container's cross axis.
305    /// [Docs](https://tailwindcss.com/docs/align-items#end)
306    fn items_end(mut self) -> Self {
307        self.style().align_items = Some(AlignItems::FlexEnd);
308        self
309    }
310
311    /// Sets the element to align flex items along the center of the container's cross axis.
312    /// [Docs](https://tailwindcss.com/docs/align-items#center)
313    fn items_center(mut self) -> Self {
314        self.style().align_items = Some(AlignItems::Center);
315        self
316    }
317
318    /// Sets the element to justify flex items along the container's main axis
319    /// such that there is an equal amount of space between each item.
320    /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
321    fn justify_between(mut self) -> Self {
322        self.style().justify_content = Some(JustifyContent::SpaceBetween);
323        self
324    }
325
326    /// Sets the element to justify flex items along the center of the container's main axis.
327    /// [Docs](https://tailwindcss.com/docs/justify-content#center)
328    fn justify_center(mut self) -> Self {
329        self.style().justify_content = Some(JustifyContent::Center);
330        self
331    }
332
333    /// Sets the element to justify flex items against the start of the container's main axis.
334    /// [Docs](https://tailwindcss.com/docs/justify-content#start)
335    fn justify_start(mut self) -> Self {
336        self.style().justify_content = Some(JustifyContent::Start);
337        self
338    }
339
340    /// Sets the element to justify flex items against the end of the container's main axis.
341    /// [Docs](https://tailwindcss.com/docs/justify-content#end)
342    fn justify_end(mut self) -> Self {
343        self.style().justify_content = Some(JustifyContent::End);
344        self
345    }
346
347    /// Sets the element to justify items along the container's main axis such
348    /// that there is an equal amount of space on each side of each item.
349    /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
350    fn justify_around(mut self) -> Self {
351        self.style().justify_content = Some(JustifyContent::SpaceAround);
352        self
353    }
354
355    /// Sets the background color of the element.
356    fn bg<F>(mut self, fill: F) -> Self
357    where
358        F: Into<Fill>,
359        Self: Sized,
360    {
361        self.style().background = Some(fill.into());
362        self
363    }
364
365    /// Sets the border color of the element.
366    fn border_color<C>(mut self, border_color: C) -> Self
367    where
368        C: Into<Hsla>,
369        Self: Sized,
370    {
371        self.style().border_color = Some(border_color.into());
372        self
373    }
374
375    /// Sets the box shadow of the element.
376    /// [Docs](https://tailwindcss.com/docs/box-shadow)
377    fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self {
378        self.style().box_shadow = Some(shadows);
379        self
380    }
381
382    /// Clears the box shadow of the element.
383    /// [Docs](https://tailwindcss.com/docs/box-shadow)
384    fn shadow_none(mut self) -> Self {
385        self.style().box_shadow = Some(Default::default());
386        self
387    }
388
389    /// Sets the box shadow of the element.
390    /// [Docs](https://tailwindcss.com/docs/box-shadow)
391    fn shadow_sm(mut self) -> Self {
392        self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
393            color: hsla(0., 0., 0., 0.05),
394            offset: point(px(0.), px(1.)),
395            blur_radius: px(2.),
396            spread_radius: px(0.),
397        }]);
398        self
399    }
400
401    /// Sets the box shadow of the element.
402    /// [Docs](https://tailwindcss.com/docs/box-shadow)
403    fn shadow_md(mut self) -> Self {
404        self.style().box_shadow = Some(smallvec![
405            BoxShadow {
406                color: hsla(0.5, 0., 0., 0.1),
407                offset: point(px(0.), px(4.)),
408                blur_radius: px(6.),
409                spread_radius: px(-1.),
410            },
411            BoxShadow {
412                color: hsla(0., 0., 0., 0.1),
413                offset: point(px(0.), px(2.)),
414                blur_radius: px(4.),
415                spread_radius: px(-2.),
416            }
417        ]);
418        self
419    }
420
421    /// Sets the box shadow of the element.
422    /// [Docs](https://tailwindcss.com/docs/box-shadow)
423    fn shadow_lg(mut self) -> Self {
424        self.style().box_shadow = Some(smallvec![
425            BoxShadow {
426                color: hsla(0., 0., 0., 0.1),
427                offset: point(px(0.), px(10.)),
428                blur_radius: px(15.),
429                spread_radius: px(-3.),
430            },
431            BoxShadow {
432                color: hsla(0., 0., 0., 0.1),
433                offset: point(px(0.), px(4.)),
434                blur_radius: px(6.),
435                spread_radius: px(-4.),
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_xl(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(20.)),
448                blur_radius: px(25.),
449                spread_radius: px(-5.),
450            },
451            BoxShadow {
452                color: hsla(0., 0., 0., 0.1),
453                offset: point(px(0.), px(8.)),
454                blur_radius: px(10.),
455                spread_radius: px(-6.),
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_2xl(mut self) -> Self {
464        self.style().box_shadow = Some(smallvec![BoxShadow {
465            color: hsla(0., 0., 0., 0.25),
466            offset: point(px(0.), px(25.)),
467            blur_radius: px(50.),
468            spread_radius: px(-12.),
469        }]);
470        self
471    }
472
473    fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
474        let style: &mut StyleRefinement = self.style();
475        &mut style.text
476    }
477
478    fn text_color(mut self, color: impl Into<Hsla>) -> Self {
479        self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
480        self
481    }
482
483    fn text_bg(mut self, bg: impl Into<Hsla>) -> Self {
484        self.text_style()
485            .get_or_insert_with(Default::default)
486            .background_color = Some(bg.into());
487        self
488    }
489
490    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
491        self.text_style()
492            .get_or_insert_with(Default::default)
493            .font_size = Some(size.into());
494        self
495    }
496
497    fn text_xs(mut self) -> Self {
498        self.text_style()
499            .get_or_insert_with(Default::default)
500            .font_size = Some(rems(0.75).into());
501        self
502    }
503
504    fn text_sm(mut self) -> Self {
505        self.text_style()
506            .get_or_insert_with(Default::default)
507            .font_size = Some(rems(0.875).into());
508        self
509    }
510
511    fn text_base(mut self) -> Self {
512        self.text_style()
513            .get_or_insert_with(Default::default)
514            .font_size = Some(rems(1.0).into());
515        self
516    }
517
518    fn text_lg(mut self) -> Self {
519        self.text_style()
520            .get_or_insert_with(Default::default)
521            .font_size = Some(rems(1.125).into());
522        self
523    }
524
525    fn text_xl(mut self) -> Self {
526        self.text_style()
527            .get_or_insert_with(Default::default)
528            .font_size = Some(rems(1.25).into());
529        self
530    }
531
532    fn text_2xl(mut self) -> Self {
533        self.text_style()
534            .get_or_insert_with(Default::default)
535            .font_size = Some(rems(1.5).into());
536        self
537    }
538
539    fn text_3xl(mut self) -> Self {
540        self.text_style()
541            .get_or_insert_with(Default::default)
542            .font_size = Some(rems(1.875).into());
543        self
544    }
545
546    fn text_decoration_none(mut self) -> Self {
547        self.text_style()
548            .get_or_insert_with(Default::default)
549            .underline = None;
550        self
551    }
552
553    fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self {
554        let style = self.text_style().get_or_insert_with(Default::default);
555        let underline = style.underline.get_or_insert_with(Default::default);
556        underline.color = Some(color.into());
557        self
558    }
559
560    fn text_decoration_solid(mut self) -> Self {
561        let style = self.text_style().get_or_insert_with(Default::default);
562        let underline = style.underline.get_or_insert_with(Default::default);
563        underline.wavy = false;
564        self
565    }
566
567    fn text_decoration_wavy(mut self) -> 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.wavy = true;
571        self
572    }
573
574    fn text_decoration_0(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.thickness = px(0.);
578        self
579    }
580
581    fn text_decoration_1(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.thickness = px(1.);
585        self
586    }
587
588    fn text_decoration_2(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(2.);
592        self
593    }
594
595    fn text_decoration_4(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(4.);
599        self
600    }
601
602    fn text_decoration_8(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(8.);
606        self
607    }
608
609    fn font(mut self, family_name: impl Into<SharedString>) -> Self {
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        self.text_style()
618            .get_or_insert_with(Default::default)
619            .line_height = Some(line_height.into());
620        self
621    }
622}