1use crate::{
2 self as gpui2, 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 gpui2_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 /// Sets the element to align flex items to the start of the container's cross axis.
141 /// [Docs](https://tailwindcss.com/docs/align-items#start)
142 fn items_start(mut self) -> Self
143 where
144 Self: Sized,
145 {
146 self.style().align_items = Some(AlignItems::FlexStart);
147 self
148 }
149
150 /// Sets the element to align flex items to the end of the container's cross axis.
151 /// [Docs](https://tailwindcss.com/docs/align-items#end)
152 fn items_end(mut self) -> Self
153 where
154 Self: Sized,
155 {
156 self.style().align_items = Some(AlignItems::FlexEnd);
157 self
158 }
159
160 /// Sets the element to align flex items along the center of the container's cross axis.
161 /// [Docs](https://tailwindcss.com/docs/align-items#center)
162 fn items_center(mut self) -> Self
163 where
164 Self: Sized,
165 {
166 self.style().align_items = Some(AlignItems::Center);
167 self
168 }
169
170 /// Sets the element to justify flex items along the container's main axis
171 /// such that there is an equal amount of space between each item.
172 /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
173 fn justify_between(mut self) -> Self
174 where
175 Self: Sized,
176 {
177 self.style().justify_content = Some(JustifyContent::SpaceBetween);
178 self
179 }
180
181 /// Sets the element to justify flex items along the center of the container's main axis.
182 /// [Docs](https://tailwindcss.com/docs/justify-content#center)
183 fn justify_center(mut self) -> Self
184 where
185 Self: Sized,
186 {
187 self.style().justify_content = Some(JustifyContent::Center);
188 self
189 }
190
191 /// Sets the element to justify flex items against the start of the container's main axis.
192 /// [Docs](https://tailwindcss.com/docs/justify-content#start)
193 fn justify_start(mut self) -> Self
194 where
195 Self: Sized,
196 {
197 self.style().justify_content = Some(JustifyContent::Start);
198 self
199 }
200
201 /// Sets the element to justify flex items against the end of the container's main axis.
202 /// [Docs](https://tailwindcss.com/docs/justify-content#end)
203 fn justify_end(mut self) -> Self
204 where
205 Self: Sized,
206 {
207 self.style().justify_content = Some(JustifyContent::End);
208 self
209 }
210
211 /// Sets the element to justify items along the container's main axis such
212 /// that there is an equal amount of space on each side of each item.
213 /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
214 fn justify_around(mut self) -> Self
215 where
216 Self: Sized,
217 {
218 self.style().justify_content = Some(JustifyContent::SpaceAround);
219 self
220 }
221
222 /// Sets the background color of the element.
223 fn bg<F>(mut self, fill: F) -> Self
224 where
225 F: Into<Fill>,
226 Self: Sized,
227 {
228 self.style().background = Some(fill.into());
229 self
230 }
231
232 /// Sets the border color of the element.
233 fn border_color<C>(mut self, border_color: C) -> Self
234 where
235 C: Into<Hsla>,
236 Self: Sized,
237 {
238 self.style().border_color = Some(border_color.into());
239 self
240 }
241
242 /// Sets the box shadow of the element.
243 /// [Docs](https://tailwindcss.com/docs/box-shadow)
244 fn shadow(mut self) -> Self
245 where
246 Self: Sized,
247 {
248 self.style().box_shadow = Some(smallvec![
249 BoxShadow {
250 color: hsla(0., 0., 0., 0.1),
251 offset: point(px(0.), px(1.)),
252 blur_radius: px(3.),
253 spread_radius: px(0.),
254 },
255 BoxShadow {
256 color: hsla(0., 0., 0., 0.1),
257 offset: point(px(0.), px(1.)),
258 blur_radius: px(2.),
259 spread_radius: px(-1.),
260 }
261 ]);
262 self
263 }
264
265 /// Clears the box shadow of the element.
266 /// [Docs](https://tailwindcss.com/docs/box-shadow)
267 fn shadow_none(mut self) -> Self
268 where
269 Self: Sized,
270 {
271 self.style().box_shadow = Some(Default::default());
272 self
273 }
274
275 /// Sets the box shadow of the element.
276 /// [Docs](https://tailwindcss.com/docs/box-shadow)
277 fn shadow_sm(mut self) -> Self
278 where
279 Self: Sized,
280 {
281 self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
282 color: hsla(0., 0., 0., 0.05),
283 offset: point(px(0.), px(1.)),
284 blur_radius: px(2.),
285 spread_radius: px(0.),
286 }]);
287 self
288 }
289
290 /// Sets the box shadow of the element.
291 /// [Docs](https://tailwindcss.com/docs/box-shadow)
292 fn shadow_md(mut self) -> Self
293 where
294 Self: Sized,
295 {
296 self.style().box_shadow = Some(smallvec![
297 BoxShadow {
298 color: hsla(0.5, 0., 0., 0.1),
299 offset: point(px(0.), px(4.)),
300 blur_radius: px(6.),
301 spread_radius: px(-1.),
302 },
303 BoxShadow {
304 color: hsla(0., 0., 0., 0.1),
305 offset: point(px(0.), px(2.)),
306 blur_radius: px(4.),
307 spread_radius: px(-2.),
308 }
309 ]);
310 self
311 }
312
313 /// Sets the box shadow of the element.
314 /// [Docs](https://tailwindcss.com/docs/box-shadow)
315 fn shadow_lg(mut self) -> Self
316 where
317 Self: Sized,
318 {
319 self.style().box_shadow = Some(smallvec![
320 BoxShadow {
321 color: hsla(0., 0., 0., 0.1),
322 offset: point(px(0.), px(10.)),
323 blur_radius: px(15.),
324 spread_radius: px(-3.),
325 },
326 BoxShadow {
327 color: hsla(0., 0., 0., 0.1),
328 offset: point(px(0.), px(4.)),
329 blur_radius: px(6.),
330 spread_radius: px(-4.),
331 }
332 ]);
333 self
334 }
335
336 /// Sets the box shadow of the element.
337 /// [Docs](https://tailwindcss.com/docs/box-shadow)
338 fn shadow_xl(mut self) -> Self
339 where
340 Self: Sized,
341 {
342 self.style().box_shadow = Some(smallvec![
343 BoxShadow {
344 color: hsla(0., 0., 0., 0.1),
345 offset: point(px(0.), px(20.)),
346 blur_radius: px(25.),
347 spread_radius: px(-5.),
348 },
349 BoxShadow {
350 color: hsla(0., 0., 0., 0.1),
351 offset: point(px(0.), px(8.)),
352 blur_radius: px(10.),
353 spread_radius: px(-6.),
354 }
355 ]);
356 self
357 }
358
359 /// Sets the box shadow of the element.
360 /// [Docs](https://tailwindcss.com/docs/box-shadow)
361 fn shadow_2xl(mut self) -> Self
362 where
363 Self: Sized,
364 {
365 self.style().box_shadow = Some(smallvec![BoxShadow {
366 color: hsla(0., 0., 0., 0.25),
367 offset: point(px(0.), px(25.)),
368 blur_radius: px(50.),
369 spread_radius: px(-12.),
370 }]);
371 self
372 }
373
374 fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
375 let style: &mut StyleRefinement = self.style();
376 &mut style.text
377 }
378
379 fn text_color(mut self, color: impl Into<Hsla>) -> Self
380 where
381 Self: Sized,
382 {
383 self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
384 self
385 }
386
387 fn text_size(mut self, size: impl Into<Rems>) -> Self
388 where
389 Self: Sized,
390 {
391 self.text_style()
392 .get_or_insert_with(Default::default)
393 .font_size = Some(size.into());
394 self
395 }
396
397 fn text_xs(mut self) -> Self
398 where
399 Self: Sized,
400 {
401 self.text_style()
402 .get_or_insert_with(Default::default)
403 .font_size = Some(rems(0.75));
404 self
405 }
406
407 fn text_sm(mut self) -> Self
408 where
409 Self: Sized,
410 {
411 self.text_style()
412 .get_or_insert_with(Default::default)
413 .font_size = Some(rems(0.875));
414 self
415 }
416
417 fn text_base(mut self) -> Self
418 where
419 Self: Sized,
420 {
421 self.text_style()
422 .get_or_insert_with(Default::default)
423 .font_size = Some(rems(1.0));
424 self
425 }
426
427 fn text_lg(mut self) -> Self
428 where
429 Self: Sized,
430 {
431 self.text_style()
432 .get_or_insert_with(Default::default)
433 .font_size = Some(rems(1.125));
434 self
435 }
436
437 fn text_xl(mut self) -> Self
438 where
439 Self: Sized,
440 {
441 self.text_style()
442 .get_or_insert_with(Default::default)
443 .font_size = Some(rems(1.25));
444 self
445 }
446
447 fn text_2xl(mut self) -> Self
448 where
449 Self: Sized,
450 {
451 self.text_style()
452 .get_or_insert_with(Default::default)
453 .font_size = Some(rems(1.5));
454 self
455 }
456
457 fn text_3xl(mut self) -> Self
458 where
459 Self: Sized,
460 {
461 self.text_style()
462 .get_or_insert_with(Default::default)
463 .font_size = Some(rems(1.875));
464 self
465 }
466
467 fn text_decoration_none(mut self) -> Self
468 where
469 Self: Sized,
470 {
471 self.text_style()
472 .get_or_insert_with(Default::default)
473 .underline = None;
474 self
475 }
476
477 fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self
478 where
479 Self: Sized,
480 {
481 let style = self.text_style().get_or_insert_with(Default::default);
482 let underline = style.underline.get_or_insert_with(Default::default);
483 underline.color = Some(color.into());
484 self
485 }
486
487 fn text_decoration_solid(mut self) -> Self
488 where
489 Self: Sized,
490 {
491 let style = self.text_style().get_or_insert_with(Default::default);
492 let underline = style.underline.get_or_insert_with(Default::default);
493 underline.wavy = false;
494 self
495 }
496
497 fn text_decoration_wavy(mut self) -> Self
498 where
499 Self: Sized,
500 {
501 let style = self.text_style().get_or_insert_with(Default::default);
502 let underline = style.underline.get_or_insert_with(Default::default);
503 underline.wavy = true;
504 self
505 }
506
507 fn text_decoration_0(mut self) -> Self
508 where
509 Self: Sized,
510 {
511 let style = self.text_style().get_or_insert_with(Default::default);
512 let underline = style.underline.get_or_insert_with(Default::default);
513 underline.thickness = px(0.);
514 self
515 }
516
517 fn text_decoration_1(mut self) -> Self
518 where
519 Self: Sized,
520 {
521 let style = self.text_style().get_or_insert_with(Default::default);
522 let underline = style.underline.get_or_insert_with(Default::default);
523 underline.thickness = px(1.);
524 self
525 }
526
527 fn text_decoration_2(mut self) -> Self
528 where
529 Self: Sized,
530 {
531 let style = self.text_style().get_or_insert_with(Default::default);
532 let underline = style.underline.get_or_insert_with(Default::default);
533 underline.thickness = px(2.);
534 self
535 }
536
537 fn text_decoration_4(mut self) -> Self
538 where
539 Self: Sized,
540 {
541 let style = self.text_style().get_or_insert_with(Default::default);
542 let underline = style.underline.get_or_insert_with(Default::default);
543 underline.thickness = px(4.);
544 self
545 }
546
547 fn text_decoration_8(mut self) -> Self
548 where
549 Self: Sized,
550 {
551 let style = self.text_style().get_or_insert_with(Default::default);
552 let underline = style.underline.get_or_insert_with(Default::default);
553 underline.thickness = px(8.);
554 self
555 }
556
557 fn font(mut self, family_name: impl Into<SharedString>) -> Self
558 where
559 Self: Sized,
560 {
561 self.text_style()
562 .get_or_insert_with(Default::default)
563 .font_family = Some(family_name.into());
564 self
565 }
566
567 fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self
568 where
569 Self: Sized,
570 {
571 self.text_style()
572 .get_or_insert_with(Default::default)
573 .line_height = Some(line_height.into());
574 self
575 }
576}