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