@framingui/ui 0.6.2 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/README.md +22 -1090
  2. package/dist/chunk-7UBERMRE.mjs +180 -0
  3. package/dist/chunk-RWYATDH5.mjs +180 -0
  4. package/dist/index.d.mts +1 -140
  5. package/dist/index.mjs +425 -1846
  6. package/dist/src/components/alert-dialog.stories.js +1 -1
  7. package/dist/src/components/alert-dialog.stories.js.map +1 -1
  8. package/dist/src/components/avatar.js +2 -2
  9. package/dist/src/components/avatar.js.map +1 -1
  10. package/dist/src/components/avatar.stories.js +2 -2
  11. package/dist/src/components/avatar.stories.js.map +1 -1
  12. package/dist/src/components/badge.js +5 -5
  13. package/dist/src/components/badge.js.map +1 -1
  14. package/dist/src/components/breadcrumb.js +7 -7
  15. package/dist/src/components/breadcrumb.js.map +1 -1
  16. package/dist/src/components/button.js +10 -10
  17. package/dist/src/components/button.js.map +1 -1
  18. package/dist/src/components/calendar.js +11 -11
  19. package/dist/src/components/calendar.js.map +1 -1
  20. package/dist/src/components/calendar.stories.js +9 -9
  21. package/dist/src/components/calendar.stories.js.map +1 -1
  22. package/dist/src/components/card.js +5 -5
  23. package/dist/src/components/card.js.map +1 -1
  24. package/dist/src/components/card.stories.js +3 -3
  25. package/dist/src/components/card.stories.js.map +1 -1
  26. package/dist/src/components/checkbox.js +1 -1
  27. package/dist/src/components/checkbox.js.map +1 -1
  28. package/dist/src/components/checkbox.stories.js +2 -2
  29. package/dist/src/components/checkbox.stories.js.map +1 -1
  30. package/dist/src/components/command.d.ts +7 -7
  31. package/dist/src/components/command.js +8 -8
  32. package/dist/src/components/command.js.map +1 -1
  33. package/dist/src/components/command.stories.js +6 -6
  34. package/dist/src/components/command.stories.js.map +1 -1
  35. package/dist/src/components/dialog.stories.js +1 -1
  36. package/dist/src/components/dialog.stories.js.map +1 -1
  37. package/dist/src/components/dropdown-menu.js +8 -8
  38. package/dist/src/components/dropdown-menu.js.map +1 -1
  39. package/dist/src/components/form.js +4 -4
  40. package/dist/src/components/form.js.map +1 -1
  41. package/dist/src/components/input.js +1 -1
  42. package/dist/src/components/input.js.map +1 -1
  43. package/dist/src/components/input.stories.js +2 -2
  44. package/dist/src/components/input.stories.js.map +1 -1
  45. package/dist/src/components/label.stories.js +2 -2
  46. package/dist/src/components/label.stories.js.map +1 -1
  47. package/dist/src/components/navigation-menu.js +4 -4
  48. package/dist/src/components/navigation-menu.js.map +1 -1
  49. package/dist/src/components/navigation-menu.stories.js +2 -2
  50. package/dist/src/components/navigation-menu.stories.js.map +1 -1
  51. package/dist/src/components/popover.js +1 -1
  52. package/dist/src/components/popover.js.map +1 -1
  53. package/dist/src/components/popover.stories.js +2 -2
  54. package/dist/src/components/popover.stories.js.map +1 -1
  55. package/dist/src/components/progress.js +1 -1
  56. package/dist/src/components/progress.js.map +1 -1
  57. package/dist/src/components/radio-group.js +2 -2
  58. package/dist/src/components/radio-group.js.map +1 -1
  59. package/dist/src/components/radio-group.stories.js +2 -2
  60. package/dist/src/components/radio-group.stories.js.map +1 -1
  61. package/dist/src/components/scroll-area.js +1 -1
  62. package/dist/src/components/scroll-area.js.map +1 -1
  63. package/dist/src/components/scroll-area.stories.js +4 -4
  64. package/dist/src/components/scroll-area.stories.js.map +1 -1
  65. package/dist/src/components/select.js +5 -5
  66. package/dist/src/components/select.js.map +1 -1
  67. package/dist/src/components/separator.js +1 -1
  68. package/dist/src/components/separator.js.map +1 -1
  69. package/dist/src/components/separator.stories.js +2 -2
  70. package/dist/src/components/separator.stories.js.map +1 -1
  71. package/dist/src/components/sheet.d.ts +1 -1
  72. package/dist/src/components/sheet.js +11 -11
  73. package/dist/src/components/sheet.js.map +1 -1
  74. package/dist/src/components/sidebar.js +13 -13
  75. package/dist/src/components/sidebar.js.map +1 -1
  76. package/dist/src/components/sidebar.stories.js +2 -2
  77. package/dist/src/components/sidebar.stories.js.map +1 -1
  78. package/dist/src/components/skeleton.js +1 -1
  79. package/dist/src/components/skeleton.js.map +1 -1
  80. package/dist/src/components/skeleton.stories.js +1 -1
  81. package/dist/src/components/skeleton.stories.js.map +1 -1
  82. package/dist/src/components/switch.js +1 -1
  83. package/dist/src/components/switch.js.map +1 -1
  84. package/dist/src/components/switch.stories.js +3 -3
  85. package/dist/src/components/switch.stories.js.map +1 -1
  86. package/dist/src/components/table.js +5 -5
  87. package/dist/src/components/table.js.map +1 -1
  88. package/dist/src/components/tabs.js +3 -3
  89. package/dist/src/components/tabs.js.map +1 -1
  90. package/dist/src/components/tabs.stories.js +2 -2
  91. package/dist/src/components/tabs.stories.js.map +1 -1
  92. package/dist/src/components/textarea.js +1 -1
  93. package/dist/src/components/textarea.js.map +1 -1
  94. package/dist/src/components/textarea.stories.js +4 -4
  95. package/dist/src/components/textarea.stories.js.map +1 -1
  96. package/dist/src/components/toast.js +6 -6
  97. package/dist/src/components/toast.js.map +1 -1
  98. package/dist/src/components/tooltip.js +1 -1
  99. package/dist/src/components/tooltip.js.map +1 -1
  100. package/dist/src/index.d.ts +0 -1
  101. package/dist/src/index.d.ts.map +1 -1
  102. package/dist/src/index.js +0 -1
  103. package/dist/src/index.js.map +1 -1
  104. package/dist/src/lib/theme-loader.d.ts.map +1 -1
  105. package/dist/src/lib/theme-loader.js +41 -29
  106. package/dist/src/lib/theme-loader.js.map +1 -1
  107. package/dist/src/lib/tokens.d.ts.map +1 -1
  108. package/dist/src/lib/tokens.js +38 -38
  109. package/dist/src/lib/tokens.js.map +1 -1
  110. package/dist/src/templates/auth/forgot-password.d.ts +2 -2
  111. package/dist/src/templates/auth/forgot-password.d.ts.map +1 -1
  112. package/dist/src/templates/auth/forgot-password.js +3 -36
  113. package/dist/src/templates/auth/forgot-password.js.map +1 -1
  114. package/dist/src/templates/auth/login.d.ts +2 -2
  115. package/dist/src/templates/auth/login.d.ts.map +1 -1
  116. package/dist/src/templates/auth/login.js +3 -36
  117. package/dist/src/templates/auth/login.js.map +1 -1
  118. package/dist/src/templates/auth/signup.d.ts +2 -2
  119. package/dist/src/templates/auth/signup.d.ts.map +1 -1
  120. package/dist/src/templates/auth/signup.js +3 -36
  121. package/dist/src/templates/auth/signup.js.map +1 -1
  122. package/dist/src/templates/auth/verification.d.ts +2 -2
  123. package/dist/src/templates/auth/verification.d.ts.map +1 -1
  124. package/dist/src/templates/auth/verification.js +3 -36
  125. package/dist/src/templates/auth/verification.js.map +1 -1
  126. package/dist/src/templates/core/landing.d.ts +2 -2
  127. package/dist/src/templates/core/landing.d.ts.map +1 -1
  128. package/dist/src/templates/core/landing.js +3 -36
  129. package/dist/src/templates/core/landing.js.map +1 -1
  130. package/dist/src/templates/core/preferences.d.ts +2 -2
  131. package/dist/src/templates/core/preferences.d.ts.map +1 -1
  132. package/dist/src/templates/core/preferences.js +3 -42
  133. package/dist/src/templates/core/preferences.js.map +1 -1
  134. package/dist/src/templates/core/profile.d.ts +2 -2
  135. package/dist/src/templates/core/profile.d.ts.map +1 -1
  136. package/dist/src/templates/core/profile.js +3 -36
  137. package/dist/src/templates/core/profile.js.map +1 -1
  138. package/dist/src/templates/create-template.d.ts +4 -0
  139. package/dist/src/templates/create-template.d.ts.map +1 -0
  140. package/dist/src/templates/create-template.js +41 -0
  141. package/dist/src/templates/create-template.js.map +1 -0
  142. package/dist/src/templates/dashboard/overview.d.ts +2 -2
  143. package/dist/src/templates/dashboard/overview.d.ts.map +1 -1
  144. package/dist/src/templates/dashboard/overview.js +3 -57
  145. package/dist/src/templates/dashboard/overview.js.map +1 -1
  146. package/dist/src/templates/feedback/confirmation.d.ts +2 -2
  147. package/dist/src/templates/feedback/confirmation.d.ts.map +1 -1
  148. package/dist/src/templates/feedback/confirmation.js +3 -36
  149. package/dist/src/templates/feedback/confirmation.js.map +1 -1
  150. package/dist/src/templates/feedback/empty.d.ts +2 -2
  151. package/dist/src/templates/feedback/empty.d.ts.map +1 -1
  152. package/dist/src/templates/feedback/empty.js +3 -36
  153. package/dist/src/templates/feedback/empty.js.map +1 -1
  154. package/dist/src/templates/feedback/error.d.ts +2 -2
  155. package/dist/src/templates/feedback/error.d.ts.map +1 -1
  156. package/dist/src/templates/feedback/error.js +3 -36
  157. package/dist/src/templates/feedback/error.js.map +1 -1
  158. package/dist/src/templates/feedback/loading.d.ts +2 -2
  159. package/dist/src/templates/feedback/loading.d.ts.map +1 -1
  160. package/dist/src/templates/feedback/loading.js +3 -36
  161. package/dist/src/templates/feedback/loading.js.map +1 -1
  162. package/dist/src/templates/feedback/success.d.ts +2 -2
  163. package/dist/src/templates/feedback/success.d.ts.map +1 -1
  164. package/dist/src/templates/feedback/success.js +3 -36
  165. package/dist/src/templates/feedback/success.js.map +1 -1
  166. package/dist/src/templates/types.js +6 -6
  167. package/dist/src/templates/types.js.map +1 -1
  168. package/dist/templates/index.d.mts +142 -0
  169. package/dist/templates/index.mjs +905 -0
  170. package/dist/tsconfig.tsbuildinfo +1 -1
  171. package/package.json +7 -2
  172. package/styles/globals.css +113 -84
