@mdigital_ui/ui 0.4.4 → 0.4.6

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 (128) hide show
  1. package/README.md +258 -662
  2. package/dist/anchor/index.js +4 -0
  3. package/dist/anchor/index.js.map +1 -0
  4. package/dist/autocomplete/index.js +6 -0
  5. package/dist/autocomplete/index.js.map +1 -0
  6. package/dist/breadcrumbs/index.js +3 -3
  7. package/dist/calendar/index.js +4 -0
  8. package/dist/calendar/index.js.map +1 -0
  9. package/dist/chunk-3Z7RLVWD.js +258 -0
  10. package/dist/chunk-3Z7RLVWD.js.map +1 -0
  11. package/dist/chunk-5YEC6FDN.js +263 -0
  12. package/dist/chunk-5YEC6FDN.js.map +1 -0
  13. package/dist/{chunk-GOBUFGGJ.js → chunk-6NXZWLSM.js} +3 -3
  14. package/dist/{chunk-GOBUFGGJ.js.map → chunk-6NXZWLSM.js.map} +1 -1
  15. package/dist/{chunk-FU5Q4WVX.js → chunk-6ROGWFQ2.js} +3 -3
  16. package/dist/{chunk-FU5Q4WVX.js.map → chunk-6ROGWFQ2.js.map} +1 -1
  17. package/dist/{chunk-LJOQ2C5W.js → chunk-6RZEJRTC.js} +3 -3
  18. package/dist/{chunk-LJOQ2C5W.js.map → chunk-6RZEJRTC.js.map} +1 -1
  19. package/dist/chunk-74AF6PO2.js +374 -0
  20. package/dist/chunk-74AF6PO2.js.map +1 -0
  21. package/dist/chunk-75N6T3IS.js +77 -0
  22. package/dist/chunk-75N6T3IS.js.map +1 -0
  23. package/dist/{chunk-BKLJDEUX.js → chunk-DBPLQZJ2.js} +38 -14
  24. package/dist/chunk-DBPLQZJ2.js.map +1 -0
  25. package/dist/chunk-ED4CQZ72.js +343 -0
  26. package/dist/chunk-ED4CQZ72.js.map +1 -0
  27. package/dist/{chunk-4ZXHLPRS.js → chunk-FY2TZ2NT.js} +4 -4
  28. package/dist/{chunk-4ZXHLPRS.js.map → chunk-FY2TZ2NT.js.map} +1 -1
  29. package/dist/{chunk-I5AD247M.js → chunk-HKQOAEFY.js} +13 -3
  30. package/dist/chunk-HKQOAEFY.js.map +1 -0
  31. package/dist/chunk-JWYBDNC6.js +307 -0
  32. package/dist/chunk-JWYBDNC6.js.map +1 -0
  33. package/dist/{chunk-W5VLFE4U.js → chunk-LHZJ2GJU.js} +32 -6
  34. package/dist/chunk-LHZJ2GJU.js.map +1 -0
  35. package/dist/{chunk-253JZOYG.js → chunk-NB66D6A5.js} +3 -2
  36. package/dist/chunk-NB66D6A5.js.map +1 -0
  37. package/dist/{chunk-BGMYX7L5.js → chunk-NF6JUJBE.js} +9 -7
  38. package/dist/chunk-NF6JUJBE.js.map +1 -0
  39. package/dist/chunk-NPK4ESMA.js +281 -0
  40. package/dist/chunk-NPK4ESMA.js.map +1 -0
  41. package/dist/{chunk-X7MF3TIF.js → chunk-PD3O6ZH4.js} +12 -5
  42. package/dist/chunk-PD3O6ZH4.js.map +1 -0
  43. package/dist/{chunk-XOEEAMMY.js → chunk-Q46WXJVW.js} +21 -21
  44. package/dist/chunk-Q46WXJVW.js.map +1 -0
  45. package/dist/chunk-QEYNOLRC.js +157 -0
  46. package/dist/chunk-QEYNOLRC.js.map +1 -0
  47. package/dist/chunk-RNG7HR6U.js +174 -0
  48. package/dist/chunk-RNG7HR6U.js.map +1 -0
  49. package/dist/{chunk-HJITFPBT.js → chunk-SZMIHNCZ.js} +13 -7
  50. package/dist/chunk-SZMIHNCZ.js.map +1 -0
  51. package/dist/chunk-TDPJYCNI.js +96 -0
  52. package/dist/chunk-TDPJYCNI.js.map +1 -0
  53. package/dist/chunk-UFYG3HKL.js +374 -0
  54. package/dist/chunk-UFYG3HKL.js.map +1 -0
  55. package/dist/chunk-VNH6R5EU.js +211 -0
  56. package/dist/chunk-VNH6R5EU.js.map +1 -0
  57. package/dist/{chunk-SFP77VS3.js → chunk-X7JN7WPF.js} +5 -2
  58. package/dist/chunk-X7JN7WPF.js.map +1 -0
  59. package/dist/chunk-YRSHBAUQ.js +201 -0
  60. package/dist/chunk-YRSHBAUQ.js.map +1 -0
  61. package/dist/chunk-YUACN5GJ.js +303 -0
  62. package/dist/chunk-YUACN5GJ.js.map +1 -0
  63. package/dist/{chunk-HVHQA34X.js → chunk-ZNGKUG2N.js} +11 -6
  64. package/dist/chunk-ZNGKUG2N.js.map +1 -0
  65. package/dist/color-picker/index.js +6 -0
  66. package/dist/color-picker/index.js.map +1 -0
  67. package/dist/date-picker/RangePicker.d.ts.map +1 -1
  68. package/dist/date-picker/index.d.ts.map +1 -1
  69. package/dist/date-picker/index.js +1 -1
  70. package/dist/date-picker/shared.d.ts +5 -0
  71. package/dist/date-picker/shared.d.ts.map +1 -1
  72. package/dist/dropdown/index.js +2 -2
  73. package/dist/float-button/index.js +5 -0
  74. package/dist/float-button/index.js.map +1 -0
  75. package/dist/index.js +51 -2996
  76. package/dist/index.js.map +1 -1
  77. package/dist/input/index.d.ts.map +1 -1
  78. package/dist/input/index.js +1 -1
  79. package/dist/input-password/index.js +2 -2
  80. package/dist/mentions/index.js +4 -0
  81. package/dist/mentions/index.js.map +1 -0
  82. package/dist/menubar/index.d.ts +3 -3
  83. package/dist/menubar/index.d.ts.map +1 -1
  84. package/dist/menubar/index.js +1 -1
  85. package/dist/multi-select/index.d.ts.map +1 -1
  86. package/dist/multi-select/index.js +3 -3
  87. package/dist/number-input/index.d.ts.map +1 -1
  88. package/dist/number-input/index.js +1 -1
  89. package/dist/qr-code/index.js +5 -0
  90. package/dist/qr-code/index.js.map +1 -0
  91. package/dist/resizable/index.js +4 -0
  92. package/dist/resizable/index.js.map +1 -0
  93. package/dist/result/index.js +4 -0
  94. package/dist/result/index.js.map +1 -0
  95. package/dist/select/index.d.ts.map +1 -1
  96. package/dist/select/index.js +3 -3
  97. package/dist/shared/useSelectBase.d.ts.map +1 -1
  98. package/dist/skeleton/index.d.ts.map +1 -1
  99. package/dist/skeleton/index.js +1 -1
  100. package/dist/table/index.js +4 -4
  101. package/dist/tabs/index.d.ts.map +1 -1
  102. package/dist/tabs/index.js +1 -1
  103. package/dist/tags-input/index.js +5 -0
  104. package/dist/tags-input/index.js.map +1 -0
  105. package/dist/toast/index.d.ts.map +1 -1
  106. package/dist/toast/index.js +1 -1
  107. package/dist/tooltip/index.d.ts.map +1 -1
  108. package/dist/tooltip/index.js +1 -1
  109. package/dist/tour/index.js +5 -0
  110. package/dist/tour/index.js.map +1 -0
  111. package/dist/typography/index.js +4 -0
  112. package/dist/typography/index.js.map +1 -0
  113. package/dist/watermark/index.js +4 -0
  114. package/dist/watermark/index.js.map +1 -0
  115. package/package.json +59 -11
  116. package/styles/global.css +498 -6016
  117. package/dist/chunk-253JZOYG.js.map +0 -1
  118. package/dist/chunk-BGMYX7L5.js.map +0 -1
  119. package/dist/chunk-BKLJDEUX.js.map +0 -1
  120. package/dist/chunk-BS4PZPY6.js +0 -322
  121. package/dist/chunk-BS4PZPY6.js.map +0 -1
  122. package/dist/chunk-HJITFPBT.js.map +0 -1
  123. package/dist/chunk-HVHQA34X.js.map +0 -1
  124. package/dist/chunk-I5AD247M.js.map +0 -1
  125. package/dist/chunk-SFP77VS3.js.map +0 -1
  126. package/dist/chunk-W5VLFE4U.js.map +0 -1
  127. package/dist/chunk-X7MF3TIF.js.map +0 -1
  128. package/dist/chunk-XOEEAMMY.js.map +0 -1
