@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.
Files changed (96) hide show
  1. package/README.md +215 -0
  2. package/dist/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
  3. package/dist/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  4. package/dist/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  5. package/dist/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  6. package/dist/assets/loading-indicator.svg +19 -0
  7. package/dist/assets/material-symbols-cdn.css +65 -0
  8. package/dist/assets/material-symbols-self-hosted.css +109 -0
  9. package/dist/hooks/index.d.ts +3 -0
  10. package/dist/hooks/useMediaQuery.d.ts +11 -0
  11. package/dist/hooks/useRipple.d.ts +26 -0
  12. package/dist/index.d.ts +65 -0
  13. package/dist/index.js +9059 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/index.mjs +8929 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/lib/material-symbols-preconnect.d.ts +42 -0
  18. package/dist/lib/theme-utils.d.ts +63 -0
  19. package/dist/lib/utils.d.ts +2 -0
  20. package/dist/material-symbols-cdn.css +65 -0
  21. package/dist/material-symbols-self-hosted.css +109 -0
  22. package/dist/types/index.d.ts +1 -0
  23. package/dist/types/md3.d.ts +14 -0
  24. package/dist/typography.css +22 -0
  25. package/dist/ui/badge.d.ts +125 -0
  26. package/dist/ui/button-group.d.ts +59 -0
  27. package/dist/ui/button.d.ts +148 -0
  28. package/dist/ui/card.d.ts +62 -0
  29. package/dist/ui/checkbox.d.ts +82 -0
  30. package/dist/ui/chip.d.ts +110 -0
  31. package/dist/ui/code-block.d.ts +14 -0
  32. package/dist/ui/dialog.d.ts +111 -0
  33. package/dist/ui/divider.d.ts +164 -0
  34. package/dist/ui/drawer.d.ts +39 -0
  35. package/dist/ui/dropdown.d.ts +29 -0
  36. package/dist/ui/fab-menu.d.ts +204 -0
  37. package/dist/ui/fab.d.ts +162 -0
  38. package/dist/ui/icon-button.d.ts +131 -0
  39. package/dist/ui/icon.d.ts +88 -0
  40. package/dist/ui/loading-indicator.d.ts +42 -0
  41. package/dist/ui/navigation-rail.d.ts +29 -0
  42. package/dist/ui/progress-indicator/circular.d.ts +3 -0
  43. package/dist/ui/progress-indicator/hooks.d.ts +3 -0
  44. package/dist/ui/progress-indicator/index.d.ts +21 -0
  45. package/dist/ui/progress-indicator/linear-flat.d.ts +10 -0
  46. package/dist/ui/progress-indicator/linear-wavy.d.ts +18 -0
  47. package/dist/ui/progress-indicator/linear.d.ts +3 -0
  48. package/dist/ui/progress-indicator/types.d.ts +151 -0
  49. package/dist/ui/progress-indicator/utils.d.ts +3 -0
  50. package/dist/ui/radio-button.d.ts +106 -0
  51. package/dist/ui/ripple.d.ts +126 -0
  52. package/dist/ui/scroll-area.d.ts +27 -0
  53. package/dist/ui/shared/constants.d.ts +86 -0
  54. package/dist/ui/shared/touch-target.d.ts +38 -0
  55. package/dist/ui/snackbar/index.d.ts +6 -0
  56. package/dist/ui/snackbar/snackbar.d.ts +196 -0
  57. package/dist/ui/switch/index.d.ts +7 -0
  58. package/dist/ui/switch/switch.d.ts +30 -0
  59. package/dist/ui/switch/switch.stories.d.ts +48 -0
  60. package/dist/ui/switch/switch.tokens.d.ts +67 -0
  61. package/dist/ui/switch/switch.types.d.ts +59 -0
  62. package/dist/ui/tabs/index.d.ts +10 -0
  63. package/dist/ui/tabs/tab.d.ts +43 -0
  64. package/dist/ui/tabs/tabs-content.d.ts +36 -0
  65. package/dist/ui/tabs/tabs-list.d.ts +40 -0
  66. package/dist/ui/tabs/tabs.d.ts +60 -0
  67. package/dist/ui/tabs/tabs.tokens.d.ts +94 -0
  68. package/dist/ui/tabs/tabs.types.d.ts +172 -0
  69. package/dist/ui/text-field/index.d.ts +11 -0
  70. package/dist/ui/text-field/subcomponents/active-indicator.d.ts +24 -0
  71. package/dist/ui/text-field/subcomponents/floating-label.d.ts +43 -0
  72. package/dist/ui/text-field/subcomponents/leading-icon.d.ts +23 -0
  73. package/dist/ui/text-field/subcomponents/outline-container.d.ts +42 -0
  74. package/dist/ui/text-field/subcomponents/prefix-suffix.d.ts +24 -0
  75. package/dist/ui/text-field/subcomponents/supporting-text.d.ts +37 -0
  76. package/dist/ui/text-field/subcomponents/trailing-icon.d.ts +41 -0
  77. package/dist/ui/text-field/text-field.d.ts +49 -0
  78. package/dist/ui/text-field/text-field.tokens.d.ts +76 -0
  79. package/dist/ui/text-field/text-field.types.d.ts +126 -0
  80. package/dist/ui/theme-provider/index.d.ts +18 -0
  81. package/dist/ui/toc.d.ts +74 -0
  82. package/dist/ui/tooltip/index.d.ts +8 -0
  83. package/dist/ui/tooltip/plain-tooltip.d.ts +2 -0
  84. package/dist/ui/tooltip/rich-tooltip.d.ts +2 -0
  85. package/dist/ui/tooltip/tooltip-box.d.ts +2 -0
  86. package/dist/ui/tooltip/tooltip-caret-shape.d.ts +9 -0
  87. package/dist/ui/tooltip/tooltip.tokens.d.ts +26 -0
  88. package/dist/ui/tooltip/tooltip.types.d.ts +56 -0
  89. package/dist/ui/tooltip/use-tooltip-position.d.ts +8 -0
  90. package/dist/ui/tooltip/use-tooltip-state.d.ts +2 -0
  91. package/dist/ui/typography/index.d.ts +16 -0
  92. package/dist/ui/typography/type-scale-tokens.d.ts +162 -0
  93. package/dist/ui/typography/typography-key-tokens.d.ts +40 -0
  94. package/dist/ui/typography/typography-tokens.d.ts +220 -0
  95. package/dist/ui/typography/typography.d.ts +265 -0
  96. 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
@@ -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,3 @@
1
+ export { useMediaQuery } from "./useMediaQuery";
2
+ export type { RippleOptions } from "./useRipple";
3
+ export { useRipple } from "./useRipple";
@@ -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
+ };
@@ -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";