styled.rs

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