Skip to main content

gpui/
styled.rs

1use crate::{
2    self as gpui, AbsoluteLength, AlignContent, AlignItems, AlignSelf, BorderStyle, CursorStyle,
3    DefiniteLength, Display, Edges, Fill, Filter, FlexDirection, FlexWrap, Font, FontFeatures,
4    FontStyle, FontWeight, FontWidth, GridPlacement, GridTemplate, GridTemplateMinSize,
5    JustifyContent, LayoutDirection, Length, Pixels, SharedString, StrikethroughStyle,
6    StyleRefinement, TextAlign, TextOverflow, TextStyleRefinement, TextTransform, UnderlineStyle,
7    UnicodeBidi, VerticalAlign, WhiteSpace, px, relative, rems,
8};
9pub use gpui_macros::{
10    border_style_methods, box_shadow_style_methods, cursor_style_methods, margin_style_methods,
11    overflow_style_methods, padding_style_methods, position_style_methods,
12    visibility_style_methods,
13};
14use palette::{Hsla, IntoColor};
15use refineable::Refineable;
16const ELLIPSIS: SharedString = SharedString::new_static("…");
17
18/// Sets an element's layout, paint and text properties.
19///
20/// Import the prelude to style an element with method calls. Setters return `Self`, allowing
21/// several choices in one expression. This card uses a column flex layout, padding, rounded
22/// corners and a shadow:
23///
24/// ```
25/// use gpui::{Display, div, prelude::*, rgb};
26///
27/// let mut card = div()
28///     .flex()
29///     .flex_col()
30///     .gap_2()
31///     .p_4()
32///     .rounded_lg()
33///     .bg(rgb(0xffffff))
34///     .shadow_md();
35///
36/// assert_eq!(card.style().display, Some(Display::Flex));
37/// ```
38///
39/// Each call writes to the element's [`StyleRefinement`]. Unset properties fall back to
40/// [`Style`](crate::Style)'s defaults. Setting the same property again normally replaces its
41/// earlier value; an additive setter such as [`Styled::blur`] documents its exception.
42/// Interaction styles use refinements too: [`hover`](crate::InteractiveElement::hover) passes
43/// an empty refinement to a closure, where these methods describe the changes for that state.
44///
45/// Setters record a request rather than measuring the element. Layout resolves `size`,
46/// `min_size`, `max_size` and percentages within the containing layout; painting then uses
47/// the resulting bounds. The [layout and style concept](crate::_documentation::concepts::layout_and_style)
48/// explains why a requested size can differ from the final size.
49///
50/// # Naming scale
51///
52/// Names generally follow Tailwind CSS. Spacing, sizing and radius suffixes use a quarter-rem
53/// scale: `p_4` is 1rem of padding, and `gap_2` is a 0.5rem gap. At the default 16px root size,
54/// those lengths are 16px and 8px. The common steps are:
55///
56/// | Suffix | Length | Pixels at the default rem size |
57/// | --- | --- | --- |
58/// | `0` | `0` | 0px |
59/// | `0p5` | `0.125rem` | 2px |
60/// | `1` | `0.25rem` | 4px |
61/// | `2` | `0.5rem` | 8px |
62/// | `4` | `1rem` | 16px |
63/// | `8` | `2rem` | 32px |
64/// | `16` | `4rem` | 64px |
65/// | `px` | `1px` | 1px |
66///
67/// A `p` inside a number denotes a decimal point: `p_1p5` is `0.375rem`. Fraction suffixes
68/// such as `_1_2` and `_1_3` use a percentage of the containing layout size on that axis.
69/// `full` means 100% for a size or the largest radius for a corner. Where allowed, `auto`
70/// leaves the choice to layout. Each method lists its available values.
71///
72/// Font sizes have their own scale, from [`Styled::text_xs`] (`0.75rem`) to
73/// [`Styled::text_3xl`] (`1.875rem`). For instance, `text_sm` is `0.875rem`, or 14px at the
74/// default root size. [`Window::set_rem_size`](crate::Window::set_rem_size) changes that
75/// root, scaling both these fonts and rem-based spacing.
76// Avoid expanding the large reflection macro while rust-analyzer indexes this trait.
77#[cfg_attr(
78    all(any(feature = "inspector", debug_assertions), not(rust_analyzer)),
79    gpui_macros::derive_inspector_reflection
80)]
81pub trait Styled: Sized {
82    /// Returns the [`StyleRefinement`] that the methods on this trait write into.
83    ///
84    /// Use this when you need to set a property that has no dedicated method. Each element stores its
85    /// own refinement, so changes here affect only this element. The refinement is merged over
86    /// [`Style`](crate::Style)'s defaults when the element is laid out and painted; an unset field does
87    /// not clear the corresponding default.
88    fn style(&mut self) -> &mut StyleRefinement;
89
90    /// Applies every property set in `refinement` to this element's style.
91    ///
92    /// Unset properties keep their current values. Nested refinements merge field by field too:
93    /// setting a text color does not clear the font weight. Apply shared styles first and specific
94    /// overrides afterward so the latter values win.
95    fn refine_style(mut self, refinement: &StyleRefinement) -> Self {
96        self.style().refine(refinement);
97
98        self
99    }
100
101    gpui_macros::style_helpers!();
102    gpui_macros::visibility_style_methods!();
103    gpui_macros::margin_style_methods!();
104    gpui_macros::padding_style_methods!();
105    gpui_macros::position_style_methods!();
106    gpui_macros::overflow_style_methods!();
107    gpui_macros::cursor_style_methods!();
108    gpui_macros::border_style_methods!();
109    gpui_macros::box_shadow_style_methods!();
110
111    /// Sets the inline direction of this element and its logical descendants.
112    ///
113    /// The direction is inherited by descendants and is used by logical inline-start/end layout. It
114    /// does not rewrite physical `left` and `right` properties. Prefer [`Styled::rtl`] or
115    /// [`Styled::ltr`] unless you need to pass a runtime [`LayoutDirection`].
116    fn direction(mut self, direction: LayoutDirection) -> Self {
117        self.style().direction = Some(direction);
118
119        self
120    }
121
122    /// Lays out this element and its logical descendants right to left.
123    ///
124    /// Use it for right-to-left languages such as Arabic and Hebrew. Descendants inherit this
125    /// direction until they set another one; physical left/right properties keep their physical
126    /// meaning. See the [layout and style](crate::_documentation::concepts::layout_and_style) page.
127    fn rtl(self) -> Self {
128        self.direction(LayoutDirection::RightToLeft)
129    }
130
131    /// Lays out this element and its logical descendants left to right.
132    ///
133    /// Use it to restore left-to-right layout inside an element that is set to [`Styled::rtl`].
134    /// Elements otherwise inherit their direction, whose resolved default is left to right.
135    fn ltr(self) -> Self {
136        self.direction(LayoutDirection::LeftToRight)
137    }
138
139    /// Sets how this element's text takes part in the Unicode bidirectional algorithm.
140    ///
141    /// Setting a value marks the property as explicit, so it overrides the default
142    /// behavior that GPUI applies otherwise.
143    fn unicode_bidi(mut self, unicode_bidi: UnicodeBidi) -> Self {
144        let style = self.style();
145        style.unicode_bidi = Some(unicode_bidi);
146        style.unicode_bidi_explicit = Some(true);
147
148        self
149    }
150
151    /// Blurs this element's own content and children, like CSS `filter: blur(<radius>)`.
152    ///
153    /// The radius is in logical pixels. This isolates the element's subtree, blurs it as
154    /// a group, and composites the result back. To blur the content behind the element
155    /// instead, use [`Styled::backdrop_blur`].
156    ///
157    /// This adds to the element's filter chain, so `.blur(8.)` composes with the other filter setters.
158    /// A later [`Styled::filter`] call replaces the chain accumulated so far; call `filter` first if
159    /// you want to append a blur afterward.
160    fn blur(mut self, radius: impl Into<Pixels>) -> Self {
161        self.style()
162            .filter
163            .get_or_insert_with(Vec::new)
164            .push(Filter::Blur(radius.into()));
165        self
166    }
167
168    /// Replaces the list of filters applied to this element's own content, like CSS `filter`.
169    ///
170    /// Any filters set before this call are discarded. To add one filter to the chain,
171    /// use a convenience setter such as [`Styled::blur`].
172    fn filter(mut self, filters: impl Into<Vec<Filter>>) -> Self {
173        self.style().filter = Some(filters.into());
174        self
175    }
176
177    /// Blurs the content behind this element, like CSS `backdrop-filter: blur(<radius>)`.
178    ///
179    /// The radius is in logical pixels. Pair it with a translucent [`Styled::bg`] so the
180    /// background tints the blurred content and the result looks like frosted glass.
181    ///
182    /// This adds to the element's backdrop filter chain. A later [`Styled::backdrop_filter`] call
183    /// replaces the chain accumulated so far; call `backdrop_filter` first if you want to append a
184    /// blur afterward.
185    fn backdrop_blur(mut self, radius: impl Into<Pixels>) -> Self {
186        self.style()
187            .backdrop_filter
188            .get_or_insert_with(Vec::new)
189            .push(Filter::Blur(radius.into()));
190        self
191    }
192
193    /// Replaces the list of filters applied to the content behind this element, like CSS `backdrop-filter`.
194    ///
195    /// Any backdrop filters set before this call are discarded. To add one filter to the
196    /// chain, use a convenience setter such as [`Styled::backdrop_blur`].
197    fn backdrop_filter(mut self, filters: impl Into<Vec<Filter>>) -> Self {
198        self.style().backdrop_filter = Some(filters.into());
199        self
200    }
201
202    /// Sets the display type of this element.
203    ///
204    /// The display type chooses the layout algorithm for the element's children. See
205    /// [`Display`] for the values.
206    fn display(mut self, display: Display) -> Self {
207        self.style().display = Some(display);
208        self
209    }
210
211    /// Sets the display type of this element to `block`.
212    ///
213    /// [Docs](https://tailwindcss.com/docs/display)
214    fn block(self) -> Self {
215        self.display(Display::Block)
216    }
217
218    /// Sets the display type of this element to `flex`.
219    ///
220    /// Its children lay out in a row by default. Use [`Styled::flex_col`] for a column.
221    ///
222    /// [Docs](https://tailwindcss.com/docs/display)
223    fn flex(self) -> Self {
224        self.display(Display::Flex)
225    }
226
227    /// Sets the display type of this element to `grid`.
228    ///
229    /// Children are placed in rows and columns. Choose the column count with
230    /// [`Styled::grid_cols`].
231    ///
232    /// [Docs](https://tailwindcss.com/docs/display)
233    fn grid(self) -> Self {
234        self.display(Display::Grid)
235    }
236
237    /// Places this element in its parent's inline formatting context as an inline box.
238    ///
239    /// Its content participates in the surrounding line layout instead of creating a block box;
240    /// whitespace and line breaks still come from the content and its surrounding layout.
241    fn inline(self) -> Self {
242        self.display(Display::Inline)
243    }
244
245    /// Places this element in its parent's paragraph as one atomic box with flex layout inside.
246    fn inline_flex(self) -> Self {
247        self.display(Display::InlineFlex)
248    }
249
250    /// Sets how this element aligns when it is placed in an inline layout.
251    ///
252    /// Use it for elements that take part in text flow, such as inline boxes inside a
253    /// paragraph. For flex and grid alignment, use [`Styled::items_center`] or
254    /// [`Styled::self_center`].
255    fn vertical_align(mut self, align: VerticalAlign) -> Self {
256        self.style().vertical_align = Some(align);
257        self
258    }
259
260    /// Aligns this inline box with the surrounding text baseline.
261    fn align_baseline(self) -> Self {
262        self.vertical_align(VerticalAlign::Baseline)
263    }
264
265    /// Aligns this inline box's midpoint with the parent baseline plus half its font's x-height.
266    ///
267    /// This is CSS `vertical-align: middle`. For flex or grid centering, use
268    /// [`Styled::self_center`] on the item or [`Styled::items_center`] on its container.
269    fn align_middle(self) -> Self {
270        self.vertical_align(VerticalAlign::Middle)
271    }
272
273    /// Aligns this inline box with the top of its line.
274    fn align_top(self) -> Self {
275        self.vertical_align(VerticalAlign::Top)
276    }
277
278    /// Aligns this inline box with the bottom of its line.
279    fn align_bottom(self) -> Self {
280        self.vertical_align(VerticalAlign::Bottom)
281    }
282
283    /// Sets the display type of this element to `none`, which removes it from layout and painting.
284    ///
285    /// Its children are removed too. Use [`Styled::invisible`] to keep the space the
286    /// element would take.
287    ///
288    /// [Docs](https://tailwindcss.com/docs/display)
289    fn hidden(self) -> Self {
290        self.display(Display::None)
291    }
292
293    /// Sets the space reserved for the scrollbar, in logical pixels or rems.
294    ///
295    /// The space affects layout only when the element's overflow is [`Overflow::Scroll`](crate::Overflow::Scroll).
296    fn scrollbar_width(mut self, width: impl Into<AbsoluteLength>) -> Self {
297        self.style().scrollbar_width = Some(width.into());
298        self
299    }
300
301    /// Fades the content clipped by this element's overflow to transparent at each edge.
302    ///
303    /// Each value is the distance over which the content fades as it approaches the
304    /// corresponding clipped edge, similar to CSS `mask-image: linear-gradient(...)`.
305    /// Use [`Edges`] to set the four edges separately.
306    fn overflow_fade(mut self, fade: impl Into<Edges<AbsoluteLength>>) -> Self {
307        let fade = fade.into();
308        let overflow_fade = &mut self.style().overflow_fade;
309        overflow_fade.top = Some(fade.top);
310        overflow_fade.right = Some(fade.right);
311        overflow_fade.bottom = Some(fade.bottom);
312        overflow_fade.left = Some(fade.left);
313        self
314    }
315
316    /// Fades content at the left and right overflow edges by the same distance.
317    ///
318    /// This clears any fade set on the top and bottom edges.
319    fn overflow_fade_x(self, fade: impl Into<AbsoluteLength>) -> Self {
320        self.overflow_fade(Edges::horizontal(fade.into()))
321    }
322
323    /// Fades content at the top and bottom overflow edges by the same distance.
324    ///
325    /// This clears any fade set on the left and right edges.
326    fn overflow_fade_y(self, fade: impl Into<AbsoluteLength>) -> Self {
327        self.overflow_fade(Edges::vertical(fade.into()))
328    }
329
330    /// Sets how this element's text handles whitespace and wrapping.
331    fn whitespace(mut self, white_space: WhiteSpace) -> Self {
332        self.text_style().white_space = Some(white_space);
333        self
334    }
335
336    /// Sets the whitespace of this element's text to `normal`, so text wraps at the available width.
337    ///
338    /// [Docs](https://tailwindcss.com/docs/whitespace#normal)
339    fn whitespace_normal(mut self) -> Self {
340        self.text_style().white_space = Some(WhiteSpace::Normal);
341        self
342    }
343
344    /// Sets the whitespace of this element's text to `nowrap`, so text stays on one line.
345    ///
346    /// [Docs](https://tailwindcss.com/docs/whitespace#nowrap)
347    fn whitespace_nowrap(mut self) -> Self {
348        self.text_style().white_space = Some(WhiteSpace::Nowrap);
349        self
350    }
351
352    /// Truncates overflowing text with an ellipsis (…) at the end.
353    ///
354    /// This sets the overflow mode; pair it with [`Styled::overflow_hidden`] and
355    /// [`Styled::whitespace_nowrap`] when you want a single clipped line. [`Styled::truncate`]
356    /// applies all three settings.
357    ///
358    /// [Docs](https://tailwindcss.com/docs/text-overflow#ellipsis)
359    fn text_ellipsis(mut self) -> Self {
360        self.text_style().text_overflow = Some(TextOverflow::Truncate(ELLIPSIS));
361        self
362    }
363
364    /// Truncates overflowing text with an ellipsis (…) at the start.
365    ///
366    /// This sets the overflow mode; pair it with [`Styled::overflow_hidden`] and
367    /// [`Styled::whitespace_nowrap`] when you want a single clipped line. Use it for file paths,
368    /// where the end matters more than the beginning.
369    /// This doesn't exist in Tailwind CSS.
370    fn text_ellipsis_start(mut self) -> Self {
371        self.text_style().text_overflow = Some(TextOverflow::TruncateStart(ELLIPSIS));
372        self
373    }
374
375    /// Truncates overflowing text with an ellipsis (…) in the middle.
376    ///
377    /// The beginning and end of the text stay visible. Pair it with
378    /// [`Styled::overflow_hidden`] and [`Styled::whitespace_nowrap`] for a single clipped line.
379    /// It is useful for file names.
380    /// This doesn't exist in Tailwind CSS.
381    fn text_ellipsis_middle(mut self) -> Self {
382        self.text_style().text_overflow = Some(TextOverflow::TruncateMiddle(ELLIPSIS));
383        self
384    }
385
386    /// Sets how this element's text is truncated when it overflows.
387    ///
388    /// See [`TextOverflow`] for the values.
389    fn text_overflow(mut self, overflow: TextOverflow) -> Self {
390        self.text_style().text_overflow = Some(overflow);
391        self
392    }
393
394    /// Sets the horizontal alignment of this element's text.
395    fn text_align(mut self, align: TextAlign) -> Self {
396        self.text_style().text_align = Some(align);
397        self
398    }
399
400    /// Aligns text to the start edge of each line, which is the left edge in left-to-right text.
401    fn text_start(self) -> Self {
402        self.text_align(TextAlign::Start)
403    }
404
405    /// Aligns text to the end edge of each line, which is the right edge in left-to-right text.
406    fn text_end(self) -> Self {
407        self.text_align(TextAlign::End)
408    }
409
410    /// Aligns text to the left edge.
411    fn text_left(mut self) -> Self {
412        self.text_align(TextAlign::Left)
413    }
414
415    /// Centers text horizontally.
416    fn text_center(mut self) -> Self {
417        self.text_align(TextAlign::Center)
418    }
419
420    /// Aligns text to the right edge.
421    fn text_right(mut self) -> Self {
422        self.text_align(TextAlign::Right)
423    }
424
425    /// Sets the space between letters in this element and its children, in logical pixels.
426    fn letter_spacing(mut self, spacing: impl Into<Pixels>) -> Self {
427        self.text_style().letter_spacing = Some(spacing.into());
428        self
429    }
430
431    /// Sets the case transformation for text in this element and its children.
432    fn text_transform(mut self, transform: TextTransform) -> Self {
433        self.text_style().text_transform = Some(transform);
434        self
435    }
436
437    /// Prevents text from wrapping and truncates overflowing text with an ellipsis (…) at the end.
438    ///
439    /// This sets [`Styled::overflow_hidden`], [`Styled::whitespace_nowrap`] and
440    /// [`Styled::text_ellipsis`].
441    ///
442    /// [Docs](https://tailwindcss.com/docs/text-overflow#truncate)
443    fn truncate(mut self) -> Self {
444        self.overflow_hidden().whitespace_nowrap().text_ellipsis()
445    }
446
447    /// Shows at most `lines` lines of text, then truncates the rest.
448    ///
449    /// This also sets [`Styled::overflow_hidden`].
450    ///
451    /// [Docs](https://tailwindcss.com/docs/line-clamp)
452    fn line_clamp(mut self, lines: usize) -> Self {
453        let mut text_style = self.text_style();
454        text_style.line_clamp = Some(lines);
455        self.overflow_hidden()
456    }
457
458    /// Sets the direction in which flex children are placed.
459    ///
460    /// See [`FlexDirection`] for the values. [Docs](https://tailwindcss.com/docs/flex-direction)
461    fn flex_direction(mut self, direction: FlexDirection) -> Self {
462        self.style().flex_direction = Some(direction);
463        self
464    }
465
466    /// Sets the flex direction to `column`, so children stack from top to bottom.
467    ///
468    /// [Docs](https://tailwindcss.com/docs/flex-direction#column)
469    fn flex_col(mut self) -> Self {
470        self.style().flex_direction = Some(FlexDirection::Column);
471        self
472    }
473
474    /// Sets the flex direction to `column-reverse`, so children stack from bottom to top.
475    ///
476    /// [Docs](https://tailwindcss.com/docs/flex-direction#column-reverse)
477    fn flex_col_reverse(mut self) -> Self {
478        self.style().flex_direction = Some(FlexDirection::ColumnReverse);
479        self
480    }
481
482    /// Sets the flex direction to `row`, so children sit left to right.
483    ///
484    /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
485    fn flex_row(mut self) -> Self {
486        self.style().flex_direction = Some(FlexDirection::Row);
487        self
488    }
489
490    /// Sets the flex direction to `row-reverse`, so children sit right to left.
491    ///
492    /// [Docs](https://tailwindcss.com/docs/flex-direction#row-reverse)
493    fn flex_row_reverse(mut self) -> Self {
494        self.style().flex_direction = Some(FlexDirection::RowReverse);
495        self
496    }
497
498    /// Lets a flex child grow and shrink to fill the space, ignoring its initial size.
499    ///
500    /// This sets `flex: 1 1 0%`: grow 1, shrink 1, basis 0. Use it on the child that
501    /// should take up the remaining space.
502    ///
503    /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
504    fn flex_1(mut self) -> Self {
505        self.style().flex_grow = Some(1.);
506        self.style().flex_shrink = Some(1.);
507        self.style().flex_basis = Some(relative(0.).into());
508        self
509    }
510
511    /// Lets a flex child grow and shrink, starting from its natural size.
512    ///
513    /// This sets `flex: 1 1 auto`.
514    ///
515    /// [Docs](https://tailwindcss.com/docs/flex#auto)
516    fn flex_auto(mut self) -> Self {
517        self.style().flex_grow = Some(1.);
518        self.style().flex_shrink = Some(1.);
519        self.style().flex_basis = Some(Length::Auto);
520        self
521    }
522
523    /// Lets a flex child shrink but not grow, starting from its natural size.
524    ///
525    /// This sets `flex: 0 1 auto`.
526    ///
527    /// [Docs](https://tailwindcss.com/docs/flex#initial)
528    fn flex_initial(mut self) -> Self {
529        self.style().flex_grow = Some(0.);
530        self.style().flex_shrink = Some(1.);
531        self.style().flex_basis = Some(Length::Auto);
532        self
533    }
534
535    /// Stops a flex child from growing or shrinking.
536    ///
537    /// This sets `flex: none`, which keeps the child at its natural size.
538    ///
539    /// [Docs](https://tailwindcss.com/docs/flex#none)
540    fn flex_none(mut self) -> Self {
541        self.style().flex_grow = Some(0.);
542        self.style().flex_shrink = Some(0.);
543        self.style().flex_basis = Some(Length::Auto);
544        self
545    }
546
547    /// Sets the starting size of a flex child before it grows or shrinks.
548    ///
549    /// [Docs](https://tailwindcss.com/docs/flex-basis)
550    fn flex_basis(mut self, basis: impl Into<Length>) -> Self {
551        self.style().flex_basis = Some(basis.into());
552        self
553    }
554
555    /// Sets the factor by which a flex child grows to fill spare space.
556    ///
557    /// A child with a factor of 2 takes twice the spare space of a child with 1.
558    ///
559    /// [Docs](https://tailwindcss.com/docs/flex-grow)
560    fn flex_grow(mut self, grow: f32) -> Self {
561        self.style().flex_grow = Some(grow);
562        self
563    }
564
565    /// Stops a flex child from growing.
566    ///
567    /// [Docs](https://tailwindcss.com/docs/flex-grow#dont-grow)
568    fn flex_grow_0(mut self) -> Self {
569        self.style().flex_grow = Some(0.);
570        self
571    }
572
573    /// Lets a flex child grow with a factor of 1.
574    ///
575    /// [Docs](https://tailwindcss.com/docs/flex-grow#grow-1)
576    fn flex_grow_1(mut self) -> Self {
577        self.style().flex_grow = Some(1.);
578        self
579    }
580
581    /// Sets the factor by which a flex child shrinks when space is short.
582    ///
583    /// [Docs](https://tailwindcss.com/docs/flex-shrink)
584    fn flex_shrink(mut self, shrink: f32) -> Self {
585        self.style().flex_shrink = Some(shrink);
586        self
587    }
588
589    /// Prevents this flex child from participating in shrinkage when space is short.
590    ///
591    /// Other constraints, including the child's minimum size, still affect its final size. This
592    /// is the usual fix for a sidebar that gets squeezed by its content area.
593    ///
594    /// [Docs](https://tailwindcss.com/docs/flex-shrink#dont-shrink)
595    fn flex_shrink_0(mut self) -> Self {
596        self.style().flex_shrink = Some(0.);
597        self
598    }
599
600    /// Lets a flex child shrink with a factor of 1.
601    ///
602    /// [Docs](https://tailwindcss.com/docs/flex-shrink#shrink-1)
603    fn flex_shrink_1(mut self) -> Self {
604        self.style().flex_shrink = Some(1.);
605        self
606    }
607
608    /// Lets flex children wrap onto new lines in the normal direction.
609    ///
610    /// [Docs](https://tailwindcss.com/docs/flex-wrap#wrap-normally)
611    fn flex_wrap(mut self) -> Self {
612        self.style().flex_wrap = Some(FlexWrap::Wrap);
613        self
614    }
615
616    /// Lets flex children wrap onto new lines in the reverse direction.
617    ///
618    /// [Docs](https://tailwindcss.com/docs/flex-wrap#wrap-reversed)
619    fn flex_wrap_reverse(mut self) -> Self {
620        self.style().flex_wrap = Some(FlexWrap::WrapReverse);
621        self
622    }
623
624    /// Stops flex children from wrapping. Inflexible children overflow the container instead.
625    ///
626    /// [Docs](https://tailwindcss.com/docs/flex-wrap#dont-wrap)
627    fn flex_nowrap(mut self) -> Self {
628        self.style().flex_wrap = Some(FlexWrap::NoWrap);
629        self
630    }
631
632    /// Aligns flex or grid children to the start of the cross axis.
633    ///
634    /// [Docs](https://tailwindcss.com/docs/align-items#start)
635    fn items_start(mut self) -> Self {
636        self.style().align_items = Some(AlignItems::FlexStart);
637        self
638    }
639
640    /// Aligns flex or grid children to the end of the cross axis.
641    ///
642    /// [Docs](https://tailwindcss.com/docs/align-items#end)
643    fn items_end(mut self) -> Self {
644        self.style().align_items = Some(AlignItems::FlexEnd);
645        self
646    }
647
648    /// Centers flex or grid children along the cross axis.
649    ///
650    /// [Docs](https://tailwindcss.com/docs/align-items#center)
651    fn items_center(mut self) -> Self {
652        self.style().align_items = Some(AlignItems::Center);
653        self
654    }
655
656    /// Aligns flex or grid children on their text baselines along the cross axis.
657    ///
658    /// [Docs](https://tailwindcss.com/docs/align-items#baseline)
659    fn items_baseline(mut self) -> Self {
660        self.style().align_items = Some(AlignItems::Baseline);
661        self
662    }
663
664    /// Stretches flex or grid children to fill the cross axis.
665    ///
666    /// [Docs](https://tailwindcss.com/docs/align-items#stretch)
667    fn items_stretch(mut self) -> Self {
668        self.style().align_items = Some(AlignItems::Stretch);
669        self
670    }
671
672    /// Aligns this flex or grid child to the start of the container's cross axis.
673    ///
674    /// [Docs](https://tailwindcss.com/docs/align-self#start)
675    fn self_start(mut self) -> Self {
676        self.style().align_self = Some(AlignSelf::Start);
677        self
678    }
679
680    /// Aligns this flex or grid child to the end of the container's cross axis.
681    ///
682    /// [Docs](https://tailwindcss.com/docs/align-self#end)
683    fn self_end(mut self) -> Self {
684        self.style().align_self = Some(AlignSelf::End);
685        self
686    }
687
688    /// Aligns this flex child to the flex-relative start of the cross axis.
689    ///
690    /// [Docs](https://tailwindcss.com/docs/align-self#start)
691    fn self_flex_start(mut self) -> Self {
692        self.style().align_self = Some(AlignSelf::FlexStart);
693        self
694    }
695
696    /// Aligns this flex child to the flex-relative end of the cross axis.
697    ///
698    /// [Docs](https://tailwindcss.com/docs/align-self#end)
699    fn self_flex_end(mut self) -> Self {
700        self.style().align_self = Some(AlignSelf::FlexEnd);
701        self
702    }
703
704    /// Centers this flex or grid child along the container's cross axis.
705    ///
706    /// [Docs](https://tailwindcss.com/docs/align-self#center)
707    fn self_center(mut self) -> Self {
708        self.style().align_self = Some(AlignSelf::Center);
709        self
710    }
711
712    /// Aligns this flex or grid child on the container's baseline along the cross axis.
713    ///
714    /// [Docs](https://tailwindcss.com/docs/align-self#baseline)
715    fn self_baseline(mut self) -> Self {
716        self.style().align_self = Some(AlignSelf::Baseline);
717        self
718    }
719
720    /// Stretches this flex or grid child to fill the container's cross axis.
721    ///
722    /// [Docs](https://tailwindcss.com/docs/align-self#stretch)
723    fn self_stretch(mut self) -> Self {
724        self.style().align_self = Some(AlignSelf::Stretch);
725        self
726    }
727
728    /// Packs flex or grid children against the start of the main axis.
729    ///
730    /// [Docs](https://tailwindcss.com/docs/justify-content#start)
731    fn justify_start(mut self) -> Self {
732        self.style().justify_content = Some(JustifyContent::Start);
733        self
734    }
735
736    /// Packs flex or grid children against the end of the main axis.
737    ///
738    /// [Docs](https://tailwindcss.com/docs/justify-content#end)
739    fn justify_end(mut self) -> Self {
740        self.style().justify_content = Some(JustifyContent::End);
741        self
742    }
743
744    /// Packs flex children against the flex-relative start of the main axis.
745    fn justify_flex_start(mut self) -> Self {
746        self.style().justify_content = Some(JustifyContent::FlexStart);
747        self
748    }
749
750    /// Packs flex children against the flex-relative end of the main axis.
751    fn justify_flex_end(mut self) -> Self {
752        self.style().justify_content = Some(JustifyContent::FlexEnd);
753        self
754    }
755
756    /// Centers flex or grid children along the main axis.
757    ///
758    /// [Docs](https://tailwindcss.com/docs/justify-content#center)
759    fn justify_center(mut self) -> Self {
760        self.style().justify_content = Some(JustifyContent::Center);
761        self
762    }
763
764    /// Spreads children along the main axis with equal space between them.
765    ///
766    /// The first and last children touch the edges.
767    ///
768    /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
769    fn justify_between(mut self) -> Self {
770        self.style().justify_content = Some(JustifyContent::SpaceBetween);
771        self
772    }
773
774    /// Spreads children along the main axis with equal space on each side of each child.
775    ///
776    /// The space at the edges is half the space between children.
777    ///
778    /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
779    fn justify_around(mut self) -> Self {
780        self.style().justify_content = Some(JustifyContent::SpaceAround);
781        self
782    }
783
784    /// Spreads children along the main axis with equal space between every child and at both edges.
785    ///
786    /// [Docs](https://tailwindcss.com/docs/justify-content#space-evenly)
787    fn justify_evenly(mut self) -> Self {
788        self.style().justify_content = Some(JustifyContent::SpaceEvenly);
789        self
790    }
791
792    /// Clears `align-content`, so lines of children use their default packing.
793    ///
794    /// [Docs](https://tailwindcss.com/docs/align-content#normal)
795    fn content_normal(mut self) -> Self {
796        self.style().align_content = None;
797        self
798    }
799
800    /// Packs lines of children in the center of the cross axis.
801    ///
802    /// [Docs](https://tailwindcss.com/docs/align-content#center)
803    fn content_center(mut self) -> Self {
804        self.style().align_content = Some(AlignContent::Center);
805        self
806    }
807
808    /// Packs lines of children against the start of the cross axis.
809    ///
810    /// [Docs](https://tailwindcss.com/docs/align-content#start)
811    fn content_start(mut self) -> Self {
812        self.style().align_content = Some(AlignContent::FlexStart);
813        self
814    }
815
816    /// Packs lines of children against the end of the cross axis.
817    ///
818    /// [Docs](https://tailwindcss.com/docs/align-content#end)
819    fn content_end(mut self) -> Self {
820        self.style().align_content = Some(AlignContent::FlexEnd);
821        self
822    }
823
824    /// Spreads lines of children along the cross axis with equal space between them.
825    ///
826    /// [Docs](https://tailwindcss.com/docs/align-content#space-between)
827    fn content_between(mut self) -> Self {
828        self.style().align_content = Some(AlignContent::SpaceBetween);
829        self
830    }
831
832    /// Spreads lines of children along the cross axis with equal space on each side of each line.
833    ///
834    /// [Docs](https://tailwindcss.com/docs/align-content#space-around)
835    fn content_around(mut self) -> Self {
836        self.style().align_content = Some(AlignContent::SpaceAround);
837        self
838    }
839
840    /// Spreads lines of children along the cross axis with equal space between every line and at both edges.
841    ///
842    /// [Docs](https://tailwindcss.com/docs/align-content#space-evenly)
843    fn content_evenly(mut self) -> Self {
844        self.style().align_content = Some(AlignContent::SpaceEvenly);
845        self
846    }
847
848    /// Stretches lines of children to fill the cross axis.
849    ///
850    /// [Docs](https://tailwindcss.com/docs/align-content#stretch)
851    fn content_stretch(mut self) -> Self {
852        self.style().align_content = Some(AlignContent::Stretch);
853        self
854    }
855
856    /// Sets the width-to-height ratio of this element.
857    ///
858    /// A ratio of `2.0` makes the element twice as wide as it is tall. The ratio is used
859    /// only when one dimension is not set explicitly.
860    ///
861    /// [Docs](https://tailwindcss.com/docs/aspect-ratio)
862    fn aspect_ratio(mut self, ratio: f32) -> Self {
863        self.style().aspect_ratio = Some(ratio);
864        self
865    }
866
867    /// Sets the aspect ratio to `1.0`, so the element's width and height are equal.
868    ///
869    /// [Docs](https://tailwindcss.com/docs/aspect-ratio)
870    fn aspect_square(mut self) -> Self {
871        self.style().aspect_ratio = Some(1.0);
872        self
873    }
874
875    /// Sets the background of this element.
876    ///
877    /// Accepts any color, such as [`Hsla`](crate::Hsla) or [`Rgba`](crate::Rgba), or a gradient or pattern as a
878    /// [`Background`](crate::Background). See [`Fill`] for the full set of accepted values.
879    fn bg<F>(mut self, fill: F) -> Self
880    where
881        F: Into<Fill>,
882        Self: Sized,
883    {
884        self.style().background = Some(fill.into());
885        self
886    }
887
888    /// Sets the border style to dashed.
889    ///
890    /// Use [`Styled::border_dashed_length`] and [`Styled::border_dashed_gap`] to tune the
891    /// dashes.
892    fn border_dashed(mut self) -> Self {
893        self.style().border_style = Some(BorderStyle::Dashed);
894        self
895    }
896
897    /// Sets the length of each border dash as a multiple of the border width.
898    ///
899    /// Negative values are clamped to `0.0`. For a 2px border, `3.0` gives 6px dashes.
900    fn border_dashed_length(mut self, length_per_border_width: f32) -> Self {
901        self.style().border_dashed_length = Some(length_per_border_width.max(0.0));
902
903        self
904    }
905
906    /// Sets the gap between border dashes as a multiple of the border width.
907    ///
908    /// Negative values are clamped to `0.0`. For a 2px border, `2.0` gives 4px gaps.
909    fn border_dashed_gap(mut self, gap_per_border_width: f32) -> Self {
910        self.style().border_dashed_gap = Some(gap_per_border_width.max(0.0));
911
912        self
913    }
914
915    /// Returns the text style refinement configured on this element.
916    ///
917    /// Use it to set a text property that has no dedicated method. The refinement is inherited
918    /// by text descendants when GPUI resolves their styles; a descendant's own value takes
919    /// precedence.
920    fn text_style(&mut self) -> &mut TextStyleRefinement {
921        let style: &mut StyleRefinement = self.style();
922        &mut style.text
923    }
924
925    /// Sets the text color of this element.
926    ///
927    /// This value cascades to its children, unless a child sets its own color.
928    fn text_color(mut self, color: impl IntoColor<Hsla>) -> Self {
929        self.text_style().color = Some(color.into_color());
930        self
931    }
932
933    /// Sets the font weight of this element and its children.
934    ///
935    /// This value cascades to its children.
936    fn font_weight(mut self, weight: FontWeight) -> Self {
937        self.text_style().font_weight = Some(weight);
938        self
939    }
940
941    /// Sets the font width of this element and its children.
942    ///
943    /// Accepts a percentage or a [`FontWidth`] preset.
944    fn font_width(mut self, width: impl Into<FontWidth>) -> Self {
945        self.text_style().font_width = Some(width.into());
946
947        self
948    }
949
950    /// Sets the background color behind the text of this element.
951    ///
952    /// This value cascades to its children.
953    fn text_bg(mut self, bg: impl IntoColor<Hsla>) -> Self {
954        self.text_style().background_color = Some(bg.into_color());
955        self
956    }
957
958    /// Sets the font size of this element and its children.
959    ///
960    /// The size is an absolute length: pass [`px`](crate::px) for logical pixels or
961    /// [`rems`](crate::rems) to scale with the window's root font size. This value
962    /// cascades to its children.
963    fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
964        self.text_style().font_size = Some(size.into());
965        self
966    }
967
968    /// Sets the font size to `0.75rem` (12px with the default 16px root size).
969    ///
970    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
971    fn text_xs(mut self) -> Self {
972        self.text_style().font_size = Some(rems(0.75).into());
973        self
974    }
975
976    /// Sets the font size to `0.875rem` (14px with the default 16px root size).
977    ///
978    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
979    fn text_sm(mut self) -> Self {
980        self.text_style().font_size = Some(rems(0.875).into());
981        self
982    }
983
984    /// Sets the font size to `1rem` (16px with the default 16px root size).
985    ///
986    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
987    fn text_base(mut self) -> Self {
988        self.text_style().font_size = Some(rems(1.0).into());
989        self
990    }
991
992    /// Sets the font size to `1.125rem` (18px with the default 16px root size).
993    ///
994    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
995    fn text_lg(mut self) -> Self {
996        self.text_style().font_size = Some(rems(1.125).into());
997        self
998    }
999
1000    /// Sets the font size to `1.25rem` (20px with the default 16px root size).
1001    ///
1002    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
1003    fn text_xl(mut self) -> Self {
1004        self.text_style().font_size = Some(rems(1.25).into());
1005        self
1006    }
1007
1008    /// Sets the font size to `1.5rem` (24px with the default 16px root size).
1009    ///
1010    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
1011    fn text_2xl(mut self) -> Self {
1012        self.text_style().font_size = Some(rems(1.5).into());
1013        self
1014    }
1015
1016    /// Sets the font size to `1.875rem` (30px with the default 16px root size).
1017    ///
1018    /// [Docs](https://tailwindcss.com/docs/font-size#setting-the-font-size)
1019    fn text_3xl(mut self) -> Self {
1020        self.text_style().font_size = Some(rems(1.875).into());
1021        self
1022    }
1023
1024    /// Sets the font style to italic.
1025    ///
1026    /// [Docs](https://tailwindcss.com/docs/font-style#italicizing-text)
1027    fn italic(mut self) -> Self {
1028        self.text_style().font_style = Some(FontStyle::Italic);
1029        self
1030    }
1031
1032    /// Sets the font style to normal, which is not italic.
1033    ///
1034    /// [Docs](https://tailwindcss.com/docs/font-style#displaying-text-normally)
1035    fn not_italic(mut self) -> Self {
1036        self.text_style().font_style = Some(FontStyle::Normal);
1037        self
1038    }
1039
1040    /// Underlines the text of this element with a 1px line.
1041    ///
1042    /// This replaces any underline style set earlier on this element, including its
1043    /// color, so call [`Styled::text_decoration_color`] after this method.
1044    /// An underline set here can cascade to text descendants; [`Styled::text_decoration_none`]
1045    /// only clears one set on the current element.
1046    ///
1047    /// [Docs](https://tailwindcss.com/docs/text-decoration-line#underling-text)
1048    fn underline(mut self) -> Self {
1049        let style = self.text_style();
1050        style.underline = Some(UnderlineStyle {
1051            thickness: px(1.),
1052            ..Default::default()
1053        });
1054        self
1055    }
1056
1057    /// Draws a line through the text of this element with a 1px line.
1058    ///
1059    /// This replaces any strikethrough set earlier on this element. It doesn't change the
1060    /// underline.
1061    ///
1062    /// [Docs](https://tailwindcss.com/docs/text-decoration-line#adding-a-line-through-text)
1063    fn line_through(mut self) -> Self {
1064        let style = self.text_style();
1065        style.strikethrough = Some(StrikethroughStyle {
1066            thickness: px(1.),
1067            ..Default::default()
1068        });
1069        self
1070    }
1071
1072    /// Removes an underline set earlier on this element. It can't remove an underline
1073    /// inherited from a parent, and it leaves any strikethrough alone.
1074    fn text_decoration_none(mut self) -> Self {
1075        self.text_style().underline = None;
1076        self
1077    }
1078
1079    /// Sets the color of the text decoration line.
1080    ///
1081    /// This sets the underline color, not the strikethrough color. If no underline is set,
1082    /// it creates one with 0px thickness, which draws nothing until you set a thickness.
1083    /// Call this after [`Styled::underline`], because `underline` replaces the whole underline
1084    /// record, including its color.
1085    fn text_decoration_color(mut self, color: impl IntoColor<Hsla>) -> Self {
1086        let style = self.text_style();
1087        let underline = style.underline.get_or_insert_with(Default::default);
1088        underline.color = Some(color.into_color());
1089        self
1090    }
1091
1092    /// Sets the text decoration style to a solid line.
1093    ///
1094    /// If no underline exists yet, this creates one with zero thickness; pair it with
1095    /// [`Styled::underline`] or a thickness method to make the line visible.
1096    ///
1097    /// [Docs](https://tailwindcss.com/docs/text-decoration-style)
1098    fn text_decoration_solid(mut self) -> Self {
1099        let style = self.text_style();
1100        let underline = style.underline.get_or_insert_with(Default::default);
1101        underline.wavy = false;
1102        self
1103    }
1104
1105    /// Sets the text decoration style to a wavy line.
1106    ///
1107    /// If no underline exists yet, this creates one with zero thickness; pair it with
1108    /// [`Styled::underline`] or a thickness method to make the line visible.
1109    ///
1110    /// [Docs](https://tailwindcss.com/docs/text-decoration-style)
1111    fn text_decoration_wavy(mut self) -> Self {
1112        let style = self.text_style();
1113        let underline = style.underline.get_or_insert_with(Default::default);
1114        underline.wavy = true;
1115        self
1116    }
1117
1118    /// Sets the text decoration thickness to `0px`, which hides the line.
1119    ///
1120    /// [Docs](https://tailwindcss.com/docs/text-decoration-thickness)
1121    fn text_decoration_0(mut self) -> Self {
1122        let style = self.text_style();
1123        let underline = style.underline.get_or_insert_with(Default::default);
1124        underline.thickness = px(0.);
1125        self
1126    }
1127
1128    /// Sets the text decoration thickness to `1px`.
1129    ///
1130    /// [Docs](https://tailwindcss.com/docs/text-decoration-thickness)
1131    fn text_decoration_1(mut self) -> Self {
1132        let style = self.text_style();
1133        let underline = style.underline.get_or_insert_with(Default::default);
1134        underline.thickness = px(1.);
1135        self
1136    }
1137
1138    /// Sets the text decoration thickness to `2px`.
1139    ///
1140    /// [Docs](https://tailwindcss.com/docs/text-decoration-thickness)
1141    fn text_decoration_2(mut self) -> Self {
1142        let style = self.text_style();
1143        let underline = style.underline.get_or_insert_with(Default::default);
1144        underline.thickness = px(2.);
1145        self
1146    }
1147
1148    /// Sets the text decoration thickness to `4px`.
1149    ///
1150    /// [Docs](https://tailwindcss.com/docs/text-decoration-thickness)
1151    fn text_decoration_4(mut self) -> Self {
1152        let style = self.text_style();
1153        let underline = style.underline.get_or_insert_with(Default::default);
1154        underline.thickness = px(4.);
1155        self
1156    }
1157
1158    /// Sets the text decoration thickness to `8px`.
1159    ///
1160    /// [Docs](https://tailwindcss.com/docs/text-decoration-thickness)
1161    fn text_decoration_8(mut self) -> Self {
1162        let style = self.text_style();
1163        let underline = style.underline.get_or_insert_with(Default::default);
1164        underline.thickness = px(8.);
1165        self
1166    }
1167
1168    /// Sets the font family of this element and its children.
1169    ///
1170    /// Pass a font family name, such as `"Menlo"`. This value cascades to its children.
1171    fn font_family(mut self, family_name: impl Into<SharedString>) -> Self {
1172        self.text_style().font_family = Some(family_name.into());
1173        self
1174    }
1175
1176    /// Sets the OpenType font features of this element and its children.
1177    fn font_features(mut self, features: FontFeatures) -> Self {
1178        self.text_style().font_features = Some(features);
1179        self
1180    }
1181
1182    /// Sets the font family, features, fallbacks, weight, width, and style of this element and its children.
1183    ///
1184    /// Use [`Styled::font_family`] to change only the family.
1185    fn font(mut self, font: Font) -> Self {
1186        let Font {
1187            family,
1188            features,
1189            fallbacks,
1190            weight,
1191            width,
1192            style,
1193        } = font;
1194
1195        let text_style = self.text_style();
1196        text_style.font_family = Some(family);
1197        text_style.font_features = Some(features);
1198        text_style.font_weight = Some(weight);
1199        text_style.font_width = Some(width);
1200        text_style.font_style = Some(style);
1201        text_style.font_fallbacks = fallbacks;
1202
1203        self
1204    }
1205
1206    /// Sets the line height of this element and its children.
1207    ///
1208    /// Pass an absolute length such as [`px`](crate::px) or [`rems`](crate::rems), or a relative
1209    /// length such as `relative(1.5)` to make each line 1.5 times the element's font size.
1210    /// Relative values are resolved against the font size, not the parent's layout size.
1211    fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self {
1212        self.text_style().line_height = Some(line_height.into());
1213        self
1214    }
1215
1216    /// Sets the opacity of this element and its children, composited together as one group.
1217    ///
1218    /// `0.0` is fully transparent and `1.0` is fully opaque.
1219    fn opacity(mut self, opacity: f32) -> Self {
1220        self.style().opacity = Some(opacity);
1221        self
1222    }
1223
1224    /// Sets the number of equal-width columns in this grid element.
1225    ///
1226    /// Columns share the remaining width equally, with a zero minimum track size. A long child
1227    /// can therefore overflow or be compressed below its min-content width. Use
1228    /// [`Styled::grid_cols_min_content`] when each column must accommodate its min-content size.
1229    fn grid_cols(mut self, cols: u16) -> Self {
1230        self.style().grid_cols = Some(GridTemplate {
1231            repeat: cols,
1232            min_size: GridTemplateMinSize::Zero,
1233        });
1234        self
1235    }
1236
1237    /// Sets the number of columns, each at least as wide as its content.
1238    ///
1239    /// Each track has a min-content minimum and then shares remaining space equally. This keeps
1240    /// unbreakable or otherwise intrinsic content from being compressed below that minimum.
1241    fn grid_cols_min_content(mut self, cols: u16) -> Self {
1242        self.style().grid_cols = Some(GridTemplate {
1243            repeat: cols,
1244            min_size: GridTemplateMinSize::MinContent,
1245        });
1246        self
1247    }
1248
1249    /// Sets the number of columns with max-content sizing as the upper track size.
1250    ///
1251    /// Each track can grow to its max-content width instead of sharing all remaining space as a
1252    /// flexible `1fr` track. The minimum remains zero, so a narrow grid can compress or overflow
1253    /// content, and unused space need not be distributed across the tracks.
1254    fn grid_cols_max_content(mut self, cols: u16) -> Self {
1255        self.style().grid_cols = Some(GridTemplate {
1256            repeat: cols,
1257            min_size: GridTemplateMinSize::MaxContent,
1258        });
1259        self
1260    }
1261
1262    /// Sets the number of equal-height rows in this grid element.
1263    ///
1264    /// Rows share the remaining height equally, with a zero minimum track size. A tall child can
1265    /// therefore overflow or be compressed below its min-content height. Use
1266    /// [`Styled::grid_rows_min_content`] when each row must accommodate that minimum.
1267    fn grid_rows(mut self, rows: u16) -> Self {
1268        self.style().grid_rows = Some(GridTemplate {
1269            repeat: rows,
1270            min_size: GridTemplateMinSize::Zero,
1271        });
1272        self
1273    }
1274
1275    /// Sets the number of rows, each at least as tall as its content.
1276    ///
1277    /// Each track has a min-content minimum and then shares remaining space equally. This keeps
1278    /// content from being compressed below its intrinsic minimum height.
1279    fn grid_rows_min_content(mut self, rows: u16) -> Self {
1280        self.style().grid_rows = Some(GridTemplate {
1281            repeat: rows,
1282            min_size: GridTemplateMinSize::MinContent,
1283        });
1284        self
1285    }
1286
1287    /// Sets the number of rows with max-content sizing as the upper track size.
1288    ///
1289    /// Each track can grow to its max-content height instead of sharing all remaining space as a
1290    /// flexible `1fr` track. The minimum remains zero, so a short grid can compress or overflow
1291    /// content, and unused space need not be distributed across the tracks.
1292    fn grid_rows_max_content(mut self, rows: u16) -> Self {
1293        self.style().grid_rows = Some(GridTemplate {
1294            repeat: rows,
1295            min_size: GridTemplateMinSize::MaxContent,
1296        });
1297        self
1298    }
1299
1300    /// Sets the grid column line where this element starts. Lines are numbered from 1;
1301    /// negative values count backward from the end of the explicit grid.
1302    fn col_start(mut self, start: i16) -> Self {
1303        let grid_location = self.style().grid_location_mut();
1304        grid_location.column.start = GridPlacement::Line(start);
1305        self
1306    }
1307
1308    /// Lets the grid place this element's start column automatically.
1309    fn col_start_auto(mut self) -> Self {
1310        let grid_location = self.style().grid_location_mut();
1311        grid_location.column.start = GridPlacement::Auto;
1312        self
1313    }
1314
1315    /// Sets the grid column line where this element ends. Lines are numbered from 1; negative values count from the end.
1316    fn col_end(mut self, end: i16) -> Self {
1317        let grid_location = self.style().grid_location_mut();
1318        grid_location.column.end = GridPlacement::Line(end);
1319        self
1320    }
1321
1322    /// Lets the grid place this element's end column automatically.
1323    fn col_end_auto(mut self) -> Self {
1324        let grid_location = self.style().grid_location_mut();
1325        grid_location.column.end = GridPlacement::Auto;
1326        self
1327    }
1328
1329    /// Makes this element span `span` grid columns.
1330    fn col_span(mut self, span: u16) -> Self {
1331        let grid_location = self.style().grid_location_mut();
1332        grid_location.column = GridPlacement::Span(span)..GridPlacement::Span(span);
1333        self
1334    }
1335
1336    /// Makes this element span all grid columns.
1337    fn col_span_full(mut self) -> Self {
1338        let grid_location = self.style().grid_location_mut();
1339        grid_location.column = GridPlacement::Line(1)..GridPlacement::Line(-1);
1340        self
1341    }
1342
1343    /// Sets the grid row line where this element starts. Lines are numbered from 1;
1344    /// negative values count backward from the end of the explicit grid.
1345    fn row_start(mut self, start: i16) -> Self {
1346        let grid_location = self.style().grid_location_mut();
1347        grid_location.row.start = GridPlacement::Line(start);
1348        self
1349    }
1350
1351    /// Lets the grid place this element's start row automatically.
1352    fn row_start_auto(mut self) -> Self {
1353        let grid_location = self.style().grid_location_mut();
1354        grid_location.row.start = GridPlacement::Auto;
1355        self
1356    }
1357
1358    /// Sets the grid row line where this element ends. Lines are numbered from 1; negative values count from the end.
1359    fn row_end(mut self, end: i16) -> Self {
1360        let grid_location = self.style().grid_location_mut();
1361        grid_location.row.end = GridPlacement::Line(end);
1362        self
1363    }
1364
1365    /// Lets the grid place this element's end row automatically.
1366    fn row_end_auto(mut self) -> Self {
1367        let grid_location = self.style().grid_location_mut();
1368        grid_location.row.end = GridPlacement::Auto;
1369        self
1370    }
1371
1372    /// Makes this element span `span` grid rows.
1373    fn row_span(mut self, span: u16) -> Self {
1374        let grid_location = self.style().grid_location_mut();
1375        grid_location.row = GridPlacement::Span(span)..GridPlacement::Span(span);
1376        self
1377    }
1378
1379    /// Makes this element span all grid rows.
1380    fn row_span_full(mut self) -> Self {
1381        let grid_location = self.style().grid_location_mut();
1382        grid_location.row = GridPlacement::Line(1)..GridPlacement::Line(-1);
1383        self
1384    }
1385
1386    /// Draws a debug border around this element.
1387    ///
1388    /// This method exists only in debug builds (`debug_assertions`).
1389    #[cfg(debug_assertions)]
1390    fn debug(mut self) -> Self {
1391        self.style().debug = Some(true);
1392        self
1393    }
1394
1395    /// Draws a debug border around this element and every element below it in the tree.
1396    ///
1397    /// This method exists only in debug builds (`debug_assertions`).
1398    #[cfg(debug_assertions)]
1399    fn debug_below(mut self) -> Self {
1400        self.style().debug_below = Some(true);
1401        self
1402    }
1403
1404    /// Sets how smooth the rounded corners are, from `0.0` for circular corners to `1.0` for maximum smoothing.
1405    /// In debug builds, values outside this range trigger an assertion.
1406    fn rounded_smoothing(mut self, amount: f32) -> Self {
1407        debug_assert!(
1408            (0.0..=1.0).contains(&amount),
1409            "corner smoothing must be between 0 and 1"
1410        );
1411        self.style().corner_smoothing = Some(amount);
1412        self
1413    }
1414
1415    /// Sets corner smoothing to `0.6`, which matches iOS-style corners.
1416    fn rounded_smoothing_ios(mut self) -> Self {
1417        self.style().corner_smoothing = Some(0.6);
1418        self
1419    }
1420}