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 the whitespace of the element to `normal`.
105    /// [Docs](https://tailwindcss.com/docs/whitespace#normal)
106    fn whitespace_normal(mut self) -> Self {
107        self.text_style()
108            .get_or_insert_with(Default::default)
109            .white_space = Some(WhiteSpace::Normal);
110        self
111    }
112
113    /// Sets the whitespace of the element to `nowrap`.
114    /// [Docs](https://tailwindcss.com/docs/whitespace#nowrap)
115    fn whitespace_nowrap(mut self) -> Self {
116        self.text_style()
117            .get_or_insert_with(Default::default)
118            .white_space = Some(WhiteSpace::Nowrap);
119        self
120    }
121
122    /// Sets the flex direction of the element to `column`.
123    /// [Docs](https://tailwindcss.com/docs/flex-direction#column)
124    fn flex_col(mut self) -> Self {
125        self.style().flex_direction = Some(FlexDirection::Column);
126        self
127    }
128
129    /// Sets the flex direction of the element to `row`.
130    /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
131    fn flex_row(mut self) -> Self {
132        self.style().flex_direction = Some(FlexDirection::Row);
133        self
134    }
135
136    /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
137    /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
138    fn flex_1(mut self) -> Self {
139        self.style().flex_grow = Some(1.);
140        self.style().flex_shrink = Some(1.);
141        self.style().flex_basis = Some(relative(0.).into());
142        self
143    }
144
145    /// Sets the element to allow a flex item to grow and shrink, taking into account its initial size.
146    /// [Docs](https://tailwindcss.com/docs/flex#auto)
147    fn flex_auto(mut self) -> Self {
148        self.style().flex_grow = Some(1.);
149        self.style().flex_shrink = Some(1.);
150        self.style().flex_basis = Some(Length::Auto);
151        self
152    }
153
154    /// Sets the element to allow a flex item to shrink but not grow, taking into account its initial size.
155    /// [Docs](https://tailwindcss.com/docs/flex#initial)
156    fn flex_initial(mut self) -> Self {
157        self.style().flex_grow = Some(0.);
158        self.style().flex_shrink = Some(1.);
159        self.style().flex_basis = Some(Length::Auto);
160        self
161    }
162
163    /// Sets the element to prevent a flex item from growing or shrinking.
164    /// [Docs](https://tailwindcss.com/docs/flex#none)
165    fn flex_none(mut self) -> Self {
166        self.style().flex_grow = Some(0.);
167        self.style().flex_shrink = Some(0.);
168        self
169    }
170
171    /// Sets the element to allow a flex item to grow to fill any available space.
172    /// [Docs](https://tailwindcss.com/docs/flex-grow)
173    fn grow(mut self) -> Self {
174        self.style().flex_grow = Some(1.);
175        self
176    }
177
178    /// Sets the element to align flex items to the start of the container's cross axis.
179    /// [Docs](https://tailwindcss.com/docs/align-items#start)
180    fn items_start(mut self) -> Self {
181        self.style().align_items = Some(AlignItems::FlexStart);
182        self
183    }
184
185    /// Sets the element to align flex items to the end of the container's cross axis.
186    /// [Docs](https://tailwindcss.com/docs/align-items#end)
187    fn items_end(mut self) -> Self {
188        self.style().align_items = Some(AlignItems::FlexEnd);
189        self
190    }
191
192    /// Sets the element to align flex items along the center of the container's cross axis.
193    /// [Docs](https://tailwindcss.com/docs/align-items#center)
194    fn items_center(mut self) -> Self {
195        self.style().align_items = Some(AlignItems::Center);
196        self
197    }
198
199    /// Sets the element to justify flex items along the container's main axis
200    /// such that there is an equal amount of space between each item.
201    /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
202    fn justify_between(mut self) -> Self {
203        self.style().justify_content = Some(JustifyContent::SpaceBetween);
204        self
205    }
206
207    /// Sets the element to justify flex items along the center of the container's main axis.
208    /// [Docs](https://tailwindcss.com/docs/justify-content#center)
209    fn justify_center(mut self) -> Self {
210        self.style().justify_content = Some(JustifyContent::Center);
211        self
212    }
213
214    /// Sets the element to justify flex items against the start of the container's main axis.
215    /// [Docs](https://tailwindcss.com/docs/justify-content#start)
216    fn justify_start(mut self) -> Self {
217        self.style().justify_content = Some(JustifyContent::Start);
218        self
219    }
220
221    /// Sets the element to justify flex items against the end of the container's main axis.
222    /// [Docs](https://tailwindcss.com/docs/justify-content#end)
223    fn justify_end(mut self) -> Self {
224        self.style().justify_content = Some(JustifyContent::End);
225        self
226    }
227
228    /// Sets the element to justify items along the container's main axis such
229    /// that there is an equal amount of space on each side of each item.
230    /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
231    fn justify_around(mut self) -> Self {
232        self.style().justify_content = Some(JustifyContent::SpaceAround);
233        self
234    }
235
236    /// Sets the background color of the element.
237    fn bg<F>(mut self, fill: F) -> Self
238    where
239        F: Into<Fill>,
240        Self: Sized,
241    {
242        self.style().background = Some(fill.into());
243        self
244    }
245
246    /// Sets the border color of the element.
247    fn border_color<C>(mut self, border_color: C) -> Self
248    where
249        C: Into<Hsla>,
250        Self: Sized,
251    {
252        self.style().border_color = Some(border_color.into());
253        self
254    }
255
256    /// Sets the box shadow of the element.
257    /// [Docs](https://tailwindcss.com/docs/box-shadow)
258    fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self {
259        self.style().box_shadow = Some(shadows);
260        self
261    }
262
263    /// Clears the box shadow of the element.
264    /// [Docs](https://tailwindcss.com/docs/box-shadow)
265    fn shadow_none(mut self) -> Self {
266        self.style().box_shadow = Some(Default::default());
267        self
268    }
269
270    /// Sets the box shadow of the element.
271    /// [Docs](https://tailwindcss.com/docs/box-shadow)
272    fn shadow_sm(mut self) -> Self {
273        self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
274            color: hsla(0., 0., 0., 0.05),
275            offset: point(px(0.), px(1.)),
276            blur_radius: px(2.),
277            spread_radius: px(0.),
278        }]);
279        self
280    }
281
282    /// Sets the box shadow of the element.
283    /// [Docs](https://tailwindcss.com/docs/box-shadow)
284    fn shadow_md(mut self) -> Self {
285        self.style().box_shadow = Some(smallvec![
286            BoxShadow {
287                color: hsla(0.5, 0., 0., 0.1),
288                offset: point(px(0.), px(4.)),
289                blur_radius: px(6.),
290                spread_radius: px(-1.),
291            },
292            BoxShadow {
293                color: hsla(0., 0., 0., 0.1),
294                offset: point(px(0.), px(2.)),
295                blur_radius: px(4.),
296                spread_radius: px(-2.),
297            }
298        ]);
299        self
300    }
301
302    /// Sets the box shadow of the element.
303    /// [Docs](https://tailwindcss.com/docs/box-shadow)
304    fn shadow_lg(mut self) -> Self {
305        self.style().box_shadow = Some(smallvec![
306            BoxShadow {
307                color: hsla(0., 0., 0., 0.1),
308                offset: point(px(0.), px(10.)),
309                blur_radius: px(15.),
310                spread_radius: px(-3.),
311            },
312            BoxShadow {
313                color: hsla(0., 0., 0., 0.1),
314                offset: point(px(0.), px(4.)),
315                blur_radius: px(6.),
316                spread_radius: px(-4.),
317            }
318        ]);
319        self
320    }
321
322    /// Sets the box shadow of the element.
323    /// [Docs](https://tailwindcss.com/docs/box-shadow)
324    fn shadow_xl(mut self) -> Self {
325        self.style().box_shadow = Some(smallvec![
326            BoxShadow {
327                color: hsla(0., 0., 0., 0.1),
328                offset: point(px(0.), px(20.)),
329                blur_radius: px(25.),
330                spread_radius: px(-5.),
331            },
332            BoxShadow {
333                color: hsla(0., 0., 0., 0.1),
334                offset: point(px(0.), px(8.)),
335                blur_radius: px(10.),
336                spread_radius: px(-6.),
337            }
338        ]);
339        self
340    }
341
342    /// Sets the box shadow of the element.
343    /// [Docs](https://tailwindcss.com/docs/box-shadow)
344    fn shadow_2xl(mut self) -> Self {
345        self.style().box_shadow = Some(smallvec![BoxShadow {
346            color: hsla(0., 0., 0., 0.25),
347            offset: point(px(0.), px(25.)),
348            blur_radius: px(50.),
349            spread_radius: px(-12.),
350        }]);
351        self
352    }
353
354    fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
355        let style: &mut StyleRefinement = self.style();
356        &mut style.text
357    }
358
359    fn text_color(mut self, color: impl Into<Hsla>) -> Self {
360        self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
361        self
362    }
363
364    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
365        self.text_style()
366            .get_or_insert_with(Default::default)
367            .font_size = Some(size.into());
368        self
369    }
370
371    fn text_xs(mut self) -> Self {
372        self.text_style()
373            .get_or_insert_with(Default::default)
374            .font_size = Some(rems(0.75).into());
375        self
376    }
377
378    fn text_sm(mut self) -> Self {
379        self.text_style()
380            .get_or_insert_with(Default::default)
381            .font_size = Some(rems(0.875).into());
382        self
383    }
384
385    fn text_base(mut self) -> Self {
386        self.text_style()
387            .get_or_insert_with(Default::default)
388            .font_size = Some(rems(1.0).into());
389        self
390    }
391
392    fn text_lg(mut self) -> Self {
393        self.text_style()
394            .get_or_insert_with(Default::default)
395            .font_size = Some(rems(1.125).into());
396        self
397    }
398
399    fn text_xl(mut self) -> Self {
400        self.text_style()
401            .get_or_insert_with(Default::default)
402            .font_size = Some(rems(1.25).into());
403        self
404    }
405
406    fn text_2xl(mut self) -> Self {
407        self.text_style()
408            .get_or_insert_with(Default::default)
409            .font_size = Some(rems(1.5).into());
410        self
411    }
412
413    fn text_3xl(mut self) -> Self {
414        self.text_style()
415            .get_or_insert_with(Default::default)
416            .font_size = Some(rems(1.875).into());
417        self
418    }
419
420    fn text_decoration_none(mut self) -> Self {
421        self.text_style()
422            .get_or_insert_with(Default::default)
423            .underline = None;
424        self
425    }
426
427    fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self {
428        let style = self.text_style().get_or_insert_with(Default::default);
429        let underline = style.underline.get_or_insert_with(Default::default);
430        underline.color = Some(color.into());
431        self
432    }
433
434    fn text_decoration_solid(mut self) -> Self {
435        let style = self.text_style().get_or_insert_with(Default::default);
436        let underline = style.underline.get_or_insert_with(Default::default);
437        underline.wavy = false;
438        self
439    }
440
441    fn text_decoration_wavy(mut self) -> Self {
442        let style = self.text_style().get_or_insert_with(Default::default);
443        let underline = style.underline.get_or_insert_with(Default::default);
444        underline.wavy = true;
445        self
446    }
447
448    fn text_decoration_0(mut self) -> Self {
449        let style = self.text_style().get_or_insert_with(Default::default);
450        let underline = style.underline.get_or_insert_with(Default::default);
451        underline.thickness = px(0.);
452        self
453    }
454
455    fn text_decoration_1(mut self) -> Self {
456        let style = self.text_style().get_or_insert_with(Default::default);
457        let underline = style.underline.get_or_insert_with(Default::default);
458        underline.thickness = px(1.);
459        self
460    }
461
462    fn text_decoration_2(mut self) -> Self {
463        let style = self.text_style().get_or_insert_with(Default::default);
464        let underline = style.underline.get_or_insert_with(Default::default);
465        underline.thickness = px(2.);
466        self
467    }
468
469    fn text_decoration_4(mut self) -> Self {
470        let style = self.text_style().get_or_insert_with(Default::default);
471        let underline = style.underline.get_or_insert_with(Default::default);
472        underline.thickness = px(4.);
473        self
474    }
475
476    fn text_decoration_8(mut self) -> Self {
477        let style = self.text_style().get_or_insert_with(Default::default);
478        let underline = style.underline.get_or_insert_with(Default::default);
479        underline.thickness = px(8.);
480        self
481    }
482
483    fn font(mut self, family_name: impl Into<SharedString>) -> Self {
484        self.text_style()
485            .get_or_insert_with(Default::default)
486            .font_family = Some(family_name.into());
487        self
488    }
489
490    fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self {
491        self.text_style()
492            .get_or_insert_with(Default::default)
493            .line_height = Some(line_height.into());
494        self
495    }
496}