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