package/README.md CHANGED
@@ -1,483 +1,313 @@
1
1
  # @mdigital_ui/ui
2
2
 
3
- Modern React component library built with Tailwind CSS v4, CVA, and Radix UI primitives.
3
+ React component library. 76 components. Tailwind CSS v4, CVA, Radix UI.
4
4
 
5
- ## Features
6
-
7
- - **Tailwind CSS v4** with OKLCH color system and CSS-first configuration
8
- - **Full TypeScript** support with exported types for every component
9
- - **Dark Mode** built-in via `.dark` class toggle
10
- - **Theme Presets** (Corporate, Vibrant, Minimal) with CSS variable overrides
11
- - **Tree-Shakeable** ESM with subpath imports
12
- - **Accessible** keyboard navigation, ARIA attributes, focus management, reduced-motion support
13
- - **ClassNames API** for granular styling of every component part
14
-
15
- ## Installation
5
+ ## Install
16
6
 
17
7
  ```bash
18
- pnpm add @mdigital_ui/ui
19
- # or
20
8
  npm install @mdigital_ui/ui
21
9
  ```
22
10
 
23
- ### Peer Dependencies
11
+ Peer deps: `react`, `react-dom`, `lucide-react`, `tailwindcss` (v4+)
24
12
 
25
- ```bash
26
- pnpm add react react-dom tailwindcss
27
- ```
13
+ ## Setup
28
14
 
29
- ## Quick Start
15
+ Your project needs Tailwind CSS v4 with either `@tailwindcss/vite` or `@tailwindcss/postcss`.
30
16
 
31
- ### 1. Import Styles
17
+ In your CSS entry point:
32
18
 
33
- ```tsx
34
- // One import — includes light mode, dark mode, and all utilities
35
- import '@mdigital_ui/ui/styles/global.css'
19
+ ```css
20
+ @import "tailwindcss";
21
+ @import "@mdigital_ui/ui/styles/global.css";
36
22
  ```
37
23
 
38
- That's it. Dark mode works automatically via `.dark` class on `<html>`.
24
+ That's it. Our CSS provides:
25
+ - `@theme` — all design tokens as CSS variables (override in `:root`)
26
+ - `@source "../dist"` — Tailwind auto-scans our compiled components for class names
27
+ - `@custom-variant dark` — dark mode via `.dark` class
28
+ - `@utility` — slot-based color system, stroke utilities
29
+ - Component-specific styles (datepicker, animations)
39
30
 
40
- > **Note:** You do NOT need your own Tailwind CSS setup to use this library.
41
- > The compiled CSS is self-contained with all utilities pre-built.
42
- > If you DO have your own Tailwind setup, the library CSS works alongside it.
31
+ Your Tailwind build processes everything. When Tailwind ships new utilities or features, you get them immediately.
43
32
 
44
- ### 2. Use Components
33
+ ## Usage
45
34
 
46
35
  ```tsx
47
36
  import Button from '@mdigital_ui/ui/button'
48
37
  import Input from '@mdigital_ui/ui/input'
49
38
  import { Card, CardHeader, CardTitle, CardContent } from '@mdigital_ui/ui/card'
50
-
51
- function App() {
52
- return (
53
- <Card>
54
- <CardHeader>
55
- <CardTitle>Sign In</CardTitle>
56
- </CardHeader>
57
- <CardContent>
58
- <Input label="Email" placeholder="you@example.com" />
59
- <Button color="primary" className="mt-4">Submit</Button>
60
- </CardContent>
61
- </Card>
62
- )
63
- }
64
39
  ```
65
40
 
66
- ### 3. Dark Mode (optional)
41
+ Barrel import also works:
67
42
 
68
43
  ```tsx
69
- import { ThemeProvider } from '@mdigital_ui/ui/theme'
70
-
71
- function App() {
72
- return (
73
- <ThemeProvider defaultTheme="system">
74
- {/* Your app */}
75
- </ThemeProvider>
76
- )
77
- }
44
+ import { Button, Input, Card } from '@mdigital_ui/ui'
78
45
  ```
79
46
 
80
- For SSR apps, add this script in `<head>` to prevent flash:
47
+ ## Dark Mode
81
48
 
82
- ```html
83
- <script dangerouslySetInnerHTML={{ __html: themeScript }} />
84
- ```
85
-
86
- ### 4. Theme Presets (optional)
49
+ Toggle `.dark` class on `<html>`:
87
50
 
88
51
  ```tsx
