@discourser/design-system 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AbsoluteCenter.d.ts +4 -0
- package/dist/components/AbsoluteCenter.d.ts.map +1 -0
- package/dist/components/Accordion.d.ts +12 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Avatar.d.ts +17 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Badge.d.ts +13 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Button.d.ts +39 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Card.d.ts +17 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Checkbox.d.ts +507 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/CloseButton.d.ts +4 -0
- package/dist/components/CloseButton.d.ts.map +1 -0
- package/dist/components/Dialog.d.ts +16 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/Drawer.d.ts +17 -0
- package/dist/components/Drawer.d.ts.map +1 -0
- package/dist/components/Group.d.ts +4 -0
- package/dist/components/Group.d.ts.map +1 -0
- package/dist/components/Heading.d.ts +10 -0
- package/dist/components/Heading.d.ts.map +1 -0
- package/dist/components/Icon.d.ts +4 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/IconButton.d.ts +5 -0
- package/dist/components/IconButton.d.ts.map +1 -0
- package/dist/components/Input.d.ts +5 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/InputAddon.d.ts +4 -0
- package/dist/components/InputAddon.d.ts.map +1 -0
- package/dist/components/InputGroup.d.ts +14 -0
- package/dist/components/InputGroup.d.ts.map +1 -0
- package/dist/components/Loader.d.ts +25 -0
- package/dist/components/Loader.d.ts.map +1 -0
- package/dist/components/Popover.d.ts +20 -0
- package/dist/components/Popover.d.ts.map +1 -0
- package/dist/components/Progress.d.ts +14 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/RadioGroup.d.ts +14 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/Select.d.ts +26 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Skeleton.d.ts +16 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Slider.d.ts +34 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Spinner.d.ts +4 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Switch.d.ts +10 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Tabs.d.ts +11 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Textarea.d.ts +5 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Toast.d.ts +4 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Tooltip.d.ts +19 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/index.d.ts +30 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/contracts/design-language.contract.d.ts +175 -0
- package/dist/contracts/design-language.contract.d.ts.map +1 -0
- package/dist/index.d.ts +7 -21506
- package/dist/index.d.ts.map +1 -0
- package/dist/languages/index.d.ts +4 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/material3.language.d.ts +9 -0
- package/dist/languages/material3.language.d.ts.map +1 -0
- package/dist/languages/transform.d.ts +98 -0
- package/dist/languages/transform.d.ts.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/preset/colors/index.d.ts +1485 -0
- package/dist/preset/colors/index.d.ts.map +1 -0
- package/dist/preset/colors/m3-error.d.ts +295 -0
- package/dist/preset/colors/m3-error.d.ts.map +1 -0
- package/dist/preset/colors/m3-neutral.d.ts +301 -0
- package/dist/preset/colors/m3-neutral.d.ts.map +1 -0
- package/dist/preset/colors/m3-primary.d.ts +312 -0
- package/dist/preset/colors/m3-primary.d.ts.map +1 -0
- package/dist/preset/index.d.ts +3 -0
- package/dist/preset/index.d.ts.map +1 -0
- package/dist/preset/layer-styles.d.ts +6 -0
- package/dist/preset/layer-styles.d.ts.map +1 -0
- package/dist/preset/recipes/absolute-center.d.ts +2 -0
- package/dist/preset/recipes/absolute-center.d.ts.map +1 -0
- package/dist/preset/recipes/accordion.d.ts +2 -0
- package/dist/preset/recipes/accordion.d.ts.map +1 -0
- package/dist/preset/recipes/avatar.d.ts +2 -0
- package/dist/preset/recipes/avatar.d.ts.map +1 -0
- package/dist/preset/recipes/badge.d.ts +2 -0
- package/dist/preset/recipes/badge.d.ts.map +1 -0
- package/dist/preset/recipes/button.d.ts +2 -0
- package/dist/preset/recipes/button.d.ts.map +1 -0
- package/dist/preset/recipes/card.d.ts +2 -0
- package/dist/preset/recipes/card.d.ts.map +1 -0
- package/dist/preset/recipes/checkbox.d.ts +2 -0
- package/dist/preset/recipes/checkbox.d.ts.map +1 -0
- package/dist/preset/recipes/dialog.d.ts +2 -0
- package/dist/preset/recipes/dialog.d.ts.map +1 -0
- package/dist/preset/recipes/drawer.d.ts +2 -0
- package/dist/preset/recipes/drawer.d.ts.map +1 -0
- package/dist/preset/recipes/field.d.ts +2 -0
- package/dist/preset/recipes/field.d.ts.map +1 -0
- package/dist/preset/recipes/group.d.ts +2 -0
- package/dist/preset/recipes/group.d.ts.map +1 -0
- package/dist/preset/recipes/heading.d.ts +2 -0
- package/dist/preset/recipes/heading.d.ts.map +1 -0
- package/dist/preset/recipes/index.d.ts +28 -0
- package/dist/preset/recipes/index.d.ts.map +1 -0
- package/dist/preset/recipes/input-addon.d.ts +2 -0
- package/dist/preset/recipes/input-addon.d.ts.map +1 -0
- package/dist/preset/recipes/input-group.d.ts +2 -0
- package/dist/preset/recipes/input-group.d.ts.map +1 -0
- package/dist/preset/recipes/input.d.ts +114 -0
- package/dist/preset/recipes/input.d.ts.map +1 -0
- package/dist/preset/recipes/popover.d.ts +2 -0
- package/dist/preset/recipes/popover.d.ts.map +1 -0
- package/dist/preset/recipes/progress.d.ts +2 -0
- package/dist/preset/recipes/progress.d.ts.map +1 -0
- package/dist/preset/recipes/radio-group.d.ts +2 -0
- package/dist/preset/recipes/radio-group.d.ts.map +1 -0
- package/dist/preset/recipes/select.d.ts +2 -0
- package/dist/preset/recipes/select.d.ts.map +1 -0
- package/dist/preset/recipes/skeleton.d.ts +2 -0
- package/dist/preset/recipes/skeleton.d.ts.map +1 -0
- package/dist/preset/recipes/slider.d.ts +2 -0
- package/dist/preset/recipes/slider.d.ts.map +1 -0
- package/dist/preset/recipes/spinner.d.ts +2 -0
- package/dist/preset/recipes/spinner.d.ts.map +1 -0
- package/dist/preset/recipes/switch.d.ts +2 -0
- package/dist/preset/recipes/switch.d.ts.map +1 -0
- package/dist/preset/recipes/tabs.d.ts +2 -0
- package/dist/preset/recipes/tabs.d.ts.map +1 -0
- package/dist/preset/recipes/textarea.d.ts +2 -0
- package/dist/preset/recipes/textarea.d.ts.map +1 -0
- package/dist/preset/recipes/toast.d.ts +2 -0
- package/dist/preset/recipes/toast.d.ts.map +1 -0
- package/dist/preset/recipes/tooltip.d.ts +2 -0
- package/dist/preset/recipes/tooltip.d.ts.map +1 -0
- package/dist/preset/semantic-tokens.d.ts +197 -0
- package/dist/preset/semantic-tokens.d.ts.map +1 -0
- package/dist/preset/shadows.d.ts +49 -0
- package/dist/preset/shadows.d.ts.map +1 -0
- package/dist/preset/text-styles.d.ts +6 -0
- package/dist/preset/text-styles.d.ts.map +1 -0
- package/dist/recipes/button.recipe.d.ts +2 -0
- package/dist/recipes/button.recipe.d.ts.map +1 -0
- package/dist/recipes/card.recipe.d.ts +2 -0
- package/dist/recipes/card.recipe.d.ts.map +1 -0
- package/dist/recipes/dialog.recipe.d.ts +2 -0
- package/dist/recipes/dialog.recipe.d.ts.map +1 -0
- package/dist/recipes/icon-button.recipe.d.ts +2 -0
- package/dist/recipes/icon-button.recipe.d.ts.map +1 -0
- package/dist/recipes/index.d.ts +7 -0
- package/dist/recipes/index.d.ts.map +1 -0
- package/dist/recipes/input.recipe.d.ts +2 -0
- package/dist/recipes/input.recipe.d.ts.map +1 -0
- package/dist/recipes/switch.recipe.d.ts +2 -0
- package/dist/recipes/switch.recipe.d.ts.map +1 -0
- package/dist/stories/foundations/components/ColorSwatch.d.ts +21 -0
- package/dist/stories/foundations/components/ColorSwatch.d.ts.map +1 -0
- package/dist/stories/foundations/components/ElevationCard.d.ts +11 -0
- package/dist/stories/foundations/components/ElevationCard.d.ts.map +1 -0
- package/dist/stories/foundations/components/SpacingBox.d.ts +11 -0
- package/dist/stories/foundations/components/SpacingBox.d.ts.map +1 -0
- package/dist/stories/foundations/components/TypeSpecimen.d.ts +12 -0
- package/dist/stories/foundations/components/TypeSpecimen.d.ts.map +1 -0
- package/dist/utils/cn.d.ts +6 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/components/AbsoluteCenter.tsx +7 -0
- package/src/components/Accordion.tsx +27 -0
- package/src/components/Avatar.tsx +55 -0
- package/src/components/Badge.tsx +29 -0
- package/src/components/Button.tsx +116 -0
- package/src/components/Card.tsx +24 -0
- package/src/components/Checkbox.tsx +48 -0
- package/src/components/CloseButton.tsx +21 -0
- package/src/components/Dialog.tsx +25 -0
- package/src/components/Drawer.tsx +29 -0
- package/src/components/Group.tsx +7 -0
- package/src/components/Heading.tsx +9 -0
- package/src/components/Icon.tsx +6 -0
- package/src/components/IconButton.tsx +10 -0
- package/src/components/Input.tsx +7 -0
- package/src/components/InputAddon.tsx +7 -0
- package/src/components/InputGroup.tsx +44 -0
- package/src/components/Loader.tsx +71 -0
- package/src/components/Popover.tsx +34 -0
- package/src/components/Progress.tsx +19 -0
- package/src/components/RadioGroup.tsx +21 -0
- package/src/components/Select.tsx +70 -0
- package/src/components/Skeleton.tsx +37 -0
- package/src/components/Slider.tsx +156 -0
- package/src/components/Spinner.tsx +7 -0
- package/src/components/Switch.tsx +19 -0
- package/src/components/Tabs.tsx +17 -0
- package/src/components/Textarea.tsx +7 -0
- package/src/components/Toast.tsx +96 -0
- package/src/components/Tooltip.tsx +65 -0
- package/src/components/index.ts +48 -0
- package/src/contracts/design-language.contract.ts +198 -0
- package/src/global.css +4 -0
- package/src/index.ts +18 -0
- package/src/languages/index.ts +9 -0
- package/src/languages/material3.language.ts +379 -0
- package/src/languages/transform.ts +131 -0
- package/src/main.ts +33 -0
- package/src/preset/colors/index.ts +14 -0
- package/src/preset/colors/m3-error.ts +76 -0
- package/src/preset/colors/m3-neutral.ts +89 -0
- package/src/preset/colors/m3-primary.ts +107 -0
- package/src/preset/index.ts +189 -0
- package/src/preset/layer-styles.ts +14 -0
- package/src/preset/recipes/absolute-center.ts +37 -0
- package/src/preset/recipes/accordion.ts +92 -0
- package/src/preset/recipes/avatar.ts +152 -0
- package/src/preset/recipes/badge.ts +49 -0
- package/src/preset/recipes/button.ts +110 -0
- package/src/preset/recipes/card.ts +69 -0
- package/src/preset/recipes/checkbox.ts +109 -0
- package/src/preset/recipes/dialog.ts +157 -0
- package/src/preset/recipes/drawer.ts +203 -0
- package/src/preset/recipes/field.ts +40 -0
- package/src/preset/recipes/group.ts +77 -0
- package/src/preset/recipes/heading.ts +26 -0
- package/src/preset/recipes/index.ts +40 -0
- package/src/preset/recipes/input-addon.ts +42 -0
- package/src/preset/recipes/input-group.ts +66 -0
- package/src/preset/recipes/input.ts +87 -0
- package/src/preset/recipes/popover.ts +77 -0
- package/src/preset/recipes/progress.ts +120 -0
- package/src/preset/recipes/radio-group.ts +99 -0
- package/src/preset/recipes/select.ts +175 -0
- package/src/preset/recipes/skeleton.ts +64 -0
- package/src/preset/recipes/slider.ts +174 -0
- package/src/preset/recipes/spinner.ts +33 -0
- package/src/preset/recipes/switch.ts +136 -0
- package/src/preset/recipes/tabs.ts +177 -0
- package/src/preset/recipes/textarea.ts +82 -0
- package/src/preset/recipes/toast.ts +51 -0
- package/src/preset/recipes/tooltip.ts +38 -0
- package/src/preset/semantic-tokens.ts +75 -0
- package/src/preset/shadows.ts +50 -0
- package/src/preset/text-styles.ts +21 -0
- package/src/recipes/button.recipe.ts +120 -0
- package/src/recipes/card.recipe.ts +50 -0
- package/src/recipes/dialog.recipe.ts +130 -0
- package/src/recipes/icon-button.recipe.ts +96 -0
- package/src/recipes/index.ts +6 -0
- package/src/recipes/input.recipe.ts +93 -0
- package/src/recipes/switch.recipe.ts +117 -0
- package/src/stories/foundations/Colors.mdx +380 -0
- package/src/stories/foundations/Elevation.mdx +292 -0
- package/src/stories/foundations/Spacing.mdx +223 -0
- package/src/stories/foundations/Typography.mdx +264 -0
- package/src/stories/foundations/components/ColorSwatch.tsx +166 -0
- package/src/stories/foundations/components/ElevationCard.tsx +81 -0
- package/src/stories/foundations/components/SpacingBox.tsx +94 -0
- package/src/stories/foundations/components/TypeSpecimen.tsx +117 -0
- package/src/test/setup.ts +12 -0
- package/src/test/vitest.d.ts +29 -0
- package/src/utils/cn.ts +8 -0
- package/src/vite-env.d.ts +1 -0
- package/dist/index.d.cts +0 -21506
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
import { ColorSwatch, TonalSwatch, SemanticSwatch } from './components/ColorSwatch';
|
|
3
|
+
import { material3Language } from '../../languages/material3.language';
|
|
4
|
+
|
|
5
|
+
<Meta title="Foundations/Colors" />
|
|
6
|
+
|
|
7
|
+
# Colors
|
|
8
|
+
|
|
9
|
+
The Discourser Design System uses Material Design 3's color system, which provides a comprehensive palette of colors organized into tonal palettes and semantic tokens.
|
|
10
|
+
|
|
11
|
+
## Color Philosophy
|
|
12
|
+
|
|
13
|
+
Material Design 3 uses a three-tiered color system:
|
|
14
|
+
|
|
15
|
+
1. **Tonal Palettes**: Base color scales from 0-100, generated from source colors
|
|
16
|
+
2. **Semantic Tokens**: Context-aware color roles that adapt to light/dark themes
|
|
17
|
+
3. **Dynamic Color**: Colors that work harmoniously together across all contexts
|
|
18
|
+
|
|
19
|
+
## Tonal Palettes
|
|
20
|
+
|
|
21
|
+
Each palette contains 13 tones (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 100). Lower numbers are darker, higher numbers are lighter.
|
|
22
|
+
|
|
23
|
+
### Primary
|
|
24
|
+
|
|
25
|
+
The primary palette is derived from TastyMakers green (#63A002).
|
|
26
|
+
|
|
27
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
28
|
+
{Object.entries(material3Language.colors.primary).map(([tone, value]) => (
|
|
29
|
+
<TonalSwatch key={tone} paletteName="primary" tone={Number(tone)} value={value} />
|
|
30
|
+
))}
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
### Secondary
|
|
34
|
+
|
|
35
|
+
Supporting colors that complement the primary palette.
|
|
36
|
+
|
|
37
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
38
|
+
{Object.entries(material3Language.colors.secondary).map(([tone, value]) => (
|
|
39
|
+
<TonalSwatch key={tone} paletteName="secondary" tone={Number(tone)} value={value} />
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
### Tertiary
|
|
44
|
+
|
|
45
|
+
Additional accent colors for variety and visual interest.
|
|
46
|
+
|
|
47
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
48
|
+
{Object.entries(material3Language.colors.tertiary).map(([tone, value]) => (
|
|
49
|
+
<TonalSwatch key={tone} paletteName="tertiary" tone={Number(tone)} value={value} />
|
|
50
|
+
))}
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
### Neutral
|
|
54
|
+
|
|
55
|
+
For backgrounds, surfaces, and other neutral elements.
|
|
56
|
+
|
|
57
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
58
|
+
{Object.entries(material3Language.colors.neutral).map(([tone, value]) => (
|
|
59
|
+
<TonalSwatch key={tone} paletteName="neutral" tone={Number(tone)} value={value} />
|
|
60
|
+
))}
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
### Neutral Variant
|
|
64
|
+
|
|
65
|
+
Alternative neutral colors with subtle color temperature.
|
|
66
|
+
|
|
67
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
68
|
+
{Object.entries(material3Language.colors.neutralVariant).map(([tone, value]) => (
|
|
69
|
+
<TonalSwatch key={tone} paletteName="neutralVariant" tone={Number(tone)} value={value} />
|
|
70
|
+
))}
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
### Error
|
|
74
|
+
|
|
75
|
+
For error states, alerts, and destructive actions.
|
|
76
|
+
|
|
77
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)', gap: '2px', marginBottom: '32px' }}>
|
|
78
|
+
{Object.entries(material3Language.colors.error).map(([tone, value]) => (
|
|
79
|
+
<TonalSwatch key={tone} paletteName="error" tone={Number(tone)} value={value} />
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Semantic Tokens
|
|
86
|
+
|
|
87
|
+
Semantic tokens are context-aware colors that automatically adapt to light and dark themes. **Always use semantic tokens in your components** instead of directly referencing tonal palette values.
|
|
88
|
+
|
|
89
|
+
### Primary Colors
|
|
90
|
+
|
|
91
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
92
|
+
<SemanticSwatch
|
|
93
|
+
name="primary"
|
|
94
|
+
lightValue={material3Language.semantic.primary}
|
|
95
|
+
darkValue={material3Language.semanticDark.primary}
|
|
96
|
+
description="Primary brand color for key actions and emphasis"
|
|
97
|
+
/>
|
|
98
|
+
<SemanticSwatch
|
|
99
|
+
name="onPrimary"
|
|
100
|
+
lightValue={material3Language.semantic.onPrimary}
|
|
101
|
+
darkValue={material3Language.semanticDark.onPrimary}
|
|
102
|
+
description="Text/icons on primary color"
|
|
103
|
+
/>
|
|
104
|
+
<SemanticSwatch
|
|
105
|
+
name="primaryContainer"
|
|
106
|
+
lightValue={material3Language.semantic.primaryContainer}
|
|
107
|
+
darkValue={material3Language.semanticDark.primaryContainer}
|
|
108
|
+
description="Container for primary elements"
|
|
109
|
+
/>
|
|
110
|
+
<SemanticSwatch
|
|
111
|
+
name="onPrimaryContainer"
|
|
112
|
+
lightValue={material3Language.semantic.onPrimaryContainer}
|
|
113
|
+
darkValue={material3Language.semanticDark.onPrimaryContainer}
|
|
114
|
+
description="Text/icons on primary container"
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
### Secondary Colors
|
|
119
|
+
|
|
120
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
121
|
+
<SemanticSwatch
|
|
122
|
+
name="secondary"
|
|
123
|
+
lightValue={material3Language.semantic.secondary}
|
|
124
|
+
darkValue={material3Language.semanticDark.secondary}
|
|
125
|
+
description="Secondary actions and less prominent elements"
|
|
126
|
+
/>
|
|
127
|
+
<SemanticSwatch
|
|
128
|
+
name="onSecondary"
|
|
129
|
+
lightValue={material3Language.semantic.onSecondary}
|
|
130
|
+
darkValue={material3Language.semanticDark.onSecondary}
|
|
131
|
+
description="Text/icons on secondary color"
|
|
132
|
+
/>
|
|
133
|
+
<SemanticSwatch
|
|
134
|
+
name="secondaryContainer"
|
|
135
|
+
lightValue={material3Language.semantic.secondaryContainer}
|
|
136
|
+
darkValue={material3Language.semanticDark.secondaryContainer}
|
|
137
|
+
description="Container for secondary elements"
|
|
138
|
+
/>
|
|
139
|
+
<SemanticSwatch
|
|
140
|
+
name="onSecondaryContainer"
|
|
141
|
+
lightValue={material3Language.semantic.onSecondaryContainer}
|
|
142
|
+
darkValue={material3Language.semanticDark.onSecondaryContainer}
|
|
143
|
+
description="Text/icons on secondary container"
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
### Tertiary Colors
|
|
148
|
+
|
|
149
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
150
|
+
<SemanticSwatch
|
|
151
|
+
name="tertiary"
|
|
152
|
+
lightValue={material3Language.semantic.tertiary}
|
|
153
|
+
darkValue={material3Language.semanticDark.tertiary}
|
|
154
|
+
description="Contrasting accent color for visual interest"
|
|
155
|
+
/>
|
|
156
|
+
<SemanticSwatch
|
|
157
|
+
name="onTertiary"
|
|
158
|
+
lightValue={material3Language.semantic.onTertiary}
|
|
159
|
+
darkValue={material3Language.semanticDark.onTertiary}
|
|
160
|
+
description="Text/icons on tertiary color"
|
|
161
|
+
/>
|
|
162
|
+
<SemanticSwatch
|
|
163
|
+
name="tertiaryContainer"
|
|
164
|
+
lightValue={material3Language.semantic.tertiaryContainer}
|
|
165
|
+
darkValue={material3Language.semanticDark.tertiaryContainer}
|
|
166
|
+
description="Container for tertiary elements"
|
|
167
|
+
/>
|
|
168
|
+
<SemanticSwatch
|
|
169
|
+
name="onTertiaryContainer"
|
|
170
|
+
lightValue={material3Language.semantic.onTertiaryContainer}
|
|
171
|
+
darkValue={material3Language.semanticDark.onTertiaryContainer}
|
|
172
|
+
description="Text/icons on tertiary container"
|
|
173
|
+
/>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
### Error Colors
|
|
177
|
+
|
|
178
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
179
|
+
<SemanticSwatch
|
|
180
|
+
name="error"
|
|
181
|
+
lightValue={material3Language.semantic.error}
|
|
182
|
+
darkValue={material3Language.semanticDark.error}
|
|
183
|
+
description="Error states and destructive actions"
|
|
184
|
+
/>
|
|
185
|
+
<SemanticSwatch
|
|
186
|
+
name="onError"
|
|
187
|
+
lightValue={material3Language.semantic.onError}
|
|
188
|
+
darkValue={material3Language.semanticDark.onError}
|
|
189
|
+
description="Text/icons on error color"
|
|
190
|
+
/>
|
|
191
|
+
<SemanticSwatch
|
|
192
|
+
name="errorContainer"
|
|
193
|
+
lightValue={material3Language.semantic.errorContainer}
|
|
194
|
+
darkValue={material3Language.semanticDark.errorContainer}
|
|
195
|
+
description="Container for error messages"
|
|
196
|
+
/>
|
|
197
|
+
<SemanticSwatch
|
|
198
|
+
name="onErrorContainer"
|
|
199
|
+
lightValue={material3Language.semantic.onErrorContainer}
|
|
200
|
+
darkValue={material3Language.semanticDark.onErrorContainer}
|
|
201
|
+
description="Text/icons on error container"
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
### Surface Colors
|
|
206
|
+
|
|
207
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
208
|
+
<SemanticSwatch
|
|
209
|
+
name="surface"
|
|
210
|
+
lightValue={material3Language.semantic.surface}
|
|
211
|
+
darkValue={material3Language.semanticDark.surface}
|
|
212
|
+
description="Base surface color for cards and containers"
|
|
213
|
+
/>
|
|
214
|
+
<SemanticSwatch
|
|
215
|
+
name="onSurface"
|
|
216
|
+
lightValue={material3Language.semantic.onSurface}
|
|
217
|
+
darkValue={material3Language.semanticDark.onSurface}
|
|
218
|
+
description="Primary text and icons on surface"
|
|
219
|
+
/>
|
|
220
|
+
<SemanticSwatch
|
|
221
|
+
name="surfaceVariant"
|
|
222
|
+
lightValue={material3Language.semantic.surfaceVariant}
|
|
223
|
+
darkValue={material3Language.semanticDark.surfaceVariant}
|
|
224
|
+
description="Alternative surface for variety"
|
|
225
|
+
/>
|
|
226
|
+
<SemanticSwatch
|
|
227
|
+
name="onSurfaceVariant"
|
|
228
|
+
lightValue={material3Language.semantic.onSurfaceVariant}
|
|
229
|
+
darkValue={material3Language.semanticDark.onSurfaceVariant}
|
|
230
|
+
description="Text/icons on surface variant"
|
|
231
|
+
/>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
### Surface Containers
|
|
235
|
+
|
|
236
|
+
M3 provides 5 surface container levels for creating subtle depth without elevation.
|
|
237
|
+
|
|
238
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
239
|
+
<SemanticSwatch
|
|
240
|
+
name="surfaceContainerLowest"
|
|
241
|
+
lightValue={material3Language.semantic.surfaceContainerLowest}
|
|
242
|
+
darkValue={material3Language.semanticDark.surfaceContainerLowest}
|
|
243
|
+
description="Lowest container level"
|
|
244
|
+
/>
|
|
245
|
+
<SemanticSwatch
|
|
246
|
+
name="surfaceContainerLow"
|
|
247
|
+
lightValue={material3Language.semantic.surfaceContainerLow}
|
|
248
|
+
darkValue={material3Language.semanticDark.surfaceContainerLow}
|
|
249
|
+
description="Low container level"
|
|
250
|
+
/>
|
|
251
|
+
<SemanticSwatch
|
|
252
|
+
name="surfaceContainer"
|
|
253
|
+
lightValue={material3Language.semantic.surfaceContainer}
|
|
254
|
+
darkValue={material3Language.semanticDark.surfaceContainer}
|
|
255
|
+
description="Default container level"
|
|
256
|
+
/>
|
|
257
|
+
<SemanticSwatch
|
|
258
|
+
name="surfaceContainerHigh"
|
|
259
|
+
lightValue={material3Language.semantic.surfaceContainerHigh}
|
|
260
|
+
darkValue={material3Language.semanticDark.surfaceContainerHigh}
|
|
261
|
+
description="High container level"
|
|
262
|
+
/>
|
|
263
|
+
<SemanticSwatch
|
|
264
|
+
name="surfaceContainerHighest"
|
|
265
|
+
lightValue={material3Language.semantic.surfaceContainerHighest}
|
|
266
|
+
darkValue={material3Language.semanticDark.surfaceContainerHighest}
|
|
267
|
+
description="Highest container level"
|
|
268
|
+
/>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
### Outline Colors
|
|
272
|
+
|
|
273
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
274
|
+
<SemanticSwatch
|
|
275
|
+
name="outline"
|
|
276
|
+
lightValue={material3Language.semantic.outline}
|
|
277
|
+
darkValue={material3Language.semanticDark.outline}
|
|
278
|
+
description="Important borders and dividers"
|
|
279
|
+
/>
|
|
280
|
+
<SemanticSwatch
|
|
281
|
+
name="outlineVariant"
|
|
282
|
+
lightValue={material3Language.semantic.outlineVariant}
|
|
283
|
+
darkValue={material3Language.semanticDark.outlineVariant}
|
|
284
|
+
description="Decorative borders and dividers"
|
|
285
|
+
/>
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
### Inverse Colors
|
|
289
|
+
|
|
290
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
291
|
+
<SemanticSwatch
|
|
292
|
+
name="inverseSurface"
|
|
293
|
+
lightValue={material3Language.semantic.inverseSurface}
|
|
294
|
+
darkValue={material3Language.semanticDark.inverseSurface}
|
|
295
|
+
description="Inverted surface (e.g., tooltips, snackbars)"
|
|
296
|
+
/>
|
|
297
|
+
<SemanticSwatch
|
|
298
|
+
name="inverseOnSurface"
|
|
299
|
+
lightValue={material3Language.semantic.inverseOnSurface}
|
|
300
|
+
darkValue={material3Language.semanticDark.inverseOnSurface}
|
|
301
|
+
description="Text on inverse surface"
|
|
302
|
+
/>
|
|
303
|
+
<SemanticSwatch
|
|
304
|
+
name="inversePrimary"
|
|
305
|
+
lightValue={material3Language.semantic.inversePrimary}
|
|
306
|
+
darkValue={material3Language.semanticDark.inversePrimary}
|
|
307
|
+
description="Primary color on inverse surface"
|
|
308
|
+
/>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
### Utility Colors
|
|
312
|
+
|
|
313
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '24px', marginBottom: '32px' }}>
|
|
314
|
+
<SemanticSwatch
|
|
315
|
+
name="background"
|
|
316
|
+
lightValue={material3Language.semantic.background}
|
|
317
|
+
darkValue={material3Language.semanticDark.background}
|
|
318
|
+
description="Page background color"
|
|
319
|
+
/>
|
|
320
|
+
<SemanticSwatch
|
|
321
|
+
name="onBackground"
|
|
322
|
+
lightValue={material3Language.semantic.onBackground}
|
|
323
|
+
darkValue={material3Language.semanticDark.onBackground}
|
|
324
|
+
description="Text/icons on background"
|
|
325
|
+
/>
|
|
326
|
+
<SemanticSwatch
|
|
327
|
+
name="scrim"
|
|
328
|
+
lightValue={material3Language.semantic.scrim}
|
|
329
|
+
darkValue={material3Language.semanticDark.scrim}
|
|
330
|
+
description="Overlay for modals and dialogs"
|
|
331
|
+
/>
|
|
332
|
+
<SemanticSwatch
|
|
333
|
+
name="shadow"
|
|
334
|
+
lightValue={material3Language.semantic.shadow}
|
|
335
|
+
darkValue={material3Language.semanticDark.shadow}
|
|
336
|
+
description="Shadow color for elevation"
|
|
337
|
+
/>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Usage Guidelines
|
|
343
|
+
|
|
344
|
+
### When to Use Semantic Tokens vs Tonal Palettes
|
|
345
|
+
|
|
346
|
+
**✅ Always use semantic tokens** for:
|
|
347
|
+
- Component backgrounds and text
|
|
348
|
+
- Interactive states (hover, focus, disabled)
|
|
349
|
+
- Theme-aware UI elements
|
|
350
|
+
- Any production code
|
|
351
|
+
|
|
352
|
+
**⚠️ Only use tonal palettes** when:
|
|
353
|
+
- Creating new semantic tokens
|
|
354
|
+
- Generating custom color schemes
|
|
355
|
+
- Design exploration and prototyping
|
|
356
|
+
|
|
357
|
+
### Example Usage in Components
|
|
358
|
+
|
|
359
|
+
```tsx
|
|
360
|
+
import { css } from 'styled-system/css';
|
|
361
|
+
|
|
362
|
+
// ✅ Good: Using semantic tokens
|
|
363
|
+
const buttonStyle = css({
|
|
364
|
+
bg: 'primary',
|
|
365
|
+
color: 'onPrimary',
|
|
366
|
+
_hover: {
|
|
367
|
+
bg: 'primaryContainer'
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// ❌ Bad: Using tonal palette directly
|
|
372
|
+
const buttonStyle = css({
|
|
373
|
+
bg: '#4C662B', // Hard-coded color
|
|
374
|
+
color: '#FFFFFF'
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Accessibility
|
|
379
|
+
|
|
380
|
+
All semantic token pairings (e.g., `primary` with `onPrimary`) meet WCAG AA contrast requirements. When creating custom combinations, always verify contrast ratios.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
import { ElevationGrid } from './components/ElevationCard';
|
|
3
|
+
import { material3Language } from '../../languages/material3.language';
|
|
4
|
+
|
|
5
|
+
<Meta title="Foundations/Elevation" />
|
|
6
|
+
|
|
7
|
+
# Elevation
|
|
8
|
+
|
|
9
|
+
Elevation in Material Design 3 creates depth and hierarchy through the use of shadows. The Discourser Design System provides 6 elevation levels, from no elevation to the highest prominence.
|
|
10
|
+
|
|
11
|
+
## Elevation Scale
|
|
12
|
+
|
|
13
|
+
<ElevationGrid elevations={material3Language.elevation.levels} />
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Elevation Reference
|
|
18
|
+
|
|
19
|
+
| Level | Shadow Value | Use Case |
|
|
20
|
+
|-------|--------------|----------|
|
|
21
|
+
| **level0** | none | Flat elements, no elevation needed |
|
|
22
|
+
| **level1** | `0px 1px 2px rgba(0,0,0,0.3), 0px 1px 3px 1px rgba(0,0,0,0.15)` | Cards at rest, contained buttons |
|
|
23
|
+
| **level2** | `0px 1px 2px rgba(0,0,0,0.3), 0px 2px 6px 2px rgba(0,0,0,0.15)` | Cards on hover, raised buttons |
|
|
24
|
+
| **level3** | `0px 4px 8px 3px rgba(0,0,0,0.15), 0px 1px 3px rgba(0,0,0,0.3)` | Dialogs, dropdowns, popovers |
|
|
25
|
+
| **level4** | `0px 6px 10px 4px rgba(0,0,0,0.15), 0px 2px 3px rgba(0,0,0,0.3)` | Navigation drawer, modal sheets |
|
|
26
|
+
| **level5** | `0px 8px 12px 6px rgba(0,0,0,0.15), 0px 4px 4px rgba(0,0,0,0.3)` | Floating action buttons, tooltips |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Usage Guidelines
|
|
31
|
+
|
|
32
|
+
### Component Elevation Hierarchy
|
|
33
|
+
|
|
34
|
+
Material Design 3 uses elevation to communicate importance and interactivity:
|
|
35
|
+
|
|
36
|
+
**Level 0 (No Elevation)**
|
|
37
|
+
- Background surfaces
|
|
38
|
+
- Flat buttons
|
|
39
|
+
- Content that shouldn't float
|
|
40
|
+
|
|
41
|
+
**Level 1 (Subtle)**
|
|
42
|
+
- Cards in their default state
|
|
43
|
+
- Contained buttons
|
|
44
|
+
- Search bars
|
|
45
|
+
- List items with separation
|
|
46
|
+
|
|
47
|
+
**Level 2 (Moderate)**
|
|
48
|
+
- Cards on hover
|
|
49
|
+
- Raised buttons
|
|
50
|
+
- Chips
|
|
51
|
+
- App bars
|
|
52
|
+
|
|
53
|
+
**Level 3 (Prominent)**
|
|
54
|
+
- Dialogs and modals
|
|
55
|
+
- Dropdown menus
|
|
56
|
+
- Date pickers
|
|
57
|
+
- Autocomplete suggestions
|
|
58
|
+
|
|
59
|
+
**Level 4 (High)**
|
|
60
|
+
- Navigation drawers
|
|
61
|
+
- Bottom sheets
|
|
62
|
+
- Side sheets
|
|
63
|
+
- Large modals
|
|
64
|
+
|
|
65
|
+
**Level 5 (Highest)**
|
|
66
|
+
- Floating Action Buttons (FAB)
|
|
67
|
+
- Tooltips
|
|
68
|
+
- Snackbars
|
|
69
|
+
- Banner notifications
|
|
70
|
+
|
|
71
|
+
### Interactive States
|
|
72
|
+
|
|
73
|
+
Use elevation changes to indicate interactivity:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { css } from 'styled-system/css';
|
|
77
|
+
|
|
78
|
+
const interactiveCardStyle = css({
|
|
79
|
+
boxShadow: 'level1',
|
|
80
|
+
transition: 'box-shadow 200ms',
|
|
81
|
+
_hover: {
|
|
82
|
+
boxShadow: 'level2'
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Accessibility Considerations
|
|
88
|
+
|
|
89
|
+
**Don't rely on elevation alone** to convey meaning:
|
|
90
|
+
- Elevation is visual only
|
|
91
|
+
- Use proper semantic HTML
|
|
92
|
+
- Provide alternative cues (borders, colors, icons)
|
|
93
|
+
- Consider users with low vision or color blindness
|
|
94
|
+
|
|
95
|
+
### Dark Mode
|
|
96
|
+
|
|
97
|
+
Elevation works differently in dark themes:
|
|
98
|
+
- In light themes, shadows create depth
|
|
99
|
+
- In dark themes, surfaces also get lighter tints with higher elevation
|
|
100
|
+
- This is handled automatically by Material Design 3
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Visual Comparison
|
|
105
|
+
|
|
106
|
+
### Cards with Different Elevations
|
|
107
|
+
|
|
108
|
+
<div style={{
|
|
109
|
+
display: 'grid',
|
|
110
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
111
|
+
gap: '24px',
|
|
112
|
+
padding: '32px',
|
|
113
|
+
backgroundColor: '#f5f5f5',
|
|
114
|
+
borderRadius: '8px',
|
|
115
|
+
marginBottom: '32px'
|
|
116
|
+
}}>
|
|
117
|
+
<div style={{
|
|
118
|
+
padding: '24px',
|
|
119
|
+
backgroundColor: '#fff',
|
|
120
|
+
borderRadius: '12px',
|
|
121
|
+
boxShadow: material3Language.elevation.levels.level0,
|
|
122
|
+
textAlign: 'center'
|
|
123
|
+
}}>
|
|
124
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 0</div>
|
|
125
|
+
<div style={{ fontSize: '12px', color: '#666' }}>Flat surface</div>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<div style={{
|
|
129
|
+
padding: '24px',
|
|
130
|
+
backgroundColor: '#fff',
|
|
131
|
+
borderRadius: '12px',
|
|
132
|
+
boxShadow: material3Language.elevation.levels.level1,
|
|
133
|
+
textAlign: 'center'
|
|
134
|
+
}}>
|
|
135
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 1</div>
|
|
136
|
+
<div style={{ fontSize: '12px', color: '#666' }}>Subtle depth</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div style={{
|
|
140
|
+
padding: '24px',
|
|
141
|
+
backgroundColor: '#fff',
|
|
142
|
+
borderRadius: '12px',
|
|
143
|
+
boxShadow: material3Language.elevation.levels.level2,
|
|
144
|
+
textAlign: 'center'
|
|
145
|
+
}}>
|
|
146
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 2</div>
|
|
147
|
+
<div style={{ fontSize: '12px', color: '#666' }}>Moderate depth</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
### Floating Elements
|
|
152
|
+
|
|
153
|
+
<div style={{
|
|
154
|
+
display: 'grid',
|
|
155
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
156
|
+
gap: '24px',
|
|
157
|
+
padding: '32px',
|
|
158
|
+
backgroundColor: '#f5f5f5',
|
|
159
|
+
borderRadius: '8px'
|
|
160
|
+
}}>
|
|
161
|
+
<div style={{
|
|
162
|
+
padding: '24px',
|
|
163
|
+
backgroundColor: '#fff',
|
|
164
|
+
borderRadius: '12px',
|
|
165
|
+
boxShadow: material3Language.elevation.levels.level3,
|
|
166
|
+
textAlign: 'center'
|
|
167
|
+
}}>
|
|
168
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 3</div>
|
|
169
|
+
<div style={{ fontSize: '12px', color: '#666' }}>Prominent float</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<div style={{
|
|
173
|
+
padding: '24px',
|
|
174
|
+
backgroundColor: '#fff',
|
|
175
|
+
borderRadius: '12px',
|
|
176
|
+
boxShadow: material3Language.elevation.levels.level4,
|
|
177
|
+
textAlign: 'center'
|
|
178
|
+
}}>
|
|
179
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 4</div>
|
|
180
|
+
<div style={{ fontSize: '12px', color: '#666' }}>High elevation</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<div style={{
|
|
184
|
+
padding: '24px',
|
|
185
|
+
backgroundColor: '#fff',
|
|
186
|
+
borderRadius: '12px',
|
|
187
|
+
boxShadow: material3Language.elevation.levels.level5,
|
|
188
|
+
textAlign: 'center'
|
|
189
|
+
}}>
|
|
190
|
+
<div style={{ fontWeight: '600', marginBottom: '8px' }}>Level 5</div>
|
|
191
|
+
<div style={{ fontSize: '12px', color: '#666' }}>Highest elevation</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Example Usage
|
|
198
|
+
|
|
199
|
+
### Basic Elevation
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { css } from 'styled-system/css';
|
|
203
|
+
|
|
204
|
+
const cardStyle = css({
|
|
205
|
+
boxShadow: 'level1',
|
|
206
|
+
borderRadius: 'medium',
|
|
207
|
+
padding: 'lg'
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Interactive Elevation
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { css } from 'styled-system/css';
|
|
215
|
+
|
|
216
|
+
const elevatedButtonStyle = css({
|
|
217
|
+
boxShadow: 'level2',
|
|
218
|
+
transition: 'all',
|
|
219
|
+
transitionDuration: 'fast',
|
|
220
|
+
_hover: {
|
|
221
|
+
boxShadow: 'level3'
|
|
222
|
+
},
|
|
223
|
+
_active: {
|
|
224
|
+
boxShadow: 'level1'
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Modal Overlay
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
import { css } from 'styled-system/css';
|
|
233
|
+
|
|
234
|
+
const modalStyle = css({
|
|
235
|
+
position: 'fixed',
|
|
236
|
+
top: '50%',
|
|
237
|
+
left: '50%',
|
|
238
|
+
transform: 'translate(-50%, -50%)',
|
|
239
|
+
boxShadow: 'level3',
|
|
240
|
+
borderRadius: 'large',
|
|
241
|
+
backgroundColor: 'surface',
|
|
242
|
+
padding: 'xl'
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Best Practices
|
|
249
|
+
|
|
250
|
+
### Do's ✅
|
|
251
|
+
|
|
252
|
+
- Use elevation consistently across similar components
|
|
253
|
+
- Animate elevation changes for smooth transitions
|
|
254
|
+
- Reserve higher elevations for truly important elements
|
|
255
|
+
- Test elevation in both light and dark themes
|
|
256
|
+
- Consider mobile devices where shadows may be subtle
|
|
257
|
+
|
|
258
|
+
### Don'ts ❌
|
|
259
|
+
|
|
260
|
+
- Don't use too many different elevation levels on one screen
|
|
261
|
+
- Don't stack elements with the same elevation
|
|
262
|
+
- Don't use elevation as the only indicator of interactivity
|
|
263
|
+
- Don't apply elevation to every element
|
|
264
|
+
- Don't forget to transition elevation changes
|
|
265
|
+
|
|
266
|
+
### Performance
|
|
267
|
+
|
|
268
|
+
Shadows can impact rendering performance:
|
|
269
|
+
- Use CSS box-shadow (not filters) for best performance
|
|
270
|
+
- Consider reducing elevation complexity on mobile
|
|
271
|
+
- Avoid animating shadows on many elements simultaneously
|
|
272
|
+
- Test on low-end devices
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Surface Containers vs Elevation
|
|
277
|
+
|
|
278
|
+
Material Design 3 provides two ways to create depth:
|
|
279
|
+
|
|
280
|
+
**Elevation (Shadows)**
|
|
281
|
+
- Creates visual depth through shadows
|
|
282
|
+
- Best for floating elements
|
|
283
|
+
- More prominent visual effect
|
|
284
|
+
- Works in both light and dark themes
|
|
285
|
+
|
|
286
|
+
**Surface Containers (Tonal Levels)**
|
|
287
|
+
- Creates depth through color tints
|
|
288
|
+
- Best for stacked surfaces
|
|
289
|
+
- Subtle, material-like layering
|
|
290
|
+
- See the Colors documentation for surface container tokens
|
|
291
|
+
|
|
292
|
+
Use surface containers for general layering, and elevation for interactive or floating elements.
|