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 the whitespace of the element to `normal`.
105 /// [Docs](https://tailwindcss.com/docs/whitespace#normal)
106 fn whitespace_normal(mut self) -> Self {
107 self.text_style()
108 .get_or_insert_with(Default::default)
109 .white_space = Some(WhiteSpace::Normal);
110 self
111 }
112
113 /// Sets the whitespace of the element to `nowrap`.
114 /// [Docs](https://tailwindcss.com/docs/whitespace#nowrap)
115 fn whitespace_nowrap(mut self) -> Self {
116 self.text_style()
117 .get_or_insert_with(Default::default)
118 .white_space = Some(WhiteSpace::Nowrap);
119 self
120 }
121
122 /// Sets the flex direction of the element to `column`.
123 /// [Docs](https://tailwindcss.com/docs/flex-direction#column)
124 fn flex_col(mut self) -> Self {
125 self.style().flex_direction = Some(FlexDirection::Column);
126 self
127 }
128
129 /// Sets the flex direction of the element to `row`.
130 /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
131 fn flex_row(mut self) -> Self {
132 self.style().flex_direction = Some(FlexDirection::Row);
133 self
134 }
135
136 /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
137 /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
138 fn flex_1(mut self) -> Self {
139 self.style().flex_grow = Some(1.);
140 self.style().flex_shrink = Some(1.);
141 self.style().flex_basis = Some(relative(0.).into());
142 self
143 }
144
145 /// Sets the element to allow a flex item to grow and shrink, taking into account its initial size.
146 /// [Docs](https://tailwindcss.com/docs/flex#auto)
147 fn flex_auto(mut self) -> Self {
148 self.style().flex_grow = Some(1.);
149 self.style().flex_shrink = Some(1.);
150 self.style().flex_basis = Some(Length::Auto);
151 self
152 }
153
154 /// Sets the element to allow a flex item to shrink but not grow, taking into account its initial size.
155 /// [Docs](https://tailwindcss.com/docs/flex#initial)
156 fn flex_initial(mut self) -> Self {
157 self.style().flex_grow = Some(0.);
158 self.style().flex_shrink = Some(1.);
159 self.style().flex_basis = Some(Length::Auto);
160 self
161 }
162
163 /// Sets the element to prevent a flex item from growing or shrinking.
164 /// [Docs](https://tailwindcss.com/docs/flex#none)
165 fn flex_none(mut self) -> Self {
166 self.style().flex_grow = Some(0.);
167 self.style().flex_shrink = Some(0.);
168 self
169 }
170
171 /// Sets the element to allow a flex item to grow to fill any available space.
172 /// [Docs](https://tailwindcss.com/docs/flex-grow)
173 fn grow(mut self) -> Self {
174 self.style().flex_grow = Some(1.);
175 self
176 }
177
178 /// Sets the element to align flex items to the start of the container's cross axis.
179 /// [Docs](https://tailwindcss.com/docs/align-items#start)
180 fn items_start(mut self) -> Self {
181 self.style().align_items = Some(AlignItems::FlexStart);
182 self
183 }
184
185 /// Sets the element to align flex items to the end of the container's cross axis.
186 /// [Docs](https://tailwindcss.com/docs/align-items#end)
187 fn items_end(mut self) -> Self {
188 self.style().align_items = Some(AlignItems::FlexEnd);
189 self
190 }
191
192 /// Sets the element to align flex items along the center of the container's cross axis.
193 /// [Docs](https://tailwindcss.com/docs/align-items#center)
194 fn items_center(mut self) -> Self {
195 self.style().align_items = Some(AlignItems::Center);
196 self
197 }
198
199 /// Sets the element to justify flex items along the container's main axis
200 /// such that there is an equal amount of space between each item.
201 /// [Docs](https://tailwindcss.com/docs/justify-content#space-between)
202 fn justify_between(mut self) -> Self {
203 self.style().justify_content = Some(JustifyContent::SpaceBetween);
204 self
205 }
206
207 /// Sets the element to justify flex items along the center of the container's main axis.
208 /// [Docs](https://tailwindcss.com/docs/justify-content#center)
209 fn justify_center(mut self) -> Self {
210 self.style().justify_content = Some(JustifyContent::Center);
211 self
212 }
213
214 /// Sets the element to justify flex items against the start of the container's main axis.
215 /// [Docs](https://tailwindcss.com/docs/justify-content#start)
216 fn justify_start(mut self) -> Self {
217 self.style().justify_content = Some(JustifyContent::Start);
218 self
219 }
220
221 /// Sets the element to justify flex items against the end of the container's main axis.
222 /// [Docs](https://tailwindcss.com/docs/justify-content#end)
223 fn justify_end(mut self) -> Self {
224 self.style().justify_content = Some(JustifyContent::End);
225 self
226 }
227
228 /// Sets the element to justify items along the container's main axis such
229 /// that there is an equal amount of space on each side of each item.
230 /// [Docs](https://tailwindcss.com/docs/justify-content#space-around)
231 fn justify_around(mut self) -> Self {
232 self.style().justify_content = Some(JustifyContent::SpaceAround);
233 self
234 }
235
236 /// Sets the background color of the element.
237 fn bg<F>(mut self, fill: F) -> Self
238 where
239 F: Into<Fill>,
240 Self: Sized,
241 {
242 self.style().background = Some(fill.into());
243 self
244 }
245
246 /// Sets the border color of the element.
247 fn border_color<C>(mut self, border_color: C) -> Self
248 where
249 C: Into<Hsla>,
250 Self: Sized,
251 {
252 self.style().border_color = Some(border_color.into());
253 self
254 }
255
256 /// Sets the box shadow of the element.
257 /// [Docs](https://tailwindcss.com/docs/box-shadow)
258 fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self {
259 self.style().box_shadow = Some(shadows);
260 self
261 }
262
263 /// Clears the box shadow of the element.
264 /// [Docs](https://tailwindcss.com/docs/box-shadow)
265 fn shadow_none(mut self) -> Self {
266 self.style().box_shadow = Some(Default::default());
267 self
268 }
269
270 /// Sets the box shadow of the element.
271 /// [Docs](https://tailwindcss.com/docs/box-shadow)
272 fn shadow_sm(mut self) -> Self {
273 self.style().box_shadow = Some(smallvec::smallvec![BoxShadow {
274 color: hsla(0., 0., 0., 0.05),
275 offset: point(px(0.), px(1.)),
276 blur_radius: px(2.),
277 spread_radius: px(0.),
278 }]);
279 self
280 }
281
282 /// Sets the box shadow of the element.
283 /// [Docs](https://tailwindcss.com/docs/box-shadow)
284 fn shadow_md(mut self) -> Self {
285 self.style().box_shadow = Some(smallvec![
286 BoxShadow {
287 color: hsla(0.5, 0., 0., 0.1),
288 offset: point(px(0.), px(4.)),
289 blur_radius: px(6.),
290 spread_radius: px(-1.),
291 },
292 BoxShadow {
293 color: hsla(0., 0., 0., 0.1),
294 offset: point(px(0.), px(2.)),
295 blur_radius: px(4.),
296 spread_radius: px(-2.),
297 }
298 ]);
299 self
300 }
301
302 /// Sets the box shadow of the element.
303 /// [Docs](https://tailwindcss.com/docs/box-shadow)
304 fn shadow_lg(mut self) -> Self {
305 self.style().box_shadow = Some(smallvec![
306 BoxShadow {
307 color: hsla(0., 0., 0., 0.1),
308 offset: point(px(0.), px(10.)),
309 blur_radius: px(15.),
310 spread_radius: px(-3.),
311 },
312 BoxShadow {
313 color: hsla(0., 0., 0., 0.1),
314 offset: point(px(0.), px(4.)),
315 blur_radius: px(6.),
316 spread_radius: px(-4.),
317 }
318 ]);
319 self
320 }
321
322 /// Sets the box shadow of the element.
323 /// [Docs](https://tailwindcss.com/docs/box-shadow)
324 fn shadow_xl(mut self) -> Self {
325 self.style().box_shadow = Some(smallvec![
326 BoxShadow {
327 color: hsla(0., 0., 0., 0.1),
328 offset: point(px(0.), px(20.)),
329 blur_radius: px(25.),
330 spread_radius: px(-5.),
331 },
332 BoxShadow {
333 color: hsla(0., 0., 0., 0.1),
334 offset: point(px(0.), px(8.)),
335 blur_radius: px(10.),
336 spread_radius: px(-6.),
337 }
338 ]);
339 self
340 }
341
342 /// Sets the box shadow of the element.
343 /// [Docs](https://tailwindcss.com/docs/box-shadow)
344 fn shadow_2xl(mut self) -> Self {
345 self.style().box_shadow = Some(smallvec![BoxShadow {
346 color: hsla(0., 0., 0., 0.25),
347 offset: point(px(0.), px(25.)),
348 blur_radius: px(50.),
349 spread_radius: px(-12.),
350 }]);
351 self
352 }
353
354 fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
355 let style: &mut StyleRefinement = self.style();
356 &mut style.text
357 }
358
359 fn text_color(mut self, color: impl Into<Hsla>) -> Self {
360 self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
361 self
362 }
363
364 fn text_bg(mut self, bg: impl Into<Hsla>) -> Self {
365 self.text_style()
366 .get_or_insert_with(Default::default)
367 .background_color = Some(bg.into());
368 self
369 }
370
371 fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self {
372 self.text_style()
373 .get_or_insert_with(Default::default)
374 .font_size = Some(size.into());
375 self
376 }
377
378 fn text_xs(mut self) -> Self {
379 self.text_style()
380 .get_or_insert_with(Default::default)
381 .font_size = Some(rems(0.75).into());
382 self
383 }
384
385 fn text_sm(mut self) -> Self {
386 self.text_style()
387 .get_or_insert_with(Default::default)
388 .font_size = Some(rems(0.875).into());
389 self
390 }
391
392 fn text_base(mut self) -> Self {
393 self.text_style()
394 .get_or_insert_with(Default::default)
395 .font_size = Some(rems(1.0).into());
396 self
397 }
398
399 fn text_lg(mut self) -> Self {
400 self.text_style()
401 .get_or_insert_with(Default::default)
402 .font_size = Some(rems(1.125).into());
403 self
404 }
405
406 fn text_xl(mut self) -> Self {
407 self.text_style()
408 .get_or_insert_with(Default::default)
409 .font_size = Some(rems(1.25).into());
410 self
411 }
412
413 fn text_2xl(mut self) -> Self {
414 self.text_style()
415 .get_or_insert_with(Default::default)
416 .font_size = Some(rems(1.5).into());
417 self
418 }
419
420 fn text_3xl(mut self) -> Self {
421 self.text_style()
422 .get_or_insert_with(Default::default)
423 .font_size = Some(rems(1.875).into());
424 self
425 }
426
427 fn text_decoration_none(mut self) -> Self {
428 self.text_style()
429 .get_or_insert_with(Default::default)
430 .underline = None;
431 self
432 }
433
434 fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self {
435 let style = self.text_style().get_or_insert_with(Default::default);
436 let underline = style.underline.get_or_insert_with(Default::default);
437 underline.color = Some(color.into());
438 self
439 }
440
441 fn text_decoration_solid(mut self) -> Self {
442 let style = self.text_style().get_or_insert_with(Default::default);
443 let underline = style.underline.get_or_insert_with(Default::default);
444 underline.wavy = false;
445 self
446 }
447
448 fn text_decoration_wavy(mut self) -> Self {
449 let style = self.text_style().get_or_insert_with(Default::default);
450 let underline = style.underline.get_or_insert_with(Default::default);
451 underline.wavy = true;
452 self
453 }
454
455 fn text_decoration_0(mut self) -> Self {
456 let style = self.text_style().get_or_insert_with(Default::default);
457 let underline = style.underline.get_or_insert_with(Default::default);
458 underline.thickness = px(0.);
459 self
460 }
461
462 fn text_decoration_1(mut self) -> Self {
463 let style = self.text_style().get_or_insert_with(Default::default);
464 let underline = style.underline.get_or_insert_with(Default::default);
465 underline.thickness = px(1.);
466 self
467 }
468
469 fn text_decoration_2(mut self) -> Self {
470 let style = self.text_style().get_or_insert_with(Default::default);
471 let underline = style.underline.get_or_insert_with(Default::default);
472 underline.thickness = px(2.);
473 self
474 }
475
476 fn text_decoration_4(mut self) -> Self {
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(4.);
480 self
481 }
482
483 fn text_decoration_8(mut self) -> Self {
484 let style = self.text_style().get_or_insert_with(Default::default);
485 let underline = style.underline.get_or_insert_with(Default::default);
486 underline.thickness = px(8.);
487 self
488 }
489
490 fn font(mut self, family_name: impl Into<SharedString>) -> Self {
491 self.text_style()
492 .get_or_insert_with(Default::default)
493 .font_family = Some(family_name.into());
494 self
495 }
496
497 fn line_height(mut self, line_height: impl Into<DefiniteLength>) -> Self {
498 self.text_style()
499 .get_or_insert_with(Default::default)
500 .line_height = Some(line_height.into());
501 self
502 }
503}