89
- // Import a preset after global.css
90
- import '@mdigital_ui/ui/styles/global.css'
91
- import '@mdigital_ui/ui/styles/themes/presets/corporate.css'
92
-
93
- // Set preset on html element
94
- // <html data-theme="corporate">
95
- ```
52
+ import { ThemeProvider, useTheme } from '@mdigital_ui/ui/theme'
96
53
 
97
- Available presets: `corporate`, `vibrant`, `minimal`
54
+ <ThemeProvider defaultTheme="system">
55
+ <App />
56
+ </ThemeProvider>
98
57
 
99
- Presets work independently of dark/light mode — combine freely:
100
- ```html
101
- <html class="dark" data-theme="corporate">
58
+ // anywhere:
59
+ const { theme, setTheme, resolvedTheme } = useTheme()
60
+ setTheme('dark') // 'light' | 'dark' | 'system'
102
61
  ```
103
62
 
104
- ### Import Patterns
63
+ SSR flash prevention — add to `<head>`:
105
64
 
106
65
  ```tsx
107
- // Subpath imports (recommended, best tree-shaking)
108
- import Button from '@mdigital_ui/ui/button'
109
- import Select from '@mdigital_ui/ui/select'
66
+ import { themeScript } from '@mdigital_ui/ui/theme'
67
+
68
+ <script dangerouslySetInnerHTML={{ __html: themeScript }} />
69
+ ```
110
70
 
111
- // Barrel import
112
- import { Button, Select, Input } from '@mdigital_ui/ui'
71
+ All components use CSS custom properties. Dark mode swaps values at `:root` level. No `dark:` prefixes needed.
113
72
 
114
- // Type imports
115
- import type { ButtonProps, SelectProps } from '@mdigital_ui/ui'
73
+ ## Theme Presets
74
+
75
+ ```tsx
76
+ import '@mdigital_ui/ui/styles/global.css'
77
+ import '@mdigital_ui/ui/styles/themes/presets/corporate.css'
116
78
  ```
117
79
 
118
- ---
80
+ ```html
81
+ <html data-theme="corporate" class="dark">
82
+ ```
119
83
 
120
- ## Components
84
+ Presets: `corporate`, `vibrant`, `minimal`. Independent of dark/light — combine freely.
121
85
 
122
- ### Form Inputs
123
-
124
- | Component | Import | Description |
125
- |-----------|--------|-------------|
126
- | **Input** | `input` | Text input with validation states, icons, clearable |
127
- | **FloatInput** | `float-input` | Floating label input |
128
- | **InputPassword** | `input-password` | Password input with visibility toggle |
129
- | **InputOTP** | `input-otp` | One-time password code input |
130
- | **InputGroup** | `input-group` | Input with prefix/suffix addons |
131
- | **NumberInput** | `number-input` | Numeric input with increment/decrement buttons |
132
- | **Textarea** | `textarea` | Multi-line text input with auto-resize |
133
- | **Select** | `select` | Searchable dropdown with virtualization |
134
- | **MultiSelect** | `multi-select` | Multiple selection with tags |
135
- | **Cascader** | `cascader` | Cascading multi-level selection |
136
- | **TreeSelect** | `tree-select` | Tree-based dropdown selection |
137
- | **DatePicker** | `date-picker` | Date, range, and time pickers |
138
- | **Upload** | `upload` | File upload (drag-drop, button, avatar variants) |
139
- | **Checkbox** | `checkbox` | Single checkbox |
140
- | **CheckboxGroup** | `checkbox-group` | Grouped checkboxes |
141
- | **Radio** | `radio` | Single radio button |
142
- | **RadioGroup** | `radio-group` | Grouped radio buttons |
143
- | **Switch** | `switch` | Toggle switch |
144
- | **Slider** | `slider` | Range slider |
145
- | **Rating** | `rating` | Star rating |
146
- | **Toggle** | `toggle` | Toggle button (pressed/unpressed) |
147
- | **ToggleGroup** | `toggle-group` | Grouped toggle buttons |
148
-
149
- ### Form Utilities
150
-
151
- | Component | Import | Description |
152
- |-----------|--------|-------------|
153
- | **Form** | `form` | Form wrapper with react-hook-form + zod validation |
154
- | **Clipboard** | `clipboard` | Copy-to-clipboard with visual feedback |
155
-
156
- ### Layout & Containers
157
-
158
- | Component | Import | Description |
159
- |-----------|--------|-------------|
160
- | **Button** | `button` | Button with solid, outline, soft, dashed, link, ghost variants |
161
- | **ButtonGroup** | `button-group` | Grouped buttons |
162
- | **Card** | `card` | Content card with header, body, footer, image sub-components |
163
- | **Grid** | `grid` | Responsive CSS grid layout |
164
- | **Divider** | `divider` | Horizontal/vertical content separator |
165
- | **ScrollArea** | `scroll-area` | Custom scrollbar container |
86
+ ## Custom Tokens
166
87
 
167
- ### Navigation
88
+ All tokens live in one `@theme` block. Override after our import:
168
89
 
169
- | Component | Import | Description |
170
- |-----------|--------|-------------|
171
- | **Tabs** | `tabs` | Tabbed content navigation |
172
- | **Breadcrumbs** | `breadcrumbs` | Hierarchical breadcrumb trail |
173
- | **Pagination** | `pagination` | Page navigation with page size control |
174
- | **Stepper** | `stepper` | Step progress indicator |
175
- | **Dropdown** | `dropdown` | Dropdown action menu |
176
- | **ContextMenu** | `context-menu` | Right-click context menu with submenus |
177
- | **Menubar** | `menubar` | Horizontal menu bar |
178
- | **NavigationMenu** | `navigation-menu` | Navigation with dropdown panels |
179
- | **Link** | `link` | Styled anchor element |
180
- | **Command** | `command` | Command palette / search (Cmd+K) |
181
-
182
- ### Overlays & Feedback
183
-
184
- | Component | Import | Description |
185
- |-----------|--------|-------------|
186
- | **Modal** | `modal` | Dialog overlay with Radix primitives |
187
- | **Drawer** | `drawer` | Slide-in side panel |
188
- | **Tooltip** | `tooltip` | Hover information popup |
189
- | **Popover** | `popover` | Contextual popup with positioning |
190
- | **Notification** | `notification` | Inline alert/notification |
191
- | **Toast** | `toast` | Temporary toast notifications (Sonner) |
192
- | **FetchingOverlay** | `fetching-overlay` | Loading overlay |
193
- | **Progress** | `progress` | Progress bar (linear, circular, semicircle) |
194
- | **Spinner** | `spinner` | Loading spinner |
195
- | **Skeleton** | `skeleton` | Content loading placeholder |
196
- | **Empty** | `empty` | Empty state with icon, title, action |
197
-
198
- ### Data Display
199
-
200
- | Component | Import | Description |
201
- |-----------|--------|-------------|
202
- | **Table** | `table` | Data table with TanStack Table (sorting, filtering, pagination, pinning, editing) |
203
- | **Tree** | `tree` | Hierarchical tree view with checkboxes |
204
- | **Descriptions** | `descriptions` | Key-value description list |
205
- | **Timeline** | `timeline` | Vertical timeline |
206
- | **Transfer** | `transfer` | Dual-list transfer |
207
- | **Carousel** | `carousel` | Content slider (Swiper) |
208
- | **Image** | `image` | Lazy-loaded image with blur placeholder |
209
- | **Collapse** | `collapse` | Collapsible content panel |
210
- | **Accordion** | `accordion` | Accordion panels (single/multiple) |
211
-
212
- ### Badges & Tags
213
-
214
- | Component | Import | Description |
215
- |-----------|--------|-------------|
216
- | **Badge** | `badge` | Status indicator label |
217
- | **Tag** | `tag` | Removable tag/chip with keyboard support |
218
- | **Avatar** | `avatar` | User avatar with image, fallback, status indicator |
219
- | **Kbd** | `kbd` | Keyboard key indicator |
220
- | **Ribbon** | `ribbon` | Corner ribbon overlay |
90
+ ```css
91
+ :root {
92
+ --color-primary: oklch(0.55 0.22 270);
93
+ --color-primary-hover: oklch(0.50 0.24 270);
94
+ --color-primary-foreground: oklch(1 0 0);
221
95
 
222
- ### Theme
96
+ --color-background: oklch(0.98 0 0);
97
+ --color-surface: oklch(0.95 0 0);
98
+ --color-border: oklch(0.90 0 0);
99
+ --color-text-primary: oklch(0.15 0 0);
100
+ --color-text-secondary: oklch(0.45 0 0);
223
101
 
224
- | Component | Import | Description |
225
- |-----------|--------|-------------|
226
- | **ThemeProvider** | `theme` | Theme context with dark mode persistence |
102
+ --button-height-md: 2.5rem;
103
+ --input-height-md: 2.5rem;
104
+ --font-sans: 'Inter', system-ui, sans-serif;
105
+ }
106
+ ```
227
107
 
228
- ---
108
+ Full token list in [CSS Variables](#css-variables).
229
109
 
230
110
  ## Common Props
231
111
 
232
- Most components share these variant props:
233
-
234
- ### `color`
112
+ ### color
235
113
 
236
114
  ```
