shadow.rs
1use gpui::{
2 App, Application, Bounds, BoxShadow, Context, Div, SharedString, Window, WindowBounds,
3 WindowOptions, div, hsla, point, prelude::*, px, relative, rgb, size,
4};
5
6use smallvec::smallvec;
7
8struct Shadow {}
9
10impl Shadow {
11 fn base() -> Div {
12 div()
13 .size_16()
14 .bg(rgb(0xffffff))
15 .rounded_full()
16 .border_1()
17 .border_color(hsla(0.0, 0.0, 0.0, 0.1))
18 }
19
20 fn square() -> Div {
21 div()
22 .size_16()
23 .bg(rgb(0xffffff))
24 .border_1()
25 .border_color(hsla(0.0, 0.0, 0.0, 0.1))
26 }
27
28 fn rounded_small() -> Div {
29 div()
30 .size_16()
31 .bg(rgb(0xffffff))
32 .rounded(px(4.))
33 .border_1()
34 .border_color(hsla(0.0, 0.0, 0.0, 0.1))
35 }
36
37 fn rounded_medium() -> Div {
38 div()
39 .size_16()
40 .bg(rgb(0xffffff))
41 .rounded(px(8.))
42 .border_1()
43 .border_color(hsla(0.0, 0.0, 0.0, 0.1))
44 }
45
46 fn rounded_large() -> Div {
47 div()
48 .size_16()
49 .bg(rgb(0xffffff))
50 .rounded(px(12.))
51 .border_1()
52 .border_color(hsla(0.0, 0.0, 0.0, 0.1))
53 }
54}
55
56fn example(label: impl Into<SharedString>, example: impl IntoElement) -> impl IntoElement {
57 let label = label.into();
58
59 div()
60 .flex()
61 .flex_col()
62 .justify_center()
63 .items_center()
64 .w(relative(1. / 6.))
65 .border_r_1()
66 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
67 .child(
68 div()
69 .flex()
70 .items_center()
71 .justify_center()
72 .flex_1()
73 .py_12()
74 .child(example),
75 )
76 .child(
77 div()
78 .w_full()
79 .border_t_1()
80 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
81 .p_1()
82 .flex()
83 .items_center()
84 .child(label),
85 )
86}
87
88impl Render for Shadow {
89 fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
90 div()
91 .id("shadow-example")
92 .overflow_y_scroll()
93 .bg(rgb(0xffffff))
94 .size_full()
95 .text_xs()
96 .child(div().flex().flex_col().w_full().children(vec![
97 div()
98 .border_b_1()
99 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
100 .flex()
101 .flex_row()
102 .children(vec![
103 example(
104 "Square",
105 Shadow::square()
106 .shadow(smallvec![BoxShadow {
107 color: hsla(0.0, 0.5, 0.5, 0.3),
108 offset: point(px(0.), px(8.)),
109 blur_radius: px(8.),
110 spread_radius: px(0.),
111 }]),
112 ),
113 example(
114 "Rounded 4",
115 Shadow::rounded_small()
116 .shadow(smallvec![BoxShadow {
117 color: hsla(0.0, 0.5, 0.5, 0.3),
118 offset: point(px(0.), px(8.)),
119 blur_radius: px(8.),
120 spread_radius: px(0.),
121 }]),
122 ),
123 example(
124 "Rounded 8",
125 Shadow::rounded_medium()
126 .shadow(smallvec![BoxShadow {
127 color: hsla(0.0, 0.5, 0.5, 0.3),
128 offset: point(px(0.), px(8.)),
129 blur_radius: px(8.),
130 spread_radius: px(0.),
131 }]),
132 ),
133 example(
134 "Rounded 16",
135 Shadow::rounded_large()
136 .shadow(smallvec![BoxShadow {
137 color: hsla(0.0, 0.5, 0.5, 0.3),
138 offset: point(px(0.), px(8.)),
139 blur_radius: px(8.),
140 spread_radius: px(0.),
141 }]),
142 ),
143 example(
144 "Circle",
145 Shadow::base()
146 .shadow(smallvec![BoxShadow {
147 color: hsla(0.0, 0.5, 0.5, 0.3),
148 offset: point(px(0.), px(8.)),
149 blur_radius: px(8.),
150 spread_radius: px(0.),
151 }]),
152 ),
153 ]),
154 div()
155 .border_b_1()
156 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
157 .flex()
158 .w_full()
159 .children(vec![
160 example("None", Shadow::base()),
161 // Small shadow
162 example("Small", Shadow::base().shadow_sm()),
163 // Medium shadow
164 example("Medium", Shadow::base().shadow_md()),
165 // Large shadow
166 example("Large", Shadow::base().shadow_lg()),
167 example("Extra Large", Shadow::base().shadow_xl()),
168 example("2X Large", Shadow::base().shadow_2xl()),
169 ]),
170 // Horizontal list of increasing blur radii
171 div()
172 .border_b_1()
173 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
174 .flex()
175 .children(vec![
176 example(
177 "Blur 0",
178 Shadow::base().shadow(smallvec![BoxShadow {
179 color: hsla(0.0, 0.0, 0.0, 0.3),
180 offset: point(px(0.), px(8.)),
181 blur_radius: px(0.),
182 spread_radius: px(0.),
183 }]),
184 ),
185 example(
186 "Blur 2",
187 Shadow::base().shadow(smallvec![BoxShadow {
188 color: hsla(0.0, 0.0, 0.0, 0.3),
189 offset: point(px(0.), px(8.)),
190 blur_radius: px(2.),
191 spread_radius: px(0.),
192 }]),
193 ),
194 example(
195 "Blur 4",
196 Shadow::base().shadow(smallvec![BoxShadow {
197 color: hsla(0.0, 0.0, 0.0, 0.3),
198 offset: point(px(0.), px(8.)),
199 blur_radius: px(4.),
200 spread_radius: px(0.),
201 }]),
202 ),
203 example(
204 "Blur 8",
205 Shadow::base().shadow(smallvec![BoxShadow {
206 color: hsla(0.0, 0.0, 0.0, 0.3),
207 offset: point(px(0.), px(8.)),
208 blur_radius: px(8.),
209 spread_radius: px(0.),
210 }]),
211 ),
212 example(
213 "Blur 16",
214 Shadow::base().shadow(smallvec![BoxShadow {
215 color: hsla(0.0, 0.0, 0.0, 0.3),
216 offset: point(px(0.), px(8.)),
217 blur_radius: px(16.),
218 spread_radius: px(0.),
219 }]),
220 ),
221 ]),
222 // Horizontal list of increasing spread radii
223 div()
224 .border_b_1()
225 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
226 .flex()
227 .children(vec![
228 example(
229 "Spread 0",
230 Shadow::base().shadow(smallvec![BoxShadow {
231 color: hsla(0.0, 0.0, 0.0, 0.3),
232 offset: point(px(0.), px(8.)),
233 blur_radius: px(8.),
234 spread_radius: px(0.),
235 }]),
236 ),
237 example(
238 "Spread 2",
239 Shadow::base().shadow(smallvec![BoxShadow {
240 color: hsla(0.0, 0.0, 0.0, 0.3),
241 offset: point(px(0.), px(8.)),
242 blur_radius: px(8.),
243 spread_radius: px(2.),
244 }]),
245 ),
246 example(
247 "Spread 4",
248 Shadow::base().shadow(smallvec![BoxShadow {
249 color: hsla(0.0, 0.0, 0.0, 0.3),
250 offset: point(px(0.), px(8.)),
251 blur_radius: px(8.),
252 spread_radius: px(4.),
253 }]),
254 ),
255 example(
256 "Spread 8",
257 Shadow::base().shadow(smallvec![BoxShadow {
258 color: hsla(0.0, 0.0, 0.0, 0.3),
259 offset: point(px(0.), px(8.)),
260 blur_radius: px(8.),
261 spread_radius: px(8.),
262 }]),
263 ),
264 example(
265 "Spread 16",
266 Shadow::base().shadow(smallvec![BoxShadow {
267 color: hsla(0.0, 0.0, 0.0, 0.3),
268 offset: point(px(0.), px(8.)),
269 blur_radius: px(8.),
270 spread_radius: px(16.),
271 }]),
272 ),
273 ]),
274 // Square spread examples
275 div()
276 .border_b_1()
277 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
278 .flex()
279 .children(vec![
280 example(
281 "Square Spread 0",
282 Shadow::square().shadow(smallvec![BoxShadow {
283 color: hsla(0.0, 0.0, 0.0, 0.3),
284 offset: point(px(0.), px(8.)),
285 blur_radius: px(8.),
286 spread_radius: px(0.),
287 }]),
288 ),
289 example(
290 "Square Spread 8",
291 Shadow::square().shadow(smallvec![BoxShadow {
292 color: hsla(0.0, 0.0, 0.0, 0.3),
293 offset: point(px(0.), px(8.)),
294 blur_radius: px(8.),
295 spread_radius: px(8.),
296 }]),
297 ),
298 example(
299 "Square Spread 16",
300 Shadow::square().shadow(smallvec![BoxShadow {
301 color: hsla(0.0, 0.0, 0.0, 0.3),
302 offset: point(px(0.), px(8.)),
303 blur_radius: px(8.),
304 spread_radius: px(16.),
305 }]),
306 ),
307 ]),
308 // Rounded large spread examples
309 div()
310 .border_b_1()
311 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
312 .flex()
313 .children(vec![
314 example(
315 "Rounded Large Spread 0",
316 Shadow::rounded_large().shadow(smallvec![BoxShadow {
317 color: hsla(0.0, 0.0, 0.0, 0.3),
318 offset: point(px(0.), px(8.)),
319 blur_radius: px(8.),
320 spread_radius: px(0.),
321 }]),
322 ),
323 example(
324 "Rounded Large Spread 8",
325 Shadow::rounded_large().shadow(smallvec![BoxShadow {
326 color: hsla(0.0, 0.0, 0.0, 0.3),
327 offset: point(px(0.), px(8.)),
328 blur_radius: px(8.),
329 spread_radius: px(8.),
330 }]),
331 ),
332 example(
333 "Rounded Large Spread 16",
334 Shadow::rounded_large().shadow(smallvec![BoxShadow {
335 color: hsla(0.0, 0.0, 0.0, 0.3),
336 offset: point(px(0.), px(8.)),
337 blur_radius: px(8.),
338 spread_radius: px(16.),
339 }]),
340 ),
341 ]),
342 // Directional shadows
343 div()
344 .border_b_1()
345 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
346 .flex()
347 .children(vec![
348 example(
349 "Left",
350 Shadow::base().shadow(smallvec![BoxShadow {
351 color: hsla(0.0, 0.5, 0.5, 0.3),
352 offset: point(px(-8.), px(0.)),
353 blur_radius: px(8.),
354 spread_radius: px(0.),
355 }]),
356 ),
357 example(
358 "Right",
359 Shadow::base().shadow(smallvec![BoxShadow {
360 color: hsla(0.0, 0.5, 0.5, 0.3),
361 offset: point(px(8.), px(0.)),
362 blur_radius: px(8.),
363 spread_radius: px(0.),
364 }]),
365 ),
366 example(
367 "Top",
368 Shadow::base().shadow(smallvec![BoxShadow {
369 color: hsla(0.0, 0.5, 0.5, 0.3),
370 offset: point(px(0.), px(-8.)),
371 blur_radius: px(8.),
372 spread_radius: px(0.),
373 }]),
374 ),
375 example(
376 "Bottom",
377 Shadow::base().shadow(smallvec![BoxShadow {
378 color: hsla(0.0, 0.5, 0.5, 0.3),
379 offset: point(px(0.), px(8.)),
380 blur_radius: px(8.),
381 spread_radius: px(0.),
382 }]),
383 ),
384 ]),
385 // Square directional shadows
386 div()
387 .border_b_1()
388 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
389 .flex()
390 .children(vec![
391 example(
392 "Square Left",
393 Shadow::square().shadow(smallvec![BoxShadow {
394 color: hsla(0.0, 0.5, 0.5, 0.3),
395 offset: point(px(-8.), px(0.)),
396 blur_radius: px(8.),
397 spread_radius: px(0.),
398 }]),
399 ),
400 example(
401 "Square Right",
402 Shadow::square().shadow(smallvec![BoxShadow {
403 color: hsla(0.0, 0.5, 0.5, 0.3),
404 offset: point(px(8.), px(0.)),
405 blur_radius: px(8.),
406 spread_radius: px(0.),
407 }]),
408 ),
409 example(
410 "Square Top",
411 Shadow::square().shadow(smallvec![BoxShadow {
412 color: hsla(0.0, 0.5, 0.5, 0.3),
413 offset: point(px(0.), px(-8.)),
414 blur_radius: px(8.),
415 spread_radius: px(0.),
416 }]),
417 ),
418 example(
419 "Square Bottom",
420 Shadow::square().shadow(smallvec![BoxShadow {
421 color: hsla(0.0, 0.5, 0.5, 0.3),
422 offset: point(px(0.), px(8.)),
423 blur_radius: px(8.),
424 spread_radius: px(0.),
425 }]),
426 ),
427 ]),
428 // Rounded large directional shadows
429 div()
430 .border_b_1()
431 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
432 .flex()
433 .children(vec![
434 example(
435 "Rounded Large Left",
436 Shadow::rounded_large().shadow(smallvec![BoxShadow {
437 color: hsla(0.0, 0.5, 0.5, 0.3),
438 offset: point(px(-8.), px(0.)),
439 blur_radius: px(8.),
440 spread_radius: px(0.),
441 }]),
442 ),
443 example(
444 "Rounded Large Right",
445 Shadow::rounded_large().shadow(smallvec![BoxShadow {
446 color: hsla(0.0, 0.5, 0.5, 0.3),
447 offset: point(px(8.), px(0.)),
448 blur_radius: px(8.),
449 spread_radius: px(0.),
450 }]),
451 ),
452 example(
453 "Rounded Large Top",
454 Shadow::rounded_large().shadow(smallvec![BoxShadow {
455 color: hsla(0.0, 0.5, 0.5, 0.3),
456 offset: point(px(0.), px(-8.)),
457 blur_radius: px(8.),
458 spread_radius: px(0.),
459 }]),
460 ),
461 example(
462 "Rounded Large Bottom",
463 Shadow::rounded_large().shadow(smallvec![BoxShadow {
464 color: hsla(0.0, 0.5, 0.5, 0.3),
465 offset: point(px(0.), px(8.)),
466 blur_radius: px(8.),
467 spread_radius: px(0.),
468 }]),
469 ),
470 ]),
471 // Multiple shadows for different shapes
472 div()
473 .border_b_1()
474 .border_color(hsla(0.0, 0.0, 0.0, 1.0))
475 .flex()
476 .children(vec![
477 example(
478 "Circle Multiple",
479 Shadow::base().shadow(smallvec![
480 BoxShadow {
481 color: hsla(0.0 / 360., 1.0, 0.5, 0.3), // Red
482 offset: point(px(0.), px(-12.)),
483 blur_radius: px(8.),
484 spread_radius: px(2.),
485 },
486 BoxShadow {
487 color: hsla(60.0 / 360., 1.0, 0.5, 0.3), // Yellow
488 offset: point(px(12.), px(0.)),
489 blur_radius: px(8.),
490 spread_radius: px(2.),
491 },
492 BoxShadow {
493 color: hsla(120.0 / 360., 1.0, 0.5, 0.3), // Green
494 offset: point(px(0.), px(12.)),
495 blur_radius: px(8.),
496 spread_radius: px(2.),
497 },
498 BoxShadow {
499 color: hsla(240.0 / 360., 1.0, 0.5, 0.3), // Blue
500 offset: point(px(-12.), px(0.)),
501 blur_radius: px(8.),
502 spread_radius: px(2.),
503 },
504 ]),
505 ),
506 example(
507 "Square Multiple",
508 Shadow::square().shadow(smallvec![
509 BoxShadow {
510 color: hsla(0.0 / 360., 1.0, 0.5, 0.3), // Red
511 offset: point(px(0.), px(-12.)),
512 blur_radius: px(8.),
513 spread_radius: px(2.),
514 },
515 BoxShadow {
516 color: hsla(60.0 / 360., 1.0, 0.5, 0.3), // Yellow
517 offset: point(px(12.), px(0.)),
518 blur_radius: px(8.),
519 spread_radius: px(2.),
520 },
521 BoxShadow {
522 color: hsla(120.0 / 360., 1.0, 0.5, 0.3), // Green
523 offset: point(px(0.), px(12.)),
524 blur_radius: px(8.),
525 spread_radius: px(2.),
526 },
527 BoxShadow {
528 color: hsla(240.0 / 360., 1.0, 0.5, 0.3), // Blue
529 offset: point(px(-12.), px(0.)),
530 blur_radius: px(8.),
531 spread_radius: px(2.),
532 },
533 ]),
534 ),
535 example(
536 "Rounded Large Multiple",
537 Shadow::rounded_large().shadow(smallvec![
538 BoxShadow {
539 color: hsla(0.0 / 360., 1.0, 0.5, 0.3), // Red
540 offset: point(px(0.), px(-12.)),
541 blur_radius: px(8.),
542 spread_radius: px(2.),
543 },
544 BoxShadow {
545 color: hsla(60.0 / 360., 1.0, 0.5, 0.3), // Yellow
546 offset: point(px(12.), px(0.)),
547 blur_radius: px(8.),
548 spread_radius: px(2.),
549 },
550 BoxShadow {
551 color: hsla(120.0 / 360., 1.0, 0.5, 0.3), // Green
552 offset: point(px(0.), px(12.)),
553 blur_radius: px(8.),
554 spread_radius: px(2.),
555 },
556 BoxShadow {
557 color: hsla(240.0 / 360., 1.0, 0.5, 0.3), // Blue
558 offset: point(px(-12.), px(0.)),
559 blur_radius: px(8.),
560 spread_radius: px(2.),
561 },
562 ]),
563 ),
564 ]),
565 ]))
566 }
567}
568
569fn main() {
570 Application::new().run(|cx: &mut App| {
571 let bounds = Bounds::centered(None, size(px(1000.0), px(800.0)), cx);
572 cx.open_window(
573 WindowOptions {
574 window_bounds: Some(WindowBounds::Windowed(bounds)),
575 ..Default::default()
576 },
577 |_, cx| cx.new(|_| Shadow {}),
578 )
579 .unwrap();
580
581 cx.activate(true);
582 });
583}