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;
  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) -> Self
299    where
300        Self: Sized,
301    {
302        self.style().box_shadow = Some(smallvec![
303            BoxShadow {
304                color: hsla(0., 0., 0., 0.1),
305                offset: point(px(0.), px(1.)),
306                blur_radius: px(3.),
307                spread_radius: px(0.),
308            },
309            BoxShadow {
310                color: hsla(0., 0., 0., 0.1),
311                offset: point(px(0.), px(1.)),
312                blur_radius: px(2.),
313                spread_radius: px(-1.),
314            }
315        ]);
316        self
317    }
318
319    /// Clears the box shadow of the element.
320    /// [Docs](https://tailwindcss.com/docs/box-shadow)
321    fn shadow_none(mut self) -> Self
322    where
323        Self: Sized,
324    {
325        self.style().box_shadow = Some(Default::default());
326        self
327    }
328
329    /// Sets the box shadow of the element.
330    /// [Docs](https://tailwindcss.com/docs/box-shadow)
331    fn shadow_sm(mut self) -> Self
332    where
333        Self: Sized,
334    {
335        self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
336            color: hsla(0., 0., 0., 0.05),
337            offset: point(px(0.), px(1.)),
338            blur_radius: px(2.),
339            spread_radius: px(0.),
340        }]);
341        self
342    }
343
344    /// Sets the box shadow of the element.
345    /// [Docs](https://tailwindcss.com/docs/box-shadow)
346    fn shadow_md(mut self) -> Self
347    where
348        Self: Sized,
349    {
350        self.style().box_shadow = Some(smallvec![
351            BoxShadow {
352                color: hsla(0.5, 0., 0., 0.1),
353                offset: point(px(0.), px(4.)),
354                blur_radius: px(6.),
355                spread_radius: px(-1.),
356            },
357            BoxShadow {
358                color: hsla(0., 0., 0., 0.1),
359                offset: point(px(0.), px(2.)),
360                blur_radius: px(4.),
361                spread_radius: px(-2.),
362            }
363        ]);
364        self
365    }
366
367    /// Sets the box shadow of the element.
368    /// [Docs](https://tailwindcss.com/docs/box-shadow)
369    fn shadow_lg(mut self) -> Self
370    where
371        Self: Sized,
372    {
373        self.style().box_shadow = Some(smallvec![
374            BoxShadow {
375                color: hsla(0., 0., 0., 0.1),
376                offset: point(px(0.), px(10.)),
377                blur_radius: px(15.),
378                spread_radius: px(-3.),
379            },
380            BoxShadow {
381                color: hsla(0., 0., 0., 0.1),
382                offset: point(px(0.), px(4.)),
383                blur_radius: px(6.),
384                spread_radius: px(-4.),
385            }
386        ]);
387        self
388    }
389
390    /// Sets the box shadow of the element.
391    /// [Docs](https://tailwindcss.com/docs/box-shadow)
392    fn shadow_xl(mut self) -> Self
393    where
394        Self: Sized,
395    {
396        self.style().box_shadow = Some(smallvec![
397            BoxShadow {
398                color: hsla(0., 0., 0., 0.1),
399                offset: point(px(0.), px(20.)),
400                blur_radius: px(25.),
401                spread_radius: px(-5.),
402            },
403            BoxShadow {
404                color: hsla(0., 0., 0., 0.1),
405                offset: point(px(0.), px(8.)),
406                blur_radius: px(10.),
407                spread_radius: px(-6.),
408            }
409        ]);
410        self
411    }
412
413    /// Sets the box shadow of the element.
414    /// [Docs](https://tailwindcss.com/docs/box-shadow)
415    fn shadow_2xl(mut self) -> Self
416    where
417        Self: Sized,
418    {
419        self.style().box_shadow = Some(smallvec![BoxShadow {
420            color: hsla(0., 0., 0., 0.25),
421            offset: point(px(0.), px(25.)),
422            blur_radius: px(50.),
423            spread_radius: px(-12.),
424        }]);
425        self
426    }
427
428    fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
429        let style: &mut StyleRefinement = self.style();
430        &mut style.text
431    }
432
433    fn text_color(mut self, color: impl Into<Hsla>) -> Self
434    where
435        Self: Sized,
436    {
437        self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
438        self
439    }
440
441    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self
442    where
443        Self: Sized,
444    {
445        self.text_style()
446            .get_or_insert_with(Default::default)
447            .font_size = Some(size.into());
448        self
449    }
450
451    fn text_xs(mut self) -> Self
452    where
453        Self: Sized,
454    {
455        self.text_style()
456            .get_or_insert_with(Default::default)
457            .font_size = Some(rems(0.75).into());
458        self
459    }
460
461    fn text_sm(mut self) -> Self
462    where
463        Self: Sized,
464    {
465        self.text_style()
466            .get_or_insert_with(Default::default)
467            .font_size = Some(rems(0.875).into());
468        self
469    }
470
471    fn text_base(mut self) -> Self
472    where
473        Self: Sized,
474    {
475        self.text_style()
476            .get_or_insert_with(Default::default)
477            .font_size = Some(rems(1.0).into());
478        self
479    }
480
481    fn text_lg(mut self) -> Self
482    where
483        Self: Sized,
484    {
485        self.text_style()
486            .get_or_insert_with(Default::default)
487            .font_size = Some(rems(1.125).into());
488        self
489    }
490
491    fn text_xl(mut self) -> Self
492    where
493        Self: Sized,
494    {
495        self.text_style()
496            .get_or_insert_with(Default::default)
497            .font_size = Some(rems(1.25).into());
498        self
499    }
500
501    fn text_2xl(mut self) -> Self
502    where
503        Self: Sized,
504    {
505        self.text_style()
506            .get_or_insert_with(Default::default)
507            .font_size = Some(rems(1.5).into());
508        self
509    }
510
511    fn text_3xl(mut self) -> Self
512    where
513        Self: Sized,
514    {
515        self.text_style()
516            .get_or_insert_with(Default::default)
517            .font_size = Some(rems(1.875).into());
518        self
519    }
520
521    fn text_decoration_none(mut self) -> Self
522    where
523        Self: Sized,
524    {
525        self.text_style()
526            .get_or_insert_with(Default::default)
527            .underline = None;
528        self
529    }
530
531    fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self
532    where
533        Self: Sized,
534    {
535        let style = self.text_style().get_or_insert_with(Default::default);
536        let underline = style.underline.get_or_insert_with(Default::default);
537        underline.color = Some(color.into());
538        self
539    }
540
541    fn text_decoration_solid(mut self) -> Self
542    where
543        Self: Sized,
544    {
545        let style = self.text_style().get_or_insert_with(Default::default);
546        let underline = style.underline.get_or_insert_with(Default::default);
547        underline.wavy = false;
548        self
549    }
550
551    fn text_decoration_wavy(mut self) -> Self
552    where
553        Self: Sized,
554    {
555        let style = self.text_style().get_or_insert_with(Default::default);
556        let underline = style.underline.get_or_insert_with(Default::default);
557        underline.wavy = true;
558        self
559    }
560
561    fn text_decoration_0(mut self) -> Self
562    where
563        Self: Sized,
564    {
565        let style = self.text_style().get_or_insert_with(Default::default);
566        let underline = style.underline.get_or_insert_with(Default::default);
567        underline.thickness = px(0.);
568        self
569    }
570
571    fn text_decoration_1(mut self) -> Self
572    where
573        Self: Sized,
574    {
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(1.);
578        self
579    }
580
581    fn text_decoration_2(mut self) -> Self
582    where
583        Self: Sized,
584    {
585        let style = self.text_style().get_or_insert_with(Default::default);
586        let underline = style.underline.get_or_insert_with(Default::default);
587        underline.thickness = px(2.);
588        self
589    }
590
591    fn text_decoration_4(mut self) -> Self
592    where
593        Self: Sized,
594    {
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.thickness = px(4.);
598        self
599    }
600
601    fn text_decoration_8(mut self) -> Self
602    where
603        Self: Sized,
604    {
605        let style = self.text_style().get_or_insert_with(Default::default);
606        let underline = style.underline.get_or_insert_with(Default::default);
607        underline.thickness = px(8.);
608        self
609    }
610
611    fn font(mut self, family_name: impl Into<SharedString>) -> Self
612    where
613        Self: Sized,
614    {
615        self.text_style()
616            .get_or_insert_with(Default::default)
617            .font_family = Some(family_name.into());
618        self
619    }
620
621    fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self
622    where
623        Self: Sized,
624    {
625        self.text_style()
626            .get_or_insert_with(Default::default)
627            .line_height = Some(line_height.into());
628        self
629    }
630}