237
- "default" | "primary" | "secondary" | "accent" | "success" | "error" | "warning" | "info"
115
+ 'default' | 'primary' | 'secondary' | 'accent' | 'success' | 'error' | 'warning' | 'info'
238
116
  ```
239
117
 
240
- ### `size`
118
+ ### size
241
119
 
242
120
  ```
243
- "xs" | "sm" | "md" | "lg"
121
+ 'xs' | 'sm' | 'md' | 'lg'
244
122
  ```
245
123
 
246
- ### `variant`
247
-
248
- Varies per component. Common patterns:
124
+ ### variant
249
125
 
250
- - **Button**: `"solid" | "outline" | "soft" | "dashed" | "link" | "ghost"`
251
- - **Card**: `"default" | "solid" | "outline" | "soft" | "ghost" | "elevated"`
252
- - **Input/Textarea**: `"outline" | "filled"`
253
- - **Notification**: `"default" | "solid" | "outline" | "soft"`
254
- - **Badge/Tag**: `"default" | "solid" | "outline" | "soft"`
126
+ Per-component. Examples:
127
+ - Button: `solid`, `outline`, `soft`, `dashed`, `link`, `ghost`
128
+ - Card: `default`, `solid`, `outline`, `soft`, `ghost`, `elevated`
129
+ - Input: `outline`, `filled`
130
+ - Badge/Tag: `default`, `solid`, `outline`, `soft`
255
131
 
256
- ### Validation States
132
+ ### Validation
257
133
 
258
- Form components support validation via boolean or string props:
134
+ Form components accept validation as string (message) or boolean:
259
135
 
260
136
  ```tsx
261
- <Input error="Email is required" />
137
+ <Input error="Required field" />
262
138
  <Input warning="Weak password" />
263
139
  <Input success />
264
- <Input info="We'll never share your email" />
265
140
  ```
266
141
 
267
- ---
268
-
269
142
  ## Styling
270
143
 
271
- ### className (Root Element)
144
+ ### className
272
145
 
273
- Every component accepts `className` for the root element:
146
+ Root element:
274
147
 
275
148
  ```tsx
276
- <Button className="shadow-lg my-4">Submit</Button>
149
+ <Button className="shadow-lg mt-4">Submit</Button>
277
150
  ```
278
151
 
279
- ### classNames (Component Parts)
152
+ ### classNames
280
153
 
281
- Most components expose a `classNames` prop for styling internal parts:
154
+ Target internal parts:
282
155
 
283
156
  ```tsx
284
- <Button
157
+ <Input
285
158
  classNames={{
286
- root: 'shadow-lg',
287
- icon: 'text-white',
288
- content: 'font-bold uppercase',
289
- spinner: 'opacity-50',
159
+ root: 'mb-4',
160
+ label: 'font-bold',
161
+ input: 'tracking-wide',
162
+ helper: 'italic',
290
163
  }}
291
- >
292
- Submit
293
- </Button>
164
+ />
294
165
  ```
295
166
 
296
- ### Semantic CSS Classes
167
+ ### CSS selectors
297
168
 
298
- Every component part has a semantic class in the format `{component}_{slot}`:
169
+ Every part gets a semantic class and `data-slot`:
299
170
 
300
171
  ```css
301
- /* Target in CSS */
302
172
  .button_root { border-radius: 12px; }
303
173
  .input_label { font-weight: 700; }
