@bug-on/md3-react 0.1.0
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/README.md +215 -0
- package/dist/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
- package/dist/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
- package/dist/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
- package/dist/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
- package/dist/assets/loading-indicator.svg +19 -0
- package/dist/assets/material-symbols-cdn.css +65 -0
- package/dist/assets/material-symbols-self-hosted.css +109 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/useMediaQuery.d.ts +11 -0
- package/dist/hooks/useRipple.d.ts +26 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +9059 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +8929 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/material-symbols-preconnect.d.ts +42 -0
- package/dist/lib/theme-utils.d.ts +63 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/material-symbols-cdn.css +65 -0
- package/dist/material-symbols-self-hosted.css +109 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/md3.d.ts +14 -0
- package/dist/typography.css +22 -0
- package/dist/ui/badge.d.ts +125 -0
- package/dist/ui/button-group.d.ts +59 -0
- package/dist/ui/button.d.ts +148 -0
- package/dist/ui/card.d.ts +62 -0
- package/dist/ui/checkbox.d.ts +82 -0
- package/dist/ui/chip.d.ts +110 -0
- package/dist/ui/code-block.d.ts +14 -0
- package/dist/ui/dialog.d.ts +111 -0
- package/dist/ui/divider.d.ts +164 -0
- package/dist/ui/drawer.d.ts +39 -0
- package/dist/ui/dropdown.d.ts +29 -0
- package/dist/ui/fab-menu.d.ts +204 -0
- package/dist/ui/fab.d.ts +162 -0
- package/dist/ui/icon-button.d.ts +131 -0
- package/dist/ui/icon.d.ts +88 -0
- package/dist/ui/loading-indicator.d.ts +42 -0
- package/dist/ui/navigation-rail.d.ts +29 -0
- package/dist/ui/progress-indicator/circular.d.ts +3 -0
- package/dist/ui/progress-indicator/hooks.d.ts +3 -0
- package/dist/ui/progress-indicator/index.d.ts +21 -0
- package/dist/ui/progress-indicator/linear-flat.d.ts +10 -0
- package/dist/ui/progress-indicator/linear-wavy.d.ts +18 -0
- package/dist/ui/progress-indicator/linear.d.ts +3 -0
- package/dist/ui/progress-indicator/types.d.ts +151 -0
- package/dist/ui/progress-indicator/utils.d.ts +3 -0
- package/dist/ui/radio-button.d.ts +106 -0
- package/dist/ui/ripple.d.ts +126 -0
- package/dist/ui/scroll-area.d.ts +27 -0
- package/dist/ui/shared/constants.d.ts +86 -0
- package/dist/ui/shared/touch-target.d.ts +38 -0
- package/dist/ui/snackbar/index.d.ts +6 -0
- package/dist/ui/snackbar/snackbar.d.ts +196 -0
- package/dist/ui/switch/index.d.ts +7 -0
- package/dist/ui/switch/switch.d.ts +30 -0
- package/dist/ui/switch/switch.stories.d.ts +48 -0
- package/dist/ui/switch/switch.tokens.d.ts +67 -0
- package/dist/ui/switch/switch.types.d.ts +59 -0
- package/dist/ui/tabs/index.d.ts +10 -0
- package/dist/ui/tabs/tab.d.ts +43 -0
- package/dist/ui/tabs/tabs-content.d.ts +36 -0
- package/dist/ui/tabs/tabs-list.d.ts +40 -0
- package/dist/ui/tabs/tabs.d.ts +60 -0
- package/dist/ui/tabs/tabs.tokens.d.ts +94 -0
- package/dist/ui/tabs/tabs.types.d.ts +172 -0
- package/dist/ui/text-field/index.d.ts +11 -0
- package/dist/ui/text-field/subcomponents/active-indicator.d.ts +24 -0
- package/dist/ui/text-field/subcomponents/floating-label.d.ts +43 -0
- package/dist/ui/text-field/subcomponents/leading-icon.d.ts +23 -0
- package/dist/ui/text-field/subcomponents/outline-container.d.ts +42 -0
- package/dist/ui/text-field/subcomponents/prefix-suffix.d.ts +24 -0
- package/dist/ui/text-field/subcomponents/supporting-text.d.ts +37 -0
- package/dist/ui/text-field/subcomponents/trailing-icon.d.ts +41 -0
- package/dist/ui/text-field/text-field.d.ts +49 -0
- package/dist/ui/text-field/text-field.tokens.d.ts +76 -0
- package/dist/ui/text-field/text-field.types.d.ts +126 -0
- package/dist/ui/theme-provider/index.d.ts +18 -0
- package/dist/ui/toc.d.ts +74 -0
- package/dist/ui/tooltip/index.d.ts +8 -0
- package/dist/ui/tooltip/plain-tooltip.d.ts +2 -0
- package/dist/ui/tooltip/rich-tooltip.d.ts +2 -0
- package/dist/ui/tooltip/tooltip-box.d.ts +2 -0
- package/dist/ui/tooltip/tooltip-caret-shape.d.ts +9 -0
- package/dist/ui/tooltip/tooltip.tokens.d.ts +26 -0
- package/dist/ui/tooltip/tooltip.types.d.ts +56 -0
- package/dist/ui/tooltip/use-tooltip-position.d.ts +8 -0
- package/dist/ui/tooltip/use-tooltip-state.d.ts +2 -0
- package/dist/ui/typography/index.d.ts +16 -0
- package/dist/ui/typography/type-scale-tokens.d.ts +162 -0
- package/dist/ui/typography/typography-key-tokens.d.ts +40 -0
- package/dist/ui/typography/typography-tokens.d.ts +220 -0
- package/dist/ui/typography/typography.d.ts +265 -0
- package/package.json +80 -0
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# @bug-on/md3-react
|
|
2
|
+
|
|
3
|
+
> ⚠️ **Work in progress** — Material Design 3 Expressive React Component Library
|
|
4
|
+
|
|
5
|
+
Thư viện UI React với đầy đủ animation, accessible (a11y), hỗ trợ Next.js App Router.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @bug-on/md3-react
|
|
11
|
+
# hoặc
|
|
12
|
+
pnpm add @bug-on/md3-react
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Peer Dependencies
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react react-dom
|
|
19
|
+
# Optional (cho animated components):
|
|
20
|
+
npm install motion
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Setup với TailwindCSS v4
|
|
24
|
+
|
|
25
|
+
```css
|
|
26
|
+
/* globals.css */
|
|
27
|
+
@import "@bug-on/md3-tailwind";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { Button, useRipple } from '@bug-on/md3-react';
|
|
34
|
+
|
|
35
|
+
export default function Page() {
|
|
36
|
+
return (
|
|
37
|
+
<Button colorStyle="filled" size="md">
|
|
38
|
+
Get Started
|
|
39
|
+
</Button>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Components
|
|
45
|
+
|
|
46
|
+
| Component | Description |
|
|
47
|
+
|--------------|--------------------------------------------|
|
|
48
|
+
| `Button` | MD3 Expressive button, 5 variants, 5 sizes |
|
|
49
|
+
| `ButtonGroup`| Group toggle buttons |
|
|
50
|
+
| `Card` | MD3 Card container |
|
|
51
|
+
| `CodeBlock` | Syntax-highlighted code block |
|
|
52
|
+
| `Icon` | Material Symbols variable font icon |
|
|
53
|
+
|
|
54
|
+
## Icons
|
|
55
|
+
|
|
56
|
+
`<Icon />` renders [Material Symbols](https://fonts.google.com/icons) using a CSS variable font — zero SVG overhead, all 4 axes controllable as props.
|
|
57
|
+
|
|
58
|
+
### 1. Load the font
|
|
59
|
+
|
|
60
|
+
There are two ways to load the font depending on your use case.
|
|
61
|
+
|
|
62
|
+
#### Option A: CDN Mode (Default & easiest)
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// 1. Import CDN CSS (In your main app entry, e.g. layout.tsx / main.tsx)
|
|
66
|
+
import '@bug-on/md3-react/material-symbols-cdn.css';
|
|
67
|
+
|
|
68
|
+
// 2. Add Preconnect to <head> as early as possible for best performance
|
|
69
|
+
import { MaterialSymbolsPreconnect } from '@bug-on/md3-react';
|
|
70
|
+
|
|
71
|
+
export default function RootLayout({ children }) {
|
|
72
|
+
return (
|
|
73
|
+
<html>
|
|
74
|
+
<head>
|
|
75
|
+
<MaterialSymbolsPreconnect />
|
|
76
|
+
</head>
|
|
77
|
+
<body>{children}</body>
|
|
78
|
+
</html>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Option B: Self-Hosted Mode (Production / GDPR)
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
// 1. Download font from: https://github.com/google/material-design-icons/tree/master/variablefont
|
|
87
|
+
// 2. Place it in your public/fonts/ directory
|
|
88
|
+
// 3. Import Self-hosted CSS
|
|
89
|
+
import '@bug-on/md3-react/material-symbols-self-hosted.css';
|
|
90
|
+
|
|
91
|
+
// Note: MaterialSymbolsPreconnect is NOT needed for self-hosting
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
> **Why `font-display: block`?**
|
|
95
|
+
> We specifically use `block` instead of `swap` for icon fonts to prevent layout shift. If `swap` is used, the browser renders the raw text (like "arrow_forward") until the font loads, which looks broken.
|
|
96
|
+
|
|
97
|
+
### 2. Basic usage
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { Icon } from '@bug-on/md3-react';
|
|
101
|
+
|
|
102
|
+
<Icon name="home" />
|
|
103
|
+
<Icon name="arrow_forward" />
|
|
104
|
+
<Icon name="settings" variant="rounded" />
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
> **Note:** Icon names use `snake_case` ligatures — `"arrow_forward"`, not `"ArrowForward"`.
|
|
108
|
+
|
|
109
|
+
### 3. Props
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Default | Description |
|
|
112
|
+
|------|------|---------|-------------|
|
|
113
|
+
| `name` | `string` | *required* | Material Symbol name (snake_case) |
|
|
114
|
+
| `variant` | `'outlined' \| 'rounded' \| 'sharp'` | `'outlined'` | Font family variant |
|
|
115
|
+
| `fill` | `0 \| 1` | `0` | FILL axis — 0=outlined, 1=filled |
|
|
116
|
+
| `weight` | `100..700` | `400` | wght axis — stroke weight |
|
|
117
|
+
| `grade` | `-50 \| -25 \| 0 \| 100 \| 200` | `0` | GRAD axis — fine weight adjustment |
|
|
118
|
+
| `opticalSize` | `20 \| 24 \| 40 \| 48` | `24` | opsz axis + font-size |
|
|
119
|
+
| `size` | `number` | — | Explicit font-size override (px) |
|
|
120
|
+
| `animateFill` | `boolean` | `false` | Spring-animate FILL transitions |
|
|
121
|
+
| `className` | `string` | — | Additional Tailwind/CSS classes |
|
|
122
|
+
|
|
123
|
+
### 4. Variable font axes
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
// Heavier weight — matches Bold typography
|
|
127
|
+
<Icon name="star" weight={700} />
|
|
128
|
+
|
|
129
|
+
// Filled, optimised for 48dp display
|
|
130
|
+
<Icon name="favorite" fill={1} opticalSize={48} />
|
|
131
|
+
|
|
132
|
+
// Dark background compensation (grade reduces visual weight)
|
|
133
|
+
<Icon name="home" grade={-25} className="text-white" />
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 5. Animated fill
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
const [isLiked, setIsLiked] = useState(false);
|
|
140
|
+
|
|
141
|
+
<Icon
|
|
142
|
+
name="favorite"
|
|
143
|
+
fill={isLiked ? 1 : 0}
|
|
144
|
+
animateFill
|
|
145
|
+
className="text-red-500"
|
|
146
|
+
/>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
When `animateFill` is true, the icon uses `motion/react` (`m.span`) to spring-animate the `font-variation-settings` transition — same critically-damped spring as button shape morphing.
|
|
150
|
+
|
|
151
|
+
### 6. As icon prop for other components
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
<Button icon={<Icon name="add" />}>New item</Button>
|
|
155
|
+
<Button icon={<Icon name="send" fill={1} />} iconPosition="trailing">Send</Button>
|
|
156
|
+
|
|
157
|
+
<IconButton aria-label="Close" onClick={handleClose}>
|
|
158
|
+
<Icon name="close" />
|
|
159
|
+
</IconButton>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 7. Tailwind utility classes
|
|
163
|
+
|
|
164
|
+
The `@bug-on/md3-tailwind` plugin adds icon utility classes for CSS-only control:
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<!-- Variant -->
|
|
168
|
+
<span class="md-icon icon-rounded">home</span>
|
|
169
|
+
|
|
170
|
+
<!-- Fill -->
|
|
171
|
+
<span class="md-icon icon-fill-1">favorite</span>
|
|
172
|
+
|
|
173
|
+
<!-- Weight -->
|
|
174
|
+
<span class="md-icon icon-weight-300">star</span>
|
|
175
|
+
|
|
176
|
+
<!-- Grade (named aliases) -->
|
|
177
|
+
<span class="md-icon icon-grade-low">settings</span> <!-- -25 -->
|
|
178
|
+
<span class="md-icon icon-grade-high">star</span> <!-- 200 -->
|
|
179
|
+
|
|
180
|
+
<!-- Size (sets font-size + opsz axis together) -->
|
|
181
|
+
<span class="md-icon icon-size-48">home</span>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 8. Production optimisation — Font subsetting
|
|
185
|
+
|
|
186
|
+
The full Material Symbols font is ~295 KB. For production, subset to only the icons you use:
|
|
187
|
+
|
|
188
|
+
```css
|
|
189
|
+
/* In your CSS, replace the CDN import with a subsetted URL */
|
|
190
|
+
@import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&icon_names=arrow_forward,close,home,settings&display=block');
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Each icon adds ~1.7 KB. See [Google Fonts subsetting docs](https://developers.google.com/fonts/docs/material_symbols#use_the_icon_font_from_google_fonts).
|
|
194
|
+
|
|
195
|
+
### 9. Self-hosting
|
|
196
|
+
|
|
197
|
+
For offline/production use, see the self-hosting guide inside `material-symbols-self-hosted.css` (comments include `@font-face` declarations for all three variants).
|
|
198
|
+
|
|
199
|
+
## Hooks
|
|
200
|
+
|
|
201
|
+
| Hook | Description |
|
|
202
|
+
|------------------|---------------------------------------------|
|
|
203
|
+
| `useRipple` | MD3 Ripple effect (thuần DOM, no-lib) |
|
|
204
|
+
| `useMediaQuery` | SSR-safe responsive media query hook |
|
|
205
|
+
|
|
206
|
+
## Accessibility
|
|
207
|
+
|
|
208
|
+
Tất cả components tuân thủ **WAI-ARIA** guidelines:
|
|
209
|
+
- Đầy đủ `aria-*` attributes
|
|
210
|
+
- Focus visible rõ ràng
|
|
211
|
+
- Keyboard navigation
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg width="100%" height="100%" viewBox="4 4 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill="#D0BCFF">
|
|
3
|
+
<animate attributeName="d" dur="5s" repeatCount="indefinite" calcMode="spline" keySplines="0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8" keyTimes="0; 0.14; 0.14; 0.29; 0.29; 0.43; 0.43; 0.57; 0.57; 0.71; 0.71; 0.86; 0.86; 1" values="M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z;
|
|
4
|
+
M20.3 8.6 21.1 8 22 7.6 23 7.3 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.2 15.5 37.6 16.5 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8 17.6 9.8 18.6 9.6 19.5 9.2Z;
|
|
5
|
+
M18.6 9.6 19.5 9.2 20.3 8.6 21.1 8 22 7.6 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.6 16.4 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8Z;
|
|
6
|
+
M18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.2 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 33.7 13.1 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.5 30.5 39.5 30 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7.1 21.7 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8 15.4 12.3 16.2 11.7 17 11.1 17.8 10.5Z;
|
|
7
|
+
M15.4 12.3 16.2 11.7 17 11.1 17.8 10.5 18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.3 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.4 30.5 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8Z;
|
|
8
|
+
M17 12.8 17.7 12.1 18.5 11.5 19.3 10.9 20.1 10.5 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 25 9 26 9 27 9 27.6 9.1 28 9.1 28.9 9.3 29.9 9.6 30.9 9.9 31.8 10.3 32.6 10.8 33.5 11.3 34.3 11.9 34.6 12.2 35 12.6 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.6 18.5 38.6 18.7 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.3 38.2 26.4 37.8 27.3 37.4 28.2 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.8 32.5 33.5 32.8 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.2 37.3 27.9 37.5 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 22.5 39 21.5 39 20.5 38.9 20.4 38.9 19.5 38.8 18.6 38.6 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.4 35.8 13.3 35.8 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.6 30 9.4 29.3 9.3 29 9.1 28 9 27 9 26 9 25 9.2 24 9.4 23 9.6 22.1 9.8 21.7 10 21.1 10.4 20.2 10.9 19.4 11.4 18.5 12.1 17.8 12.7 17 13.4 16.3 14.2 15.6 14.2 15.5 14.9 14.9 15.6 14.2 16.3 13.5Z;
|
|
9
|
+
M33.5 11.3 34.3 11.9 35 12.6 35.3 12.8 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.3 17.7 38.6 18.5 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.4 37.8 27.3 37.4 28.2 36.9 28.9 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.5 32.8 33.1 33.2 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.7 37 28.2 37.3 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 23.3 38.9 22.5 39 21.5 39 20.5 38.9 19.5 38.8 18.6 38.6 17.6 38.3 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.3 35.8 12.7 35.2 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.7 30.3 9.6 29.9 9.3 29 9.1 28 9 27 9 26 9 25 9.1 24.5 9.2 24 9.4 23 9.6 22.1 10 21.1 10.4 20.2 10.9 19.4 11.1 19.1 11.5 18.5 12.1 17.7 12.7 17 13.5 16.3 14.2 15.6 14.9 14.9 14.9 14.8 15.6 14.2 16.3 13.5 17 12.8 17.7 12.1 18.5 11.5 19.3 11 19.3 10.9 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 24.7 9.1 25 9 26 9 27 9 28 9.1 28.9 9.3 29.9 9.6 30.4 9.7 30.9 9.9 31.8 10.3 32.6 10.8Z;
|
|
10
|
+
M33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.8 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.6 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7 27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1Z;
|
|
11
|
+
M27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1 33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.9 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.5 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7Z;
|
|
12
|
+
M27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 34.8 11.3 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.9 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.4 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35 36 35.7 35.3 36.4 34.4 37 34.1 37.2 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.6 10 30.1 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10 16.6 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 20.9 11 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11Z;
|
|
13
|
+
M36 35.7 35.3 36.4 34.4 37 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.2 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11 27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.8 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35Z;
|
|
14
|
+
M32.1 32.1 31.4 32.8 30.7 33.5 29.9 34.1 29.1 34.7 28.3 35.3 27.6 35.8 27.5 35.8 26.6 36.4 25.8 36.8 24.9 37.3 24 37.7 23.1 38 22.1 38.3 21.2 38.6 20.2 38.8 19.2 38.9 18.2 39 17.2 39 16.6 38.9 16.3 38.9 15.3 38.7 14.3 38.4 13.4 38 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10 34.6 9.6 33.7 9.3 32.7 9.1 31.7 9.1 31.4 9 30.8 9 29.8 9.1 28.8 9.2 27.8 9.4 26.8 9.7 25.9 10 24.9 10.3 24 10.7 23.1 11.2 22.2 11.6 21.4 12.2 20.5 12.2 20.4 12.7 19.7 13.3 18.9 13.9 18.1 14.5 17.3 15.2 16.6 15.9 15.9 16.6 15.2 17.3 14.5 18.1 13.9 18.9 13.3 19.7 12.7 20.4 12.2 20.5 12.2 21.4 11.6 22.2 11.2 23.1 10.7 24 10.3 24.9 10 25.9 9.7 26.8 9.4 27.8 9.2 28.8 9.1 29.8 9 30.8 9 31.4 9.1 31.7 9.1 32.7 9.3 33.7 9.6 34.6 10 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 38 13.4 38.4 14.3 38.7 15.3 38.9 16.3 38.9 16.6 39 17.2 39 18.2 38.9 19.2 38.8 20.2 38.6 21.2 38.3 22.1 38 23.1 37.7 24 37.3 24.9 36.8 25.8 36.4 26.6 35.8 27.5 35.8 27.6 35.3 28.3 34.7 29.1 34.1 29.9 33.5 30.7 32.8 31.4Z;
|
|
15
|
+
M24.3 10.2 24.9 10 25.9 9.7 26.8 9.4 27.1 9.4 27.8 9.2 28.8 9.1 29.8 9 29.9 9 30.8 9 31.7 9.1 32.7 9.3 32.8 9.3 33.7 9.6 34.6 10 35.5 10.5 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 37.5 12.5 38 13.4 38.4 14.3 38.7 15.2 38.7 15.3 38.9 16.3 39 17.2 39 18.1 39 18.2 38.9 19.2 38.8 20.2 38.6 20.9 38.6 21.2 38.3 22.1 38 23.1 37.8 23.7 37.7 24 37.3 24.9 36.8 25.8 36.5 26.4 36.4 26.6 35.8 27.5 35.3 28.3 35 28.8 34.7 29.1 34.1 29.9 33.5 30.7 33.1 31.1 32.8 31.4 32.1 32.1 31.4 32.8 31.1 33.1 30.7 33.5 29.9 34.1 29.1 34.7 28.8 35 28.3 35.3 27.5 35.8 26.6 36.4 26.4 36.5 25.8 36.8 24.9 37.3 24 37.7 23.7 37.8 23.1 38 22.1 38.3 21.2 38.6 20.9 38.6 20.2 38.8 19.2 38.9 18.2 39 18.1 39 17.2 39 16.3 38.9 15.3 38.7 15.2 38.7 14.3 38.4 13.4 38 12.5 37.5 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10.5 35.5 10 34.6 9.6 33.7 9.3 32.8 9.3 32.7 9.1 31.7 9 30.8 9 29.9 9 29.8 9.1 28.8 9.2 27.8 9.4 27.1 9.4 26.8 9.7 25.9 10 24.9 10.2 24.3 10.3 24 10.7 23.1 11.2 22.2 11.5 21.6 11.6 21.4 12.2 20.5 12.7 19.7 13 19.2 13.3 18.9 13.9 18.1 14.5 17.3 14.9 16.9 15.2 16.6 15.9 15.9 16.6 15.2 16.9 14.9 17.3 14.5 18.1 13.9 18.9 13.3 19.2 13 19.7 12.7 20.5 12.2 21.4 11.6 21.6 11.5 22.2 11.2 23.1 10.7 24 10.3Z;
|
|
16
|
+
M22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.3 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.4 38.9 26.2 39.6 27 40.2 27.7 40.5 28.6 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.8 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.6 9.1 21.8 8.4 21 7.8 20.3 7.5 19.4 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.2 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1 20.9 10.4 21.4 9.5 21.9 8.7Z"></animate>
|
|
17
|
+
<animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="5s" repeatCount="indefinite" calcMode="spline" keySplines="0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8; 0.5 0.2 0 0.8" keyTimes="0; 0.14; 0.29; 0.43; 0.57; 0.71; 0.86; 1" values="0 24 24; 154 24 24; 309 24 24; 463 24 24; 617 24 24; 771 24 24; 926 24 24; 1080 24 24"></animateTransform>
|
|
18
|
+
</path>
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Material Symbols — CDN version (Google Fonts)
|
|
3
|
+
*
|
|
4
|
+
* USAGE IN APP'S HTML <head>:
|
|
5
|
+
* Add preconnect hints BEFORE this CSS loads for fastest performance:
|
|
6
|
+
*
|
|
7
|
+
* <link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
* <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
|
9
|
+
*
|
|
10
|
+
* Then import this CSS:
|
|
11
|
+
* import '@bug-on/md3-react/material-symbols-cdn.css'
|
|
12
|
+
*
|
|
13
|
+
* WHY TWO preconnect?
|
|
14
|
+
* Google Fonts serves the CSS stylesheet from fonts.googleapis.com
|
|
15
|
+
* but the actual .woff2 font files come from fonts.gstatic.com (different origin).
|
|
16
|
+
* The crossorigin attribute is required for font files (CORS request).
|
|
17
|
+
*
|
|
18
|
+
* FONT-DISPLAY NOTE for icon fonts:
|
|
19
|
+
* We use font-display: block (NOT swap) because:
|
|
20
|
+
* - swap would briefly show raw text like "arrow_forward" before icon loads = jarring layout shift
|
|
21
|
+
* - block hides text during load period (max 3s), then shows icon = cleaner UX
|
|
22
|
+
* - optional is NOT suitable: if font misses the load window, icons never appear
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* INSTRUCTION:
|
|
27
|
+
* Use the <MaterialSymbolsPreconnect /> component to load the actual Google Fonts CSS!
|
|
28
|
+
*
|
|
29
|
+
* We NO LONGER use @import url(...) here because CSS bundlers (like Next.js/Webpack)
|
|
30
|
+
* often merge global CSS files and push @import statements below regular CSS rules.
|
|
31
|
+
* According to CSS spec, any @import MUST be at the very top, so it breaks randomly.
|
|
32
|
+
* Loading via `<link rel="stylesheet">` (handled by MaterialSymbolsPreconnect) is fully robust.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
* BASE ICON STYLES
|
|
37
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
*
|
|
39
|
+
* This class ensures that Material Symbols render correctly as ligatures
|
|
40
|
+
* across all browsers and prevents common layout issues.
|
|
41
|
+
*/
|
|
42
|
+
.md-icon {
|
|
43
|
+
font-family: inherit; /* Set dynamically by the Icon component */
|
|
44
|
+
font-weight: normal;
|
|
45
|
+
font-style: normal;
|
|
46
|
+
display: inline-flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
width: 1em;
|
|
50
|
+
height: 1em;
|
|
51
|
+
line-height: normal;
|
|
52
|
+
text-transform: none;
|
|
53
|
+
letter-spacing: normal;
|
|
54
|
+
word-wrap: normal;
|
|
55
|
+
white-space: nowrap;
|
|
56
|
+
direction: ltr;
|
|
57
|
+
|
|
58
|
+
/* Enable ligature rendering support for modern browsers */
|
|
59
|
+
font-feature-settings: "liga";
|
|
60
|
+
|
|
61
|
+
/* Improved rendering quality */
|
|
62
|
+
-webkit-font-smoothing: antialiased;
|
|
63
|
+
-moz-osx-font-smoothing: grayscale;
|
|
64
|
+
text-rendering: optimizeLegibility;
|
|
65
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Material Symbols — Self-Hosted version
|
|
3
|
+
*
|
|
4
|
+
* SETUP STEPS:
|
|
5
|
+
*
|
|
6
|
+
* Step 1 — Download font files
|
|
7
|
+
* Truy cập: https://github.com/google/material-design-icons/tree/master/variablefont
|
|
8
|
+
* Download file: MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2
|
|
9
|
+
* (và Rounded / Sharp nếu cần)
|
|
10
|
+
*
|
|
11
|
+
* Step 2 — Place font files in your app
|
|
12
|
+
* Recommended location: public/fonts/ hoặc src/assets/fonts/
|
|
13
|
+
* Example: public/fonts/MaterialSymbolsOutlined.woff2
|
|
14
|
+
*
|
|
15
|
+
* Step 3 — Copy và điều chỉnh @font-face block bên dưới
|
|
16
|
+
* Thay đổi src url() để trỏ đúng đường dẫn trong project của bạn
|
|
17
|
+
*
|
|
18
|
+
* Step 4 — Import file này:
|
|
19
|
+
* import '@bug-on/md3-react/material-symbols-self-hosted.css'
|
|
20
|
+
*
|
|
21
|
+
* PERFORMANCE NOTES:
|
|
22
|
+
* - Self-hosting tốt hơn CDN khi bạn dùng CDN + HTTP/2 cho static assets
|
|
23
|
+
* - Nếu không có CDN, Google Fonts CDN có thể nhanh hơn do cache sharing
|
|
24
|
+
* - Dùng font-display: block cho icon fonts (xem lý do ở file CDN)
|
|
25
|
+
* - WOFF2 là format duy nhất cần thiết (100% modern browser support, Brotli compression)
|
|
26
|
+
* - Không cần WOFF fallback nữa
|
|
27
|
+
*
|
|
28
|
+
* SUBSETTING (QUAN TRỌNG để giảm file size):
|
|
29
|
+
* Full variable font ~295 KB. Sau khi subset còn ~1-2 KB cho vài chục icons.
|
|
30
|
+
* Dùng tool: https://everythingfonts.com/subsetter
|
|
31
|
+
* Hoặc dùng Google Fonts text parameter để subset trên CDN:
|
|
32
|
+
* ?family=Material+Symbols+Outlined&text=home%20search%20settings
|
|
33
|
+
*
|
|
34
|
+
* GDPR NOTE:
|
|
35
|
+
* Self-hosting loại bỏ việc gửi user IP đến Google servers,
|
|
36
|
+
* giải quyết GDPR compliance requirement.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
@font-face {
|
|
40
|
+
font-family: "Material Symbols Outlined";
|
|
41
|
+
font-style: normal;
|
|
42
|
+
/* Khai báo full axis range để browser biết đây là variable font */
|
|
43
|
+
font-weight: 100 700;
|
|
44
|
+
/* font-display: block là bắt buộc cho icon fonts:
|
|
45
|
+
* - Tránh render text thô "arrow_forward" thay vì icon
|
|
46
|
+
* - Max 3s block, sau đó icon xuất hiện
|
|
47
|
+
* Tham khảo: https://web.dev/articles/font-best-practices#icon_fonts */
|
|
48
|
+
font-display: block;
|
|
49
|
+
src: url("/fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2")
|
|
50
|
+
format("woff2");
|
|
51
|
+
/* unicode-range: chỉ load font khi page chứa ký tự trong range này.
|
|
52
|
+
* Material Symbols dùng PUA (Private Use Area) cho ligatures. */
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
* Rounded variant — uncomment nếu dùng
|
|
57
|
+
*
|
|
58
|
+
@font-face {
|
|
59
|
+
font-family: 'Material Symbols Rounded';
|
|
60
|
+
font-style: normal;
|
|
61
|
+
font-weight: 100 700;
|
|
62
|
+
font-display: block;
|
|
63
|
+
src: url('/fonts/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2') format('woff2');
|
|
64
|
+
}
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Sharp variant — uncomment nếu dùng
|
|
69
|
+
*
|
|
70
|
+
@font-face {
|
|
71
|
+
font-family: 'Material Symbols Sharp';
|
|
72
|
+
font-style: normal;
|
|
73
|
+
font-weight: 100 700;
|
|
74
|
+
font-display: block;
|
|
75
|
+
src: url('/fonts/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].woff2') format('woff2');
|
|
76
|
+
}
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
* BASE ICON STYLES
|
|
81
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
*
|
|
83
|
+
* This class ensures that Material Symbols render correctly as ligatures
|
|
84
|
+
* across all browsers and prevents common layout issues.
|
|
85
|
+
*/
|
|
86
|
+
.md-icon {
|
|
87
|
+
font-family: inherit; /* Set dynamically by the Icon component */
|
|
88
|
+
font-weight: normal;
|
|
89
|
+
font-style: normal;
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
width: 1em;
|
|
94
|
+
height: 1em;
|
|
95
|
+
line-height: normal;
|
|
96
|
+
text-transform: none;
|
|
97
|
+
letter-spacing: normal;
|
|
98
|
+
word-wrap: normal;
|
|
99
|
+
white-space: nowrap;
|
|
100
|
+
direction: ltr;
|
|
101
|
+
|
|
102
|
+
/* Enable ligature rendering support for modern browsers */
|
|
103
|
+
font-feature-settings: "liga";
|
|
104
|
+
|
|
105
|
+
/* Improved rendering quality */
|
|
106
|
+
-webkit-font-smoothing: antialiased;
|
|
107
|
+
-moz-osx-font-smoothing: grayscale;
|
|
108
|
+
text-rendering: optimizeLegibility;
|
|
109
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useMediaQuery — Responsive hook chuẩn SSR-safe
|
|
3
|
+
*
|
|
4
|
+
* Tránh hydration mismatch bằng cách khởi tạo với `false`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* const isMobile = useMediaQuery('(max-width: 768px)');
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare function useMediaQuery(query: string): boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface RippleOptions {
|
|
2
|
+
/** Thời gian hiệu ứng ripple (ms). Mặc định: 600 */
|
|
3
|
+
duration?: number;
|
|
4
|
+
/** Màu ripple. Mặc định: 'currentColor' */
|
|
5
|
+
color?: string;
|
|
6
|
+
/** Opacity. Mặc định: 0.12 (chuẩn MD3) */
|
|
7
|
+
opacity?: number;
|
|
8
|
+
/** Tắt ripple (ví dụ khi disabled) */
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* useRipple — Material Design 3 Expressive Ripple Effect
|
|
13
|
+
*
|
|
14
|
+
* Hook thuần DOM, không phụ thuộc thư viện animation ngoài.
|
|
15
|
+
* Chú ý: Yêu cầu element có `position: relative` và `overflow: hidden`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* const { rippleRef, onPointerDown } = useRipple();
|
|
20
|
+
* <button ref={rippleRef} onPointerDown={onPointerDown}>Click me</button>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function useRipple<T extends HTMLElement = HTMLElement>(options?: RippleOptions): {
|
|
24
|
+
rippleRef: import("react").RefObject<T | null>;
|
|
25
|
+
onPointerDown: (event: React.PointerEvent<T>) => void;
|
|
26
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export { useMediaQuery } from "./hooks/useMediaQuery";
|
|
2
|
+
/** @deprecated Use `useRippleState` (Framer Motion) from the main package instead. DOM-only ripple. */
|
|
3
|
+
export { useRipple as useDOMRipple } from "./hooks/useRipple";
|
|
4
|
+
export { MaterialSymbolsPreconnect } from "./lib/material-symbols-preconnect";
|
|
5
|
+
export type { MD3ColorScheme, ThemeMode } from "./lib/theme-utils";
|
|
6
|
+
export { applyTheme, generateM3Theme } from "./lib/theme-utils";
|
|
7
|
+
export { cn } from "./lib/utils";
|
|
8
|
+
export type { MD3ColorStyle, MD3Shape, MD3Size, PolymorphicProps, PolymorphicRef, } from "./types/md3";
|
|
9
|
+
export type { BadgedBoxProps, BadgeProps } from "./ui/badge";
|
|
10
|
+
export { Badge, BadgedBox } from "./ui/badge";
|
|
11
|
+
export type { BaseButtonProps, ButtonProps } from "./ui/button";
|
|
12
|
+
export { Button } from "./ui/button";
|
|
13
|
+
export type { ButtonGroupProps } from "./ui/button-group";
|
|
14
|
+
export { ButtonGroup } from "./ui/button-group";
|
|
15
|
+
export type { CardProps } from "./ui/card";
|
|
16
|
+
export { Card } from "./ui/card";
|
|
17
|
+
export type { CheckboxProps, CheckboxState, TriStateCheckboxProps, } from "./ui/checkbox";
|
|
18
|
+
export { Checkbox, TriStateCheckbox } from "./ui/checkbox";
|
|
19
|
+
export type { ChipProps } from "./ui/chip";
|
|
20
|
+
export { Chip } from "./ui/chip";
|
|
21
|
+
export type { CodeBlockProps } from "./ui/code-block";
|
|
22
|
+
export { CodeBlock } from "./ui/code-block";
|
|
23
|
+
export type { DialogContentProps, DialogFullScreenContentProps, DialogProps, } from "./ui/dialog";
|
|
24
|
+
export { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogFullScreenContent, DialogHeader, DialogIcon, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, } from "./ui/dialog";
|
|
25
|
+
export type { DividerProps } from "./ui/divider";
|
|
26
|
+
export { buildWavePath, Divider } from "./ui/divider";
|
|
27
|
+
export type { DrawerContentProps, DrawerProps } from "./ui/drawer";
|
|
28
|
+
export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, } from "./ui/drawer";
|
|
29
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "./ui/dropdown";
|
|
30
|
+
export type { FABPositionProps, FABProps } from "./ui/fab";
|
|
31
|
+
export { FAB, FABPosition } from "./ui/fab";
|
|
32
|
+
export type { FABMenuItemData, FABMenuItemProps, FABMenuProps, ToggleFABProps, } from "./ui/fab-menu";
|
|
33
|
+
export { FABMenu, FABMenuItem, ToggleFAB } from "./ui/fab-menu";
|
|
34
|
+
export type { IconProps } from "./ui/icon";
|
|
35
|
+
export { Icon } from "./ui/icon";
|
|
36
|
+
export type { BaseIconButtonProps, IconButtonProps } from "./ui/icon-button";
|
|
37
|
+
export { IconButton } from "./ui/icon-button";
|
|
38
|
+
export type { LoadingIndicatorProps } from "./ui/loading-indicator";
|
|
39
|
+
export { LoadingIndicator } from "./ui/loading-indicator";
|
|
40
|
+
export type { NavigationRailItemProps, NavigationRailLabelVisibility, NavigationRailProps, NavigationRailVariant, } from "./ui/navigation-rail";
|
|
41
|
+
export { NavigationRail, NavigationRailItem } from "./ui/navigation-rail";
|
|
42
|
+
export type { CircularProgressProps, LinearProgressProps, ProgressIndicatorProps, } from "./ui/progress-indicator";
|
|
43
|
+
export { ProgressIndicator } from "./ui/progress-indicator";
|
|
44
|
+
export type { RadioButtonColors, RadioButtonProps, RadioGroupProps, } from "./ui/radio-button";
|
|
45
|
+
export { RadioButton, RadioGroup } from "./ui/radio-button";
|
|
46
|
+
export type { RippleOrigin, RippleProps, UseRippleStateOptions, } from "./ui/ripple";
|
|
47
|
+
export { Ripple, useRipple, useRippleState } from "./ui/ripple";
|
|
48
|
+
export type { ScrollAreaOrientation, ScrollAreaProps, ScrollAreaType, } from "./ui/scroll-area";
|
|
49
|
+
export { ScrollArea, ScrollAreaScrollbar, } from "./ui/scroll-area";
|
|
50
|
+
export type { SnackbarData, SnackbarDuration, SnackbarHostProps, SnackbarProps, SnackbarResult, SnackbarVisuals, UseSnackbarStateReturn, } from "./ui/snackbar";
|
|
51
|
+
export { Snackbar, SnackbarHost, SnackbarProvider, useSnackbar, useSnackbarState, } from "./ui/snackbar";
|
|
52
|
+
export type { SwitchProps } from "./ui/switch";
|
|
53
|
+
export { Switch, SwitchColors, SwitchTokens } from "./ui/switch";
|
|
54
|
+
export type { TabProps, TabsContentProps, TabsListProps, TabsProps, TabsVariant, } from "./ui/tabs";
|
|
55
|
+
export { Tab, Tabs, TabsColors, TabsContent, TabsList, TabsTokens, } from "./ui/tabs";
|
|
56
|
+
export type { TextFieldHandle, TextFieldInputType, TextFieldProps, TextFieldTrailingIconMode, TextFieldVariant, } from "./ui/text-field";
|
|
57
|
+
export { TextField } from "./ui/text-field";
|
|
58
|
+
export type { MD3ThemeProviderProps } from "./ui/theme-provider";
|
|
59
|
+
export { MD3ThemeProvider, useTheme, useThemeMode } from "./ui/theme-provider";
|
|
60
|
+
export type { TableOfContentsProps, ToCItem } from "./ui/toc";
|
|
61
|
+
export { TableOfContents } from "./ui/toc";
|
|
62
|
+
export type { CaretConfig, PlainTooltipProps, RichTooltipProps, TooltipBoxProps, TooltipPlacement, TooltipState, TooltipStateConfig, TooltipTrigger, } from "./ui/tooltip";
|
|
63
|
+
export { PlainTooltip, RichTooltip, TooltipBox, TooltipCaretShape, TooltipTokens, useTooltipPosition, useTooltipState, } from "./ui/tooltip";
|
|
64
|
+
export type { TextStyle, TypeScaleTokensType, TypographyProviderProps, } from "./ui/typography";
|
|
65
|
+
export { MD3_EXPRESSIVE_FONT_VARIATION, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, useTypography, } from "./ui/typography";
|