@7onic-ui/tokens 0.2.3 → 0.2.5

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 (2) hide show
  1. package/llms.txt +248 -1989
  2. package/package.json +1 -1
package/llms.txt CHANGED
@@ -1,17 +1,17 @@
1
- # 7onic Design System — AI Guide (Full)
1
+ # 7onic Design System — AI Guide (Tokens)
2
2
 
3
3
  ## What is 7onic?
4
4
 
5
- Token-driven React design system with 42 components on Radix UI.
6
- Single source of truth design tokens to code. Use this to build any React service.
5
+ Token-driven design system. Single source of truth design tokens to code.
6
+ Use the token system to style any project with consistent colors, spacing, typography, and more.
7
7
 
8
8
  - Documentation: https://7onic.design
9
- - npm: `@7onic-ui/react` (components) + `@7onic-ui/tokens` (design tokens)
10
- - For tokens-only guide, see: https://7onic.design/llms.txt
9
+ - npm: `@7onic-ui/tokens` (design tokens)
10
+ - For components + tokens guide, see: https://7onic.design/llms-full.txt
11
11
 
12
12
  ---
13
13
 
14
- # ═══ SECTION 1: PROJECT SETUP & AI RULES ═══
14
+ # ═══ SECTION 1: PROJECT SETUP ═══
15
15
 
16
16
  ## How to Start
17
17
 
@@ -23,19 +23,18 @@ Before writing any code, present this checklist and wait for answers:
23
23
  2. **Dark mode** — Yes or no?
24
24
  3. **Font** — Use default, or custom font? If custom, which font?
25
25
  4. **Locale** — Which language(s)? (for CJK font loading)
26
- 5. **What are you building?** — Describe the project
27
26
 
28
- **If the user answers in natural language** (e.g., "Make me a dashboard with dark mode, English only"), extract the answers from their message. **If any item is missing, ask a follow-up question for the missing items only.** Do not proceed until all 5 items are answered.
27
+ **If the user answers in natural language**, extract the answers. **If any item is missing, ask a follow-up question for the missing items only.** Do not proceed until all 4 items are answered.
29
28
 
30
29
  ### Step 2: Execute full setup (all at once, do not skip any)
31
30
 
32
31
  After receiving answers, execute ALL of the following in order. Every step is mandatory.
33
32
 
34
- **2-1. Install packages (skip if already installed):**
33
+ **2-1. Install package (skip if already installed):**
35
34
  ```bash
36
- npm install @7onic-ui/react @7onic-ui/tokens lucide-react
35
+ npm install @7onic-ui/tokens
37
36
  ```
38
- > Check package.json first. If packages are already listed in dependencies, skip this step.
37
+ > Check package.json first. If already listed in dependencies, skip this step.
39
38
 
40
39
  **2-2. Create or update globals.css with token imports:**
41
40
 
@@ -45,7 +44,7 @@ npm install @7onic-ui/react @7onic-ui/tokens lucide-react
45
44
 
46
45
  **New project (Tailwind v4):**
47
46
  ```css
48
- /* globals.css — ALL imports are required, do not skip any */
47
+ /* globals.css (Next.js) or src/index.css (Vite) — ALL imports are required, do not skip any */
49
48
  @import "tailwindcss";
50
49
  @import "@7onic-ui/tokens/css/variables.css";
51
50
  @import "@7onic-ui/tokens/css/themes/light.css";
@@ -53,9 +52,11 @@ npm install @7onic-ui/react @7onic-ui/tokens lucide-react
53
52
  @import "@7onic-ui/tokens/tailwind/v4-theme.css";
54
53
  ```
55
54
 
55
+ > **Vite + Tailwind v4**: `npx 7onic init` auto-injects `@import "tailwindcss"` if not present, and automatically configures the `@/` path alias (`tsconfig.app.json` + `vite.config.ts`). No manual CSS or alias setup needed.
56
+
56
57
  **Existing project with Tailwind v3** (detect from tailwind.config.js):
57
58
  ```css
58
- /* globals.css */
59
+ /* globals.css — @import must come BEFORE @tailwind directives */
59
60
  @import '@7onic-ui/tokens/css/variables.css';
60
61
  @import '@7onic-ui/tokens/css/themes/light.css';
61
62
  @import '@7onic-ui/tokens/css/themes/dark.css'; /* omit ONLY if dark mode = no */
@@ -68,10 +69,7 @@ npm install @7onic-ui/react @7onic-ui/tokens lucide-react
68
69
  const preset = require('@7onic-ui/tokens/tailwind/v3-preset')
69
70
  module.exports = {
70
71
  presets: [preset],
71
- content: [
72
- './src/**/*.{js,ts,jsx,tsx}',
73
- './node_modules/@7onic-ui/react/dist/**/*.{js,mjs}',
74
- ],
72
+ content: ['./src/**/*.{js,ts,jsx,tsx}'],
75
73
  }
76
74
  ```
77
75
 
