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