304
- .card_header { padding: 2rem; }
305
- .modal_overlay { backdrop-filter: blur(8px); }
306
- ```
307
-
308
- ### data-slot Attributes
309
-
310
- All component parts include `data-slot` attributes for CSS targeting:
311
-
312
- ```css
313
- [data-slot="root"] { /* ... */ }
314
- [data-slot="content"] { /* ... */ }
315
- ```
316
-
317
- ### ClassNames Reference
318
-
319
- Every `classNames` key maps to a semantic class `{component}_{key}` and a `data-slot="{key}"` attribute.
320
-
321
- <details>
322
- <summary><strong>Form Components</strong></summary>
323
-
324
- | Component | classNames keys |
325
- |-----------|----------------|
326
- | **Input** | `root`, `wrapper`, `label`, `input`, `leftIcon`, `rightIcon`, `clearButton`, `helper`, `error` |
327
- | **FloatInput** | `root`, `wrapper`, `label`, `input`, `helper`, `error` |
328
- | **InputPassword** | `root`, `wrapper`, `label`, `input`, `toggleButton`, `toggleIcon`, `helper`, `error` |
329
- | **InputOTP** | `root`, `wrapper`, `label`, `slot`, `slotActive`, `helper` |
330
- | **InputGroup** | `root`, `addon`, `input` |
331
- | **NumberInput** | `root`, `wrapper`, `label`, `input`, `increment`, `decrement`, `helper`, `error` |
332
- | **Textarea** | `root`, `wrapper`, `label`, `textarea`, `counter`, `helper`, `error` |
333
- | **Select** | `root`, `trigger`, `triggerIcon`, `search`, `dropdown`, `option`, `optionSelected`, `group`, `groupLabel`, `empty`, `label`, `helper` |
334
- | **MultiSelect** | `root`, `trigger`, `tag`, `tagRemove`, `dropdown`, `option`, `optionSelected`, `selectAll`, `empty`, `label`, `helper` |
335
- | **Cascader** | `root`, `trigger`, `dropdown`, `menu`, `option` |
336
- | **TreeSelect** | `root`, `trigger`, `dropdown`, `tree`, `node`, `checkbox`, `label` |
337
- | **DatePicker** | `root`, `trigger`, `calendar`, `header`, `navigation`, `day`, `daySelected`, `dayToday` |
338
- | **Upload** | `root`, `dropzone`, `input`, `icon`, `text`, `hint`, `fileList`, `fileItem`, `progress` |
339
- | **Checkbox** | `root`, `checkbox`, `indicator`, `label`, `description` |
340
- | **CheckboxGroup** | `root`, `label`, `group`, `item`, `helper`, `error` |
341
- | **Radio** | `root`, `radio`, `indicator`, `label`, `description` |
342
- | **RadioGroup** | `root`, `label`, `group`, `item`, `helper`, `error` |
343
- | **Switch** | `root`, `track`, `thumb`, `label`, `description` |
344
- | **Slider** | `root`, `track`, `range`, `thumb`, `label`, `value` |
345
- | **Rating** | `root`, `star`, `starFilled`, `label` |
346
- | **Toggle** | `root` |
347
- | **ToggleGroup** | `root`, `item` |
348
- | **Clipboard** | `root`, `input`, `button` |
349
- | **Form** | `root`, `field`, `label`, `control`, `description`, `message` |
350
-
351
- </details>
352
-
353
- <details>
354
- <summary><strong>Layout & Navigation Components</strong></summary>
355
-
356
- | Component | classNames keys |
357
- |-----------|----------------|
358
- | **Button** | `root`, `icon`, `leftIcon`, `rightIcon`, `content`, `spinner` |
359
- | **ButtonGroup** | `root`, `button` |
360
- | **Card** | `root`, `header`, `title`, `description`, `content`, `footer`, `action`, `image` |
361
- | **Tabs** | `root`, `list`, `tab`, `tabActive`, `panel` |
362
- | **Accordion** | `root`, `item`, `trigger`, `content`, `icon` |
363
- | **Collapse** | `root`, `header`, `content`, `icon` |
364
- | **Breadcrumbs** | `root`, `list`, `item`, `link`, `separator`, `current` |
365
- | **Pagination** | `root`, `list`, `item`, `button`, `buttonActive`, `ellipsis`, `info` |
366
- | **Stepper** | `root`, `step`, `stepActive`, `stepCompleted`, `icon`, `label`, `description`, `connector` |
367
- | **Dropdown** | `root`, `trigger`, `menu`, `item`, `itemIcon`, `itemLabel`, `divider` |
368
- | **ContextMenu** | `root`, `content`, `item`, `itemIcon`, `itemLabel`, `divider`, `submenu` |
369
- | **Menubar** | `root`, `menu`, `trigger`, `content`, `item`, `separator` |
370
- | **NavigationMenu** | `root`, `list`, `item`, `trigger`, `link`, `content` |
371
- | **Link** | `root` |
372
- | **Command** | `root`, `input`, `inputIcon`, `list`, `empty`, `group`, `groupLabel`, `item`, `itemIcon`, `shortcut` |
373
- | **ScrollArea** | `root`, `viewport`, `scrollbar`, `thumb` |
374
-
375
- </details>
376
-
377
- <details>
378
- <summary><strong>Overlay & Feedback Components</strong></summary>
379
-
380
- | Component | classNames keys |
381
- |-----------|----------------|
382
- | **Modal** | `root`, `overlay`, `content`, `header`, `title`, `description`, `body`, `footer`, `closeButton` |
383
- | **Drawer** | `root`, `overlay`, `content`, `header`, `title`, `description`, `body`, `footer`, `handle`, `closeButton` |
384
- | **Tooltip** | `root`, `trigger`, `content`, `arrow` |
385
- | **Popover** | `content` |
386
- | **Notification** | `root`, `icon`, `content`, `title`, `description`, `action`, `closeButton` |
387
- | **Toast** | `root`, `title`, `description`, `action`, `closeButton` |
388
- | **Progress** | `root`, `track`, `fill`, `label`, `value` |
389
- | **Empty** | `root`, `icon`, `title`, `description`, `action` |
390
-
391
- </details>
392
-
393
- <details>
394
- <summary><strong>Data Display Components</strong></summary>
395
-
396
- | Component | classNames keys |
397
- |-----------|----------------|
398
- | **Table** | `root`, `wrapper`, `header`, `headerRow`, `headerCell`, `body`, `row`, `cell`, `footer`, `pagination`, `empty`, `skeleton`, `actions` |
399
- | **Tree** | `root`, `node`, `nodeContent`, `icon`, `expandIcon`, `label` |
400
- | **Descriptions** | `root`, `item`, `label`, `content` |
401
- | **Timeline** | `root`, `item`, `dot`, `connector`, `content`, `title`, `description` |
402
- | **Transfer** | `root`, `list`, `header`, `search`, `item`, `actions` |
403
- | **Carousel** | `root`, `wrapper`, `slide`, `navigation`, `navButton`, `pagination`, `dot`, `dotActive` |
404
- | **Image** | `root`, `image`, `placeholder`, `error` |
405
- | **Avatar** | `root`, `image`, `fallback`, `status` |
406
- | **AvatarGroup** | `root`, `overflow` |
407
- | **Tag** | `root`, `content`, `closeButton` |
408
-
409
- </details>
410
-
411
- **Single-element components** (use `className` directly): Badge, Divider, Kbd, Skeleton, Spinner, Ribbon, Grid, FetchingOverlay
412
-
413
- ---
414
-
415
- ## Theming
416
-
417
- ### Dark Mode
418
-
419
- Add the `dark` class to `<html>`:
420
-
421
- ```tsx
422
- <html className={isDark ? 'dark' : ''}>
174
+ [data-slot="trigger"] { min-width: 200px; }
423
175
  ```
424
176
 
425
- All components adapt automatically via CSS variables.
426
-
427
- ### Theme Presets
428
-
429
- ```tsx
430
- import '@mdigital_ui/ui/styles/themes/presets/corporate.css'
431
- // or vibrant.css, minimal.css
432
-
433
- <html data-theme="corporate">
434
- ```
435
-
436
- | Preset | Style |
437
- |--------|-------|
438
- | `corporate` | Professional navy blue |
439
- | `vibrant` | Bold purple/magenta |
440
- | `minimal` | Muted grayscale |
441
-
442
- Combine with dark mode: `<html className="dark" data-theme="vibrant">`
443
-
444
- ### ThemeProvider
177
+ ## Components
445
178
 
446
- ```tsx
447
- import { ThemeProvider, useTheme } from '@mdigital_ui/ui/theme'
179
+ ### Inputs
180
+
181
+ | Component | Path |
182
+ |-----------|------|
183
+ | Input | `input` |
184
+ | FloatInput | `float-input` |
185
+ | InputPassword | `input-password` |
186
+ | InputOTP | `input-otp` |
187
+ | InputGroup | `input-group` |
188
+ | NumberInput | `number-input` |
189
+ | Textarea | `textarea` |
190
+ | Select | `select` |
191
+ | MultiSelect | `multi-select` |
192
+ | Cascader | `cascader` |
193
+ | TreeSelect | `tree-select` |
194
+ | DatePicker | `date-picker` |
195
+ | ColorPicker | `color-picker` |
196
+ | Autocomplete | `autocomplete` |
197
+ | Mentions | `mentions` |
198
+ | Checkbox | `checkbox` |
199
+ | CheckboxGroup | `checkbox-group` |
200
+ | Radio | `radio` |
201
+ | RadioGroup | `radio-group` |
202
+ | Switch | `switch` |
203
+ | Slider | `slider` |
204
+ | Rating | `rating` |
205
+ | Toggle | `toggle` |
206
+ | ToggleGroup | `toggle-group` |
207
+ | Upload | `upload` |
208
+ | Clipboard | `clipboard` |
209
+ | TagsInput | `tags-input` |
210
+
211
+ ### Layout
212
+
213
+ | Component | Path |
214
+ |-----------|------|
215
+ | Button | `button` |
216
+ | ButtonGroup | `button-group` |
217
+ | Card | `card` |
218
+ | Grid | `grid` |
219
+ | Divider | `divider` |
220
+ | Collapse | `collapse` |
221
+ | Accordion | `accordion` |
222
+ | ScrollArea | `scroll-area` |
223
+ | Resizable | `resizable` |
448
224
 