@@ -88,7 +86,7 @@ module.exports = {
88
86
  - Locale includes Korean → load Noto Sans KR font
89
87
 
90
88
  **2-5. Verify setup is complete before writing any UI code:**
91
- - [ ] Packages installed (@7onic-ui/react, @7onic-ui/tokens, lucide-react)
89
+ - [ ] Package installed (@7onic-ui/tokens)
92
90
  - [ ] globals.css has ALL required imports in correct order
93
91
  - [ ] Body has `bg-background text-foreground`
94
92
  - [ ] Dark mode toggle (if selected)
@@ -106,48 +104,28 @@ import { Search, Settings, ChevronDown, X } from 'lucide-react'
106
104
  // ❌ Legacy alias — avoid
107
105
  import { SearchIcon, SettingsIcon } from 'lucide-react'
108
106
 
109
- // ⚠️ Name collision with 7onic component — use alias
110
- import { Badge } from '@7onic-ui/react'
107
+ // ⚠️ Name collision with your own component — use alias
111
108
  import { Badge as BadgeIcon } from 'lucide-react'
112
109
  ```
113
110
 
114
- ### Step 3: Add Toaster to root layout (if using Toast)
115
-
116
- Place `<Toaster />` once in your root layout file. Without this, `toast()` calls will not render.
117
-
118
- ```tsx
119
- import { Toaster } from '@7onic-ui/react'
120
-
121
- // In your root layout (e.g., app/layout.tsx)
122
- <body className="bg-background text-foreground">
123
- {children}
124
- <Toaster position="bottom-right" />
125
- </body>
126
- ```
127
-
128
- ### Step 4: Start building
129
-
130
- Design freely based on user's project description. Always use 7onic components + tokens.
111
+ ### Step 3: Start building
131
112
 
132
- ### Component Dependencies (auto-install during development)
133
-
134
- | Component | Additional Package | When to install |
135
- |---|---|---|
136
- | Chart (Bar, Line, Area, Pie) | `recharts` | `npm install recharts` — import from `@7onic-ui/react/chart` (separate entry point) |
113
+ Use token classes for all styling. See Token Reference below.
137
114
 
138
115
  ---
139
116
 
140
- ## AI Rules Whitelist System
117
+ # ═══ SECTION 2: AI RULES ═══
141
118
 
142
- ### Core Principle
119
+ ## Core Principle
143
120
 
144
- **Token values are user-defined.** Every project has different brand colors and design decisions. The token NAMES are the API — never assume or hardcode specific values.
121
+ **Token values are user-defined.** Every project has different brand colors, spacing, and design decisions. The token NAMES are the API — never assume or hardcode specific values.
145
122
 
146
- ### Whitelist — ONLY These Are Allowed
123
+ ## Whitelist — ONLY These Are Allowed
147
124
 
148
- 1. **7onic components + Props** always prefer components over raw HTML
149
- 2. **Token classes** — colors, spacing, typography, radius, shadows, z-index, icon sizes, duration, easing, opacity, scale
150
- 3. **Tailwind structural utilities** — layout, positioning, display, overflow, sizing, and more:
125
+ When writing any code, you may ONLY use:
126
+
127
+ 1. **Token classes** — colors, spacing, typography, radius, shadows, z-index, icon sizes, duration, easing, opacity, scale (listed in Token Reference below)
128
+ 2. **Tailwind structural utilities** — layout, positioning, display, overflow, sizing, and more:
151
129
  - Layout: flex, grid, block, inline, hidden, container
152
130
  - Position: relative, absolute, fixed, sticky, top-0, inset-0
153
131
  - Flex/Grid: items-center, justify-between, gap-4, col-span-2
@@ -164,84 +142,38 @@ Design freely based on user's project description. Always use 7onic components +
164
142
  - ⚠️ Utilities that implicitly use color (divide, border) must be paired with a token color:
165
143
  `divide-y divide-border` ✅ / `divide-y` alone ❌ (may not adapt to dark mode)
166
144
  `border border-border` ✅ / `border` alone ❌
167
- 4. **Tailwind visual utilities using token values** — gradients, transforms, transitions:
145
+ 3. **Tailwind visual utilities using token values** — gradients, transforms, transitions:
168
146
  - Gradient: bg-gradient-to-r, from-primary, to-secondary (token colors only)
169
147
  - Transform: rotate-45, translate-x-1
170
148
  - Transition: transition-all, transition-colors (with token durations)
171
149
  - Backdrop: backdrop-blur, backdrop-blur-sm
172
- 5. **Responsive prefixes** — sm:, md:, lg:, xl:, 2xl: (on allowed classes only)
173
- 6. **State prefixes** — hover:, focus:, active:, disabled: (on allowed classes only, token values only)
174
- 7. **Layout dimension arbitrary values** — height and width ONLY: h-[300px], max-w-[1200px] (when no token fits)
175
- 8. **Opacity modifier** — append `/0-100` to any token color for transparency:
150
+ 4. **Responsive prefixes** — sm:, md:, lg:, xl:, 2xl: (on allowed classes only)
151
+ 5. **State prefixes** — hover:, focus:, active:, disabled: (on allowed classes only, token values only)
152
+ 6. **Layout dimension arbitrary values** — height and width ONLY: h-[300px], max-w-[1200px], min-h-screen (when no token fits)
153
+ 7. **Opacity modifier** — append `/0-100` to any token color for transparency:
176
154
  - `bg-primary/50`, `text-foreground/70`, `border-border/30`
177
155
  - Do NOT use `opacity-*` utility as a workaround — it affects the entire element including children
178
156
  - `bg-primary/10` ✅ (only background is transparent) / `bg-primary opacity-10` ❌ (children also become transparent)
179
157
 
180
- 9. **Token-first rule** — Before adding any Tailwind utility, check if the property is already included in a design token. Typography tokens (`text-sm`, `text-md`, etc.) include both font-size AND line-height as a pair. Do NOT override with Tailwind line-height utilities:
181
- - `text-sm` ✅ (token provides font-size + line-height)
182
- - `text-sm leading-relaxed` ❌ (overrides token line-height)
183
- - `text-sm leading-none` ❌ (overrides token line-height)
184
- - `text-sm leading-[18px]` ❌ (hardcodes line-height)
185
-
186
158
  **Everything not in this list is FORBIDDEN.**
187
159
 
188
160
  ⚠️ **Gradient/visual utilities must use token colors only:** `from-primary to-secondary` ✅ / `from-blue-500 to-purple-600` ❌
189
161
 
190
- ### Decision TreeFor Every UI Element
191
-
192
- ```
193
- Step 1: Does a 7onic component exist for this?
194
- → YES: Use the component. Style via Props (variant/size/color).
195
- className ONLY for layout (margin, width, flex positioning).
196
- → NO: Step 2
197
-
198
- Step 2: Is this a layout/structural element? (flex container, grid, section wrapper)
199
- → YES: Use div/section + token classes only.
200
- → NO: Step 3
201
-
202
- Step 3: Re-check the 42 components. Most UI can be built with component combinations.
203
- → Still no match: Use div + token classes only.
204
- ```
205
-
206
- ### ❌ Forbidden Patterns
207
-
208
- ```tsx
209
- // ❌ HTML instead of components
210
- <button className="bg-primary rounded-lg px-4 py-2"> → <Button>
211
- <input className="border rounded-lg px-3 h-10"> → <Input>
212
- <div className="border rounded-xl p-6 shadow-sm"> → <Card>
213
- <table className="w-full"> → <Table>
214
-
215
- // ❌ className overriding component styles
216
- <Button className="bg-blue-500 text-white"> → <Button color="primary">
217
- <Badge className="bg-red-100 text-red-700"> → <Badge color="error">
218
-
219
- // ❌ Raw Tailwind colors
220
- bg-blue-500, text-gray-700, bg-white, border-gray-200
221
-
222
- // ❌ Dark mode prefix
223
- dark:bg-gray-900, dark:text-white
224
-
225
- // ❌ Arbitrary values (except layout dimensions)
226
- p-[17px], text-[13px], rounded-[7px], z-[999]
162
+ ## ForbiddenNever Use These
227
163
 
228
- // Inline styles
229
- style={{ color: '#333', padding: '20px' }}
230
-
231
- // @apply with raw values
232
- @apply bg-blue-500
233
-
234
- // Icon sizing with w/h
235
- w-4 h-4, w-5 h-5 → icon-sm, icon-md
236
-
237
- // Radix direct import
238
- import * as Dialog from '@radix-ui/react-dialog' → import { Modal } from '@7onic-ui/react'
239
-
240
- // Unnecessary component wrappers
241
- function MyButton(props) { return <Button {...props} /> } → Use Button directly
242
- ```
243
-
244
- ### When User Requests Custom Values
164
+ | Category | Forbidden | Use Instead |
165
+ |---|---|---|
166
+ | Raw colors | `bg-blue-500`, `text-gray-700`, `bg-white` | `bg-primary`, `text-foreground`, `bg-background` |
167
+ | Dark prefix | `dark:bg-gray-900`, `dark:text-white` | Semantic tokens auto-adapt |
168
+ | Arbitrary values | `p-[17px]`, `text-[13px]`, `rounded-[7px]`, `z-[999]` | `p-4`, `text-sm`, `rounded-md`, `z-modal` |
169
+ | Icon sizing | `w-4 h-4`, `w-5 h-5` | `icon-sm`, `icon-md` |
170
+ | Raw durations | `duration-150`, `duration-200` | `duration-micro`, `duration-normal` |
171
+ | Raw shadows | `shadow-[0_2px_4px...]` | `shadow-sm` |
172
+ | Inline styles | `style={{ color: '#333' }}` | `className="text-foreground"` |
173
+ | @apply raw | `@apply bg-blue-500` | `@apply bg-primary` |
174
+ | Hardcoded hex | `#FF5733`, `rgb(51,51,51)` | Token classes |
175
+
176
+ ## When User Requests Custom Values
245
177
 
246
178
  If the user explicitly asks for a value outside the token system:
247
179
 
@@ -256,64 +188,22 @@ User: "Apply it"
256
188
  AI: → Apply the custom value
257
189
  ```
258
190
 
259
- | Situation | AI Behavior |
260
- |---|---|
261
- | User request within token range | Execute immediately |
262
- | User request outside token range | Ask "bypass tokens?" execute after confirmation |
263
- | AI writing code on its own | Token system ONLY — never bypass |
264
-
265
- ### Third-Party Libraries
266
-
267
- When a feature is needed that no 7onic component covers (map, video player, rich text editor, etc.):
268
-
269
- - **Do NOT install any library without asking the user first**
270
- - Ask: "Which library would you like to use for [feature]?"
271
- - Install and use only after user's choice
272
-
273
- ### Token Customization Is the User's Responsibility
274
-
275
- The token system covers all UI needs out of the box. As AI, use existing tokens only.
276
-
277
- If the user needs custom values beyond existing tokens, they will handle it separately.
278
- Customization guide: https://7onic.design/components/theming
279
-
280
- **Never modify generated token files** — these are auto-generated from figma-tokens.json via sync-tokens. AI must never edit, add to, or delete from: `variables.css`, `light.css`, `dark.css`, `v3-preset.js`, `v4-theme.css`, `index.js`, `index.mjs`, `index.d.ts`, `tokens.json`
281
-
282
- ### Self-Check (after writing ANY code)
283
-
284
- Before presenting code to the user, scan your own output for violations:
285
-
286
- - [ ] Any raw color class? (`bg-blue-*`, `text-gray-*`, `bg-white`, `border-gray-*`)
287
- - [ ] Any arbitrary value? (`p-[*]`, `text-[*]`, `rounded-[*]`, `z-[*]`)
288
- - [ ] Any inline style? (`style={{ }}`)
289
- - [ ] Any `dark:` prefix?
290
- - [ ] Any `w-N h-N` for icons instead of `icon-*`?
291
- - [ ] Any `<button>`, `<input>`, `<table>` instead of 7onic components?
292
- - [ ] Any Radix direct import?
293
- - [ ] Any className overriding component visual styles?
294
- - [ ] Any `divide-*` or `border` without a token color? (`divide-y` alone → `divide-y divide-border`)
295
- - [ ] Any `opacity-*` on element instead of color modifier? (`bg-primary opacity-10` → `bg-primary/10`)
296
-
297
- **If ANY violation is found → fix it before showing code to the user.**
298
- **Do NOT present code with violations. Fix first, then present.**
299
-
300
- ---
301
-
302
- **When in doubt, check the documentation** — if component Props, token usage, or patterns are unclear, refer to the official docs before guessing:
303
- - Component pages: `https://7onic.design/components/{name}` (e.g., `/components/button`, `/components/navigation-menu`)
304
- - Token pages: `https://7onic.design/design-tokens/{name}` (e.g., `/design-tokens/colors`, `/design-tokens/spacing`)
305
- - Do not guess — verify from documentation first
191
+ **Rule:**
192
+ - User request within token range → execute immediately
193
+ - User request outside token range ask "custom value, bypass tokens?" → execute only after confirmation
194
+ - AI writing code on its own token system ONLY, never bypass
306
195
 
307
196
  ---
308
197
 
309
- ## Dark Mode — Automatic
198
+ ## Dark Mode
310
199
 
311
- Dark mode works automatically when using semantic tokens. No `dark:` prefix needed.
200
+ Dark mode is **automatic** when using semantic tokens. No `dark:` prefix needed.
312
201
 
313
202
  | ❌ NEVER | ✅ CORRECT |
314
203
  |---|---|
315
204
  | `bg-white dark:bg-gray-900` | `bg-background` |
316
205
  | `text-gray-900 dark:text-gray-100` | `text-foreground` |
206
+ | `text-gray-500 dark:text-gray-400` | `text-muted` |
317
207
  | `border-gray-200 dark:border-gray-700` | `border-border` |
318
208
 
319
209
  ### Dark Mode Toggle Implementation
@@ -337,1875 +227,244 @@ Strategy: `dark` class on `<html>` element.
337
227
 
338
228
  ---
339
229
 
340
- ## Token Reference (Quick)
341
-
342
- > Token values depend on the user's project configuration. Never assume specific hex values.
343
-
344
- **Semantic Colors (theme-aware):**
345
- - Background: `background`, `background-paper`, `background-elevated`, `background-muted`
346
- - Text: `foreground`, `text-muted`, `text-subtle`, `text-link`, `text-primary`
347
- - Status text: `text-info`, `text-success`, `text-error`, `text-warning`
348
- - Intent (×6): `{intent}`, `{intent}-hover`, `{intent}-active`, `{intent}-tint`, `{intent}-foreground` — where intent = primary, secondary, success, warning, error, info
349
- - Border: `border`, `border-subtle`, `border-strong`
350
- - State: `disabled`, `disabled-text`, `focus-ring`, `focus-ring-error`
351
-
352
- **Spacing:** 0, 0.5(2px), 1(4px), 1.5(6px), 2(8px), 2.5(10px), 3(12px), 3.5(14px), 4(16px), 5(20px), 6(24px), 7(28px), 8(32px), 10(40px), 12(48px), 14(56px), 16(64px), 20(80px), 24(96px)
353
-
354
- **Font:** `font-sans` (user-defined), `font-mono` (user-defined)
355
- **Font Sizes:** text-2xs(11px), text-xs(12px), text-sm(13px), text-md(14px), text-base(16px), text-lg(18px), text-xl(20px), text-2xl(24px), text-3xl(30px), text-4xl(36px), text-5xl(48px)
356
- **Font Weights:** font-normal(400), font-semibold(600), font-bold(700)
357
-
358
- **Radius:** rounded-none(0), rounded-sm(2), rounded-base(4), rounded-md(6), rounded-lg(8), rounded-xl(12), rounded-2xl(16), rounded-3xl(24), rounded-full(9999)
359
-
360
- **Shadows:** shadow-xs, shadow-sm, shadow-md, shadow-lg, shadow-xl
361
-
362
- **Z-Index:** z-sticky(100), z-dropdown(1000), z-overlay(1100), z-modal(2000), z-popover(2100), z-tooltip(2200), z-toast(3000)
363
-
364
- **Icon Sizes:** icon-2xs(12px), icon-xs(14px), icon-sm(16px), icon-md(20px), icon-lg(24px), icon-xl(32px)
365
-
366
- **Duration:** duration-instant(0), duration-fast(100), duration-micro(150), duration-normal(200), duration-slow(300), duration-slower(400), duration-slowest(500), duration-spin(1000)
367
-
368
- **Easing:** ease-linear, ease-ease, ease-ease-in, ease-ease-out, ease-ease-in-out
369
-
370
- **Opacity:** opacity-0 to opacity-100 (5% increments)
371
-
372
- **Scale:** scale-50, scale-75, scale-95, scale-pressed(0.98)
373
-
374
- **Breakpoints:** sm(640), md(768), lg(1024), xl(1280), 2xl(1536)
375
-
376
- For detailed token reference, see: https://7onic.design/llms.txt
377
-
378
- ---
379
-
380
- # ═══ SECTION 2: COMPONENT IMPORT PATTERNS ═══
381
-
382
- ## Import
383
-
384
- ```tsx
385
- // All components from single package
386
- import { Button, Card, Input, Toast } from '@7onic-ui/react'
387
- ```
388
-
389
- ## Namespace Pattern (Compound Components)
390
-
391
- 21 compound components use namespace imports. Access sub-components via dot notation:
392
-
393
- ```tsx
394
- import { Card } from '@7onic-ui/react'
395
-
396
- // ✅ Namespace usage (preferred)
397
- <Card>
398
- <Card.Header>
399
- <Card.Title>Title</Card.Title>
400
- <Card.Description>Description</Card.Description>
401
- </Card.Header>
402
- <Card.Content>Content</Card.Content>
403
- <Card.Footer>Footer</Card.Footer>
404
- </Card>
405
-
406
- // ✅ Named exports also work (backwards compatible)
407
- import { Card, CardHeader, CardTitle, CardContent } from '@7onic-ui/react'
408
- ```
409
-
410
- ### Compound Components List (24)
411
-
412
- Accordion, Alert, Avatar, Breadcrumb, Card, ChatInput, ChatMessage, Chart, Drawer, DropdownMenu, Field, MetricCard, Modal, NavigationMenu, Pagination, Popover, QuickReply, RadioGroup, Segmented, Select, Table, Tabs, ToggleGroup, Tooltip
413
-
414
- ### Standalone Components (16)
415
-
416
- Badge, Button, ButtonGroup, Checkbox, Divider, IconButton, Input, Progress, Skeleton, Slider, Spinner, Switch, Textarea, Toast, Toggle, TypingIndicator
417
-
418
- ---
419
-
420
- # ═══ SECTION 3: ALL COMPONENTS (42) ═══
421
-
422
- ---
423
-
424
- ## Forms
425
-
426
- ### Button
427
-
428
- ```tsx
429
- import { Button } from '@7onic-ui/react'
430
-
431
- <Button variant="solid" color="primary" size="default">Submit</Button>
432
- <Button variant="outline" color="default" leftIcon={<Icon />}>Cancel</Button>
433
- <Button loading>Processing...</Button>
434
- <Button variant="link" color="primary">Learn more</Button>
435
- ```
436
-
437
- | Prop | Type | Default | Description |
438
- |---|---|---|---|
439
- | variant | `'solid' \| 'outline' \| 'ghost' \| 'link'` | `'solid'` | Visual style |
440
- | color | `'default' \| 'primary' \| 'secondary' \| 'destructive'` | `'default'` | Color scheme |
441
- | size | `'xs' \| 'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | Height: 28/32/36/40/48px |
442
- | radius | `'none' \| 'sm' \| 'base' \| 'default' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| 'full'` | `'default'` | Border radius |
443
- | loading | `boolean` | `false` | Shows spinner, disables button |
444
- | leftIcon | `ReactNode` | — | Icon before label |
445
- | rightIcon | `ReactNode` | — | Icon after label |
446
- | fullWidth | `boolean` | `false` | `w-full` |
447
- | selected | `boolean` | — | Selected state (outline/ghost) |
448
- | fontWeight | `'normal' \| 'semibold'` | per variant | Override font weight |
449
- | pressEffect | `boolean` | `true` | Scale-down on press |
450
- | asChild | `boolean` | `false` | Render as child element (Slot) |
451
- | disabled | `boolean` | `false` | Disabled state |
452
-
453
- **Icon sizing by button size:** xs/sm → icon-xs(14px), md/default/lg → icon-sm(16px)
454
-
455
- ---
456
-
457
- ### IconButton
458
-
459
- ```tsx
460
- import { IconButton } from '@7onic-ui/react'
461
-
462
- <IconButton variant="ghost" size="default" aria-label="Settings">
463
- <SettingsIcon />
464
- </IconButton>
465
- ```
466
-
467
- | Prop | Type | Default | Description |
468
- |---|---|---|---|
469
- | variant | `'solid' \| 'outline' \| 'ghost' \| 'subtle'` | `'solid'` | Visual style |
470
- | color | `'default' \| 'primary' \| 'secondary' \| 'destructive'` | `'default'` | Color scheme |
471
- | size | `'xs' \| 'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | 28/32/36/40/48px (square) |
472
- | radius | Same as Button | `'default'` | Border radius |
473
- | loading | `boolean` | `false` | Shows spinner |
474
- | pressEffect | `boolean` | `true` | Scale-down on press |
475
- | asChild | `boolean` | `false` | Slot pattern |
476
-
477
- **Icon sizing:** xs → icon-xs(14px), sm/md → icon-sm(16px), default → icon-md(20px), lg → icon-lg(24px)
478
- **Always provide `aria-label`** — no visible text.
479
-
480
- ---
481
-
482
- ### ButtonGroup
483
-
484
- ```tsx
485
- import { Button, ButtonGroup } from '@7onic-ui/react'
486
-
487
- <ButtonGroup variant="outline" size="default" attached>
488
- <Button>Left</Button>
489
- <Button>Center</Button>
490
- <Button>Right</Button>
491
- </ButtonGroup>
492
- ```
493
-
494
- | Prop | Type | Default | Description |
495
- |---|---|---|---|
496
- | variant | `'outline' \| 'ghost'` | — | Applied to all children |
497
- | size | Button sizes | — | Applied to all children |
498
- | radius | Button radius values | — | Applied to all children |
499
- | fontWeight | `'normal' \| 'semibold'` | — | Applied to all children |
500
- | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
501
- | attached | `boolean` | `false` | Overlapping borders |
502
- | disabled | `boolean` | `false` | Disable all children |
503
-
504
- Provides context — child Buttons inherit variant/size/radius automatically.
505
-
506
- ---
507
-
508
- ### Input
509
-
510
- ```tsx
511
- import { Input } from '@7onic-ui/react'
512
-
513
- <Input placeholder="Email" size="default" />
514
- <Input variant="filled" leftIcon={<SearchIcon />} />
515
- <Input error rightIcon={<AlertIcon />} />
516
- ```
517
-
518
- | Prop | Type | Default | Description |
519
- |---|---|---|---|
520
- | variant | `'default' \| 'filled'` | `'default'` | Border or filled background |
521
- | size | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'xl'` | `'default'` | Height: 36/40/44/48/56px |
522
- | radius | `'none' \| 'sm' \| 'base' \| 'default' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| 'full'` | `'default'` | Border radius |
523
- | error | `boolean` | `false` | Error border state |
524
- | focusRing | `boolean` | `false` | Explicit focus ring (vs keyboard-only) |
525
- | leftIcon | `ReactNode` | — | Left icon |
526
- | rightIcon | `ReactNode` | — | Right icon |
527
-
528
- **Works with Field wrapper** for label, error, char count. See Field section.
529
-
530
- ---
531
-
532
- ### Textarea
533
-
534
- ```tsx
535
- import { Textarea } from '@7onic-ui/react'
536
-
537
- <Textarea placeholder="Message" rows={4} resize="vertical" />
538
- ```
539
-
540
- | Prop | Type | Default | Description |
541
- |---|---|---|---|
542
- | variant | `'default' \| 'filled'` | `'default'` | Border or filled |
543
- | size | `'compact' \| 'default'` | `'default'` | Padding density |
544
- | radius | Same as Input | `'default'` | Border radius |
545
- | resize | `'none' \| 'vertical' \| 'horizontal' \| 'both'` | `'vertical'` | Resize handle |
546
- | error | `boolean` | `false` | Error state |
547
- | focusRing | `boolean` | `false` | Explicit focus ring |
548
-
549
- ---
550
-
551
- ### Select
552
-
553
- ```tsx
554
- import { Select } from '@7onic-ui/react'
555
-
556
- <Select>
557
- <Select.Trigger>
558
- <Select.Value placeholder="Choose option" />
559
- </Select.Trigger>
560
- <Select.Content>
561
- <Select.Item value="a">Option A</Select.Item>
562
- <Select.Item value="b">Option B</Select.Item>
563
- <Select.Group>
564
- <Select.Label>Group</Select.Label>
565
- <Select.Item value="c">Option C</Select.Item>
566
- </Select.Group>
567
- </Select.Content>
568
- </Select>
569
- ```
570
-
571
- | Prop (Root) | Type | Default | Description |
572
- |---|---|---|---|
573
- | size | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'xl'` | `'default'` | Trigger height |
574
- | radius | Same as Input | `'default'` | Border radius |
575
- | value | `string` | — | Controlled value |
576
- | defaultValue | `string` | — | Uncontrolled default |
577
- | onValueChange | `(value: string) => void` | — | Change handler |
578
-
579
- **Sub-components:** Select.Trigger, Select.Value, Select.Content, Select.Item, Select.Group, Select.Label, Select.Separator
580
-
581
- ---
582
-
583
- ### DropdownMenu
584
-
585
- ```tsx
586
- import { DropdownMenu } from '@7onic-ui/react'
587
-
588
- <DropdownMenu>
589
- <DropdownMenu.Trigger asChild>
590
- <Button variant="outline">Options</Button>
591
- </DropdownMenu.Trigger>
592
- <DropdownMenu.Content>
593
- <DropdownMenu.Item>Edit</DropdownMenu.Item>
594
- <DropdownMenu.Item>Duplicate</DropdownMenu.Item>
595
- <DropdownMenu.Separator />
596
- <DropdownMenu.Item className="text-error">Delete</DropdownMenu.Item>
597
- </DropdownMenu.Content>
598
- </DropdownMenu>
599
- ```
600
-
601
- | Prop (Content) | Type | Default | Description |
602
- |---|---|---|---|
603
- | radius | `'md' \| 'lg' \| 'xl'` | `'lg'` | Border radius |
604
- | size | `'sm' \| 'md' \| 'lg'` | `'md'` | Item density |
605
- | flush | `boolean` | `false` | Full-width items (no padding) |
606
- | sideOffset | `number` | `4` | Gap from trigger |
607
-
608
- **Sub-components:** DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Item, DropdownMenu.CheckboxItem, DropdownMenu.RadioItem, DropdownMenu.Label, DropdownMenu.Separator, DropdownMenu.Group, DropdownMenu.Sub, DropdownMenu.SubTrigger, DropdownMenu.SubContent, DropdownMenu.Shortcut
609
-
610
- ---
611
-
612
- ### Checkbox
613
-
614
- ```tsx
615
- import { Checkbox } from '@7onic-ui/react'
616
-
617
- <Checkbox label="Accept terms" />
618
- <Checkbox size="lg" color="primary" checked />
619
- <Checkbox checked="indeterminate" />
620
- ```
621
-
622
- | Prop | Type | Default | Description |
623
- |---|---|---|---|
624
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Checkbox size |
625
- | radius | `'none' \| 'sm' \| 'md'` | `'sm'` | Border radius |
626
- | weight | `'thin' \| 'bold'` | `'bold'` | Checkmark thickness |
627
- | color | `'default' \| 'primary'` | `'default'` | Checked color |
628
- | label | `string` | — | Label text |
629
- | checked | `boolean \| 'indeterminate'` | — | Controlled state |
630
- | defaultChecked | `boolean` | — | Uncontrolled default |
631
- | onCheckedChange | `(checked: boolean \| 'indeterminate') => void` | — | Change handler |
632
- | disabled | `boolean` | `false` | Disabled state |
633
-
634
- ---
635
-
636
- ### RadioGroup
637
-
638
- ```tsx
639
- import { RadioGroup } from '@7onic-ui/react'
640
-
641
- <RadioGroup defaultValue="a">
642
- <RadioGroup.Item value="a" label="Option A" />
643
- <RadioGroup.Item value="b" label="Option B" />
644
- <RadioGroup.Item value="c" label="Option C" disabled />
645
- </RadioGroup>
646
- ```
647
-
648
- | Prop (Root) | Type | Default | Description |
649
- |---|---|---|---|
650
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Radio size |
651
- | weight | `'thin' \| 'bold'` | `'bold'` | Indicator thickness |
652
- | color | `'default' \| 'primary'` | `'default'` | Selected color |
653
- | orientation | `'horizontal' \| 'vertical'` | `'vertical'` | Layout direction |
654
- | value | `string` | — | Controlled value |
655
- | defaultValue | `string` | — | Uncontrolled default |
656
- | onValueChange | `(value: string) => void` | — | Change handler |
657
-
658
- **Sub-components:** RadioGroup.Item (with `label` prop)
659
-
660
- ---
661
-
662
- ### Switch
663
-
664
- ```tsx
665
- import { Switch } from '@7onic-ui/react'
666
-
667
- <Switch label="Notifications" />
668
- <Switch size="lg" color="primary" defaultChecked />
669
- <Switch startLabel="Off" endLabel="On" />
670
- ```
671
-
672
- | Prop | Type | Default | Description |
673
- |---|---|---|---|
674
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Track size |
675
- | color | `'default' \| 'primary' \| 'success' \| 'warning' \| 'error'` | `'default'` | Active track color |
676
- | label | `string` | — | Label text |
677
- | labelPosition | `'start' \| 'end' \| 'top' \| 'bottom'` | `'end'` | Label placement |
678
- | startLabel | `string` | — | Left label (off state) |
679
- | endLabel | `string` | — | Right label (on state) |
680
- | checkedIcon | `ReactNode` | — | Icon when checked |
681
- | uncheckedIcon | `ReactNode` | — | Icon when unchecked |
682
- | checked | `boolean` | — | Controlled state |
683
- | defaultChecked | `boolean` | — | Uncontrolled default |
684
- | onCheckedChange | `(checked: boolean) => void` | — | Change handler |
685
- | disabled | `boolean` | `false` | Disabled state |
686
-
687
- ---
688
-
689
- ### Toggle
690
-
691
- ```tsx
692
- import { Toggle } from '@7onic-ui/react'
693
-
694
- <Toggle variant="default" aria-label="Bold">
695
- <BoldIcon />
696
- </Toggle>
697
- <Toggle variant="outline" pressed>Active</Toggle>
698
- ```
699
-
700
- | Prop | Type | Default | Description |
701
- |---|---|---|---|
702
- | variant | `'default' \| 'outline' \| 'ghost' \| 'outline-ghost'` | `'default'` | Visual style |
703
- | size | `'xs' \| 'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | 28/32/36/40/48px |
704
- | radius | Same as Button | `'default'` | Border radius |
705
- | fontWeight | `'normal' \| 'semibold'` | per variant | Font weight |
706
- | iconOnly | `boolean` | `false` | Square mode (no text padding) |
707
- | pressEffect | `boolean` | `true` | Scale-down on press |
708
- | pressed | `boolean` | — | Controlled state |
709
- | defaultPressed | `boolean` | — | Uncontrolled default |
710
- | onPressedChange | `(pressed: boolean) => void` | — | Change handler |
711
-
712
- ---
713
-
714
- ### ToggleGroup
715
-
716
- ```tsx
717
- import { ToggleGroup } from '@7onic-ui/react'
718
-
719
- <ToggleGroup type="single" defaultValue="center">
720
- <ToggleGroup.Item value="left"><AlignLeftIcon /></ToggleGroup.Item>
721
- <ToggleGroup.Item value="center"><AlignCenterIcon /></ToggleGroup.Item>
722
- <ToggleGroup.Item value="right"><AlignRightIcon /></ToggleGroup.Item>
723
- </ToggleGroup>
724
- ```
230
+ # ═══ SECTION 3: TOKEN REFERENCE ═══
725
231
 
726
- | Prop (Root) | Type | Default | Description |
727
- |---|---|---|---|
728
- | type | `'single' \| 'multiple'` | required | Selection mode |
729
- | variant | `'default' \| 'outline'` | `'default'` | Visual style |
730
- | size | `'xs' \| 'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | Item size |
731
- | radius | Same as Button | `'default'` | Border radius |
732
- | fontWeight | `'normal' \| 'semibold'` | per variant | Font weight |
733
- | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
734
- | value | `string \| string[]` | — | Controlled value |
735
- | defaultValue | `string \| string[]` | — | Uncontrolled default |
736
- | onValueChange | `(value) => void` | — | Change handler |
737
-
738
- **Sub-components:** ToggleGroup.Item
232
+ > Token values depend on the user's project configuration.
233
+ > The names below are the API. Never assume specific hex values.
739
234
 
740
- ---
235
+ ## Colors — Semantic (theme-aware, USE THESE)
741
236
 
742
- ### Segmented
237
+ **Background:**
238
+ - `background` — main page background
239
+ - `background-paper` — card/surface background
240
+ - `background-elevated` — elevated surface (above paper)
241
+ - `background-muted` — subtle/subdued background
743
242
 
744
- ```tsx
745
- import { Segmented } from '@7onic-ui/react'
243
+ **Text:**
244
+ - `foreground` (alias: `text`) primary text
245
+ - `text-muted` — secondary text, lower emphasis
246
+ - `text-subtle` — tertiary text, lowest emphasis
247
+ - `text-link` — link color
248
+ - `text-primary` — brand-colored text
746
249
 
747
- <Segmented defaultValue="all">
748
- <Segmented.Item value="all">All</Segmented.Item>
749
- <Segmented.Item value="active">Active</Segmented.Item>
750
- <Segmented.Item value="inactive">Inactive</Segmented.Item>
751
- </Segmented>
752
- ```
250
+ **Intent Status:**
251
+ - `text-info` / `text-success` / `text-error` / `text-warning`
753
252
 
754
- | Prop (Root) | Type | Default | Description |
755
- |---|---|---|---|
756
- | variant | `'default' \| 'outline' \| 'underline' \| 'ghost'` | `'default'` | Visual style |
757
- | size | `'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | 32/36/40/48px (no xs) |
758
- | radius | Same as Button (excl. none) | `'default'` | Border radius |
759
- | fontWeight | `'normal' \| 'semibold'` | per variant | Font weight |
760
- | value | `string` | | Controlled value |
761
- | defaultValue | `string` | — | Uncontrolled default |
762
- | onValueChange | `(value: string) => void` | — | Change handler |
253
+ **Intent Colors (each has 5 variants):**
254
+ - `primary` / `primary-hover` / `primary-active` / `primary-tint` / `primary-foreground`
255
+ - `secondary` / `secondary-hover` / `secondary-active` / `secondary-tint` / `secondary-foreground`
256
+ - `success` / `success-hover` / `success-active` / `success-tint` / `success-foreground`
257
+ - `warning` / `warning-hover` / `warning-active` / `warning-tint` / `warning-foreground`
258
+ - `error` / `error-hover` / `error-active` / `error-tint` / `error-foreground`
259
+ - `info` / `info-hover` / `info-active` / `info-tint` / `info-foreground`
763
260
 
764
- **Sub-components:** Segmented.Item
765
- **Note:** Only 4 sizes (no xs) intentional design decision.
261
+ **Border:**
262
+ - `border`default border
263
+ - `border-subtle` — lighter/softer border
264
+ - `border-strong` — stronger/darker border
766
265
 
767
- ---
266
+ **State:**
267
+ - `disabled` — disabled background
268
+ - `disabled-text` — disabled text
269
+ - `focus-ring` — focus indicator
270
+ - `focus-ring-error` — error focus indicator
768
271
 
769
- ### Slider
272
+ ## Colors — Primitive (raw palette, use sparingly)
770
273
 
771
- ```tsx
772
- import { Slider } from '@7onic-ui/react'
274
+ 7 color families, each with 50–900 shades (10 steps):
275
+ `gray`, `primary`, `secondary`, `blue`, `green`, `red`, `yellow`
773
276
 
774
- <Slider defaultValue={[50]} showTooltip="auto" />
775
- <Slider defaultValue={[20, 80]} color="primary" />
776
- ```
277
+ Usage: `bg-primary-100`, `text-gray-600`, `border-blue-300`
278
+ **Prefer semantic tokens over primitives** — primitives don't auto-adapt to dark mode.
279
+ **Note:** The actual colors of each palette depend on the user's token configuration.
777
280
 
778
- | Prop | Type | Default | Description |
779
- |---|---|---|---|
780
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Track/thumb size |
781
- | color | `'default' \| 'primary'` | `'default'` | Active track color |
782
- | showTooltip | `'auto' \| 'always' \| 'never'` | `'auto'` | Tooltip display |
783
- | formatLabel | `(value: number) => string` | — | Tooltip value formatter |
784
- | startContent | `ReactNode` | — | Left content (label/icon) |
785
- | endContent | `ReactNode` | — | Right content (label/icon) |
786
- | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Direction |
787
- | value | `number[]` | — | Controlled value(s) |
788
- | defaultValue | `number[]` | — | Uncontrolled default |
789
- | onValueChange | `(value: number[]) => void` | — | Change handler |
790
- | min | `number` | `0` | Minimum value |
791
- | max | `number` | `100` | Maximum value |
792
- | step | `number` | `1` | Step increment |
281
+ ## Spacing
793
282
 
794
- ---
283
+ | Token | Value | Common Use |
284
+ |---|---|---|
285
+ | `0` | 0 | Reset |
286
+ | `0.5` | 2px | Micro gap |
287
+ | `1` | 4px | Tight gap |
288
+ | `1.5` | 6px | Small gap |
289
+ | `2` | 8px | Default gap |
290
+ | `2.5` | 10px | — |
291
+ | `3` | 12px | Section gap |
292
+ | `3.5` | 14px | — |
293
+ | `4` | 16px | Card padding |
294
+ | `5` | 20px | — |
295
+ | `6` | 24px | Section padding |
296
+ | `7` | 28px | — |
297
+ | `8` | 32px | Large padding |
298
+ | `10` | 40px | — |
299
+ | `12` | 48px | — |
300
+ | `14` | 56px | — |
301
+ | `16` | 64px | Page margin |
302
+ | `20` | 80px | — |
303
+ | `24` | 96px | Hero spacing |
304
+
305
+ ## Typography
306
+
307
+ **Font Families:**
308
+ - `font-sans` — sans-serif body font (user-defined)
309
+ - `font-mono` — monospace code font (user-defined)
310
+
311
+ **Font Sizes:**
312
+
313
+ | Class | Size | Line Height | Use Case |
314
+ |---|---|---|---|
315
+ | `text-2xs` | 11px | 16px | Fine print |
316
+ | `text-xs` | 12px | 18px | Caption, badge |
317
+ | `text-sm` | 13px | 20px | Body small, table |
318
+ | `text-md` | 14px | 22px | Body default |
319
+ | `text-base` | 16px | 26px | Body large |
320
+ | `text-lg` | 18px | 28px | Subtitle |
321
+ | `text-xl` | 20px | 30px | Title |
322
+ | `text-2xl` | 24px | 34px | Heading |
323
+ | `text-3xl` | 30px | 40px | Hero subtitle |
324
+ | `text-4xl` | 36px | 46px | Hero title |
325
+ | `text-5xl` | 48px | 58px | Display |
326
+
327
+ **Font Weights:**
328
+ - `font-normal` (400) — body text
329
+ - `font-semibold` (600) — labels, emphasis
330
+ - `font-bold` (700) — headings
331
+
332
+ ## Border Radius
333
+
334
+ | Class | Value | Use Case |
335
+ |---|---|---|
336
+ | `rounded-none` | 0px | Square |
337
+ | `rounded-sm` | 2px | Subtle |
338
+ | `rounded-base` | 4px | Default (checkbox) |
339
+ | `rounded-md` | 6px | Default (button) |
340
+ | `rounded-lg` | 8px | Card, input |
341
+ | `rounded-xl` | 12px | Large card |
342
+ | `rounded-2xl` | 16px | Modal |
343
+ | `rounded-3xl` | 24px | Pill shape |
344
+ | `rounded-full` | 9999px | Circle, pill button |
345
+
346
+ ## Shadows
347
+
348
+ | Class | Description |
349
+ |---|---|
350
+ | `shadow-xs` | Barely visible — subtle elevation |
351
+ | `shadow-sm` | Default card shadow |
352
+ | `shadow-md` | Dropdown, popover |
353
+ | `shadow-lg` | Modal, drawer |
354
+ | `shadow-xl` | Floating action |
795
355
 
796
- ### Field (Form Wrapper)
356
+ Shadows automatically adapt between light and dark themes.
797
357
 
798
- ```tsx
799
- import { Field, Input, Textarea } from '@7onic-ui/react'
800
-
801
- <Field error="Invalid email">
802
- <Field.Label required>Email</Field.Label>
803
- <Input placeholder="you@example.com" />
804
- <Field.Error />
805
- </Field>
806
-
807
- <Field>
808
- <Field.Label>Bio</Field.Label>
809
- <Textarea placeholder="Tell us about yourself" maxLength={200} />
810
- <Field.CharCount />
811
- </Field>
812
- ```
358
+ ## Z-Index (named stack)
813
359
 
814
- | Prop (Root) | Type | Default | Description |
815
- |---|---|---|---|
816
- | gap | `'none' \| 'xs' \| 'sm' \| 'default' \| 'lg'` | `'default'` | Gap between elements |
817
- | error | `string \| boolean` | | Error message (passed to children via context) |
818
- | disabled | `boolean` | `false` | Disabled state (passed to children via context) |
360
+ | Class | Value | Use Case |
361
+ |---|---|---|
362
+ | `z-0` | 0 | Default |
363
+ | `z-10`–`z-50` | 10–50 | Layout layers |
364
+ | `z-sticky` | 100 | Sticky header |
365
+ | `z-dropdown` | 1000 | Dropdown menu |
366
+ | `z-overlay` | 1100 | Overlay/backdrop |
367
+ | `z-modal` | 2000 | Modal dialog |
368
+ | `z-popover` | 2100 | Popover |
369
+ | `z-tooltip` | 2200 | Tooltip |
370
+ | `z-toast` | 3000 | Toast notification |
819
371
 
820
- **Sub-components:** Field.Label (with `required` prop), Field.Error, Field.CharCount
821
- **Context:** Input, Textarea, Checkbox, RadioGroup, Select auto-detect Field context for error/disabled/id.
372
+ **Never use arbitrary z-index values.** Always use these named tokens.
822
373
 
823
- ---
374
+ ## Icon Sizes (6-step scale)
824
375
 
825
- ## Data Display
376
+ | Class | Size | Use Case |
377
+ |---|---|---|
378
+ | `icon-2xs` | 12px | Badge icon, small indicator |
379
+ | `icon-xs` | 14px | xs/sm button icon, tag |
380
+ | `icon-sm` | 16px | Default button icon, form element |
381
+ | `icon-md` | 20px | Navigation, default icon button |
382
+ | `icon-lg` | 24px | Large icon button, card |
383
+ | `icon-xl` | 32px | Hero, feature icon |
826
384
 
827
- ### Avatar
385
+ **Never use `w-4 h-4` for icons.** Always use `icon-{size}` classes.
828
386
 
829
- ```tsx
830
- import { Avatar } from '@7onic-ui/react'
831
-
832
- <Avatar size="default">
833
- <Avatar.Image src="/photo.jpg" alt="User" />
834
- <Avatar.Fallback name="John Doe" colorized />
835
- </Avatar>
836
-
837
- <Avatar.Group max={3}>
838
- <Avatar><Avatar.Image src="/a.jpg" /><Avatar.Fallback>A</Avatar.Fallback></Avatar>
839
- <Avatar><Avatar.Image src="/b.jpg" /><Avatar.Fallback>B</Avatar.Fallback></Avatar>
840
- <Avatar><Avatar.Image src="/c.jpg" /><Avatar.Fallback>C</Avatar.Fallback></Avatar>
841
- <Avatar><Avatar.Fallback>+2</Avatar.Fallback></Avatar>
842
- </Avatar.Group>
843
- ```
387
+ ## Duration
844
388
 
845
- | Prop (Root) | Type | Default | Description |
846
- |---|---|---|---|
847
- | size | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'xl' \| '2xl'` | `'default'` | Avatar size |
848
- | shape | `'circle' \| 'square'` | `'circle'` | Avatar shape |
849
- | status | `'online' \| 'offline' \| 'busy' \| 'away'` | | Status indicator dot |
389
+ | Class | Value | Use Case |
390
+ |---|---|---|
391
+ | `duration-instant` | 0ms | No animation |
392
+ | `duration-fast` | 100ms | Micro interactions |
393
+ | `duration-micro` | 150ms | Button press, toggle |
394
+ | `duration-normal` | 200ms | Default transition |
395
+ | `duration-slow` | 300ms | Panel slide |
396
+ | `duration-slower` | 400ms | Page transition |
397
+ | `duration-slowest` | 500ms | Complex animation |
398
+ | `duration-spin` | 1000ms | Spinner rotation |
850
399
 
851
- | Prop (Fallback) | Type | Default | Description |
852
- |---|---|---|---|
853
- | name | `string` | — | Auto-generates initials |
854
- | colorized | `boolean` | `false` | Deterministic color from name hash |
855
- | colorVariant | `'vivid' \| 'soft'` | `'vivid'` | Color intensity |
400
+ ## Easing
856
401
 
857
- | Prop (Group) | Type | Default | Description |
858
- |---|---|---|---|
859
- | max | `number` | | Max visible avatars |
860
- | size | Same as Root | | Override all children |
861
- | shape | Same as Root | | Override all children |
402
+ - `ease-linear` constant speed
403
+ - `ease-ease` — natural acceleration/deceleration
404
+ - `ease-ease-in` — slow start
405
+ - `ease-ease-out`slow end
406
+ - `ease-ease-in-out`slow start and end
862
407
 
863
- **Sub-components:** Avatar.Image, Avatar.Fallback, Avatar.Group
408
+ ## Opacity
864
409
 
865
- ---
410
+ 21-step scale: `opacity-0`, `opacity-5`, `opacity-10` ... `opacity-95`, `opacity-100`
411
+ Each 5% increment. Values: 0, 0.05, 0.10 ... 0.95, 1.0
866
412
 
867
- ### Badge
413
+ ## Scale (Transform)
868
414
 
869
- ```tsx
870
- import { Badge } from '@7onic-ui/react'
415
+ | Class | Value | Use Case |
416
+ |---|---|---|
417
+ | `scale-50` | 0.5 | Half size |
418
+ | `scale-75` | 0.75 | Reduced |
419
+ | `scale-95` | 0.95 | Hover shrink |
420
+ | `scale-pressed` | 0.98 | Button press effect |
871
421
 
872
- <Badge variant="solid" color="primary">New</Badge>
873
- <Badge variant="subtle" color="success" dot>Active</Badge>
874
- <Badge variant="outline" removable onRemove={() => {}}>Tag</Badge>
875
- ```
422
+ ## Breakpoints
876
423
 
877
- | Prop | Type | Default | Description |
878
- |---|---|---|---|
879
- | variant | `'solid' \| 'subtle' \| 'outline'` | `'subtle'` | Visual style |
880
- | color | `'default' \| 'primary' \| 'success' \| 'warning' \| 'error' \| 'info'` | `'default'` | Color scheme |
881
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Badge size |
882
- | radius | `'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'full'` | Border radius |
883
- | icon | `ReactNode` | | Leading icon |
884
- | dot | `boolean` | `false` | Status dot indicator |
885
- | removable | `boolean` | `false` | Shows remove button |
886
- | onRemove | `() => void` | — | Remove handler |
887
- | asChild | `boolean` | `false` | Slot pattern |
424
+ | Class | Min Width | Use Case |
425
+ |---|---|---|
426
+ | `sm:` | 640px | Mobile landscape |
427
+ | `md:` | 768px | Tablet |
428
+ | `lg:` | 1024px | Desktop |
429
+ | `xl:` | 1280px | Wide desktop |
430
+ | `2xl:` | 1536px | Ultra-wide |
888
431
 
889
432
  ---
890
433
 
891
- ### Card
434
+ # ═══ SECTION 4: TOKEN CUSTOMIZATION ═══
892
435
 
893
- ```tsx
894
- import { Card } from '@7onic-ui/react'
895
-
896
- <Card variant="default" interactive>
897
- <Card.Image src="/cover.jpg" overlay overlayOpacity={40} />
898
- <Card.Header>
899
- <Card.Title icon={<StarIcon />}>Featured</Card.Title>
900
- <Card.Description>Card description</Card.Description>
901
- <Card.Action><IconButton variant="ghost"><MoreIcon /></IconButton></Card.Action>
902
- </Card.Header>
903
- <Card.Content>Main content</Card.Content>
904
- <Card.Footer>Footer actions</Card.Footer>
905
- </Card>
906
- ```
907
-
908
- | Prop (Root) | Type | Default | Description |
909
- |---|---|---|---|
910
- | variant | `'default' \| 'outline' \| 'ghost'` | `'default'` | Visual style |
911
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Padding scale |
912
- | radius | `'sm' \| 'base' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | `'xl'` | Border radius |
913
- | direction | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
914
- | interactive | `boolean` | `false` | Hover shadow + lift |
915
- | asChild | `boolean` | `false` | Slot pattern |
916
-
917
- | Prop (Image) | Type | Default | Description |
918
- |---|---|---|---|
919
- | overlay | `boolean` | `false` | Gradient overlay |
920
- | overlayOpacity | `10-90` | `60` | Overlay darkness |
921
-
922
- **Sub-components:** Card.Image, Card.Header, Card.Title (with `icon`), Card.Description, Card.Action, Card.Content, Card.Footer
436
+ ## ⛔ Rule for AI: Use Existing Tokens Only
923
437
 
924
- ---
438
+ The token system is comprehensive — semantic colors, primitives, spacing, typography, radius, shadows, z-index, icon sizes, duration, easing, opacity, scale, and breakpoints cover all UI needs.
925
439
 
926
- ### Table
440
+ **Every visual value you need already exists as a token.** Use it.
927
441
 
928
- ```tsx
929
- import { Table } from '@7onic-ui/react'
930
-
931
- <Table variant="default" stickyHeader>
932
- <Table.Header>
933
- <Table.Row>
934
- <Table.Head sortable sortDirection="asc" onSort={() => {}}>Name</Table.Head>
935
- <Table.Head align="right">Amount</Table.Head>
936
- </Table.Row>
937
- </Table.Header>
938
- <Table.Body>
939
- <Table.Row interactive>
940
- <Table.Cell>John</Table.Cell>
941
- <Table.Cell align="right">$100</Table.Cell>
942
- </Table.Row>
943
- </Table.Body>
944
- </Table>
945
- ```
442
+ - **Always use token names** (`bg-primary`, `text-foreground`, `rounded-lg`) — never hardcode values
443
+ - **Never assume specific color values** — token values are defined by the user's project
444
+ - **Never add CSS variables, hex values, or arbitrary Tailwind values**
445
+ - **Token customization is the user's responsibility** — if the user needs custom values, they will handle it separately. See: https://7onic.design/components/theming
446
+ - **Never modify generated token files** — the following files are auto-generated from figma-tokens.json via sync-tokens. AI must never edit, add to, or delete from these files: `variables.css`, `light.css`, `dark.css`, `v3-preset.js`, `v4-theme.css`, `index.js`, `index.mjs`, `index.d.ts`, `tokens.json`
946
447
 
947
- | Prop (Root) | Type | Default | Description |
948
- |---|---|---|---|
949
- | variant | `'default' \| 'bordered' \| 'striped'` | `'default'` | Visual style |
950
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Cell padding |
951
- | stickyHeader | `boolean` | `false` | Sticky header row |
448
+ ### Self-Check (after writing ANY code)
952
449
 
953
- | Prop (Head) | Type | Default | Description |
954
- |---|---|---|---|
955
- | align | `'left' \| 'center' \| 'right'` | `'left'` | Text alignment |
956
- | sortable | `boolean` | `false` | Shows sort indicator |
957
- | sortDirection | `'asc' \| 'desc' \| null` | — | Current sort state |
958
- | onSort | `() => void` | — | Sort handler |
450
+ Before presenting code to the user, scan your own output for violations:
959
451
 
960
- | Prop (Row) | Type | Default | Description |
961
- |---|---|---|---|
962
- | interactive | `boolean` | `false` | Hover highlight |
963
- | selected | `boolean` | `false` | Selected state |
452
+ - [ ] Any raw color class? (`bg-blue-*`, `text-gray-*`, `bg-white`, `border-gray-*`)
453
+ - [ ] Any arbitrary value? (`p-[*]`, `text-[*]`, `rounded-[*]`, `z-[*]`)
454
+ - [ ] Any inline style? (`style={{ }}`)
455
+ - [ ] Any `dark:` prefix?
456
+ - [ ] Any `w-N h-N` for icons instead of `icon-*`?
457
+ - [ ] Any `divide-*` or `border` without a token color? (`divide-y` alone → `divide-y divide-border`)
458
+ - [ ] Any `opacity-*` on element instead of color modifier? (`bg-primary opacity-10` → `bg-primary/10`)
964
459
 
965
- **Sub-components:** Table.Header, Table.Body, Table.Footer, Table.Row, Table.Head, Table.Cell, Table.Caption
460
+ **If ANY violation is found fix it before showing code to the user.**
461
+ **Do NOT present code with violations. Fix first, then present.**
966
462
 
967
463
  ---
968
464
 
969
- ## Layout
970
-
971
- ### Tabs
972
-
973
- ```tsx
974
- import { Tabs } from '@7onic-ui/react'
975
-
976
- <Tabs defaultValue="tab1">
977
- <Tabs.List variant="line" size="default">
978
- <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
979
- <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
980
- </Tabs.List>
981
- <Tabs.Content value="tab1">Content 1</Tabs.Content>
982
- <Tabs.Content value="tab2">Content 2</Tabs.Content>
983
- </Tabs>
984
- ```
985
-
986
- | Prop (List) | Type | Default | Description |
987
- |---|---|---|---|
988
- | variant | `'line' \| 'enclosed' \| 'pill'` | `'line'` | Tab style |
989
- | size | `'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | Tab size |
990
- | fitted | `boolean` | `false` | Full width tabs |
991
- | color | `'default' \| 'primary'` | `'default'` | Active tab color |
992
- | radius | `'none' \| 'sm' \| 'md' \| 'default' \| 'lg' \| 'full'` | `'default'` | Border radius (enclosed/pill) |
993
-
994
- **Sub-components:** Tabs.List, Tabs.Trigger, Tabs.Content
995
-
996
- ---
997
-
998
- ### Accordion
999
-
1000
- ```tsx
1001
- import { Accordion } from '@7onic-ui/react'
1002
-
1003
- <Accordion type="single" collapsible defaultValue="item-1">
1004
- <Accordion.Item value="item-1">
1005
- <Accordion.Trigger>Section 1</Accordion.Trigger>
1006
- <Accordion.Content>Content 1</Accordion.Content>
1007
- </Accordion.Item>
1008
- <Accordion.Item value="item-2">
1009
- <Accordion.Trigger>Section 2</Accordion.Trigger>
1010
- <Accordion.Content>Content 2</Accordion.Content>
1011
- </Accordion.Item>
1012
- </Accordion>
1013
- ```
1014
-
1015
- | Prop (Root) | Type | Default | Description |
1016
- |---|---|---|---|
1017
- | type | `'single' \| 'multiple'` | required | Expansion mode |
1018
- | variant | `'default' \| 'bordered' \| 'splitted'` | `'default'` | Visual style |
1019
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Padding scale |
1020
- | iconPosition | `'left' \| 'right'` | `'right'` | Chevron placement |
1021
- | collapsible | `boolean` | `false` | Allow all closed (single only) |
1022
-
1023
- **Sub-components:** Accordion.Item, Accordion.Trigger (with `icon` prop), Accordion.Content
1024
-
1025
- ---
1026
-
1027
- ### Divider
1028
-
1029
- ```tsx
1030
- import { Divider } from '@7onic-ui/react'
1031
-
1032
- <Divider />
1033
- <Divider variant="dashed" color="muted" />
1034
- <Divider label="OR" labelPosition="center" />
1035
- <Divider orientation="vertical" />
1036
- ```
1037
-
1038
- | Prop | Type | Default | Description |
1039
- |---|---|---|---|
1040
- | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Direction |
1041
- | variant | `'solid' \| 'dashed' \| 'dotted'` | `'solid'` | Line style |
1042
- | color | `'default' \| 'muted' \| 'strong'` | `'default'` | Line color |
1043
- | spacing | `'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | Margin around line |
1044
- | label | `string` | — | Center label text |
1045
- | labelPosition | `'left' \| 'center' \| 'right'` | `'center'` | Label placement |
1046
-
1047
- ---
1048
-
1049
- ## Overlay
1050
-
1051
- ### Modal
1052
-
1053
- ```tsx
1054
- import { Modal, Button } from '@7onic-ui/react'
1055
-
1056
- <Modal>
1057
- <Modal.Trigger asChild>
1058
- <Button>Open Modal</Button>
1059
- </Modal.Trigger>
1060
- <Modal.Portal>
1061
- <Modal.Overlay />
1062
- <Modal.Content size="md">
1063
- <Modal.Header>
1064
- <Modal.Title>Confirm</Modal.Title>
1065
- <Modal.Description>Are you sure?</Modal.Description>
1066
- </Modal.Header>
1067
- <Modal.Body>Modal body content</Modal.Body>
1068
- <Modal.Footer>
1069
- <Modal.Close asChild><Button variant="outline">Cancel</Button></Modal.Close>
1070
- <Button color="primary">Confirm</Button>
1071
- </Modal.Footer>
1072
- </Modal.Content>
1073
- </Modal.Portal>
1074
- </Modal>
1075
- ```
1076
-
1077
- | Prop (Content) | Type | Default | Description |
1078
- |---|---|---|---|
1079
- | size | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Modal width |
1080
- | scrollBehavior | `'inside' \| 'outside'` | `'inside'` | Scroll target |
1081
- | showCloseButton | `boolean` | `true` | Show X button |
1082
-
1083
- **Sub-components:** Modal.Trigger, Modal.Portal, Modal.Overlay, Modal.Content, Modal.Header, Modal.Title, Modal.Description, Modal.Body, Modal.Footer, Modal.Close
1084
-
1085
- **Required structure:** Portal → Overlay + Content. Don't forget Portal and Overlay.
1086
-
1087
- ---
1088
-
1089
- ### Drawer
1090
-
1091
- ```tsx
1092
- import { Drawer, Button } from '@7onic-ui/react'
1093
-
1094
- <Drawer>
1095
- <Drawer.Trigger asChild>
1096
- <Button>Open Drawer</Button>
1097
- </Drawer.Trigger>
1098
- <Drawer.Portal>
1099
- <Drawer.Overlay />
1100
- <Drawer.Content side="right" size="md">
1101
- <Drawer.Header>
1102
- <Drawer.Title>Settings</Drawer.Title>
1103
- </Drawer.Header>
1104
- <Drawer.Body>Content</Drawer.Body>
1105
- <Drawer.Footer>
1106
- <Drawer.Close asChild><Button variant="outline">Close</Button></Drawer.Close>
1107
- </Drawer.Footer>
1108
- </Drawer.Content>
1109
- </Drawer.Portal>
1110
- </Drawer>
1111
- ```
1112
-
1113
- | Prop (Content) | Type | Default | Description |
1114
- |---|---|---|---|
1115
- | side | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | Slide direction |
1116
- | size | `'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Width/height |
1117
- | showCloseButton | `boolean` | `true` | Show X button |
1118
-
1119
- **Sub-components:** Drawer.Trigger, Drawer.Portal, Drawer.Overlay, Drawer.Content, Drawer.Header, Drawer.Title, Drawer.Description, Drawer.Body, Drawer.Footer, Drawer.Close
1120
-
1121
- ---
1122
-
1123
- ### Tooltip
1124
-
1125
- ```tsx
1126
- import { Tooltip } from '@7onic-ui/react'
1127
-
1128
- <Tooltip.Provider>
1129
- <Tooltip>
1130
- <Tooltip.Trigger asChild>
1131
- <Button>Hover me</Button>
1132
- </Tooltip.Trigger>
1133
- <Tooltip.Portal>
1134
- <Tooltip.Content side="top" showArrow>
1135
- Tooltip text
1136
- <Tooltip.Arrow />
1137
- </Tooltip.Content>
1138
- </Tooltip.Portal>
1139
- </Tooltip>
1140
- </Tooltip.Provider>
1141
- ```
1142
-
1143
- | Prop (Root) | Type | Default | Description |
1144
- |---|---|---|---|
1145
- | delayDuration | `number` | `200` | Hover delay (ms) |
1146
-
1147
- | Prop (Content) | Type | Default | Description |
1148
- |---|---|---|---|
1149
- | variant | `'default' \| 'inverted'` | `'default'` | Dark/light bg |
1150
- | size | `'sm' \| 'default'` | `'default'` | Padding scale |
1151
- | side | `'top' \| 'right' \| 'bottom' \| 'left'` | `'top'` | Placement |
1152
- | showArrow | `boolean` | `false` | Show arrow |
1153
- | sideOffset | `number` | `4` | Gap from trigger |
1154
-
1155
- **⚠️ Tooltip.Provider is required** — wrap your app or section with it.
1156
- **Sub-components:** Tooltip.Provider, Tooltip.Trigger, Tooltip.Content, Tooltip.Arrow, Tooltip.Portal
1157
-
1158
- ---
1159
-
1160
- ### Popover
1161
-
1162
- ```tsx
1163
- import { Popover, Button } from '@7onic-ui/react'
1164
-
1165
- <Popover>
1166
- <Popover.Trigger asChild>
1167
- <Button variant="outline">Open</Button>
1168
- </Popover.Trigger>
1169
- <Popover.Portal>
1170
- <Popover.Content side="bottom" showArrow showClose>
1171
- <Popover.Arrow />
1172
- <p>Popover content</p>
1173
- </Popover.Content>
1174
- </Popover.Portal>
1175
- </Popover>
1176
- ```
1177
-
1178
- | Prop (Content) | Type | Default | Description |
1179
- |---|---|---|---|
1180
- | variant | `'default' \| 'elevated'` | `'default'` | Shadow style |
1181
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Padding scale |
1182
- | side | `'top' \| 'right' \| 'bottom' \| 'left'` | `'bottom'` | Placement |
1183
- | showArrow | `boolean` | `false` | Show arrow |
1184
- | showClose | `boolean` | `false` | Show X button |
1185
-
1186
- **Sub-components:** Popover.Trigger, Popover.Content, Popover.Arrow, Popover.Close, Popover.Anchor, Popover.Portal
1187
-
1188
- ---
1189
-
1190
- ## Feedback
1191
-
1192
- ### Alert
1193
-
1194
- ```tsx
1195
- import { Alert } from '@7onic-ui/react'
1196
-
1197
- <Alert color="success" closable onClose={() => {}}>
1198
- <Alert.Title>Success</Alert.Title>
1199
- <Alert.Description>Operation completed.</Alert.Description>
1200
- </Alert>
1201
-
1202
- <Alert variant="filled" color="error" icon={<ErrorIcon />}>
1203
- <Alert.Title>Error</Alert.Title>
1204
- </Alert>
1205
- ```
1206
-
1207
- | Prop (Root) | Type | Default | Description |
1208
- |---|---|---|---|
1209
- | variant | `'default' \| 'outline' \| 'filled'` | `'default'` | Visual style |
1210
- | color | `'info' \| 'success' \| 'warning' \| 'error'` | `'info'` | Color scheme |
1211
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Padding scale |
1212
- | radius | Same as Card | `'lg'` | Border radius |
1213
- | closable | `boolean` | `false` | Show close button |
1214
- | onClose | `() => void` | — | Close handler |
1215
- | icon | `ReactNode` | auto | Custom icon (auto-selects by color) |
1216
- | hideIcon | `boolean` | `false` | Hide icon |
1217
-
1218
- **Sub-components:** Alert.Title, Alert.Description
1219
-
1220
- ---
1221
-
1222
- ### Toast (Imperative API)
1223
-
1224
- ```tsx
1225
- import { Toaster, toast } from '@7onic-ui/react'
1226
-
1227
- // 1. Add Toaster provider to your app layout (once)
1228
- <Toaster position="bottom-right" />
1229
-
1230
- // 2. Call toast() anywhere
1231
- toast('Default notification')
1232
- toast.success('Saved successfully')
1233
- toast.error('Something went wrong')
1234
- toast.warning('Please check your input')
1235
- toast.info('New update available')
1236
- toast.loading('Processing...')
1237
-
1238
- // With options
1239
- toast.success('Saved', {
1240
- description: 'Your changes have been saved.',
1241
- duration: 5000,
1242
- action: { label: 'Undo', onClick: () => {} },
1243
- })
1244
-
1245
- // Promise
1246
- toast.promise(fetchData(), {
1247
- loading: 'Loading...',
1248
- success: 'Data loaded',
1249
- error: 'Failed to load',
1250
- })
1251
-
1252
- // Dismiss
1253
- const id = toast('Message')
1254
- toast.dismiss(id) // Dismiss specific
1255
- toast.dismiss() // Dismiss all
1256
- ```
1257
-
1258
- | Prop (Toaster) | Type | Default | Description |
1259
- |---|---|---|---|
1260
- | position | `'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right'` | `'bottom-right'` | Toast position |
1261
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Toast size |
1262
- | duration | `number` | `4000` | Auto-dismiss ms (0 = persistent) |
1263
- | closeButton | `boolean` | `false` | Show close button |
1264
- | richColors | `boolean` | `false` | Filled color backgrounds |
1265
- | expand | `boolean` | `false` | Show all toasts expanded |
1266
- | visibleToasts | `number` | `3` | Max visible at once |
1267
-
1268
- **⚠️ No Portal needed.** Just place `<Toaster />` in your root layout. Call `toast()` from anywhere.
1269
-
1270
- ---
1271
-
1272
- ### Progress
1273
-
1274
- ```tsx
1275
- import { Progress } from '@7onic-ui/react'
1276
-
1277
- <Progress value={65} showValue />
1278
- <Progress type="circular" value={75} color="primary" />
1279
- <Progress variant="striped" animated value={50} />
1280
- ```
1281
-
1282
- | Prop | Type | Default | Description |
1283
- |---|---|---|---|
1284
- | type | `'linear' \| 'circular'` | `'linear'` | Shape |
1285
- | value | `number` | `0` | Current value |
1286
- | max | `number` | `100` | Maximum value |
1287
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Bar/circle size |
1288
- | variant | `'default' \| 'striped'` | `'default'` | Bar fill style |
1289
- | color | `'default' \| 'primary'` | `'default'` | Fill color |
1290
- | showValue | `boolean` | `false` | Show percentage text |
1291
- | formatLabel | `(value: number, max: number) => string` | — | Custom label |
1292
- | animated | `boolean` | `false` | Animate stripes |
1293
-
1294
- ---
1295
-
1296
- ### Spinner
1297
-
1298
- ```tsx
1299
- import { Spinner } from '@7onic-ui/react'
1300
-
1301
- <Spinner />
1302
- <Spinner variant="dots" size="lg" color="primary" />
1303
- <Spinner variant="bars" speed="slow" />
1304
- <Spinner variant="orbit" orbitStyle="morph" />
1305
- ```
1306
-
1307
- | Prop | Type | Default | Description |
1308
- |---|---|---|---|
1309
- | variant | `'ring' \| 'dots' \| 'bars' \| 'orbit'` | `'ring'` | Animation style |
1310
- | orbitStyle | `'ring' \| 'dots' \| 'cube' \| 'flip' \| 'morph'` | `'ring'` | Orbit sub-variant |
1311
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Spinner size |
1312
- | color | `'default' \| 'primary' \| 'current'` | `'default'` | Color |
1313
- | speed | `'slow' \| 'default' \| 'fast'` | `'default'` | Animation speed |
1314
- | label | `string` | `'Loading'` | aria-label text |
1315
-
1316
- ---
1317
-
1318
- ### Skeleton
1319
-
1320
- ```tsx
1321
- import { Skeleton } from '@7onic-ui/react'
1322
-
1323
- <Skeleton variant="text" count={3} />
1324
- <Skeleton variant="circular" width={48} height={48} />
1325
- <Skeleton variant="rectangular" width="100%" height={200} />
1326
-
1327
- {/* Conditional rendering */}
1328
- <Skeleton loading={isLoading}>
1329
- <ActualContent />
1330
- </Skeleton>
1331
- ```
1332
-
1333
- | Prop | Type | Default | Description |
1334
- |---|---|---|---|
1335
- | variant | `'text' \| 'circular' \| 'rectangular'` | `'text'` | Shape |
1336
- | animation | `'pulse' \| 'wave' \| false` | `'pulse'` | Animation style |
1337
- | width | `number \| string` | — | Width (px or CSS) |
1338
- | height | `number \| string` | — | Height (px or CSS) |
1339
- | radius | `number \| string` | — | Border radius |
1340
- | count | `number` | `1` | Multi-line count |
1341
- | loading | `boolean` | `true` | Show skeleton vs children |
1342
- | children | `ReactNode` | — | Content (shown when loading=false) |
1343
-
1344
- ---
1345
-
1346
- ## Navigation
1347
-
1348
- ### Breadcrumb
1349
-
1350
- ```tsx
1351
- import { Breadcrumb } from '@7onic-ui/react'
1352
-
1353
- <Breadcrumb>
1354
- <Breadcrumb.List>
1355
- <Breadcrumb.Item>
1356
- <Breadcrumb.Link href="/">Home</Breadcrumb.Link>
1357
- </Breadcrumb.Item>
1358
- <Breadcrumb.Separator />
1359
- <Breadcrumb.Item>
1360
- <Breadcrumb.Link href="/docs">Docs</Breadcrumb.Link>
1361
- </Breadcrumb.Item>
1362
- <Breadcrumb.Separator />
1363
- <Breadcrumb.Item>
1364
- <Breadcrumb.Page>Current</Breadcrumb.Page>
1365
- </Breadcrumb.Item>
1366
- </Breadcrumb.List>
1367
- </Breadcrumb>
1368
- ```
1369
-
1370
- | Prop (Root) | Type | Default | Description |
1371
- |---|---|---|---|
1372
- | separator | `ReactNode` | `'/'` | Custom separator |
1373
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Text size |
1374
- | maxItems | `number` | — | Collapse threshold |
1375
- | itemsBeforeCollapse | `number` | `1` | Items before ellipsis |
1376
- | itemsAfterCollapse | `number` | `1` | Items after ellipsis |
1377
-
1378
- **Sub-components:** Breadcrumb.List, Breadcrumb.Item, Breadcrumb.Link (with `asChild`), Breadcrumb.Page, Breadcrumb.Separator, Breadcrumb.Ellipsis
1379
-
1380
- ---
1381
-
1382
- ### Pagination
1383
-
1384
- ```tsx
1385
- import { Pagination } from '@7onic-ui/react'
1386
-
1387
- {/* Quick mode */}
1388
- <Pagination total={10} defaultValue={1} />
1389
-
1390
- {/* Compound mode */}
1391
- <Pagination total={20} value={page} onChange={setPage}>
1392
- <Pagination.Content>
1393
- <Pagination.Previous />
1394
- <Pagination.Items />
1395
- <Pagination.Next />
1396
- </Pagination.Content>
1397
- </Pagination>
1398
- ```
1399
-
1400
- | Prop (Root) | Type | Default | Description |
1401
- |---|---|---|---|
1402
- | total | `number` | required | Total pages |
1403
- | value | `number` | — | Controlled page |
1404
- | defaultValue | `number` | `1` | Uncontrolled default |
1405
- | onChange | `(page: number) => void` | — | Change handler |
1406
- | siblings | `number` | `1` | Pages beside current |
1407
- | boundaries | `number` | `1` | Pages at start/end |
1408
- | variant | `'default' \| 'outline' \| 'ghost'` | `'default'` | Visual style |
1409
- | color | `'default' \| 'primary'` | `'default'` | Active page color |
1410
- | size | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'xl'` | `'default'` | Button size |
1411
- | radius | `'none' \| 'sm' \| 'md' \| 'default' \| 'lg' \| 'full'` | `'default'` | Border radius |
1412
- | loop | `boolean` | `false` | Wrap around |
1413
- | disabled | `boolean` | `false` | Disabled state |
1414
-
1415
- **Sub-components:** Pagination.Content, Pagination.Item, Pagination.Link, Pagination.Previous, Pagination.Next, Pagination.First, Pagination.Last, Pagination.Ellipsis, Pagination.Items
1416
-
1417
- ---
1418
-
1419
- ### NavigationMenu
1420
-
1421
- ```tsx
1422
- import { NavigationMenu } from '@7onic-ui/react'
1423
-
1424
- {/* Horizontal (header) */}
1425
- <NavigationMenu orientation="horizontal">
1426
- <NavigationMenu.List>
1427
- <NavigationMenu.Item>
1428
- <NavigationMenu.Link href="/" active>Home</NavigationMenu.Link>
1429
- </NavigationMenu.Item>
1430
- <NavigationMenu.Item>
1431
- <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>
1432
- <NavigationMenu.Content>
1433
- <NavigationMenu.Link href="/product-a">Product A</NavigationMenu.Link>
1434
- <NavigationMenu.Link href="/product-b">Product B</NavigationMenu.Link>
1435
- </NavigationMenu.Content>
1436
- </NavigationMenu.Item>
1437
- </NavigationMenu.List>
1438
- <NavigationMenu.Viewport />
1439
- </NavigationMenu>
1440
-
1441
- {/* Vertical (sidebar) */}
1442
- <NavigationMenu orientation="vertical" size="default">
1443
- <NavigationMenu.List>
1444
- <NavigationMenu.Group label="Main">
1445
- <NavigationMenu.Item>
1446
- <NavigationMenu.Link href="/" icon={<HomeIcon />} active>Dashboard</NavigationMenu.Link>
1447
- </NavigationMenu.Item>
1448
- </NavigationMenu.Group>
1449
- </NavigationMenu.List>
1450
- </NavigationMenu>
1451
- ```
1452
-
1453
- | Prop (Root) | Type | Default | Description |
1454
- |---|---|---|---|
1455
- | orientation | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout mode |
1456
- | size | `'sm' \| 'md' \| 'default' \| 'lg'` | `'default'` | Item size |
1457
- | collapsed | `boolean` | `false` | Icon-only mode (vertical) |
1458
- | radius | Same as Button | `'default'` | Border radius |
1459
- | fontWeight | `'normal' \| 'semibold'` | `'normal'` | Font weight |
1460
-
1461
- | Prop (Link) | Type | Default | Description |
1462
- |---|---|---|---|
1463
- | active | `boolean` | `false` | Current page indicator |
1464
- | icon | `ReactNode` | — | Leading icon |
1465
- | asChild | `boolean` | `false` | Slot pattern |
1466
-
1467
- **Sub-components:** NavigationMenu.List, NavigationMenu.Item, NavigationMenu.Trigger, NavigationMenu.Content, NavigationMenu.Link, NavigationMenu.Group (vertical only, with `label`), NavigationMenu.Indicator (horizontal only), NavigationMenu.Viewport
1468
-
1469
- ---
1470
-
1471
- ## Charts
1472
-
1473
- ### Chart (Container + Sub-components)
1474
-
1475
- All chart types use the Chart namespace:
1476
-
1477
- ```tsx
1478
- import { Chart } from '@7onic-ui/react/chart'
1479
-
1480
- const chartConfig = {
1481
- revenue: { label: 'Revenue', color: 'var(--color-chart-1)' },
1482
- profit: { label: 'Profit', color: 'var(--color-chart-2)' },
1483
- }
1484
-
1485
- {/* Line Chart */}
1486
- <Chart config={chartConfig} className="h-[300px]">
1487
- <Chart.XAxis dataKey="month" />
1488
- <Chart.YAxis />
1489
- <Chart.Tooltip content={<Chart.TooltipContent />} />
1490
- <Chart.Legend content={<Chart.LegendContent />} />
1491
- <Chart.Line dataKey="revenue" type="monotone" />
1492
- <Chart.Line dataKey="profit" type="monotone" variant="dashed" />
1493
- </Chart>
1494
-
1495
- {/* Bar Chart */}
1496
- <Chart config={chartConfig} className="h-[300px]" hoverFade>
1497
- <Chart.XAxis dataKey="month" />
1498
- <Chart.YAxis />
1499
- <Chart.Tooltip content={<Chart.TooltipContent />} />
1500
- <Chart.Bar dataKey="revenue" radius="md" />
1501
- <Chart.Bar dataKey="profit" radius="md" />
1502
- </Chart>
1503
-
1504
- {/* Area Chart */}
1505
- <Chart config={chartConfig} className="h-[300px]">
1506
- <Chart.XAxis dataKey="month" />
1507
- <Chart.YAxis />
1508
- <Chart.Tooltip content={<Chart.TooltipContent />} />
1509
- <Chart.Area dataKey="revenue" type="monotone" variant="gradient" />
1510
- </Chart>
1511
-
1512
- {/* Pie Chart */}
1513
- <Chart config={chartConfig} className="h-[300px]">
1514
- <Chart.Tooltip content={<Chart.TooltipContent />} />
1515
- <Chart.Pie data={data} dataKey="value" nameKey="name" variant="donut" label="outside" />
1516
- </Chart>
1517
- ```
1518
-
1519
- **⚠️ chartConfig is REQUIRED.** It maps data keys to labels and colors.
1520
-
1521
- | Prop (Container) | Type | Default | Description |
1522
- |---|---|---|---|
1523
- | config | `ChartConfig` | required | Data key → label/color mapping |
1524
- | hoverFade | `boolean` | `false` | Fade non-hovered elements |
1525
-
1526
- | Prop (Bar) | Type | Default | Description |
1527
- |---|---|---|---|
1528
- | radius | `'none' \| 'sm' \| 'base' \| 'md' \| 'lg'` | `'none'` | Bar corner radius |
1529
- | layout | `'vertical' \| 'horizontal'` | `'vertical'` | Bar direction |
1530
- | variant | `'solid' \| 'outline'` | `'solid'` | Fill style |
1531
- | stackPosition | `'top' \| 'bottom'` | `'top'` | Stack position |
1532
-
1533
- | Prop (Line) | Type | Default | Description |
1534
- |---|---|---|---|
1535
- | type | `'linear' \| 'monotone' \| 'step' \| 'natural'` | `'monotone'` | Curve type |
1536
- | variant | `'solid' \| 'dashed'` | `'solid'` | Line style |
1537
- | dot | `boolean` | `true` | Show data points |
1538
- | activeDot | `boolean` | `true` | Show active point |
1539
-
1540
- | Prop (Area) | Type | Default | Description |
1541
- |---|---|---|---|
1542
- | type | `'linear' \| 'monotone' \| 'step' \| 'natural'` | `'monotone'` | Curve type |
1543
- | variant | `'solid' \| 'gradient'` | `'solid'` | Fill style |
1544
- | fillOpacity | `number` | `0.4` | Fill opacity (0-1) |
1545
-
1546
- | Prop (Pie) | Type | Default | Description |
1547
- |---|---|---|---|
1548
- | variant | `'pie' \| 'donut'` | `'pie'` | Pie or donut |
1549
- | label | `'none' \| 'outside' \| 'inside'` | `'none'` | Label display |
1550
- | labelContent | `'value' \| 'percent'` | `'value'` | Label format |
1551
- | activeShape | `boolean` | `true` | Expand on hover |
1552
-
1553
- **Chart Colors (CSS variables):**
1554
- `--color-chart-1` (blue), `--color-chart-2` (pink), `--color-chart-3` (lavender), `--color-chart-4` (sky), `--color-chart-5` (rose)
1555
- Each has light/dark theme variants.
1556
-
1557
- **ChartConfig format:**
1558
- ```tsx
1559
- type ChartConfig = {
1560
- [dataKey: string]: {
1561
- label?: ReactNode
1562
- icon?: ComponentType
1563
- color?: string // CSS color or variable
1564
- // OR theme-specific:
1565
- theme?: { light: string, dark: string }
1566
- }
1567
- }
1568
- ```
1569
-
1570
- ---
1571
-
1572
- ### MetricCard
1573
-
1574
- ```tsx
1575
- import { MetricCard } from '@7onic-ui/react'
1576
-
1577
- <MetricCard>
1578
- <MetricCard.Header>
1579
- <MetricCard.Title>Revenue</MetricCard.Title>
1580
- <MetricCard.Symbol><DollarIcon /></MetricCard.Symbol>
1581
- </MetricCard.Header>
1582
- <MetricCard.Value animated>$12,450</MetricCard.Value>
1583
- <MetricCard.Trend direction="up">+12.5%</MetricCard.Trend>
1584
- <MetricCard.Description>vs. last month</MetricCard.Description>
1585
- </MetricCard>
1586
- ```
1587
-
1588
- | Prop (Root) | Type | Default | Description |
1589
- |---|---|---|---|
1590
- | variant | `'default' \| 'elevated' \| 'ghost'` | `'default'` | Visual style |
1591
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Padding scale |
1592
- | radius | Same as Card + `'none'` | `'xl'` | Border radius |
1593
-
1594
- | Prop (Value) | Type | Default | Description |
1595
- |---|---|---|---|
1596
- | animated | `boolean` | `false` | Number count-up animation |
1597
-
1598
- | Prop (Trend) | Type | Default | Description |
1599
- |---|---|---|---|
1600
- | direction | `'up' \| 'down' \| 'neutral'` | — | Trend arrow + color |
1601
-
1602
- **Sub-components:** MetricCard.Header, MetricCard.Title, MetricCard.Value, MetricCard.Trend, MetricCard.Description, MetricCard.Symbol
1603
-
1604
- ---
1605
-
1606
- # ═══ SECTION 4: COMPONENT USAGE GUIDE ═══
1607
-
1608
- ## Component Selection
1609
-
1610
- Before creating custom UI, check if 7onic already has it:
1611
-
1612
- | Need | Use This Component |
1613
- |---|---|
1614
- | Action trigger | Button, IconButton |
1615
- | Text input | Input (single line), Textarea (multi line) |
1616
- | Selection (one) | RadioGroup, Select, Segmented |
1617
- | Selection (many) | Checkbox, ToggleGroup |
1618
- | Boolean toggle | Switch, Toggle, Checkbox |
1619
- | Container | Card |
1620
- | Data table | Table |
1621
- | Tabs | Tabs |
1622
- | Collapsible | Accordion |
1623
- | Dialog | Modal |
1624
- | Side panel | Drawer |
1625
- | Hint text | Tooltip |
1626
- | Rich hint | Popover |
1627
- | Notification | Toast (imperative), Alert (inline) |
1628
- | Loading | Spinner (indeterminate), Progress (determinate), Skeleton (placeholder) |
1629
- | Navigation | Breadcrumb, Pagination, NavigationMenu |
1630
- | Data visualization | Chart (Line/Area/Bar/Pie), MetricCard |
1631
- | Metric display | MetricCard |
1632
- | Tag / chip | Badge (with `removable`) |
1633
- | Avatar | Avatar |
1634
- | Separator | Divider |
1635
-
1636
- **If the component exists, use it.** Don't build custom versions with HTML + classes.
1637
-
1638
- ---
1639
-
1640
- ## Import Pattern
1641
-
1642
- ```tsx
1643
- // ✅ Single import path
1644
- import { Button, Card, Input, toast } from '@7onic-ui/react'
1645
-
1646
- // ✅ Chart components use a separate entry point (recharts is optional)
1647
- import { Chart } from '@7onic-ui/react/chart'
1648
-
1649
- // ❌ Never import from internal paths
1650
- import { Button } from '@7onic-ui/react/components/button' // WRONG
1651
-
1652
- // ❌ Never import Radix directly
1653
- import * as Dialog from '@radix-ui/react-dialog' // WRONG → use Modal
1654
- ```
1655
-
1656
- ---
1657
-
1658
- ## Compound Component Structure
1659
-
1660
- Compound components have **required sub-components**. Missing them causes errors or broken UI.
1661
-
1662
- **Modal — required structure:**
1663
- ```tsx
1664
- <Modal>
1665
- <Modal.Trigger>...</Modal.Trigger>
1666
- <Modal.Portal> {/* ← Required for correct z-index */}
1667
- <Modal.Overlay /> {/* ← Required for backdrop */}
1668
- <Modal.Content>
1669
- <Modal.Header>
1670
- <Modal.Title>...</Modal.Title>
1671
- </Modal.Header>
1672
- <Modal.Body>...</Modal.Body>
1673
- </Modal.Content>
1674
- </Modal.Portal>
1675
- </Modal>
1676
- ```
1677
-
1678
- **Drawer — same pattern as Modal** (Portal + Overlay + Content required)
1679
-
1680
- **Tooltip — Provider required:**
1681
- ```tsx
1682
- <Tooltip.Provider> {/* ← Required, wrap app once */}
1683
- <Tooltip>
1684
- <Tooltip.Trigger>...</Tooltip.Trigger>
1685
- <Tooltip.Portal>
1686
- <Tooltip.Content>...</Tooltip.Content>
1687
- </Tooltip.Portal>
1688
- </Tooltip>
1689
- </Tooltip.Provider>
1690
- ```
1691
-
1692
- **Toast — imperative API, no compound structure:**
1693
- ```tsx
1694
- // Place Toaster once in layout
1695
- <Toaster />
1696
- // Call toast() anywhere
1697
- toast.success('Done')
1698
- ```
1699
-
1700
- ---
1701
-
1702
- ## asChild Pattern (Slot)
1703
-
1704
- `asChild` replaces the component's DOM element with its child, keeping styles and behavior:
1705
-
1706
- ```tsx
1707
- // ❌ Double <a> — broken HTML
1708
- <Link href="/about">
1709
- <Button>About</Button>
1710
- </Link>
1711
-
1712
- // ✅ Button renders as <a> with Button styles
1713
- <Button asChild>
1714
- <Link href="/about">About</Link>
1715
- </Button>
1716
-
1717
- // ✅ DropdownMenu item as link
1718
- <DropdownMenu.Item asChild>
1719
- <Link href="/settings">Settings</Link>
1720
- </DropdownMenu.Item>
1721
-
1722
- // ✅ Breadcrumb as Next.js Link
1723
- <Breadcrumb.Link asChild>
1724
- <Link href="/">Home</Link>
1725
- </Breadcrumb.Link>
1726
- ```
1727
-
1728
- **Use `asChild` when combining 7onic components with routing `<Link>`.**
1729
- Components that support `asChild`: Button, IconButton, Badge, Card, Modal.Trigger, Modal.Close, Drawer.Trigger, Drawer.Close, DropdownMenu.Item, Breadcrumb.Link, NavigationMenu.Link, Tooltip.Trigger, Popover.Trigger
1730
-
1731
- ---
1732
-
1733
- ## Props Usage
1734
-
1735
- **Always use allowed values.** Don't pass arbitrary strings to variant/size/color props.
1736
-
1737
- ```tsx
1738
- // ✅ Correct
1739
- <Button variant="solid" size="default" color="primary" />
1740
-
1741
- // ❌ Wrong — invalid values
1742
- <Button variant="primary" /> // 'primary' is a color, not a variant
1743
- <Button size="medium" /> // Use 'md' or 'default', not 'medium'
1744
- <Button color="blue" /> // Use 'primary', not raw color names
1745
- ```
1746
-
1747
- **`className` on components = layout ONLY** (margin, width, flex positioning). All visual styling (color, size, radius, variant) must use Props.
1748
-
1749
- **Style via Props, not className:**
1750
- ```tsx
1751
- // ✅ Use Props
1752
- <Button color="primary" size="lg" />
1753
- <Badge color="error" variant="subtle" />
1754
-
1755
- // ❌ Don't override with className
1756
- <Button className="bg-blue-500 text-white" />
1757
- <Badge className="bg-red-100" />
1758
- ```
1759
-
1760
- ---
1761
-
1762
- ## Form Patterns
1763
-
1764
- **Use Field wrapper** for labeled form elements with validation:
1765
-
1766
- ```tsx
1767
- import { Field, Input, Textarea, Checkbox } from '@7onic-ui/react'
1768
-
1769
- {/* Text input with label + error */}
1770
- <Field error={errors.email}>
1771
- <Field.Label required>Email</Field.Label>
1772
- <Input placeholder="you@example.com" />
1773
- <Field.Error />
1774
- </Field>
1775
-
1776
- {/* Textarea with character count */}
1777
- <Field>
1778
- <Field.Label>Bio</Field.Label>
1779
- <Textarea maxLength={200} />
1780
- <Field.CharCount />
1781
- </Field>
1782
- ```
1783
-
1784
- **Field context auto-connects** to Input, Textarea, Select, Checkbox, RadioGroup:
1785
- - Passes `error` state
1786
- - Passes `disabled` state
1787
- - Auto-generates matching `id` / `htmlFor` / `aria-describedby`
1788
-
1789
- ---
1790
-
1791
- ## Chart Patterns
1792
-
1793
- **⚠️ recharts is required.** Auto-install when using any Chart component:
1794
- ```bash
1795
- npm install recharts
1796
- ```
1797
-
1798
- **Always provide chartConfig:**
1799
- ```tsx
1800
- const chartConfig = {
1801
- revenue: { label: 'Revenue', color: 'var(--color-chart-1)' },
1802
- expenses: { label: 'Expenses', color: 'var(--color-chart-2)' },
1803
- }
1804
- ```
1805
-
1806
- **Available chart colors (CSS variables, auto-adapt to light/dark):**
1807
- - `var(--color-chart-1)` — blue
1808
- - `var(--color-chart-2)` — pink
1809
- - `var(--color-chart-3)` — lavender
1810
- - `var(--color-chart-4)` — sky
1811
- - `var(--color-chart-5)` — rose
1812
-
1813
- **Container height is required (layout arbitrary value — allowed):**
1814
- ```tsx
1815
- <Chart config={chartConfig} className="h-[300px]">
1816
- ```
1817
-
1818
- ---
1819
-
1820
- ## Overlay Patterns
1821
-
1822
- **All overlays use Portal for correct stacking:**
1823
- ```tsx
1824
- <Modal.Portal>
1825
- <Modal.Overlay />
1826
- <Modal.Content>...</Modal.Content>
1827
- </Modal.Portal>
1828
- ```
1829
-
1830
- **Z-index hierarchy (automatic via tokens) — never set custom z-index:**
1831
- 1. `z-dropdown` (1000) — Dropdown, Select
1832
- 2. `z-overlay` (1100) — Modal/Drawer overlay
1833
- 3. `z-modal` (2000) — Modal/Drawer content
1834
- 4. `z-popover` (2100) — Popover
1835
- 5. `z-tooltip` (2200) — Tooltip
1836
- 6. `z-toast` (3000) — Toast
1837
-
1838
- ---
1839
-
1840
- ## Accessibility
1841
-
1842
- **Built-in (via Radix UI):** keyboard navigation, focus trap, ARIA attributes, screen reader.
1843
-
1844
- **Do NOT override:**
1845
- ```tsx
1846
- // ❌ Never remove focus ring
1847
- <Button className="outline-none focus:outline-none" />
1848
-
1849
- // ✅ Focus ring is managed by the design system
1850
- <Button />
1851
- ```
1852
-
1853
- **Always provide labels:**
1854
- ```tsx
1855
- <IconButton aria-label="Close"><XIcon /></IconButton>
1856
-
1857
- <Field>
1858
- <Field.Label>Email</Field.Label>
1859
- <Input />
1860
- </Field>
1861
- ```
1862
-
1863
- ---
1864
-
1865
- ## Responsive Layout
1866
-
1867
- **Mobile-first with token breakpoints:**
1868
- ```tsx
1869
- <div className="flex flex-col md:flex-row gap-4 md:gap-6">
1870
- <Card className="w-full md:w-1/2">...</Card>
1871
- <Card className="w-full md:w-1/2">...</Card>
1872
- </div>
1873
- ```
1874
-
1875
- **Use component Props for sizing, not className overrides:**
1876
- ```tsx
1877
- // ✅ Correct
1878
- <Button size="default" />
1879
-
1880
- // ❌ Wrong
1881
- <Button size="sm" className="md:h-10 md:px-4" />
1882
- ```
1883
-
1884
- ---
1885
-
1886
- ## Performance
1887
-
1888
- **Tree-shaking works automatically:**
1889
- ```tsx
1890
- import { Button, Card, Input } from '@7onic-ui/react'
1891
- ```
1892
-
1893
- **Don't wrap components unnecessarily:**
1894
- ```tsx
1895
- // ❌ Unnecessary
1896
- function MyButton(props) { return <Button {...props} /> }
1897
-
1898
- // ✅ Use directly
1899
- <Button variant="solid" color="primary">Submit</Button>
1900
- ```
1901
-
1902
- **Next.js App Router:** 7onic components have `'use client'` internally — they render in Server Components.
1903
- But if YOUR code uses React hooks (`useState`, `useEffect`) or event handlers (`onClick`, `onChange`), add `'use client'` at the top of your file. When in doubt, add `'use client'` — it's always safe.
1904
-
1905
- ---
1906
-
1907
- # ═══ SECTION 5: COMPLETE COMPONENT SUMMARY ═══
1908
-
1909
- ## Quick Reference Table
1910
-
1911
- | Component | Type | Variants | Sizes | Colors | Key Feature |
1912
- |---|---|---|---|---|---|
1913
- | Button | Standalone | solid/outline/ghost/link | xs/sm/md/default/lg | default/primary/secondary/destructive | loading, icons, press effect |
1914
- | IconButton | Standalone | solid/outline/ghost/subtle | xs/sm/md/default/lg | default/primary/secondary/destructive | Square, icon-only |
1915
- | ButtonGroup | Container | outline/ghost | (inherits) | (inherits) | Context provider, attached |
1916
- | Input | Standalone | default/filled | xs/sm/default/lg/xl | — | leftIcon/rightIcon, error |
1917
- | Textarea | Standalone | default/filled | compact/default | — | resize options |
1918
- | Select | Compound | — | xs/sm/default/lg/xl | — | Trigger + Content + Item |
1919
- | DropdownMenu | Compound | — | sm/md/lg | — | CheckboxItem, RadioItem, Sub |
1920
- | Checkbox | Standalone | — | sm/default/lg | default/primary | indeterminate, label |
1921
- | RadioGroup | Compound | — | sm/default/lg | default/primary | Item with label |
1922
- | Switch | Standalone | — | sm/default/lg | 5 colors | label positions, icons |
1923
- | Toggle | Standalone | default/outline/ghost/outline-ghost | xs/sm/md/default/lg | — | pressed state |
1924
- | ToggleGroup | Compound | default/outline | xs/sm/md/default/lg | — | single/multiple |
1925
- | Segmented | Compound | default/outline/underline/ghost | sm/md/default/lg | — | Tab-like selection |
1926
- | Slider | Standalone | — | sm/default/lg | default/primary | tooltip, range |
1927
- | Field | Compound | — | — | — | Label, Error, CharCount |
1928
- | Avatar | Compound | — | xs/sm/default/lg/xl/2xl | — | colorized fallback, Group |
1929
- | Badge | Standalone | solid/subtle/outline | sm/default/lg | default/primary/success/warning/error/info | dot, removable |
1930
- | Card | Compound | default/outline/ghost | sm/default/lg | — | Image overlay, interactive |
1931
- | Table | Compound | default/bordered/striped | sm/default/lg | — | stickyHeader, sortable |
1932
- | Tabs | Compound | line/enclosed/pill | sm/md/default/lg | default/primary | fitted |
1933
- | Accordion | Compound | default/bordered/splitted | sm/default/lg | — | single/multiple |
1934
- | Divider | Standalone | solid/dashed/dotted | — | default/muted/strong | label |
1935
- | Modal | Compound | — | xs/sm/md/lg/xl/full | — | scrollBehavior |
1936
- | Drawer | Compound | — | sm/md/lg/xl/full | — | 4 sides |
1937
- | Tooltip | Compound | default/inverted | sm/default | — | Provider required |
1938
- | Popover | Compound | default/elevated | sm/default/lg | — | arrow, close button |
1939
- | Alert | Compound | default/outline/filled | sm/default/lg | info/success/warning/error | closable |
1940
- | Toast | Imperative | — | sm/default/lg | 6 types | promise, action |
1941
- | Progress | Standalone | default/striped | sm/default/lg | default/primary | linear/circular |
1942
- | Spinner | Standalone | ring/dots/bars/orbit | sm/default/lg | default/primary/current | 5 orbit styles |
1943
- | Skeleton | Standalone | text/circular/rectangular | — | — | pulse/wave, count |
1944
- | Breadcrumb | Compound | — | sm/default/lg | — | maxItems collapse |
1945
- | Pagination | Compound | default/outline/ghost | xs/sm/default/lg/xl | default/primary | compound or auto |
1946
- | NavigationMenu | Compound | — | sm/md/default/lg | — | horizontal/vertical, collapsed |
1947
- | Chart | Compound | — | — | chart colors | Bar/Line/Area/Pie |
1948
- | MetricCard | Compound | default/elevated/ghost | sm/default/lg | — | animated value, trend |
1949
- | TypingIndicator | Standalone | dots/cursor | sm/default/lg | default/primary/muted | speed (dots only), animate-typing-cursor, showLabel |
1950
- | QuickReply | Compound | outline/filled/ghost | sm/default/lg | default/primary | layout (scroll/wrap), radius (md/lg/full), gap, icon, asChild |
1951
- | ChatInput | Compound | outline/filled | sm/default/lg | default/primary | layout (default/inline), radius (sm/md/lg/xl/2xl/full), buttonRadius, auto-resize, showCount, loading, onStop |
1952
- | ChatMessage | Compound | bubble/flat | sm/default/lg | default/muted/primary/dark | role (assistant/user), tail, avatarSize, radius (md/lg/xl/2xl), typing, actions, Avatar/Content/Footer sub-components |
1953
- ---
1954
-
1955
- ### TypingIndicator
1956
-
1957
- ```tsx
1958
- import { TypingIndicator } from '@7onic-ui/react'
1959
-
1960
- {/* Default — dots, muted, default size */}
1961
- <TypingIndicator />
1962
-
1963
- {/* Cursor variant */}
1964
- <TypingIndicator variant="cursor" />
1965
-
1966
- {/* Chat bubble */}
1967
- <TypingIndicator variant="dots" color="muted" />
1968
-
1969
- {/* AI response — fast with label */}
1970
- <TypingIndicator
1971
- variant="dots"
1972
- color="primary"
1973
- speed="fast"
1974
- showLabel
1975
- label="AI is typing..."
1976
- />
1977
-
1978
- {/* Large cursor, primary color */}
1979
- <TypingIndicator variant="cursor" size="lg" color="primary" />
1980
- ```
1981
-
1982
- | Prop | Type | Default | Description |
1983
- |---|---|---|---|
1984
- | variant | `'dots' \| 'cursor'` | `'dots'` | Animation style |
1985
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size |
1986
- | color | `'default' \| 'primary' \| 'muted'` | `'muted'` | Color |
1987
- | speed | `'slow' \| 'default' \| 'fast'` | `'default'` | Speed (dots only) |
1988
- | label | `string` | `'Typing'` | aria-label and showLabel text |
1989
- | showLabel | `boolean` | `false` | Show text label alongside indicator |
1990
-
1991
- ---
1992
-
1993
- ### QuickReply
1994
-
1995
- ```tsx
1996
- import { QuickReply } from '@7onic-ui/react'
1997
-
1998
- {/* Basic suggested replies */}
1999
- <QuickReply aria-label="Suggested replies">
2000
- <QuickReply.Item>About payment</QuickReply.Item>
2001
- <QuickReply.Item>Shipping info</QuickReply.Item>
2002
- <QuickReply.Item>Return policy</QuickReply.Item>
2003
- </QuickReply>
2004
-
2005
- {/* Primary color, filled variant */}
2006
- <QuickReply color="primary" variant="filled" aria-label="Quick replies">
2007
- <QuickReply.Item>Payment</QuickReply.Item>
2008
- <QuickReply.Item>Shipping</QuickReply.Item>
2009
- </QuickReply>
2010
-
2011
- {/* Wrap layout for FAQ */}
2012
- <QuickReply layout="wrap" aria-label="FAQ topics">
2013
- <QuickReply.Item>Payments</QuickReply.Item>
2014
- <QuickReply.Item>Shipping</QuickReply.Item>
2015
- <QuickReply.Item>Returns</QuickReply.Item>
2016
- <QuickReply.Item>Account</QuickReply.Item>
2017
- </QuickReply>
2018
-
2019
- {/* With icon */}
2020
- <QuickReply aria-label="Actions">
2021
- <QuickReply.Item icon={<MessageCircle />}>Contact us</QuickReply.Item>
2022
- <QuickReply.Item icon={<Package />}>Track order</QuickReply.Item>
2023
- </QuickReply>
2024
- ```
2025
-
2026
- | Prop (QuickReply) | Type | Default | Description |
2027
- |---|---|---|---|
2028
- | layout | `'scroll' \| 'wrap'` | `'scroll'` | Chip layout mode |
2029
- | variant | `'outline' \| 'filled' \| 'ghost'` | `'outline'` | Visual style |
2030
- | color | `'default' \| 'primary'` | `'default'` | Color theme |
2031
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Chip size |
2032
- | radius | `'md' \| 'lg' \| 'full'` | `'full'` | Border radius |
2033
- | gap | `'sm' \| 'default' \| 'lg'` | `'default'` | Gap between chips |
2034
-
2035
- | Prop (QuickReply.Item) | Type | Default | Description |
2036
- |---|---|---|---|
2037
- | icon | `ReactNode` | — | Leading icon |
2038
- | asChild | `boolean` | `false` | Compose with custom element (Radix Slot) |
2039
- | disabled | `boolean` | `false` | Disable the chip |
2040
- | onClick | `() => void` | — | Click callback |
2041
-
2042
- ---
2043
-
2044
- ### ChatInput
2045
-
2046
- ```tsx
2047
- import { ChatInput } from '@7onic-ui/react'
2048
-
2049
- {/* Basic uncontrolled */}
2050
- <ChatInput onSubmit={(value) => console.log(value)}>
2051
- <ChatInput.Field placeholder="Ask me anything..." />
2052
- <ChatInput.Submit />
2053
- </ChatInput>
2054
-
2055
- {/* Controlled mode */}
2056
- const [value, setValue] = useState('')
2057
- <ChatInput onSubmit={(v) => { handleSend(v); setValue('') }}>
2058
- <ChatInput.Field
2059
- value={value}
2060
- onChange={(e) => setValue(e.target.value)}
2061
- placeholder="Ask me anything..."
2062
- />
2063
- <ChatInput.Submit />
2064
- </ChatInput>
2065
-
2066
- {/* With loading state + stop */}
2067
- <ChatInput onSubmit={handleSubmit}>
2068
- <ChatInput.Field placeholder="Ask me anything..." />
2069
- <ChatInput.Submit
2070
- loading={isLoading}
2071
- onStop={() => abortController.abort()}
2072
- />
2073
- </ChatInput>
2074
-
2075
- {/* Character count */}
2076
- <ChatInput onSubmit={(value) => console.log(value)}>
2077
- <ChatInput.Field placeholder="Ask me anything..." showCount maxLength={500} />
2078
- <ChatInput.Submit />
2079
- </ChatInput>
2080
-
2081
- {/* Filled variant, large, custom radius */}
2082
- <ChatInput variant="filled" size="lg" radius="2xl" onSubmit={(v) => console.log(v)}>
2083
- <ChatInput.Field placeholder="Ask me anything..." maxRows={6} />
2084
- <ChatInput.Submit />
2085
- </ChatInput>
2086
-
2087
- {/* Inline layout (single-line field + button side by side) */}
2088
- <ChatInput layout="inline" radius="full" onSubmit={(value) => console.log(value)}>
2089
- <ChatInput.Field placeholder="Message..." />
2090
- <ChatInput.Submit />
2091
- </ChatInput>
2092
-
2093
- {/* Inline with custom button radius */}
2094
- <ChatInput layout="inline" radius="xl" onSubmit={handleSubmit}>
2095
- <ChatInput.Field placeholder="Message..." />
2096
- <ChatInput.Submit buttonRadius="full" loading={isLoading} onStop={handleStop} />
2097
- </ChatInput>
2098
- ```
2099
-
2100
- | Prop (ChatInput) | Type | Default | Description |
2101
- |---|---|---|---|
2102
- | variant | `'outline' \| 'filled'` | `'outline'` | Visual style |
2103
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale |
2104
- | radius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Corner radius (`'full'` available in inline layout) |
2105
- | color | `'default' \| 'primary'` | `'default'` | Submit button color |
2106
- | layout | `'default' \| 'inline'` | `'default'` | `'inline'` renders field and button side by side |
2107
- | disabled | `boolean` | `false` | Disable input and submit |
2108
- | onSubmit | `(value: string) => void` | — | Submit callback |
2109
-
2110
- | Prop (ChatInput.Field) | Type | Default | Description |
2111
- |---|---|---|---|
2112
- | maxRows | `number` | `8` | Max rows before scrolling |
2113
- | showCount | `boolean` | `false` | Show character counter (default layout only) |
2114
- | maxLength | `number` | — | Max characters |
2115
- | placeholder | `string` | — | Placeholder text |
2116
-
2117
- | Prop (ChatInput.Submit) | Type | Default | Description |
2118
- |---|---|---|---|
2119
- | loading | `boolean` | `false` | Switch to stop icon — button stays enabled |
2120
- | onStop | `() => void` | — | Called on click when loading |
2121
- | buttonRadius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | — | Override button radius (default: auto from container radius) |
2122
- | children | `ReactNode` | — | Custom icon (default: send arrow) |
2123
-
2124
- ### ChatMessage
2125
-
2126
- ```tsx
2127
- import { ChatMessage } from '@7onic-ui/react'
2128
-
2129
- {/* Assistant message */}
2130
- <ChatMessage role="assistant">
2131
- <ChatMessage.Avatar />
2132
- <div className="flex flex-col gap-1">
2133
- <ChatMessage.Content>How can I help you today?</ChatMessage.Content>
2134
- <ChatMessage.Footer timestamp="12:34" />
2135
- </div>
2136
- </ChatMessage>
2137
-
2138
- {/* User message with status */}
2139
- <ChatMessage role="user">
2140
- <div className="flex flex-col gap-1 items-end">
2141
- <ChatMessage.Content>Thank you for your help!</ChatMessage.Content>
2142
- <ChatMessage.Footer timestamp="12:34" status="read" />
2143
- </div>
2144
- </ChatMessage>
2145
-
2146
- {/* Typing animation */}
2147
- <ChatMessage role="assistant" typing>
2148
- <ChatMessage.Avatar />
2149
- <ChatMessage.Content />
2150
- </ChatMessage>
2151
-
2152
- {/* Custom avatar + hover actions */}
2153
- <ChatMessage
2154
- role="assistant"
2155
- actions={<button aria-label="Copy">...</button>}
2156
- >
2157
- <ChatMessage.Avatar initials="AI" />
2158
- <div className="flex flex-col gap-1">
2159
- <ChatMessage.Content>Response text here.</ChatMessage.Content>
2160
- <ChatMessage.Footer timestamp="12:34" />
2161
- </div>
2162
- </ChatMessage>
2163
-
2164
- {/* User bubble with muted color (common pattern) */}
2165
- <ChatMessage role="user" color="muted">
2166
- <div className="flex flex-col gap-1 items-end">
2167
- <ChatMessage.Content>Message text</ChatMessage.Content>
2168
- <ChatMessage.Footer timestamp="12:34" status="read" />
2169
- </div>
2170
- </ChatMessage>
2171
-
2172
- {/* History (flat) layout — full-width, no footer */}
2173
- <div className="flex flex-col gap-3">
2174
- <ChatMessage role="assistant" variant="flat">
2175
- <ChatMessage.Avatar />
2176
- <ChatMessage.Content className="w-full">Here is the answer.</ChatMessage.Content>
2177
- </ChatMessage>
2178
- <ChatMessage role="user" variant="flat" color="muted">
2179
- <ChatMessage.Content className="w-full">Thanks!</ChatMessage.Content>
2180
- </ChatMessage>
2181
- </div>
2182
- ```
2183
-
2184
- | Prop (ChatMessage) | Type | Default | Description |
2185
- |---|---|---|---|
2186
- | role | `'assistant' \| 'user'` | `'assistant'` | Aligns left (assistant) or right (user) |
2187
- | variant | `'bubble' \| 'flat'` | `'bubble'` | Bubble style with background/border, or flat with no fill |
2188
- | color | `'default' \| 'muted' \| 'primary' \| 'dark'` | `'default'` | Bubble background color |
2189
- | size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale affecting padding and font |
2190
- | radius | `'md' \| 'lg' \| 'xl' \| '2xl'` | `'2xl'` | Bubble corner radius |
2191
- | tail | `boolean` | `true` | Asymmetric tail corner (sharp on avatar side) — bubble only |
2192
- | avatarSize | `'sm' \| 'md' \| 'lg'` | — | Avatar size — also adjusts gap between avatar and bubble |
2193
- | typing | `boolean` | `false` | Show animated typing dots inside Content |
2194
- | actions | `ReactNode` | — | Hover-reveal action buttons (copy, react, etc.) |
2195
-
2196
- | Prop (ChatMessage.Avatar) | Type | Default | Description |
2197
- |---|---|---|---|
2198
- | size | `'sm' \| 'md' \| 'lg'` | `'md'` | Avatar size: 24/28/32px |
2199
- | src | `string` | — | Avatar image URL |
2200
- | alt | `string` | `'Avatar'` | Alt text |
2201
- | initials | `string` | — | 1–2 character initials (fallback) |
2202
- | icon | `ReactNode` | — | Custom icon (fallback) |
2203
-
2204
- | Prop (ChatMessage.Footer) | Type | Default | Description |
2205
- |---|---|---|---|
2206
- | timestamp | `string` | — | Pre-formatted time string |
2207
- | status | `'sending' \| 'sent' \| 'read' \| 'error' \| ReactNode` | — | Delivery status (built-in presets or custom node) |
2208
- | size | `'sm' \| 'default' \| 'lg'` | — | Size override (defaults to context value from root) |
465
+ - **When in doubt, check the documentation** — if token usage is unclear, refer to the official docs:
466
+ - Token pages: `https://7onic.design/design-tokens/{name}` (e.g., `/design-tokens/colors`, `/design-tokens/spacing`)
467
+ - Do not guess token values or usage — verify from the documentation first
2209
468
 
2210
469
  ---
2211
470
 
@@ -2215,4 +474,4 @@ import { ChatMessage } from '@7onic-ui/react'
2215
474
  - npm (tokens): https://npmjs.com/package/@7onic-ui/tokens
2216
475
  - npm (react): https://npmjs.com/package/@7onic-ui/react
2217
476
  - GitHub: https://github.com/itonys/7onic
2218
- - Tokens-only AI guide: https://7onic.design/llms.txt
477
+ - Full AI guide (tokens + components): https://7onic.design/llms-full.txt