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