449
- <ThemeProvider defaultTheme="system" storageKey="my-app-theme">
450
- <App />
451
- </ThemeProvider>
225
+ ### Navigation
452
226
 
453
- // In any component:
454
- const { theme, setTheme, resolvedTheme } = useTheme()
455
- ```
227
+ | Component | Path |
228
+ |-----------|------|
229
+ | Tabs | `tabs` |
230
+ | Breadcrumbs | `breadcrumbs` |
231
+ | Pagination | `pagination` |
232
+ | Stepper | `stepper` |
233
+ | Dropdown | `dropdown` |
234
+ | ContextMenu | `context-menu` |
235
+ | Menubar | `menubar` |
236
+ | NavigationMenu | `navigation-menu` |
237
+ | Command | `command` |
238
+ | Anchor | `anchor` |
239
+ | Link | `link` |
240
+ | FloatButton | `float-button` |
241
+
242
+ ### Overlays
243
+
244
+ | Component | Path |
245
+ |-----------|------|
246
+ | Modal | `modal` |
247
+ | Drawer | `drawer` |
248
+ | Tooltip | `tooltip` |
249
+ | Popover | `popover` |
250
+ | Tour | `tour` |
251
+
252
+ ### Feedback
253
+
254
+ | Component | Path |
255
+ |-----------|------|
256
+ | Notification | `notification` |
257
+ | Alert | `alert` |
258
+ | Toast | `toast` |
259
+ | Progress | `progress` |
260
+ | Spinner | `spinner` |
261
+ | Skeleton | `skeleton` |
262
+ | Result | `result` |
263
+ | FetchingOverlay | `fetching-overlay` |
264
+
265
+ ### Data
266
+
267
+ | Component | Path |
268
+ |-----------|------|
269
+ | Table | `table` |
270
+ | Tree | `tree` |
271
+ | Calendar | `calendar` |
272
+ | Descriptions | `descriptions` |
273
+ | Timeline | `timeline` |
274
+ | Transfer | `transfer` |
275
+ | Carousel | `carousel` |
276
+ | Image | `image` |
277
+ | QRCode | `qr-code` |
278
+
279
+ ### Display
280
+
281
+ | Component | Path |
282
+ |-----------|------|
283
+ | Badge | `badge` |
284
+ | Tag | `tag` |
285
+ | Avatar | `avatar` |
286
+ | Kbd | `kbd` |
287
+ | Typography | `typography` |
288
+ | Watermark | `watermark` |
456
289
 
457
- ### Custom CSS Variables
290
+ ### Theme
458
291
 
459
- Override any design token after the UI kit styles:
292
+ | Export | Path |
293
+ |--------|------|
294
+ | ThemeProvider, useTheme, themeScript | `theme` |
460
295
 
461
- ```css
462
- :root {
463
- /* Brand Colors (OKLCH) */
464
- --color-primary: oklch(0.55 0.22 270);
465
- --color-primary-hover: oklch(0.50 0.24 270);
466
- --color-accent: oklch(0.75 0.18 45);
296
+ ### Hooks
467
297
 
468
- /* Component Sizing */
469
- --button-height-md: 2.5rem;
470
- --input-height-md: 2.5rem;
298
+ | Hook | Path |
299
+ |------|------|
300
+ | useControllable | `hooks/useControllable` |
301
+ | useDebounce | `hooks/useDebounce` |
302
+ | useThrottle | `hooks/useThrottle` |
303
+ | useMediaQuery | `hooks/useMediaQuery` |
304
+ | useRipple | `hooks/useRipple` |
471
305
 
472
- /* Typography */
473
- --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
474
- }
475
- ```
306
+ ## CSS Variables
476
307
 
477
308
  <details>
478
- <summary><strong>All CSS Variables</strong></summary>
309
+ <summary>Colors</summary>
479
310
 
480
- **Colors**
481
311
  ```
482
312
  --color-primary / -hover / -active / -foreground
483
313
  --color-secondary / -hover / -active / -foreground
@@ -486,320 +316,86 @@ Override any design token after the UI kit styles:
486
316
  --color-error / -hover / -active / -foreground
487
317
  --color-warning / -hover / -active / -foreground
488
318
  --color-info / -hover / -active / -foreground
319
+
489
320
  --color-background / -secondary