package/README.md CHANGED
@@ -1,33 +1,21 @@
1
- # @framingui
1
+ # @framingui/ui
2
2
 
3
- FramingUI Reference Component Library - High-quality, accessible React components with CSS Variables theming.
3
+ > Production-ready React components with CSS Variables theming
4
4
 
5
- ## Overview
6
-
7
- @framingui provides 20 production-ready components + 13 screen templates built with:
8
-
9
- - **Screen Templates (NEW)**: 13 full-page layouts for rapid development
10
- - **React 19** - Latest React features with Server Components support
11
- - **TypeScript 5.7+** - Full type safety with strict mode
12
- - **Radix UI v1.0+** - Accessible headless primitives
13
- - **CSS Variables** - 3-layer architecture (Atomic → Semantic → Component)
14
- - **WCAG 2.1 AA** - Fully accessible
5
+ [![npm](https://img.shields.io/npm/v/@framingui/ui)](https://www.npmjs.com/package/@framingui/ui)
6
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
15
7
 
16
8
  ## Installation
17
9
 
18
10
  ```bash
19
- pnpm add @framingui
20
- # or
21
- yarn add @framingui
11
+ npm install @framingui/ui
22
12
  ```
23
13
 
24
14
  ## Quick Start
25
15
 
26
- ### Import Components
27
-
28
16
  ```tsx
29
- import { Button, Input, Card } from '@framingui';
30
- import '@framingui/styles';
17
+ import { Button, Input, Card } from '@framingui/ui';
18
+ import '@framingui/ui/styles';
31
19
 
32
20
  export default function App() {
33
21
  return (
@@ -47,1086 +35,30 @@ export default function App() {
47
35
  }
48
36
  ```
49
37
 
50
- ### CSS Variables Theming
51
-
52
- Import the CSS Variables template and customize:
53
-
54
- ```css
55
- @import '@framingui/styles';
56
-
57
- :root {
58
- /* Button Tokens */
59
- --button-primary-background: #3b82f6;
60
- --button-primary-foreground: white;
61
-
62
- /* Input Tokens */
63
- --input-border: #d1d5db;
64
- --input-background: white;
65
-
66
- /* Card Tokens */
67
- --card-background: white;
68
- --card-border: #e5e7eb;
69
-
70
- /* ... customize 100+ other tokens */
71
- }
72
- ```
73
-
74
38
  ## Components
75
39
 
76
- ### Primitive Components (14)
77
-
78
- Core UI building blocks with single responsibility:
79
-
80
- - **Button** - Interactive button with loading states and variants (default, primary, secondary, destructive, outline, ghost, link)
81
- - **Input** - Text input with error states and type support (text, email, password, number)
82
- - **Checkbox** - Checkbox with indeterminate support and form integration
83
- - **RadioGroup** - Radio button groups with keyboard navigation
84
- - **Switch** - Toggle switch with checked/unchecked states
85
- - **Slider** - Range slider with min/max/step configuration
86
- - **Text** - Polymorphic text component with size variants
87
- - **Heading** - Hierarchical headings (h1-h6) with level prop
88
- - **Badge** - Status badges (default, primary, secondary, destructive, outline)
89
- - **Avatar** - User avatars with image/fallback support
90
- - **Progress** - Progress bar with value 0-100
91
- - **Link** - Navigation links (default, muted, underline variants)
92
- - **Image** - Image component with alt text and optional object-fit
93
- - **List** - Polymorphic list component (ul/ol)
94
-
95
- ### Composed Components (6)
96
-
97
- Complex components built from primitives:
98
-
99
- - **Card** - Card container with header/content/footer structure
100
- - **Form** - Form with validation context and error handling
101
- - **Modal** - Dialog/modal overlay with Portal rendering
102
- - **Dropdown** - Dropdown menu with keyboard navigation
103
- - **Tabs** - Tabbed navigation with automatic ARIA labels
104
- - **Table** - Data table with semantic HTML structure
105
-
106
- ---
107
-
108
- ## Component Examples
109
-
110
- ### Button
111
-
112
- ```tsx
113
- import { Button } from '@framingui';
114
-
115
- // Variants
116
- <Button variant="default">Default</Button>
117
- <Button variant="primary">Primary</Button>
118
- <Button variant="secondary">Secondary</Button>
119
- <Button variant="destructive">Delete</Button>
120
- <Button variant="outline">Outline</Button>
121
- <Button variant="ghost">Ghost</Button>
122
- <Button variant="link">Link</Button>
123
-
124
- // Sizes
125
- <Button size="sm">Small</Button>
126
- <Button size="md">Medium</Button>
127
- <Button size="lg">Large</Button>
128
-
129
- // States
130
- <Button loading>Loading...</Button>
131
- <Button disabled>Disabled</Button>
132
- ```
133
-
134
- **Props:**
135
-
136
- - `variant`: `"default" | "primary" | "secondary" | "destructive" | "outline" | "ghost" | "link"`
137
- - `size`: `"sm" | "md" | "lg"`
138
- - `loading`: `boolean`
139
- - All native `<button>` props
140
-
141
- ---
142
-
143
- ### Input
144
-
145
- ```tsx
146
- import { Input } from '@framingui';
147
-
148
- // Basic usage
149
- <Input type="text" placeholder="Enter text..." />
150
- <Input type="email" placeholder="Email address" />
151
- <Input type="password" placeholder="Password" />
152
-
153
- // With error state
154
- <Input type="text" aria-invalid="true" />
155
-
156
- // Disabled
157
- <Input disabled placeholder="Disabled input" />
158
- ```
159
-
160
- **Props:**
161
-
162
- - `type`: `"text" | "email" | "password" | "number" | "search" | "tel" | "url"`
163
- - All native `<input>` props
164
-
165
- ---
166
-
167
- ### Card
168
-
169
- ```tsx
170
- import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@framingui';
171
-
172
- <Card>
173
- <CardHeader>
174
- <CardTitle>Card Title</CardTitle>
175
- <CardDescription>Card description or subtitle</CardDescription>
176
- </CardHeader>
177
- <CardContent>
178
- <p>Main content goes here</p>
179
- </CardContent>
180
- <CardFooter>
181
- <Button>Action</Button>
182
- </CardFooter>
183
- </Card>;
184
- ```
185
-
186
- ---
187
-
188
- ### Form
189
-
190
- ```tsx
191
- import { Form, FormField, FormLabel, FormControl, FormDescription, FormMessage } from '@framingui';
192
- import { Input } from '@framingui';
193
-
194
- <Form
195
- onSubmit={e => {
196
- e.preventDefault(); /* handle submit */
197
- }}
198
- >
199
- <FormField name="email">
200
- <FormLabel htmlFor="email">Email</FormLabel>
201
- <FormControl>
202
- <Input id="email" type="email" />
203
- </FormControl>
204
- <FormDescription>We'll never share your email.</FormDescription>
205
- <FormMessage name="email">Invalid email address</FormMessage>
206
- </FormField>
207
- </Form>;
208
- ```
209
-
210
- ---
211
-
212
- ### Modal (Dialog)
213
-
214
- ```tsx
215
- import {
216
- Modal,
217
- ModalTrigger,
218
- ModalContent,
219
- ModalHeader,
220
- ModalTitle,
221
- ModalDescription,
222
- ModalFooter,
223
- ModalClose,
224
- } from '@framingui';
225
- import { Button } from '@framingui';
226
-
227
- <Modal>
228
- <ModalTrigger asChild>
229
- <Button>Open Modal</Button>
230
- </ModalTrigger>
231
- <ModalContent>
232
- <ModalHeader>
233
- <ModalTitle>Modal Title</ModalTitle>
234
- <ModalDescription>Modal description text</ModalDescription>
235
- </ModalHeader>
236
- <div>Modal body content</div>
237
- <ModalFooter>
238
- <ModalClose asChild>
239
- <Button variant="outline">Cancel</Button>
240
- </ModalClose>
241
- <Button variant="primary">Confirm</Button>
242
- </ModalFooter>
243
- </ModalContent>
244
- </Modal>;
245
- ```
246
-
247
- ---
248
-
249
- ### Dropdown Menu
250
-
251
- ```tsx
252
- import {
253
- Dropdown,
254
- DropdownTrigger,
255
- DropdownContent,
256
- DropdownItem,
257
- DropdownSeparator,
258
- } from '@framingui';
259
- import { Button } from '@framingui';
260
-
261
- <Dropdown>
262
- <DropdownTrigger asChild>
263
- <Button>Open Menu</Button>
264
- </DropdownTrigger>
265
- <DropdownContent>
266
- <DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>
267
- <DropdownItem onClick={() => console.log('Duplicate')}>Duplicate</DropdownItem>
268
- <DropdownSeparator />
269
- <DropdownItem disabled>Disabled Item</DropdownItem>
270
- <DropdownItem onClick={() => console.log('Delete')}>Delete</DropdownItem>
271
- </DropdownContent>
272
- </Dropdown>;
273
- ```
274
-
275
- ---
276
-
277
- ### Tabs
278
-
279
- ```tsx
280
- import { Tabs, TabsList, TabsTrigger, TabsContent } from '@framingui';
281
-
282
- <Tabs defaultValue="tab1">
283
- <TabsList>
284
- <TabsTrigger value="tab1">Tab 1</TabsTrigger>
285
- <TabsTrigger value="tab2">Tab 2</TabsTrigger>
286
- <TabsTrigger value="tab3">Tab 3</TabsTrigger>
287
- </TabsList>
288
- <TabsContent value="tab1">
289
- <p>Content for Tab 1</p>
290
- </TabsContent>
291
- <TabsContent value="tab2">
292
- <p>Content for Tab 2</p>
293
- </TabsContent>
294
- <TabsContent value="tab3">
295
- <p>Content for Tab 3</p>
296
- </TabsContent>
297
- </Tabs>;
298
- ```
299
-
300
- ---
301
-
302
- ### Checkbox
303
-
304
- ```tsx
305
- import { Checkbox } from '@framingui';
306
-
307
- // Basic checkbox
308
- <label>
309
- <Checkbox id="terms" />
310
- Accept terms and conditions
311
- </label>
312
-
313
- // Indeterminate state
314
- <Checkbox checked="indeterminate" />
315
-
316
- // Disabled
317
- <Checkbox disabled />
318
- ```
319
-
320
- **Props:**
321
-
322
- - `checked`: `boolean | "indeterminate"`
323
- - `onCheckedChange`: `(checked: boolean | "indeterminate") => void`
324
- - All Radix UI Checkbox props
325
-
326
- ---
327
-
328
- ### RadioGroup
329
-
330
- ```tsx
331
- import { RadioGroup, RadioGroupItem } from '@framingui';
332
-
333
- <RadioGroup defaultValue="option1">
334
- <div>
335
- <RadioGroupItem value="option1" id="opt1" />
336
- <label htmlFor="opt1">Option 1</label>
337
- </div>
338
- <div>
339
- <RadioGroupItem value="option2" id="opt2" />
340
- <label htmlFor="opt2">Option 2</label>
341
- </div>
342
- <div>
343
- <RadioGroupItem value="option3" id="opt3" />
344
- <label htmlFor="opt3">Option 3</label>
345
- </div>
346
- </RadioGroup>;
347
- ```
348
-
349
- ---
350
-
351
- ### Switch
352
-
353
- ```tsx
354
- import { Switch } from '@framingui';
355
-
356
- <label>
357
- <Switch id="notifications" />
358
- Enable notifications
359
- </label>
360
-
361
- <Switch checked onCheckedChange={(checked) => console.log(checked)} />
362
- ```
363
-
364
- **Props:**
365
-
366
- - `checked`: `boolean`
367
- - `onCheckedChange`: `(checked: boolean) => void`
368
- - All Radix UI Switch props
369
-
370
- ---
371
-
372
- ### Slider
373
-
374
- ```tsx
375
- import { Slider } from '@framingui';
376
-
377
- // Basic slider
378
- <label htmlFor="volume" id="volume-label">Volume</label>
379
- <Slider
380
- id="volume"
381
- defaultValue={[50]}
382
- min={0}
383
- max={100}
384
- step={1}
385
- aria-labelledby="volume-label"
386
- />
387
-
388
- // Range slider
389
- <Slider defaultValue={[25, 75]} min={0} max={100} />
390
- ```
391
-
392
- **Props:**
393
-
394
- - `defaultValue`: `number[]`
395
- - `min`: `number`
396
- - `max`: `number`
397
- - `step`: `number`
398
- - All Radix UI Slider props
399
-
400
- ---
401
-
402
- ### Progress
403
-
404
- ```tsx
405
- import { Progress } from '@framingui';
406
-
407
- <Progress value={50} aria-label="Upload progress" />
408
- <Progress value={75} aria-label="Loading" />
409
- <Progress value={100} aria-label="Complete" />
410
- ```
411
-
412
- **Props:**
413
-
414
- - `value`: `number` (0-100)
415
- - All Radix UI Progress props
416
-
417
- ---
418
-
419
- ### Avatar
420
-
421
- ```tsx
422
- import { Avatar, AvatarImage, AvatarFallback } from '@framingui';
423
-
424
- <Avatar>
425
- <AvatarImage src="https://example.com/avatar.jpg" alt="John Doe" />
426
- <AvatarFallback>JD</AvatarFallback>
427
- </Avatar>;
428
- ```
429
-
430
- ---
431
-
432
- ### Badge
433
-
434
- ```tsx
435
- import { Badge } from '@framingui';
436
-
437
- <Badge variant="default">Default</Badge>
438
- <Badge variant="primary">Primary</Badge>
439
- <Badge variant="secondary">Secondary</Badge>
440
- <Badge variant="destructive">Error</Badge>
441
- <Badge variant="outline">Outline</Badge>
442
- ```
443
-
444
- **Props:**
445
-
446
- - `variant`: `"default" | "primary" | "secondary" | "destructive" | "outline"`
447
-
448
- ---
449
-
450
- ### Text
451
-
452
- ```tsx
453
- import { Text } from '@framingui';
454
-
455
- // Sizes
456
- <Text size="xs">Extra small text</Text>
457
- <Text size="sm">Small text</Text>
458
- <Text size="md">Medium text</Text>
459
- <Text size="lg">Large text</Text>
460
-
461
- // Polymorphic rendering
462
- <Text as="p">Paragraph</Text>
463
- <Text as="span">Inline text</Text>
464
- <Text as="div">Block text</Text>
465
- ```
466
-
467
- **Props:**
468
-
469
- - `as`: `"p" | "span" | "div" | "label"`
470
- - `size`: `"xs" | "sm" | "md" | "lg"`
471
- - `variant`: `"default" | "muted"`
472
-
473
- ---
474
-
475
- ### Heading
476
-
477
- ```tsx
478
- import { Heading } from '@framingui';
479
-
480
- <Heading level={1}>Heading 1</Heading>
481
- <Heading level={2}>Heading 2</Heading>
482
- <Heading level={3}>Heading 3</Heading>
483
- <Heading level={4}>Heading 4</Heading>
484
- <Heading level={5}>Heading 5</Heading>
485
- <Heading level={6}>Heading 6</Heading>
486
-
487
- // Sizes
488
- <Heading level={1} size="sm">Small H1</Heading>
489
- <Heading level={2} size="lg">Large H2</Heading>
490
- ```
491
-
492
- **Props:**
493
-
494
- - `level`: `1 | 2 | 3 | 4 | 5 | 6`
495
- - `size`: `"sm" | "md" | "lg"`
496
-
497
- ---
498
-
499
- ### Link
500
-
501
- ```tsx
502
- import { Link } from '@framingui';
503
-
504
- <Link href="/home" variant="default">Default Link</Link>
505
- <Link href="/about" variant="muted">Muted Link</Link>
506
- <Link href="/contact" variant="underline">Underlined Link</Link>
507
- ```
508
-
509
- **Props:**
510
-
511
- - `href`: `string`
512
- - `variant`: `"default" | "muted" | "underline"`
513
- - All native `<a>` props
514
-
515
- ---
516
-
517
- ### List
518
-
519
- ```tsx
520
- import { List, ListItem } from '@framingui';
521
-
522
- // Unordered list
523
- <List as="ul">
524
- <ListItem>Item 1</ListItem>
525
- <ListItem>Item 2</ListItem>
526
- <ListItem>Item 3</ListItem>
527
- </List>
528
-
529
- // Ordered list
530
- <List as="ol">
531
- <ListItem>First item</ListItem>
532
- <ListItem>Second item</ListItem>
533
- <ListItem>Third item</ListItem>
534
- </List>
535
- ```
536
-
537
- **Props:**
538
-
539
- - `as`: `"ul" | "ol"`
540
-
541
- ---
542
-
543
- ### Image
544
-
545
- ```tsx
546
- import { Image } from '@framingui';
547
-
548
- <Image
549
- src="https://example.com/image.jpg"
550
- alt="Description of image"
551
- />
552
-
553
- <Image
554
- src="https://example.com/image.jpg"
555
- alt="Cover image"
556
- className="object-cover w-full h-64"
557
- />
558
- ```
559
-
560
- **Props:**
561
-
562
- - `src`: `string`
563
- - `alt`: `string` (required for accessibility)
564
- - All native `<img>` props
565
-
566
- ---
567
-
568
- ### Table
569
-
570
- ```tsx
571
- import {
572
- Table,
573
- TableHeader,
574
- TableBody,
575
- TableFooter,
576
- TableRow,
577
- TableHead,
578
- TableCell,
579
- TableCaption,
580
- } from '@framingui';
581
-
582
- <Table>
583
- <TableCaption>List of users</TableCaption>
584
- <TableHeader>
585
- <TableRow>
586
- <TableHead>Name</TableHead>
587
- <TableHead>Email</TableHead>
588
- <TableHead>Role</TableHead>
589
- </TableRow>
590
- </TableHeader>
591
- <TableBody>
592
- <TableRow>
593
- <TableCell>John Doe</TableCell>
594
- <TableCell>john@example.com</TableCell>
595
- <TableCell>Admin</TableCell>
596
- </TableRow>
597
- <TableRow>
598
- <TableCell>Jane Smith</TableCell>
599
- <TableCell>jane@example.com</TableCell>
600
- <TableCell>User</TableCell>
601
- </TableRow>
602
- </TableBody>
603
- <TableFooter>
604
- <TableRow>
605
- <TableCell colSpan={3}>Total: 2 users</TableCell>
606
- </TableRow>
607
- </TableFooter>
608
- </Table>;
609
- ```
610
-
611
- ---
612
-
613
- ## Features
614
-
615
- ### CSS Variables First
616
-
617
- All themeable properties use CSS Variables:
618
-
619
- ```tsx
620
- <Button variant="primary">
621
- {/* Uses --button-primary-background and --button-primary-foreground */}
622
- </Button>
623
- ```
624
-
625
- ### Type-Safe Variants
626
-
627
- Powered by class-variance-authority:
628
-
629
- ```tsx
630
- <Button variant="secondary" size="lg" loading>
631
- Click me
632
- </Button>
633
- ```
634
-
635
- ### Accessibility Built-In
636
-
637
- - **WCAG 2.1 AA compliant** - All components pass axe-core validation
638
- - **Proper ARIA attributes** - Screen reader friendly
639
- - **Keyboard navigation** - Full keyboard support (Tab, Arrow keys, Enter, Escape)
640
- - **Focus management** - Visible focus indicators and proper focus trapping
641
-
642
- ### Zero Config Setup
643
-
644
- Works out of the box with sensible defaults:
645
-
646
- ```tsx
647
- import { Button } from '@framingui';
648
-
649
- <Button>Just works</Button>;
650
- ```
651
-
652
- ---
40
+ ### Primitives (14)
653
41
 
654
- ## Screen Templates (Phase 3)
42
+ Button, Input, Checkbox, Radio, Switch, Slider, Text, Heading, Badge, Avatar, Progress, Link, Image, List
655
43
 
656
- **New in Phase 3**: 13 Screen Templates for rapid full-screen composition.
44
+ ### Composed (6)
657
45
 
658
- ### Overview
46
+ Card, Form, Modal, Dropdown, Tabs, Table
659
47
 
660
- Screen Templates provide pre-built, theme-aware full-screen layouts that combine multiple components into cohesive user experiences. Each template is registered in a centralized `TemplateRegistry` for easy discovery and reuse.
48
+ ## Key Features
661
49
 
662
- **Features:**
50
+ - **WCAG 2.1 AA Compliant**: Fully accessible
51
+ - **CSS Variables**: 3-layer token system (Atomic → Semantic → Component)
52
+ - **Type-Safe**: Full TypeScript support
53
+ - **Zero Config**: Works out of the box
54
+ - **98%+ Test Coverage**: Production-ready quality
663
55
 
664
- - **13 Pre-built Layouts**: Auth (4), Core (3), Feedback (5), Dashboard (1)
665
- - **Theme-Aware**: Automatically adapts to active theme via CSS Variables
666
- - **AI-Friendly**: Clear customization boundaries for AI agents
667
- - **Type-Safe**: Full TypeScript support with ScreenTemplate interface
668
- - **Responsive**: Desktop, Tablet, Mobile layouts
669
-
670
- ### Quick Start
671
-
672
- ```tsx
673
- import { templateRegistry } from '@framingui/templates';
674
-
675
- // Get all templates
676
- const allTemplates = templateRegistry.getAll(); // 13 templates
677
-
678
- // Get by category
679
- const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
680
-
681
- // Get specific template
682
- const loginTemplate = templateRegistry.get('auth.login');
683
- ```
684
-
685
- ### Available Templates (13)
686
-
687
- #### Auth Templates (4)
688
-
689
- ```tsx
690
- import {
691
- LoginTemplate,
692
- SignupTemplate,
693
- ForgotPasswordTemplate,
694
- VerificationTemplate,
695
- } from '@framingui/templates/auth';
696
- ```
697
-
698
- - **LoginTemplate** (`auth.login`) - Centered login card with email/password
699
- - **SignupTemplate** (`auth.signup`) - Registration form with terms acceptance
700
- - **ForgotPasswordTemplate** (`auth.forgot-password`) - Password reset flow
701
- - **VerificationTemplate** (`auth.verification`) - Email verification confirmation
702
-
703
- #### Core Templates (3)
704
-
705
- ```tsx
706
- import { LandingTemplate, PreferencesTemplate, ProfileTemplate } from '@framingui/templates/core';
707
- ```
708
-
709
- - **LandingTemplate** (`home.landing`) - Full-width landing page with CTA
710
- - **PreferencesTemplate** (`settings.preferences`) - Sidebar settings layout
711
- - **ProfileTemplate** (`account.profile`) - User profile with avatar editing
712
-
713
- #### Feedback Templates (5)
714
-
715
- ```tsx
716
- import {
717
- LoadingTemplate,
718
- ErrorTemplate,
719
- EmptyTemplate,
720
- ConfirmationTemplate,
721
- SuccessTemplate,
722
- } from '@framingui/templates/feedback';
723
- ```
724
-
725
- - **LoadingTemplate** (`feedback.loading`) - Loading skeleton state
726
- - **ErrorTemplate** (`feedback.error`) - Error state with retry button
727
- - **EmptyTemplate** (`feedback.empty`) - Empty state with CTA
728
- - **ConfirmationTemplate** (`feedback.confirmation`) - Dialog confirmation
729
- - **SuccessTemplate** (`feedback.success`) - Success message with next steps
730
-
731
- #### Dashboard Template (1)
732
-
733
- ```tsx
734
- import { DashboardTemplate } from '@framingui/templates/dashboard';
735
- ```
736
-
737
- - **DashboardTemplate** (`dashboard.overview`) - Dashboard layout with sidebar
738
-
739
- ### Template Features
740
-
741
- - **Type-Safe**: Full TypeScript support with `ScreenTemplate` interface
742
- - **AI-Friendly**: Clear customization boundaries (`slots`, `texts`, `options`)
743
- - **Theme-Aware**: CSS Variables for automatic theme adaptation
744
- - **Responsive**: Breakpoint-based layouts (Desktop 1024px+, Tablet 768-1024px, Mobile <768px)
745
- - **Accessible**: WCAG 2.1 AA compliance (validation in progress)
746
-
747
- ### TemplateRegistry API
748
-
749
- The `TemplateRegistry` provides centralized template management:
750
-
751
- ```tsx
752
- import { templateRegistry } from '@framingui/templates/registry';
753
-
754
- // Get all templates
755
- const allTemplates = templateRegistry.getAll(); // 13 templates
756
-
757
- // Get templates by category
758
- const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
759
-
760
- // Get specific template
761
- const loginTemplate = templateRegistry.get('auth.login');
762
-
763
- // Find by required components
764
- const formsTemplates = templateRegistry.findByRequiredComponents(['Button', 'Input', 'Form']);
765
- ```
766
-
767
- **Design Reference**: All templates follow [Claude.ai Design Philosophy](../../.moai/specs/SPEC-UI-002/reference-guide.md) - clarity, accessibility, universality.
768
-
769
- ### Phase 3 Status
770
-
771
- **Completed (2026-02-01):**
772
-
773
- - ✅ Template type system (`ScreenTemplate`, `TemplateRegistry`)
774
- - ✅ 13 templates implemented (Auth 4, Core 3, Feedback 5, Dashboard 1)
775
- - ✅ Template registry with category filtering
776
- - ✅ Storybook stories for all templates
777
- - ✅ SPEC TAG annotations (TAG-UI002-001 ~ 035)
778
- - ⚠️ Test coverage: 17.26% (improvement planned)
779
-
780
- **Next Steps:**
781
-
782
- - Test coverage to 85%+
783
- - Accessibility validation (axe-core, WCAG 2.1 AA)
784
- - Additional template variants
785
- - Template preview gallery in Storybook
786
-
787
- ---
788
-
789
-
790
- ## CSS Variables Reference
791
-
792
- @framingui uses a 3-layer CSS Variables architecture:
793
-
794
- ### Layer 1: Atomic Tokens
795
-
796
- ```css
797
- --color-primary: #3b82f6;
798
- --color-destructive: #ef4444;
799
- --spacing-sm: 0.5rem;
800
- --radius-md: 0.375rem;
801
- ```
802
-
803
- ### Layer 2: Semantic Tokens
804
-
805
- ```css
806
- --text-primary: var(--color-primary);
807
- --bg-destructive: var(--color-destructive);
808
- ```
809
-
810
- ### Layer 3: Component Tokens
811
-
812
- **Button Tokens:**
813
-
814
- ```css
815
- --button-default-background
816
- --button-default-foreground
817
- --button-primary-background
818
- --button-primary-foreground
819
- --button-secondary-background
820
- --button-secondary-foreground
821
- --button-destructive-background
822
- --button-destructive-foreground
823
- --button-outline-border
824
- --button-outline-foreground
825
- --button-ghost-hover-background
826
- --button-link-foreground
827
- --button-disabled-opacity
828
- --button-focus-ring
829
- ```
830
-
831
- **Input Tokens:**
832
-
833
- ```css
834
- --input-background
835
- --input-foreground
836
- --input-border
837
- --input-placeholder
838
- --input-focus-ring
839
- --input-disabled-background
840
- --input-disabled-foreground
841
- ```
842
-
843
- **Card Tokens:**
844
-
845
- ```css
846
- --card-background
847
- --card-foreground
848
- --card-border
849
- ```
56
+ ## Documentation
850
57
 
851
- **Modal Tokens:**
852
-
853
- ```css
854
- --modal-background
855
- --modal-border
856
- --modal-overlay-background
857
- --modal-title-foreground
858
- --modal-description-foreground
859
- ```
860
-
861
- **Form Tokens:**
862
-
863
- ```css
864
- --form-label-foreground
865
- --form-message-destructive
866
- --form-description-foreground
867
- ```
868
-
869
- **Other Component Tokens:**
870
-
871
- - Badge: `--badge-*-background`, `--badge-*-foreground`, `--badge-*-border`
872
- - Dropdown: `--dropdown-*-background`, `--dropdown-item-*`
873
- - Tabs: `--tabs-*-background`, `--tabs-trigger-*`
874
- - Table: `--table-*-background`, `--table-border`
875
- - Progress: `--progress-background`, `--progress-indicator-background`
876
- - Slider: `--slider-track-background`, `--slider-thumb-*`
877
- - Avatar: `--avatar-background`, `--avatar-foreground`
878
-
879
- ### Custom Theme Example
880
-
881
- ```css
882
- /* dark-theme.css */
883
- @import '@framingui/styles';
884
-
885
- :root {
886
- /* Atomic Layer */
887
- --color-primary: #60a5fa;
888
- --color-background: #1f2937;
889
- --color-foreground: #f9fafb;
890
-
891
- /* Button Layer */
892
- --button-primary-background: var(--color-primary);
893
- --button-primary-foreground: #000000;
894
- --button-default-background: #374151;
895
- --button-default-foreground: var(--color-foreground);
896
-
897
- /* Input Layer */
898
- --input-background: #374151;
899
- --input-foreground: var(--color-foreground);
900
- --input-border: #4b5563;
901
-
902
- /* Card Layer */
903
- --card-background: #374151;
904
- --card-foreground: var(--color-foreground);
905
- --card-border: #4b5563;
906
- }
907
- ```
908
-
909
- ---
910
-
911
- ## Development
912
-
913
- ### Setup
914
-
915
- ```bash
916
- # Clone repository
917
- git clone https://github.com/your-org/tekton.git
918
- cd tekton/packages/ui
919
-
920
- # Install dependencies (requires pnpm)
921
- pnpm install
922
- ```
923
-
924
- ### Scripts
925
-
926
- ```bash
927
- # Run tests
928
- pnpm test
929
-
930
- # Run tests with coverage (target: ≥90%)
931
- pnpm test:coverage
932
-
933
- # Run tests in watch mode
934
- pnpm test:watch
935
-
936
- # Type check (TypeScript 5.7+ strict mode)
937
- pnpm type-check
938
-
939
- # Lint (ESLint 9)
940
- pnpm lint
941
-
942
- # Build (outputs to dist/)
943
- pnpm build
944
-
945
- # Clean build artifacts
946
- pnpm clean
947
- ```
948
-
949
- ### Project Structure
950
-
951
- ```
952
- packages/ui/
953
- ├── src/
954
- │ ├── primitives/ # 14 primitive components
955
- │ │ ├── button.tsx
956
- │ │ ├── input.tsx
957
- │ │ ├── checkbox.tsx
958
- │ │ └── ...
959
- │ ├── components/ # 6 composed components
960
- │ │ ├── card.tsx
961
- │ │ ├── form.tsx
962
- │ │ ├── modal.tsx
963
- │ │ └── ...
964
- │ ├── lib/
965
- │ │ └── utils.ts # cn() utility
966
- │ └── index.ts # Main export
967
- ├── __tests__/
968
- │ ├── primitives/ # Primitive tests
969
- │ ├── components/ # Component tests
970
- │ ├── lib/ # Utility tests
971
- │ └── accessibility.test.tsx # WCAG compliance
972
- ├── vitest.config.ts
973
- ├── tsconfig.json
974
- └── package.json
975
- ```
976
-
977
- ---
978
-
979
- ## Testing
980
-
981
- All 20 components include comprehensive test coverage:
982
-
983
- ### Test Coverage (98.93%)
984
-
985
- - **Statement Coverage**: 98.93%
986
- - **Branch Coverage**: 95.52%
987
- - **Function Coverage**: 100%
988
- - **Line Coverage**: 98.93%
989
-
990
- ### Test Categories
991
-
992
- **Unit Tests (Vitest + Testing Library)**
993
-
994
- - Component rendering
995
- - Props validation
996
- - Variant behavior
997
- - State management
998
- - Event handling
999
-
1000
- **Accessibility Tests (vitest-axe)**
1001
-
1002
- - WCAG 2.1 AA compliance
1003
- - ARIA attributes
1004
- - Semantic HTML
1005
- - Color contrast (disabled in jsdom)
1006
-
1007
- **Keyboard Navigation Tests**
1008
-
1009
- - Tab navigation
1010
- - Arrow key navigation (RadioGroup, Tabs, Slider)
1011
- - Enter/Space activation
1012
- - Escape key handling (Modal, Dropdown)
1013
-
1014
- **User Interaction Tests (userEvent)**
1015
-
1016
- - Click events
1017
- - Form submissions
1018
- - Input changes
1019
- - Focus management
1020
-
1021
- ### Running Tests
1022
-
1023
- ```bash
1024
- # All tests
1025
- pnpm test
1026
-
1027
- # Specific file
1028
- pnpm vitest run __tests__/primitives/button.test.tsx
1029
-
1030
- # Watch mode
1031
- pnpm test:watch
1032
-
1033
- # Coverage report
1034
- pnpm test:coverage
1035
- ```
1036
-
1037
- ---
1038
-
1039
- ## Browser Support
1040
-
1041
- - Chrome (latest)
1042
- - Firefox (latest)
1043
- - Safari (latest)
1044
- - Edge (latest)
1045
-
1046
- **Note**: Internet Explorer is not supported.
1047
-
1048
- ---
1049
-
1050
- ## TypeScript Support
1051
-
1052
- All components are fully typed with TypeScript 5.7+:
1053
-
1054
- ```tsx
1055
- import { Button, ButtonProps } from '@framingui';
1056
-
1057
- // Type-safe props
1058
- const MyButton: React.FC<ButtonProps> = props => {
1059
- return <Button {...props} />;
1060
- };
1061
-
1062
- // Type inference
1063
- <Button
1064
- variant="primary" // ✓ Valid
1065
- variant="invalid" // ✗ TypeScript error
1066
- size="lg" // ✓ Valid
1067
- onClick={e => {
1068
- // e is typed as MouseEvent<HTMLButtonElement>
1069
- console.log(e.currentTarget);
1070
- }}
1071
- />;
1072
- ```
1073
-
1074
- ---
1075
-
1076
- ## Contributing
1077
-
1078
- Contributions are welcome! Please read our contributing guidelines before submitting a PR.
1079
-
1080
- ### Development Workflow
1081
-
1082
- 1. Fork the repository
1083
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
1084
- 3. Make your changes
1085
- 4. Run tests (`pnpm test`)
1086
- 5. Run type check (`pnpm type-check`)
1087
- 6. Run linter (`pnpm lint`)
1088
- 7. Commit changes (`git commit -m 'Add amazing feature'`)
1089
- 8. Push to branch (`git push origin feature/amazing-feature`)
1090
- 9. Open a Pull Request
1091
-
1092
- ### Code Quality Standards
1093
-
1094
- - **Test Coverage**: ≥90% (currently 98.93%)
1095
- - **TypeScript**: Strict mode, no `any` types
1096
- - **Accessibility**: WCAG 2.1 AA compliant
1097
- - **ESLint**: Zero warnings/errors
1098
- - **Documentation**: All public APIs documented
1099
-
1100
- ---
58
+ - [Component Reference](https://framingui.com/docs/components)
59
+ - [Theming Guide](https://framingui.com/docs/guides/theming)
60
+ - [CSS Variables Reference](https://framingui.com/docs/guides/css-variables)
1101
61
 
1102
62
  ## License
1103
63
 
1104
- MIT License - see [LICENSE](./LICENSE) for details
1105
-
1106
- ---
1107
-
1108
- ## Links
1109
-
1110
- - **Documentation**: [FramingUI Guide](https://github.com/tektoncd/tekton)
1111
- - **Radix UI**: [https://www.radix-ui.com/](https://www.radix-ui.com/)
1112
- - **WCAG 2.1**: [https://www.w3.org/WAI/WCAG21/quickref/](https://www.w3.org/WAI/WCAG21/quickref/)
1113
- - **React 19**: [https://react.dev/](https://react.dev/)
1114
- - **TypeScript**: [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
1115
-
1116
- ---
1117
-
1118
- ## Acknowledgments
1119
-
1120
- Built with:
1121
-
1122
- - [React 19](https://react.dev/) - UI library
1123
- - [Radix UI](https://www.radix-ui.com/) - Accessible primitives
1124
- - [class-variance-authority](https://cva.style/docs) - Variant management
1125
- - [Vitest](https://vitest.dev/) - Testing framework
1126
- - [axe-core](https://github.com/dequelabs/axe-core) - Accessibility testing
1127
-
1128
- ---
1129
-
1130
- **Version**: 1.0.0
1131
- **Last Updated**: 2026-01-26
1132
- **Maintained by**: Tekton Team
64
+ MIT