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