490
- --color-surface, --color-card, --color-card-foreground
491
- --color-border, --color-border-primary
492
- --color-text-primary, --color-text-secondary, --color-text-muted
493
- --color-gray-50 through --color-gray-950
494
- ```
321
+ --color-surface
322
+ --color-card / -foreground
323
+ --color-border / -primary / -hover / -focus
495
324
 
496
- **Sizing**
497
- ```
498
- --button-height-xs/sm/md/lg
499
- --button-padding-x-xs/sm/md/lg
500
- --input-height-xs/sm/md/lg
501
- --input-padding-x-xs/sm/md/lg
502
- --select-height-xs/sm/md/lg
503
- --select-padding-x-xs/sm/md/lg
504
- --switch-width-xs/sm/md/lg/xl
505
- --switch-height-xs/sm/md/lg/xl
506
- --textarea-min-height-xs/sm/md/lg
507
- --textarea-padding-xs/sm/md/lg
508
- ```
325
+ --color-text-primary
326
+ --color-text-secondary
327
+ --color-text-muted
328
+ --color-text-disabled
509
329
 
510
- **Effects**
511
- ```
512
- --radius-none / -sm / -md / -lg / -xl / -full
513
- --shadow-sm / -md / -lg / -xl / -2xl
514
- --transition-fast / -base / -slow
515
- --z-dropdown / -sticky / -modal / -popover / -tooltip
330
+ --color-input-bg / -text / -placeholder / -border / -border-focus / -border-error
331
+ --color-focus / -ring
332
+ --color-disabled / -text
333
+ --color-overlay
516
334
  ```
517
335
 
518
336
  </details>
519
337
 
520
- ---
521
-
522
- ## Component Examples
523
-
524
- ### Button
525
-
526
- ```tsx
527
- import Button from '@mdigital_ui/ui/button'
528
-
529
- <Button variant="solid" color="primary" size="md">Click me</Button>
530
- <Button variant="outline" color="error">Delete</Button>
531
- <Button variant="ghost" loading loadingText="Saving...">Save</Button>
532
- <Button icon={<Plus />} iconOnly aria-label="Add item" />
533
- ```
534
-
535
- **Props**: `variant`, `color`, `size`, `shape` (`rounded` | `pill` | `square`), `loading`, `loadingText`, `loadingPosition`, `icon`, `iconPlacement`, `leftIcon`, `rightIcon`, `fullWidth`, `iconOnly`
536
-
537
- ### Input
538
-
539
- ```tsx
540
- import Input from '@mdigital_ui/ui/input'
541
-
542
- <Input label="Email" placeholder="you@example.com" />
543
- <Input variant="filled" leftIcon={<Search />} clearable onClear={() => {}} />
544
- <Input error="Required" required />
545
- <Input loading showCount maxLength={100} />
546
- ```
547
-
548
- **Props**: `variant`, `size`, `label`, `error`, `warning`, `info`, `success`, `helperText`, `messagePosition`, `leftIcon`, `rightIcon`, `clearable`, `onClear`, `loading`, `maxLength`, `showCount`, `fullWidth`
549
-
550
- ### Select
551
-
552
- ```tsx
553
- import Select from '@mdigital_ui/ui/select'
554
-
555
- <Select
556
- label="Country"
557
- placeholder="Choose..."
558
- options={[
559
- { value: 'us', label: 'United States' },
560
- { value: 'uk', label: 'United Kingdom' },
561
- { value: 'de', label: 'Germany', group: 'Europe' },
562
- ]}
563
- value={value}
564
- onChange={setValue}
565
- clearable
566
- />
567
- ```
568
-
569
- **Props**: `size`, `label`, `options`, `placeholder`, `value`, `defaultValue`, `onChange`, `clearable`, `loading`, `disabled`, `fullWidth`, `error`, `warning`, `info`, `success`, `helperText`, `virtualizeThreshold`, `maxDropdownHeight`
570
-
571
- ### Table
572
-
573
- ```tsx
574
- import Table from '@mdigital_ui/ui/table'
575
-
576
- <Table
577
- data={users}
578
- columns={[
579
- { accessorKey: 'name', header: 'Name' },
580
- { accessorKey: 'email', header: 'Email' },
581
- { accessorKey: 'role', header: 'Role' },
582
- ]}
583
- enableSorting
584
- enablePagination
585
- enableRowSelection
586
- pageSize={10}
587
- color="primary"
588
- variant="outline"
589
- striped
590
- hoverable
591
- />
592
- ```
593
-
594
- **Props**: `data`, `columns`, `variant` (`outline` | `line` | `minimal`), `color`, `size`, `striped`, `hoverable`, `bordered`, `enableSorting`, `enableFiltering`, `enablePagination`, `enableRowSelection`, `enableColumnPinning`, `pageSize`, `onRowClick`
595
-
596
- ### Modal
597
-
598
- ```tsx
599
- import Modal, { ModalContent, ModalHeader, ModalTitle, ModalFooter } from '@mdigital_ui/ui/modal'
600
- import Button from '@mdigital_ui/ui/button'
601
-
602
- <Modal open={open} onOpenChange={setOpen}>
603
- <ModalContent size="md">
604
- <ModalHeader>
605
- <ModalTitle>Confirm Delete</ModalTitle>
606
- </ModalHeader>
607
- <div className="p-4">Are you sure?</div>
608
- <ModalFooter>
609
- <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
610
- <Button color="error" onClick={handleDelete}>Delete</Button>
611
- </ModalFooter>
612
- </ModalContent>
613
- </Modal>
614
- ```
615
-
616
- ### Card
617
-
618
- ```tsx
619
- import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@mdigital_ui/ui/card'
620
-
621
- <Card variant="elevated" hoverable>
622
- <CardHeader>
623
- <CardTitle>Dashboard</CardTitle>
624
- <CardDescription>Overview of your metrics</CardDescription>
625
- </CardHeader>
626
- <CardContent>Charts and data here</CardContent>
627
- <CardFooter>
628
- <Button variant="ghost">View Details</Button>
629
- </CardFooter>
630
- </Card>
631
- ```
632
-
633
- **Props**: `variant`, `color`, `size`, `shadow`, `hoverable`, `clickable`, `bordered`, `loading`
634
-
635
- ### Drawer
636
-
637
- ```tsx
638
- import { Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerBody } from '@mdigital_ui/ui/drawer'
639
-
640
- <Drawer>
641
- <DrawerTrigger asChild>
642
- <Button>Open Panel</Button>
643
- </DrawerTrigger>
644
- <DrawerContent side="right" size="md">
645
- <DrawerHeader>
646
- <DrawerTitle>Settings</DrawerTitle>
647
- </DrawerHeader>
648
- <DrawerBody>Content here</DrawerBody>
649
- </DrawerContent>
650
- </Drawer>
651
- ```
652
-
653
- ### Tabs
654
-
655
- ```tsx
656
- import Tabs from '@mdigital_ui/ui/tabs'
657
-
658
- <Tabs
659
- items={[
660
- { key: 'overview', label: 'Overview', content: <Overview /> },
661
- { key: 'settings', label: 'Settings', content: <Settings /> },
662
- { key: 'billing', label: 'Billing', content: <Billing />, disabled: true },
663
- ]}
664
- variant="underline"
665
- color="primary"
666
- />
667
- ```
668
-
669
- **Props**: `items`, `variant` (`underline` | `pills` | `enclosed` | `lifted`), `color`, `size`, `defaultValue`, `value`, `onChange`, `orientation`
670
-
671
- ### Form (react-hook-form + zod)
338
+ <details>
339
+ <summary>Sizing</summary>
672
340
 
673
- ```tsx
674
- import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@mdigital_ui/ui/form'
675
- import { useForm } from 'react-hook-form'
676
- import { zodResolver } from '@hookform/resolvers/zod'
677
- import { z } from 'zod'
678
-
679
- const schema = z.object({ email: z.string().email() })
680
-
681
- function MyForm() {
682
- const form = useForm({ resolver: zodResolver(schema) })
683
-
684
- return (
685
- <Form form={form} onSubmit={(data) => console.log(data)}>
686
- <FormField name="email" control={form.control} render={({ field }) => (
687
- <FormItem>
688
- <FormLabel>Email</FormLabel>
689
- <FormControl>
690
- <Input {...field} />
691
- </FormControl>
692
- <FormMessage />
693
- </FormItem>
694
- )} />
695
- </Form>
696
- )
697
- }
698
341
  ```
342
+ --size-xs / -sm / -md / -lg (shared base heights)
699
343
 
700
- ### Toast
701
-
702
- ```tsx
703
- import { ToastProvider, useToast } from '@mdigital_ui/ui/toast'
344
+ --button-height-xs/sm/md/lg
345
+ --button-padding-x-xs/sm/md/lg
704
346
 
