1use crate::{
2 self as gpui3, hsla, point, px, relative, rems, AlignItems, Display, Fill, FlexDirection, Hsla,
3 JustifyContent, Length, Position, SharedString, Style, StyleCascade, StyleRefinement,
4};
5use crate::{BoxShadow, TextStyleRefinement};
6use smallvec::smallvec;
7
8pub trait Styled {
9 fn style_cascade(&mut self) -> &mut StyleCascade;
10 fn computed_style(&mut self) -> &Style;
11 fn base_style(&mut self) -> &mut StyleRefinement {
12 self.style_cascade().base()
13 }
14
15 gpui3_macros::style_helpers!();
16
17 fn full(mut self) -> Self
18 where
19 Self: Sized,
20 {
21 self.base_style().size.width = Some(relative(1.).into());
22 self.base_style().size.height = Some(relative(1.).into());
23 self
24 }
25
26 fn relative(mut self) -> Self
27 where
28 Self: Sized,
29 {
30 self.base_style().position = Some(Position::Relative);
31 self
32 }
33
34 fn absolute(mut self) -> Self
35 where
36 Self: Sized,
37 {
38 self.base_style().position = Some(Position::Absolute);
39 self
40 }
41
42 fn block(mut self) -> Self
43 where
44 Self: Sized,
45 {
46 self.base_style().display = Some(Display::Block);
47 self
48 }
49
50 fn flex(mut self) -> Self
51 where
52 Self: Sized,
53 {
54 self.base_style().display = Some(Display::Flex);
55 self
56 }
57
58 fn flex_col(mut self) -> Self
59 where
60 Self: Sized,
61 {
62 self.base_style().flex_direction = Some(FlexDirection::Column);
63 self
64 }
65
66 fn flex_row(mut self) -> Self
67 where
68 Self: Sized,
69 {
70 self.base_style().flex_direction = Some(FlexDirection::Row);
71 self
72 }
73
74 fn flex_1(mut self) -> Self
75 where
76 Self: Sized,
77 {
78 self.base_style().flex_grow = Some(1.);
79 self.base_style().flex_shrink = Some(1.);
80 self.base_style().flex_basis = Some(relative(0.).into());
81 self
82 }
83
84 fn flex_auto(mut self) -> Self
85 where
86 Self: Sized,
87 {
88 self.base_style().flex_grow = Some(1.);
89 self.base_style().flex_shrink = Some(1.);
90 self.base_style().flex_basis = Some(Length::Auto);
91 self
92 }
93
94 fn flex_initial(mut self) -> Self
95 where
96 Self: Sized,
97 {
98 self.base_style().flex_grow = Some(0.);
99 self.base_style().flex_shrink = Some(1.);
100 self.base_style().flex_basis = Some(Length::Auto);
101 self
102 }
103
104 fn flex_none(mut self) -> Self
105 where
106 Self: Sized,
107 {
108 self.base_style().flex_grow = Some(0.);
109 self.base_style().flex_shrink = Some(0.);
110 self
111 }
112
113 fn grow(mut self) -> Self
114 where
115 Self: Sized,
116 {
117 self.base_style().flex_grow = Some(1.);
118 self
119 }
120
121 fn items_start(mut self) -> Self
122 where
123 Self: Sized,
124 {
125 self.base_style().align_items = Some(AlignItems::FlexStart);
126 self
127 }
128
129 fn items_end(mut self) -> Self
130 where
131 Self: Sized,
132 {
133 self.base_style().align_items = Some(AlignItems::FlexEnd);
134 self
135 }
136
137 fn items_center(mut self) -> Self
138 where
139 Self: Sized,
140 {
141 self.base_style().align_items = Some(AlignItems::Center);
142 self
143 }
144
145 fn justify_between(mut self) -> Self
146 where
147 Self: Sized,
148 {
149 self.base_style().justify_content = Some(JustifyContent::SpaceBetween);
150 self
151 }
152
153 fn justify_center(mut self) -> Self
154 where
155 Self: Sized,
156 {
157 self.base_style().justify_content = Some(JustifyContent::Center);
158 self
159 }
160
161 fn justify_start(mut self) -> Self
162 where
163 Self: Sized,
164 {
165 self.base_style().justify_content = Some(JustifyContent::Start);
166 self
167 }
168
169 fn justify_end(mut self) -> Self
170 where
171 Self: Sized,
172 {
173 self.base_style().justify_content = Some(JustifyContent::End);
174 self
175 }
176
177 fn justify_around(mut self) -> Self
178 where
179 Self: Sized,
180 {
181 self.base_style().justify_content = Some(JustifyContent::SpaceAround);
182 self
183 }
184
185 fn fill<F>(mut self, fill: F) -> Self
186 where
187 F: Into<Fill>,
188 Self: Sized,
189 {
190 self.base_style().fill = Some(fill.into());
191 self
192 }
193
194 fn border_color<C>(mut self, border_color: C) -> Self
195 where
196 C: Into<Hsla>,
197 Self: Sized,
198 {
199 self.base_style().border_color = Some(border_color.into());
200 self
201 }
202
203 fn shadow(mut self) -> Self
204 where
205 Self: Sized,
206 {
207 self.base_style().box_shadow = Some(smallvec![
208 BoxShadow {
209 color: hsla(0., 0., 0., 0.1),
210 offset: point(px(0.), px(1.)),
211 blur_radius: px(3.),
212 spread_radius: px(0.),
213 },
214 BoxShadow {
215 color: hsla(0., 0., 0., 0.1),
216 offset: point(px(0.), px(1.)),
217 blur_radius: px(2.),
218 spread_radius: px(-1.),
219 }
220 ]);
221 self
222 }
223
224 fn shadow_none(mut self) -> Self
225 where
226 Self: Sized,
227 {
228 self.base_style().box_shadow = Some(Default::default());
229 self
230 }
231
232 fn shadow_sm(mut self) -> Self
233 where
234 Self: Sized,
235 {
236 self.base_style().box_shadow = Some(smallvec::smallvec![BoxShadow {
237 color: hsla(0., 0., 0., 0.05),
238 offset: point(px(0.), px(1.)),
239 blur_radius: px(2.),
240 spread_radius: px(0.),
241 }]);
242 self
243 }
244
245 fn shadow_md(mut self) -> Self
246 where
247 Self: Sized,
248 {
249 self.base_style().box_shadow = Some(smallvec![
250 BoxShadow {
251 color: hsla(0.5, 0., 0., 0.1),
252 offset: point(px(0.), px(4.)),
253 blur_radius: px(6.),
254 spread_radius: px(-1.),
255 },
256 BoxShadow {
257 color: hsla(0., 0., 0., 0.1),
258 offset: point(px(0.), px(2.)),
259 blur_radius: px(4.),
260 spread_radius: px(-2.),
261 }
262 ]);
263 self
264 }
265
266 fn shadow_lg(mut self) -> Self
267 where
268 Self: Sized,
269 {
270 self.base_style().box_shadow = Some(smallvec![
271 BoxShadow {
272 color: hsla(0., 0., 0., 0.1),
273 offset: point(px(0.), px(10.)),
274 blur_radius: px(15.),
275 spread_radius: px(-3.),
276 },
277 BoxShadow {
278 color: hsla(0., 0., 0., 0.1),
279 offset: point(px(0.), px(4.)),
280 blur_radius: px(6.),
281 spread_radius: px(-4.),
282 }
283 ]);
284 self
285 }
286
287 fn shadow_xl(mut self) -> Self
288 where
289 Self: Sized,
290 {
291 self.base_style().box_shadow = Some(smallvec![
292 BoxShadow {
293 color: hsla(0., 0., 0., 0.1),
294 offset: point(px(0.), px(20.)),
295 blur_radius: px(25.),
296 spread_radius: px(-5.),
297 },
298 BoxShadow {
299 color: hsla(0., 0., 0., 0.1),
300 offset: point(px(0.), px(8.)),
301 blur_radius: px(10.),
302 spread_radius: px(-6.),
303 }
304 ]);
305 self
306 }
307
308 fn shadow_2xl(mut self) -> Self
309 where
310 Self: Sized,
311 {
312 self.base_style().box_shadow = Some(smallvec![BoxShadow {
313 color: hsla(0., 0., 0., 0.25),
314 offset: point(px(0.), px(25.)),
315 blur_radius: px(50.),
316 spread_radius: px(-12.),
317 }]);
318 self
319 }
320
321 fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
322 let style: &mut StyleRefinement = self.base_style();
323 &mut style.text
324 }
325
326 fn text_color(mut self, color: impl Into<Hsla>) -> Self
327 where
328 Self: Sized,
329 {
330 self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
331 self
332 }
333
334 fn text_xs(mut self) -> Self
335 where
336 Self: Sized,
337 {
338 self.text_style()
339 .get_or_insert_with(Default::default)
340 .font_size = Some(rems(0.75));
341 self
342 }
343
344 fn text_sm(mut self) -> Self
345 where
346 Self: Sized,
347 {
348 self.text_style()
349 .get_or_insert_with(Default::default)
350 .font_size = Some(rems(0.875));
351 self
352 }
353
354 fn text_base(mut self) -> Self
355 where
356 Self: Sized,
357 {
358 self.text_style()
359 .get_or_insert_with(Default::default)
360 .font_size = Some(rems(1.0));
361 self
362 }
363
364 fn text_lg(mut self) -> Self
365 where
366 Self: Sized,
367 {
368 self.text_style()
369 .get_or_insert_with(Default::default)
370 .font_size = Some(rems(1.125));
371 self
372 }
373
374 fn text_xl(mut self) -> Self
375 where
376 Self: Sized,
377 {
378 self.text_style()
379 .get_or_insert_with(Default::default)
380 .font_size = Some(rems(1.25));
381 self
382 }
383
384 fn text_2xl(mut self) -> Self
385 where
386 Self: Sized,
387 {
388 self.text_style()
389 .get_or_insert_with(Default::default)
390 .font_size = Some(rems(1.5));
391 self
392 }
393
394 fn text_3xl(mut self) -> Self
395 where
396 Self: Sized,
397 {
398 self.text_style()
399 .get_or_insert_with(Default::default)
400 .font_size = Some(rems(1.875));
401 self
402 }
403
404 fn text_decoration_none(mut self) -> Self
405 where
406 Self: Sized,
407 {
408 self.text_style()
409 .get_or_insert_with(Default::default)
410 .underline = None;
411 self
412 }
413
414 fn text_decoration_color(mut self, color: impl Into<Hsla>) -> Self
415 where
416 Self: Sized,
417 {
418 let style = self.text_style().get_or_insert_with(Default::default);
419 let underline = style.underline.get_or_insert_with(Default::default);
420 underline.color = Some(color.into());
421 self
422 }
423
424 fn text_decoration_solid(mut self) -> Self
425 where
426 Self: Sized,
427 {
428 let style = self.text_style().get_or_insert_with(Default::default);
429 let underline = style.underline.get_or_insert_with(Default::default);
430 underline.wavy = false;
431 self
432 }
433
434 fn text_decoration_wavy(mut self) -> Self
435 where
436 Self: Sized,
437 {
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.wavy = true;
441 self
442 }
443
444 fn text_decoration_0(mut self) -> Self
445 where
446 Self: Sized,
447 {
448 let style = self.text_style().get_or_insert_with(Default::default);
449 let underline = style.underline.get_or_insert_with(Default::default);
450 underline.thickness = px(0.);
451 self
452 }
453
454 fn text_decoration_1(mut self) -> Self
455 where
456 Self: Sized,
457 {
458 let style = self.text_style().get_or_insert_with(Default::default);
459 let underline = style.underline.get_or_insert_with(Default::default);
460 underline.thickness = px(1.);
461 self
462 }
463
464 fn text_decoration_2(mut self) -> Self
465 where
466 Self: Sized,
467 {
468 let style = self.text_style().get_or_insert_with(Default::default);
469 let underline = style.underline.get_or_insert_with(Default::default);
470 underline.thickness = px(2.);
471 self
472 }
473
474 fn text_decoration_4(mut self) -> Self
475 where
476 Self: Sized,
477 {
478 let style = self.text_style().get_or_insert_with(Default::default);
479 let underline = style.underline.get_or_insert_with(Default::default);
480 underline.thickness = px(4.);
481 self
482 }
483
484 fn text_decoration_8(mut self) -> Self
485 where
486 Self: Sized,
487 {
488 let style = self.text_style().get_or_insert_with(Default::default);
489 let underline = style.underline.get_or_insert_with(Default::default);
490 underline.thickness = px(8.);
491 self
492 }
493
494 fn font(mut self, family_name: impl Into<SharedString>) -> Self
495 where
496 Self: Sized,
497 {
498 self.text_style()
499 .get_or_insert_with(Default::default)
500 .font_family = Some(family_name.into());
501 self
502 }
503}