705
- // Wrap your app
706
- <ToastProvider position="top-right">
707
- <App />
708
- </ToastProvider>
347
+ --input-height-xs/sm/md/lg
348
+ --input-padding-x-xs/sm/md/lg
709
349
 
710
- // Use anywhere
711
- const { toast } = useToast()
712
- toast({ title: 'Saved', description: 'Changes saved successfully', variant: 'success' })
713
- ```
350
+ --select-height-xs/sm/md/lg
351
+ --select-padding-x-xs/sm/md/lg
714
352
 
715
- ### Command Palette
353
+ --toggle-height-xs/sm/md/lg
354
+ --toggle-padding-x-xs/sm/md/lg
716
355
 
717
- ```tsx
718
- import { Command, CommandInput, CommandList, CommandGroup, CommandItem } from '@mdigital_ui/ui/command'
719
-
720
- <Command>
721
- <CommandInput placeholder="Search..." />
722
- <CommandList>
723
- <CommandGroup heading="Actions">
724
- <CommandItem onSelect={() => {}}>Create new file</CommandItem>
725
- <CommandItem onSelect={() => {}}>Open settings</CommandItem>
726
- </CommandGroup>
727
- </CommandList>
728
- </Command>
729
- ```
356
+ --textarea-min-height-xs/sm/md/lg
357
+ --textarea-padding-xs/sm/md/lg
730
358
 
731
- ### Upload
359
+ --checkbox-size-xs/sm/md/lg
360
+ --switch-width-xs/sm/md/lg
361
+ --switch-height-xs/sm/md/lg
362
+ --otp-size-xs/sm/md/lg
732
363
 
733
- ```tsx
734
- import Upload from '@mdigital_ui/ui/upload'
735
-
736
- <Upload
737
- variant="dragger"
738
- accept="image/*"
739
- maxSize={5 * 1024 * 1024}
740
- maxCount={3}
741
- onChange={(files) => console.log(files)}
742
- color="primary"
743
- />
364
+ --accordion-padding-x-xs/sm/md/lg
365
+ --accordion-padding-y-xs/sm/md/lg
744
366
  ```
745
367
 
746
- **Props**: `variant` (`dragger` | `button` | `avatar`), `accept`, `maxSize`, `maxCount`, `multiple`, `disabled`, `onChange`, `onRemove`, `color`, `size`
368
+ </details>
747
369
 
748
- ### Tree
370
+ <details>
371
+ <summary>Effects & Layout</summary>
749
372
 
750
- ```tsx
751
- import Tree from '@mdigital_ui/ui/tree'
752
-
753
- <Tree
754
- data={[
755
- { key: '1', label: 'Documents', children: [
756
- { key: '1-1', label: 'Resume.pdf', isLeaf: true },
757
- { key: '1-2', label: 'Cover Letter.docx', isLeaf: true },
758
- ]},
759
- ]}
760
- checkable
761
- defaultExpandAll
762
- onCheck={(keys, info) => console.log(keys)}
763
- />
764
373
  ```
374
+ --shadow-sm / -md / -lg / -xl / -2xl
375
+ --overlay-stripe
765
376
 
766
- ### Progress
767
-
768
- ```tsx
769
- import Progress from '@mdigital_ui/ui/progress'
770
-
771
- <Progress value={65} color="primary" size="md" showValue />
772
- <Progress type="circular" value={80} color="success" />
773
- <Progress type="semicircle" value={45} color="warning" />
377
+ --z-dropdown (1000)
378
+ --z-sticky (1020)
379
+ --z-modal (1040)
380
+ --z-popover (1050)
381
+ --z-tooltip (1060)
382
+ --z-overlay (1070)
774
383
  ```
775
384
 
776
- ---
385
+ </details>
777
386
 
778
387
  ## TypeScript
779
388
 
780
- All components export their props and classNames types:
389
+ All props and types exported:
781
390
 
782
391
  ```tsx
783
- import type { ButtonProps, ButtonClassNames, ButtonVariant, ButtonColor } from '@mdigital_ui/ui'
784
- import type { TableProps, TableClassNames } from '@mdigital_ui/ui'
785
- import type { InputProps, SelectProps, ModalClassNames } from '@mdigital_ui/ui'
392
+ import type { ButtonProps, InputProps, SelectProps } from '@mdigital_ui/ui'
393
+ import type { TableProps, ModalClassNames, CardVariant } from '@mdigital_ui/ui'
786
394
  ```
787
395
 
788
- ---
789
-
790
- ## Accessibility
791
-
792
- - Keyboard navigation on all interactive components
793
- - ARIA roles, labels, and live regions
794
- - Focus rings with `focus-visible` (no outline on mouse click)
795
- - `prefers-reduced-motion` respected globally (all animations disabled)
796
- - Color contrast following WCAG 2.1 AA
797
-
798
- ---
799
-
800
396
  ## Browser Support
801
397
 
802
- Chrome, Firefox, Safari, Edge (latest 2 versions)
398
+ Chrome, Firefox, Safari, Edge last 2 versions.
803
399
 
804
400
  ## License
805
401