@7onic-ui/react 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -17
- package/llms.txt +544 -512
- package/package.json +4 -2
package/llms.txt
CHANGED
|
@@ -8,6 +8,7 @@ Single source of truth — design tokens to code. Use this to build any React se
|
|
|
8
8
|
- Documentation: https://7onic.design
|
|
9
9
|
- npm: `@7onic-ui/react` (components) + `@7onic-ui/tokens` (design tokens)
|
|
10
10
|
- For tokens-only guide, see: https://7onic.design/llms.txt
|
|
11
|
+
- MCP server (token search / component catalog / validate_code): https://7onic.design/components/mcp — on Claude Code: `claude plugin marketplace add itonys/7onic && claude plugin install 7onic-design@7onic`
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -27,92 +28,29 @@ Before writing any code, present this checklist and wait for answers:
|
|
|
27
28
|
|
|
28
29
|
**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.
|
|
29
30
|
|
|
30
|
-
### Step 2:
|
|
31
|
+
### Step 2: Install / Setup
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
⚠️ **DO NOT GUESS** — install procedures evolve with each Tailwind / Next / Vite version. Before writing any code, AI **MUST** fetch the live pages below and follow their instructions verbatim:
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
npm install @7onic-ui/react @7onic-ui/tokens lucide-react
|
|
37
|
-
```
|
|
38
|
-
> Check package.json first. If packages are already listed in dependencies, skip this step.
|
|
39
|
-
|
|
40
|
-
**2-2. Create or update globals.css with token imports:**
|
|
41
|
-
|
|
42
|
-
**How to detect Tailwind version:**
|
|
43
|
-
- `tailwind.config.js` (or `.ts`) exists → **v3**
|
|
44
|
-
- No config file → **v4** (uses CSS-based configuration)
|
|
45
|
-
|
|
46
|
-
**New project (Tailwind v4):**
|
|
47
|
-
```css
|
|
48
|
-
/* globals.css (Next.js) or src/index.css (Vite) — ALL imports are required, do not skip any */
|
|
49
|
-
@import "tailwindcss";
|
|
50
|
-
@import "@7onic-ui/tokens/css/variables.css";
|
|
51
|
-
@import "@7onic-ui/tokens/css/themes/light.css";
|
|
52
|
-
@import "@7onic-ui/tokens/css/themes/dark.css"; /* omit ONLY if dark mode = no */
|
|
53
|
-
@import "@7onic-ui/tokens/tailwind/v4-theme.css";
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Existing project with Tailwind v3** (detect from tailwind.config.js):
|
|
57
|
-
```css
|
|
58
|
-
/* globals.css */
|
|
59
|
-
@import '@7onic-ui/tokens/css/variables.css';
|
|
60
|
-
@import '@7onic-ui/tokens/css/themes/light.css';
|
|
61
|
-
@import '@7onic-ui/tokens/css/themes/dark.css'; /* omit ONLY if dark mode = no */
|
|
62
|
-
@tailwind base;
|
|
63
|
-
@tailwind components;
|
|
64
|
-
@tailwind utilities;
|
|
65
|
-
```
|
|
66
|
-
```js
|
|
67
|
-
// tailwind.config.js — add preset
|
|
68
|
-
const preset = require('@7onic-ui/tokens/tailwind/v3-preset')
|
|
69
|
-
module.exports = {
|
|
70
|
-
presets: [preset],
|
|
71
|
-
content: [
|
|
72
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
73
|
-
'./node_modules/@7onic-ui/react/dist/**/*.{js,mjs}',
|
|
74
|
-
],
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**2-3. Vite users only — clean up `src/index.css`:**
|
|
35
|
+
- **Official install page (SSOT)**: https://7onic.design/components/installation
|
|
36
|
+
- **Tailwind CSS official**: https://tailwindcss.com/docs/installation
|
|
79
37
|
|
|
80
|
-
|
|
38
|
+
The install instructions are intentionally **not duplicated in this file**. Setup details (packages, `tailwind.config.js`, `vite.config.ts`, `postcss.config.mjs`, `globals.css` patterns, framework default cleanup, layer wrap tips, etc.) are version-sensitive and change frequently — always defer to the live documentation above.
|
|
81
39
|
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- `button { background-color: #1a1a1a; ... }` block and all other element-level rules (`a { color: #646cff }`, etc.)
|
|
87
|
-
- `@media (prefers-color-scheme: light) { ... }` block
|
|
40
|
+
Apply user's answers from Step 1 after the install page steps are complete:
|
|
41
|
+
- Dark mode = yes → implement dark mode toggle (see below in this file)
|
|
42
|
+
- Custom font → load via `next/font/google` (Next.js) or Fontsource / CDN (Vite)
|
|
43
|
+
- Japanese / Korean locale → load Noto Sans JP / KR
|
|
88
44
|
|
|
89
|
-
|
|
45
|
+
⛔ **Do NOT proceed to Step 3 until install page setup is verified.**
|
|
90
46
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- Dark mode = yes → implement dark mode toggle (see below)
|
|
94
|
-
- Custom font → load font:
|
|
95
|
-
- **Next.js**: use `next/font/google`
|
|
96
|
-
- **Vite / Remix**: use Fontsource (`npm install @fontsource/inter`, then `import '@fontsource/inter/400.css'` in `src/main.tsx`) or Google Fonts CDN
|
|
97
|
-
- Then set `--font-family-sans` in CSS
|
|
98
|
-
- Locale includes Japanese → load Noto Sans JP font
|
|
99
|
-
- Fontsource: `npm install @fontsource/noto-sans-jp` → import in `src/main.tsx` (Vite) or `app/layout.tsx` (Next.js)
|
|
100
|
-
- CDN: Google Fonts link tag in `index.html`
|
|
101
|
-
- Locale includes Korean → load Noto Sans KR font
|
|
102
|
-
- Fontsource: `npm install @fontsource/noto-sans-kr` → import in `src/main.tsx` (Vite) or `app/layout.tsx` (Next.js)
|
|
103
|
-
- CDN: Google Fonts link tag in `index.html`
|
|
104
|
-
|
|
105
|
-
**2-5. Verify setup is complete before writing any UI code:**
|
|
106
|
-
- [ ] Packages installed (@7onic-ui/react, @7onic-ui/tokens, lucide-react)
|
|
107
|
-
- [ ] globals.css / src/index.css has ALL required imports in correct order
|
|
108
|
-
- [ ] (Vite only) Vite template CSS blocks deleted from src/index.css
|
|
109
|
-
- [ ] Dark mode toggle (if selected)
|
|
110
|
-
- [ ] Font loaded (if custom)
|
|
111
|
-
- [ ] CJK fonts loaded (if applicable)
|
|
47
|
+
### Icon Import Pattern (lucide-react)
|
|
112
48
|
|
|
113
|
-
|
|
49
|
+
⚠️ **`lucide-react` is NOT a 7onic dependency.** 7onic components themselves use inline SVG. Install separately if you want to use lucide icons in your app code:
|
|
114
50
|
|
|
115
|
-
|
|
51
|
+
```bash
|
|
52
|
+
npm install lucide-react
|
|
53
|
+
```
|
|
116
54
|
|
|
117
55
|
```tsx
|
|
118
56
|
// ✅ Official pattern — no suffix
|
|
@@ -131,7 +69,9 @@ import { Badge as BadgeIcon } from 'lucide-react'
|
|
|
131
69
|
Place `<Toaster />` once in your root layout file. Without this, `toast()` calls will not render.
|
|
132
70
|
|
|
133
71
|
```tsx
|
|
134
|
-
import { Toaster } from '@7onic-ui/react'
|
|
72
|
+
import { Toaster } from '@7onic-ui/react'
|
|
73
|
+
|
|
74
|
+
// In your root layout (e.g., app/layout.tsx)
|
|
135
75
|
<body>
|
|
136
76
|
{children}
|
|
137
77
|
<Toaster position="bottom-right" />
|
|
@@ -248,7 +188,9 @@ style={{ color: '#333', padding: '20px' }}
|
|
|
248
188
|
w-4 h-4, w-5 h-5 → icon-sm, icon-md
|
|
249
189
|
|
|
250
190
|
// ❌ Radix direct import
|
|
251
|
-
import * as Dialog from '@radix-ui/react-dialog' → import { Badge, Button, Card, Input, Table } from '@7onic-ui/react'
|
|
191
|
+
import * as Dialog from '@radix-ui/react-dialog' → import { Badge, Button, Card, Input, Table } from '@7onic-ui/react'
|
|
192
|
+
|
|
193
|
+
// ❌ Unnecessary component wrappers
|
|
252
194
|
function MyButton(props) { return <Button {...props} /> } → Use Button directly
|
|
253
195
|
```
|
|
254
196
|
|
|
@@ -402,7 +344,9 @@ import { Button, Card, Input, toast } from '@7onic-ui/react'
|
|
|
402
344
|
All components use Named imports. Works in every environment (Next.js App Router RSC, Client Components, Pages Router, Vite, CRA, CJS).
|
|
403
345
|
|
|
404
346
|
```tsx
|
|
405
|
-
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@7onic-ui/react'
|
|
347
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@7onic-ui/react'
|
|
348
|
+
|
|
349
|
+
<Card>
|
|
406
350
|
<CardHeader>
|
|
407
351
|
<CardTitle>Title</CardTitle>
|
|
408
352
|
<CardDescription>Description</CardDescription>
|
|
@@ -426,7 +370,7 @@ Badge, Button, ButtonGroup, Checkbox, Divider, IconButton, Input, Progress, Skel
|
|
|
426
370
|
|
|
427
371
|
---
|
|
428
372
|
|
|
429
|
-
# ═══ SECTION 3: ALL COMPONENTS (
|
|
373
|
+
# ═══ SECTION 3: ALL COMPONENTS (41) ═══
|
|
430
374
|
|
|
431
375
|
---
|
|
432
376
|
|
|
@@ -435,7 +379,9 @@ Badge, Button, ButtonGroup, Checkbox, Divider, IconButton, Input, Progress, Skel
|
|
|
435
379
|
### Button
|
|
436
380
|
|
|
437
381
|
```tsx
|
|
438
|
-
import { Button } from '@7onic-ui/react'
|
|
382
|
+
import { Button } from '@7onic-ui/react'
|
|
383
|
+
|
|
384
|
+
<Button variant="solid" color="primary" size="default">Submit</Button>
|
|
439
385
|
<Button variant="outline" color="default" leftIcon={<Icon />}>Cancel</Button>
|
|
440
386
|
<Button loading>Processing...</Button>
|
|
441
387
|
<Button variant="link" color="primary">Learn more</Button>
|
|
@@ -464,7 +410,9 @@ import { Button } from '@7onic-ui/react'<Button variant="solid" color="primary"
|
|
|
464
410
|
### IconButton
|
|
465
411
|
|
|
466
412
|
```tsx
|
|
467
|
-
import { IconButton } from '@7onic-ui/react'
|
|
413
|
+
import { IconButton } from '@7onic-ui/react'
|
|
414
|
+
|
|
415
|
+
<IconButton variant="ghost" size="default" aria-label="Settings">
|
|
468
416
|
<SettingsIcon />
|
|
469
417
|
</IconButton>
|
|
470
418
|
```
|
|
@@ -487,7 +435,9 @@ import { IconButton } from '@7onic-ui/react'<IconButton variant="ghost" size="de
|
|
|
487
435
|
### ButtonGroup
|
|
488
436
|
|
|
489
437
|
```tsx
|
|
490
|
-
import { Button, ButtonGroup } from '@7onic-ui/react'
|
|
438
|
+
import { Button, ButtonGroup } from '@7onic-ui/react'
|
|
439
|
+
|
|
440
|
+
<ButtonGroup variant="outline" size="default" attached>
|
|
491
441
|
<Button>Left</Button>
|
|
492
442
|
<Button>Center</Button>
|
|
493
443
|
<Button>Right</Button>
|
|
@@ -511,7 +461,9 @@ Provides context — child Buttons inherit variant/size/radius automatically.
|
|
|
511
461
|
### Input
|
|
512
462
|
|
|
513
463
|
```tsx
|
|
514
|
-
import { Input } from '@7onic-ui/react'
|
|
464
|
+
import { Input } from '@7onic-ui/react'
|
|
465
|
+
|
|
466
|
+
<Input placeholder="Email" size="default" />
|
|
515
467
|
<Input variant="filled" leftIcon={<SearchIcon />} />
|
|
516
468
|
<Input error rightIcon={<AlertIcon />} />
|
|
517
469
|
```
|
|
@@ -533,7 +485,9 @@ import { Input } from '@7onic-ui/react'<Input placeholder="Email" size="default"
|
|
|
533
485
|
### Textarea
|
|
534
486
|
|
|
535
487
|
```tsx
|
|
536
|
-
import { Textarea } from '@7onic-ui/react'
|
|
488
|
+
import { Textarea } from '@7onic-ui/react'
|
|
489
|
+
|
|
490
|
+
<Textarea placeholder="Message" rows={4} resize="vertical" />
|
|
537
491
|
```
|
|
538
492
|
|
|
539
493
|
| Prop | Type | Default | Description |
|
|
@@ -551,7 +505,9 @@ import { Textarea } from '@7onic-ui/react'<Textarea placeholder="Message" rows={
|
|
|
551
505
|
### Select
|
|
552
506
|
|
|
553
507
|
```tsx
|
|
554
|
-
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@7onic-ui/react'
|
|
508
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@7onic-ui/react'
|
|
509
|
+
|
|
510
|
+
<Select>
|
|
555
511
|
<SelectTrigger>
|
|
556
512
|
<SelectValue placeholder="Choose option" />
|
|
557
513
|
</SelectTrigger>
|
|
@@ -581,7 +537,9 @@ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrig
|
|
|
581
537
|
### DropdownMenu
|
|
582
538
|
|
|
583
539
|
```tsx
|
|
584
|
-
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@7onic-ui/react'
|
|
540
|
+
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@7onic-ui/react'
|
|
541
|
+
|
|
542
|
+
<DropdownMenu>
|
|
585
543
|
<DropdownMenuTrigger asChild>
|
|
586
544
|
<Button variant="outline">Options</Button>
|
|
587
545
|
</DropdownMenuTrigger>
|
|
@@ -601,14 +559,16 @@ import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMe
|
|
|
601
559
|
| flush | `boolean` | `false` | Full-width items (no padding) |
|
|
602
560
|
| sideOffset | `number` | `4` | Gap from trigger |
|
|
603
561
|
|
|
604
|
-
**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
|
|
562
|
+
**Sub-components:** DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Item, DropdownMenu.CheckboxItem, DropdownMenu.RadioGroup, DropdownMenu.RadioItem, DropdownMenu.Label, DropdownMenu.Separator, DropdownMenu.Group, DropdownMenu.Sub, DropdownMenu.SubTrigger, DropdownMenu.SubContent, DropdownMenu.Shortcut
|
|
605
563
|
|
|
606
564
|
---
|
|
607
565
|
|
|
608
566
|
### Checkbox
|
|
609
567
|
|
|
610
568
|
```tsx
|
|
611
|
-
import { Checkbox } from '@7onic-ui/react'
|
|
569
|
+
import { Checkbox } from '@7onic-ui/react'
|
|
570
|
+
|
|
571
|
+
<Checkbox label="Accept terms" />
|
|
612
572
|
<Checkbox size="lg" color="primary" checked />
|
|
613
573
|
<Checkbox checked="indeterminate" />
|
|
614
574
|
```
|
|
@@ -630,7 +590,9 @@ import { Checkbox } from '@7onic-ui/react'<Checkbox label="Accept terms" />
|
|
|
630
590
|
### RadioGroup
|
|
631
591
|
|
|
632
592
|
```tsx
|
|
633
|
-
import { RadioGroup, RadioGroupItem } from '@7onic-ui/react'
|
|
593
|
+
import { RadioGroup, RadioGroupItem } from '@7onic-ui/react'
|
|
594
|
+
|
|
595
|
+
<RadioGroup defaultValue="a">
|
|
634
596
|
<RadioGroupItem value="a" label="Option A" />
|
|
635
597
|
<RadioGroupItem value="b" label="Option B" />
|
|
636
598
|
<RadioGroupItem value="c" label="Option C" disabled />
|
|
@@ -654,7 +616,9 @@ import { RadioGroup, RadioGroupItem } from '@7onic-ui/react'<RadioGroup defaultV
|
|
|
654
616
|
### Switch
|
|
655
617
|
|
|
656
618
|
```tsx
|
|
657
|
-
import { Switch } from '@7onic-ui/react'
|
|
619
|
+
import { Switch } from '@7onic-ui/react'
|
|
620
|
+
|
|
621
|
+
<Switch label="Notifications" />
|
|
658
622
|
<Switch size="lg" color="primary" defaultChecked />
|
|
659
623
|
<Switch startLabel="Off" endLabel="On" />
|
|
660
624
|
```
|
|
@@ -679,7 +643,9 @@ import { Switch } from '@7onic-ui/react'<Switch label="Notifications" />
|
|
|
679
643
|
### Toggle
|
|
680
644
|
|
|
681
645
|
```tsx
|
|
682
|
-
import { Toggle } from '@7onic-ui/react'
|
|
646
|
+
import { Toggle } from '@7onic-ui/react'
|
|
647
|
+
|
|
648
|
+
<Toggle variant="default" aria-label="Bold">
|
|
683
649
|
<BoldIcon />
|
|
684
650
|
</Toggle>
|
|
685
651
|
<Toggle variant="outline" pressed>Active</Toggle>
|
|
@@ -702,7 +668,9 @@ import { Toggle } from '@7onic-ui/react'<Toggle variant="default" aria-label="Bo
|
|
|
702
668
|
### ToggleGroup
|
|
703
669
|
|
|
704
670
|
```tsx
|
|
705
|
-
import { ToggleGroup, ToggleGroupItem } from '@7onic-ui/react'
|
|
671
|
+
import { ToggleGroup, ToggleGroupItem } from '@7onic-ui/react'
|
|
672
|
+
|
|
673
|
+
<ToggleGroup type="single" defaultValue="center">
|
|
706
674
|
<ToggleGroupItem value="left"><AlignLeftIcon /></ToggleGroupItem>
|
|
707
675
|
<ToggleGroupItem value="center"><AlignCenterIcon /></ToggleGroupItem>
|
|
708
676
|
<ToggleGroupItem value="right"><AlignRightIcon /></ToggleGroupItem>
|
|
@@ -728,7 +696,9 @@ import { ToggleGroup, ToggleGroupItem } from '@7onic-ui/react'<ToggleGroup type=
|
|
|
728
696
|
### Segmented
|
|
729
697
|
|
|
730
698
|
```tsx
|
|
731
|
-
import { Segmented, SegmentedItem } from '@7onic-ui/react'
|
|
699
|
+
import { Segmented, SegmentedItem } from '@7onic-ui/react'
|
|
700
|
+
|
|
701
|
+
<Segmented defaultValue="all">
|
|
732
702
|
<SegmentedItem value="all">All</SegmentedItem>
|
|
733
703
|
<SegmentedItem value="active">Active</SegmentedItem>
|
|
734
704
|
<SegmentedItem value="inactive">Inactive</SegmentedItem>
|
|
@@ -753,7 +723,9 @@ import { Segmented, SegmentedItem } from '@7onic-ui/react'<Segmented defaultValu
|
|
|
753
723
|
### Slider
|
|
754
724
|
|
|
755
725
|
```tsx
|
|
756
|
-
import { Slider } from '@7onic-ui/react'
|
|
726
|
+
import { Slider } from '@7onic-ui/react'
|
|
727
|
+
|
|
728
|
+
<Slider defaultValue={[50]} showTooltip="auto" />
|
|
757
729
|
<Slider defaultValue={[20, 80]} color="primary" />
|
|
758
730
|
```
|
|
759
731
|
|
|
@@ -778,7 +750,9 @@ import { Slider } from '@7onic-ui/react'<Slider defaultValue={[50]} showTooltip=
|
|
|
778
750
|
### Field (Form Wrapper)
|
|
779
751
|
|
|
780
752
|
```tsx
|
|
781
|
-
import { Field, FieldCharCount, FieldError, FieldLabel, Input, Textarea } from '@7onic-ui/react'
|
|
753
|
+
import { Field, FieldCharCount, FieldError, FieldLabel, Input, Textarea } from '@7onic-ui/react'
|
|
754
|
+
|
|
755
|
+
<Field error="Invalid email">
|
|
782
756
|
<FieldLabel required>Email</FieldLabel>
|
|
783
757
|
<Input placeholder="you@example.com" />
|
|
784
758
|
<FieldError />
|
|
@@ -807,7 +781,9 @@ import { Field, FieldCharCount, FieldError, FieldLabel, Input, Textarea } from '
|
|
|
807
781
|
### Avatar
|
|
808
782
|
|
|
809
783
|
```tsx
|
|
810
|
-
import { Avatar, AvatarFallback, AvatarGroup, AvatarImage } from '@7onic-ui/react'
|
|
784
|
+
import { Avatar, AvatarFallback, AvatarGroup, AvatarImage } from '@7onic-ui/react'
|
|
785
|
+
|
|
786
|
+
<Avatar size="default">
|
|
811
787
|
<AvatarImage src="/photo.jpg" alt="User" />
|
|
812
788
|
<AvatarFallback name="John Doe" colorized />
|
|
813
789
|
</Avatar>
|
|
@@ -845,7 +821,9 @@ import { Avatar, AvatarFallback, AvatarGroup, AvatarImage } from '@7onic-ui/reac
|
|
|
845
821
|
### Badge
|
|
846
822
|
|
|
847
823
|
```tsx
|
|
848
|
-
import { Badge } from '@7onic-ui/react'
|
|
824
|
+
import { Badge } from '@7onic-ui/react'
|
|
825
|
+
|
|
826
|
+
<Badge variant="solid" color="primary">New</Badge>
|
|
849
827
|
<Badge variant="subtle" color="success" dot>Active</Badge>
|
|
850
828
|
<Badge variant="outline" removable onRemove={() => {}}>Tag</Badge>
|
|
851
829
|
```
|
|
@@ -855,7 +833,7 @@ import { Badge } from '@7onic-ui/react'<Badge variant="solid" color="primary">Ne
|
|
|
855
833
|
| variant | `'solid' \| 'subtle' \| 'outline'` | `'subtle'` | Visual style |
|
|
856
834
|
| color | `'default' \| 'primary' \| 'success' \| 'warning' \| 'error' \| 'info'` | `'default'` | Color scheme |
|
|
857
835
|
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Badge size |
|
|
858
|
-
| radius | `'sm' \| '
|
|
836
|
+
| radius | `'sm' \| 'base' \| 'md' \| 'lg' \| 'full'` | `'full'` | Border radius |
|
|
859
837
|
| icon | `ReactNode` | — | Leading icon |
|
|
860
838
|
| dot | `boolean` | `false` | Status dot indicator |
|
|
861
839
|
| removable | `boolean` | `false` | Shows remove button |
|
|
@@ -867,7 +845,9 @@ import { Badge } from '@7onic-ui/react'<Badge variant="solid" color="primary">Ne
|
|
|
867
845
|
### Card
|
|
868
846
|
|
|
869
847
|
```tsx
|
|
870
|
-
import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardImage, CardTitle, IconButton } from '@7onic-ui/react'
|
|
848
|
+
import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardImage, CardTitle, IconButton } from '@7onic-ui/react'
|
|
849
|
+
|
|
850
|
+
<Card variant="default" interactive>
|
|
871
851
|
<CardImage src="/cover.jpg" overlay overlayOpacity={40} />
|
|
872
852
|
<CardHeader>
|
|
873
853
|
<CardTitle icon={<StarIcon />}>Featured</CardTitle>
|
|
@@ -900,7 +880,9 @@ import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader,
|
|
|
900
880
|
### Table
|
|
901
881
|
|
|
902
882
|
```tsx
|
|
903
|
-
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@7onic-ui/react'
|
|
883
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@7onic-ui/react'
|
|
884
|
+
|
|
885
|
+
<Table variant="default" stickyHeader>
|
|
904
886
|
<TableHeader>
|
|
905
887
|
<TableRow>
|
|
906
888
|
<TableHead sortable sortDirection="asc" onSort={() => {}}>Name</TableHead>
|
|
@@ -947,7 +929,9 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
|
|
|
947
929
|
### Tabs
|
|
948
930
|
|
|
949
931
|
```tsx
|
|
950
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@7onic-ui/react'
|
|
932
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@7onic-ui/react'
|
|
933
|
+
|
|
934
|
+
<Tabs defaultValue="tab1">
|
|
951
935
|
<TabsList variant="line" size="default">
|
|
952
936
|
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
|
|
953
937
|
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
|
|
@@ -972,7 +956,9 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@7onic-ui/react'<Tabs
|
|
|
972
956
|
### Accordion
|
|
973
957
|
|
|
974
958
|
```tsx
|
|
975
|
-
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@7onic-ui/react'
|
|
959
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@7onic-ui/react'
|
|
960
|
+
|
|
961
|
+
<Accordion type="single" collapsible defaultValue="item-1">
|
|
976
962
|
<AccordionItem value="item-1">
|
|
977
963
|
<AccordionTrigger>Section 1</AccordionTrigger>
|
|
978
964
|
<AccordionContent>Content 1</AccordionContent>
|
|
@@ -999,7 +985,9 @@ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@7
|
|
|
999
985
|
### Divider
|
|
1000
986
|
|
|
1001
987
|
```tsx
|
|
1002
|
-
import { Divider } from '@7onic-ui/react'
|
|
988
|
+
import { Divider } from '@7onic-ui/react'
|
|
989
|
+
|
|
990
|
+
<Divider />
|
|
1003
991
|
<Divider variant="dashed" color="muted" />
|
|
1004
992
|
<Divider label="OR" labelPosition="center" />
|
|
1005
993
|
<Divider orientation="vertical" />
|
|
@@ -1021,7 +1009,9 @@ import { Divider } from '@7onic-ui/react'<Divider />
|
|
|
1021
1009
|
### Modal
|
|
1022
1010
|
|
|
1023
1011
|
```tsx
|
|
1024
|
-
import { Button, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger } from '@7onic-ui/react'
|
|
1012
|
+
import { Button, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger } from '@7onic-ui/react'
|
|
1013
|
+
|
|
1014
|
+
<Modal>
|
|
1025
1015
|
<ModalTrigger asChild>
|
|
1026
1016
|
<Button>Open Modal</Button>
|
|
1027
1017
|
</ModalTrigger>
|
|
@@ -1057,7 +1047,9 @@ import { Button, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, M
|
|
|
1057
1047
|
### AlertModal
|
|
1058
1048
|
|
|
1059
1049
|
```tsx
|
|
1060
|
-
import { AlertModal, AlertModalAction, AlertModalBody, AlertModalCancel, AlertModalContent, AlertModalDescription, AlertModalFooter, AlertModalHeader, AlertModalOverlay, AlertModalPortal, AlertModalTitle, AlertModalTrigger, Button } from '@7onic-ui/react'
|
|
1050
|
+
import { AlertModal, AlertModalAction, AlertModalBody, AlertModalCancel, AlertModalContent, AlertModalDescription, AlertModalFooter, AlertModalHeader, AlertModalOverlay, AlertModalPortal, AlertModalTitle, AlertModalTrigger, Button } from '@7onic-ui/react'
|
|
1051
|
+
|
|
1052
|
+
<AlertModal>
|
|
1061
1053
|
<AlertModalTrigger asChild>
|
|
1062
1054
|
<Button color="destructive">Delete</Button>
|
|
1063
1055
|
</AlertModalTrigger>
|
|
@@ -1091,7 +1083,9 @@ import { AlertModal, AlertModalAction, AlertModalBody, AlertModalCancel, AlertMo
|
|
|
1091
1083
|
### Drawer
|
|
1092
1084
|
|
|
1093
1085
|
```tsx
|
|
1094
|
-
import { Button, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger } from '@7onic-ui/react'
|
|
1086
|
+
import { Button, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger } from '@7onic-ui/react'
|
|
1087
|
+
|
|
1088
|
+
<Drawer>
|
|
1095
1089
|
<DrawerTrigger asChild>
|
|
1096
1090
|
<Button>Open Drawer</Button>
|
|
1097
1091
|
</DrawerTrigger>
|
|
@@ -1123,7 +1117,9 @@ import { Button, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerFooter, D
|
|
|
1123
1117
|
### Tooltip
|
|
1124
1118
|
|
|
1125
1119
|
```tsx
|
|
1126
|
-
import { Button, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger } from '@7onic-ui/react'
|
|
1120
|
+
import { Button, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger } from '@7onic-ui/react'
|
|
1121
|
+
|
|
1122
|
+
<TooltipProvider>
|
|
1127
1123
|
<Tooltip>
|
|
1128
1124
|
<TooltipTrigger asChild>
|
|
1129
1125
|
<Button>Hover me</Button>
|
|
@@ -1158,7 +1154,9 @@ import { Button, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipPr
|
|
|
1158
1154
|
### Popover
|
|
1159
1155
|
|
|
1160
1156
|
```tsx
|
|
1161
|
-
import { Button, Popover, PopoverArrow, PopoverContent, PopoverPortal, PopoverTrigger } from '@7onic-ui/react'
|
|
1157
|
+
import { Button, Popover, PopoverArrow, PopoverContent, PopoverPortal, PopoverTrigger } from '@7onic-ui/react'
|
|
1158
|
+
|
|
1159
|
+
<Popover>
|
|
1162
1160
|
<PopoverTrigger asChild>
|
|
1163
1161
|
<Button variant="outline">Open</Button>
|
|
1164
1162
|
</PopoverTrigger>
|
|
@@ -1188,7 +1186,9 @@ import { Button, Popover, PopoverArrow, PopoverContent, PopoverPortal, PopoverTr
|
|
|
1188
1186
|
### Alert
|
|
1189
1187
|
|
|
1190
1188
|
```tsx
|
|
1191
|
-
import { Alert, AlertDescription, AlertTitle } from '@7onic-ui/react'
|
|
1189
|
+
import { Alert, AlertDescription, AlertTitle } from '@7onic-ui/react'
|
|
1190
|
+
|
|
1191
|
+
<Alert color="success" closable onClose={() => {}}>
|
|
1192
1192
|
<AlertTitle>Success</AlertTitle>
|
|
1193
1193
|
<AlertDescription>Operation completed.</AlertDescription>
|
|
1194
1194
|
</Alert>
|
|
@@ -1216,7 +1216,9 @@ import { Alert, AlertDescription, AlertTitle } from '@7onic-ui/react'<Alert colo
|
|
|
1216
1216
|
### Toast (Imperative API)
|
|
1217
1217
|
|
|
1218
1218
|
```tsx
|
|
1219
|
-
import { Toaster, toast } from '@7onic-ui/react'
|
|
1219
|
+
import { Toaster, toast } from '@7onic-ui/react'
|
|
1220
|
+
|
|
1221
|
+
// 1. Add Toaster provider to your app layout (once)
|
|
1220
1222
|
<Toaster position="bottom-right" />
|
|
1221
1223
|
|
|
1222
1224
|
// 2. Call toast() anywhere
|
|
@@ -1264,7 +1266,9 @@ toast.dismiss() // Dismiss all
|
|
|
1264
1266
|
### Progress
|
|
1265
1267
|
|
|
1266
1268
|
```tsx
|
|
1267
|
-
import { Progress } from '@7onic-ui/react'
|
|
1269
|
+
import { Progress } from '@7onic-ui/react'
|
|
1270
|
+
|
|
1271
|
+
<Progress value={65} showValue />
|
|
1268
1272
|
<Progress type="circular" value={75} color="primary" />
|
|
1269
1273
|
<Progress variant="striped" animated value={50} />
|
|
1270
1274
|
```
|
|
@@ -1286,7 +1290,9 @@ import { Progress } from '@7onic-ui/react'<Progress value={65} showValue />
|
|
|
1286
1290
|
### Spinner
|
|
1287
1291
|
|
|
1288
1292
|
```tsx
|
|
1289
|
-
import { Spinner } from '@7onic-ui/react'
|
|
1293
|
+
import { Spinner } from '@7onic-ui/react'
|
|
1294
|
+
|
|
1295
|
+
<Spinner />
|
|
1290
1296
|
<Spinner variant="dots" size="lg" color="primary" />
|
|
1291
1297
|
<Spinner variant="bars" speed="slow" />
|
|
1292
1298
|
<Spinner variant="orbit" orbitStyle="morph" />
|
|
@@ -1306,7 +1312,9 @@ import { Spinner } from '@7onic-ui/react'<Spinner />
|
|
|
1306
1312
|
### Skeleton
|
|
1307
1313
|
|
|
1308
1314
|
```tsx
|
|
1309
|
-
import { Skeleton } from '@7onic-ui/react'
|
|
1315
|
+
import { Skeleton } from '@7onic-ui/react'
|
|
1316
|
+
|
|
1317
|
+
<Skeleton variant="text" count={3} />
|
|
1310
1318
|
<Skeleton variant="circular" width={48} height={48} />
|
|
1311
1319
|
<Skeleton variant="rectangular" width="100%" height={200} />
|
|
1312
1320
|
|
|
@@ -1334,7 +1342,9 @@ import { Skeleton } from '@7onic-ui/react'<Skeleton variant="text" count={3} />
|
|
|
1334
1342
|
### Breadcrumb
|
|
1335
1343
|
|
|
1336
1344
|
```tsx
|
|
1337
|
-
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@7onic-ui/react'
|
|
1345
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@7onic-ui/react'
|
|
1346
|
+
|
|
1347
|
+
<Breadcrumb>
|
|
1338
1348
|
<BreadcrumbList>
|
|
1339
1349
|
<BreadcrumbItem>
|
|
1340
1350
|
<BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
@@ -1366,7 +1376,9 @@ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbP
|
|
|
1366
1376
|
### Pagination
|
|
1367
1377
|
|
|
1368
1378
|
```tsx
|
|
1369
|
-
import { Pagination, PaginationContent, PaginationItems, PaginationNext, PaginationPrevious } from '@7onic-ui/react'
|
|
1379
|
+
import { Pagination, PaginationContent, PaginationItems, PaginationNext, PaginationPrevious } from '@7onic-ui/react'
|
|
1380
|
+
|
|
1381
|
+
{/* Quick mode — withControls (default: true), withEdges (default: false) */}
|
|
1370
1382
|
<Pagination total={10} defaultValue={1} />
|
|
1371
1383
|
<Pagination total={10} defaultValue={1} withEdges />
|
|
1372
1384
|
<Pagination total={10} defaultValue={1} withControls={false} />
|
|
@@ -1405,7 +1417,9 @@ import { Pagination, PaginationContent, PaginationItems, PaginationNext, Paginat
|
|
|
1405
1417
|
### NavigationMenu
|
|
1406
1418
|
|
|
1407
1419
|
```tsx
|
|
1408
|
-
import { NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport } from '@7onic-ui/react'
|
|
1420
|
+
import { NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport } from '@7onic-ui/react'
|
|
1421
|
+
|
|
1422
|
+
{/* Horizontal (header) */}
|
|
1409
1423
|
<NavigationMenu orientation="horizontal">
|
|
1410
1424
|
<NavigationMenuList>
|
|
1411
1425
|
<NavigationMenuItem>
|
|
@@ -1470,7 +1484,9 @@ import { NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationM
|
|
|
1470
1484
|
All chart types use the Chart namespace:
|
|
1471
1485
|
|
|
1472
1486
|
```tsx
|
|
1473
|
-
import { ChartArea, ChartBar, ChartLegend, ChartLegendContent, ChartLine, ChartPie, ChartTooltip, ChartTooltipContent, ChartXAxis, ChartYAxis } from '@7onic-ui/react/chart'
|
|
1487
|
+
import { Chart, ChartArea, ChartBar, ChartLegend, ChartLegendContent, ChartLine, ChartPie, ChartTooltip, ChartTooltipContent, ChartXAxis, ChartYAxis } from '@7onic-ui/react/chart'
|
|
1488
|
+
|
|
1489
|
+
const chartConfig = {
|
|
1474
1490
|
revenue: { label: 'Revenue', color: 'var(--color-chart-1)' },
|
|
1475
1491
|
profit: { label: 'Profit', color: 'var(--color-chart-2)' },
|
|
1476
1492
|
}
|
|
@@ -1570,7 +1586,9 @@ type ChartConfig = {
|
|
|
1570
1586
|
### MetricCard
|
|
1571
1587
|
|
|
1572
1588
|
```tsx
|
|
1573
|
-
import { MetricCard, MetricCardDescription, MetricCardHeader, MetricCardSymbol, MetricCardTitle, MetricCardTrend, MetricCardValue } from '@7onic-ui/react'
|
|
1589
|
+
import { MetricCard, MetricCardDescription, MetricCardHeader, MetricCardSymbol, MetricCardTitle, MetricCardTrend, MetricCardValue } from '@7onic-ui/react'
|
|
1590
|
+
|
|
1591
|
+
<MetricCard>
|
|
1574
1592
|
<MetricCardHeader>
|
|
1575
1593
|
<MetricCardTitle>Revenue</MetricCardTitle>
|
|
1576
1594
|
<MetricCardSymbol><DollarIcon /></MetricCardSymbol>
|
|
@@ -1599,176 +1617,439 @@ import { MetricCard, MetricCardDescription, MetricCardHeader, MetricCardSymbol,
|
|
|
1599
1617
|
|
|
1600
1618
|
---
|
|
1601
1619
|
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
## Component Selection
|
|
1605
|
-
|
|
1606
|
-
Before creating custom UI, check if 7onic already has it:
|
|
1607
|
-
|
|
1608
|
-
| Need | Use This Component |
|
|
1609
|
-
|---|---|
|
|
1610
|
-
| Action trigger | Button, IconButton |
|
|
1611
|
-
| Text input | Input (single line), Textarea (multi line) |
|
|
1612
|
-
| Selection (one) | RadioGroup, Select, Segmented |
|
|
1613
|
-
| Selection (many) | Checkbox, ToggleGroup |
|
|
1614
|
-
| Boolean toggle | Switch, Toggle, Checkbox |
|
|
1615
|
-
| Container | Card |
|
|
1616
|
-
| Data table | Table |
|
|
1617
|
-
| Tabs | Tabs |
|
|
1618
|
-
| Collapsible | Accordion |
|
|
1619
|
-
| Dialog | Modal |
|
|
1620
|
-
| Side panel | Drawer |
|
|
1621
|
-
| Hint text | Tooltip |
|
|
1622
|
-
| Rich hint | Popover |
|
|
1623
|
-
| Notification | Toast (imperative), Alert (inline) |
|
|
1624
|
-
| Loading | Spinner (indeterminate), Progress (determinate), Skeleton (placeholder) |
|
|
1625
|
-
| Navigation | Breadcrumb, Pagination, NavigationMenu |
|
|
1626
|
-
| Data visualization | Chart (Line/Area/Bar/Pie), MetricCard |
|
|
1627
|
-
| Metric display | MetricCard |
|
|
1628
|
-
| Tag / chip | Badge (with `removable`) |
|
|
1629
|
-
| Avatar | Avatar |
|
|
1630
|
-
| Separator | Divider |
|
|
1631
|
-
|
|
1632
|
-
**If the component exists, use it.** Don't build custom versions with HTML + classes.
|
|
1633
|
-
|
|
1634
|
-
---
|
|
1620
|
+
## AI Components
|
|
1635
1621
|
|
|
1636
|
-
|
|
1622
|
+
### TypingIndicator
|
|
1637
1623
|
|
|
1638
1624
|
```tsx
|
|
1639
|
-
|
|
1640
|
-
import { Button, Card, Input, toast } from '@7onic-ui/react'
|
|
1641
|
-
|
|
1642
|
-
// ✅ Chart components use a separate entry point (recharts is optional)
|
|
1643
|
-
import { ChartBar } from '@7onic-ui/react/chart'
|
|
1644
|
-
|
|
1645
|
-
// ❌ Never import from internal paths
|
|
1646
|
-
import { Button } from '@7onic-ui/react/components/button' // WRONG
|
|
1625
|
+
import { TypingIndicator } from '@7onic-ui/react'
|
|
1647
1626
|
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
```
|
|
1651
|
-
|
|
1652
|
-
---
|
|
1653
|
-
|
|
1654
|
-
## Compound Component Structure
|
|
1627
|
+
{/* Default — dots, muted, default size */}
|
|
1628
|
+
<TypingIndicator />
|
|
1655
1629
|
|
|
1656
|
-
|
|
1630
|
+
{/* Cursor variant */}
|
|
1631
|
+
<TypingIndicator variant="cursor" />
|
|
1657
1632
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
<Modal>
|
|
1661
|
-
<ModalTrigger>...</ModalTrigger>
|
|
1662
|
-
<ModalPortal> {/* ← Required for correct z-index */}
|
|
1663
|
-
<ModalOverlay /> {/* ← Required for backdrop */}
|
|
1664
|
-
<ModalContent>
|
|
1665
|
-
<ModalHeader>
|
|
1666
|
-
<ModalTitle>...</ModalTitle>
|
|
1667
|
-
</ModalHeader>
|
|
1668
|
-
<ModalBody>...</ModalBody>
|
|
1669
|
-
</ModalContent>
|
|
1670
|
-
</ModalPortal>
|
|
1671
|
-
</Modal>
|
|
1672
|
-
```
|
|
1633
|
+
{/* Chat bubble */}
|
|
1634
|
+
<TypingIndicator variant="dots" color="muted" />
|
|
1673
1635
|
|
|
1674
|
-
|
|
1636
|
+
{/* AI response — fast with label */}
|
|
1637
|
+
<TypingIndicator
|
|
1638
|
+
variant="dots"
|
|
1639
|
+
color="primary"
|
|
1640
|
+
speed="fast"
|
|
1641
|
+
showLabel
|
|
1642
|
+
label="AI is typing..."
|
|
1643
|
+
/>
|
|
1675
1644
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
<TooltipProvider> {/* ← Required, wrap app once */}
|
|
1679
|
-
<Tooltip>
|
|
1680
|
-
<TooltipTrigger>...</TooltipTrigger>
|
|
1681
|
-
<TooltipPortal>
|
|
1682
|
-
<TooltipContent>...</TooltipContent>
|
|
1683
|
-
</TooltipPortal>
|
|
1684
|
-
</Tooltip>
|
|
1685
|
-
</TooltipProvider>
|
|
1645
|
+
{/* Large cursor, primary color */}
|
|
1646
|
+
<TypingIndicator variant="cursor" size="lg" color="primary" />
|
|
1686
1647
|
```
|
|
1687
1648
|
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1649
|
+
| Prop | Type | Default | Description |
|
|
1650
|
+
|---|---|---|---|
|
|
1651
|
+
| variant | `'dots' \| 'cursor'` | `'dots'` | Animation style |
|
|
1652
|
+
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size |
|
|
1653
|
+
| color | `'default' \| 'primary' \| 'muted'` | `'muted'` | Color |
|
|
1654
|
+
| speed | `'slow' \| 'default' \| 'fast'` | `'default'` | Speed (dots only) |
|
|
1655
|
+
| label | `string` | `'Typing'` | aria-label and showLabel text |
|
|
1656
|
+
| showLabel | `boolean` | `false` | Show text label alongside indicator |
|
|
1695
1657
|
|
|
1696
1658
|
---
|
|
1697
1659
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
`asChild` replaces the component's DOM element with its child, keeping styles and behavior:
|
|
1660
|
+
### QuickReply
|
|
1701
1661
|
|
|
1702
1662
|
```tsx
|
|
1703
|
-
|
|
1704
|
-
<Link href="/about">
|
|
1705
|
-
<Button>About</Button>
|
|
1706
|
-
</Link>
|
|
1707
|
-
|
|
1708
|
-
// ✅ Button renders as <a> with Button styles
|
|
1709
|
-
<Button asChild>
|
|
1710
|
-
<Link href="/about">About</Link>
|
|
1711
|
-
</Button>
|
|
1712
|
-
|
|
1713
|
-
// ✅ DropdownMenu item as link
|
|
1714
|
-
<DropdownMenuItem asChild>
|
|
1715
|
-
<Link href="/settings">Settings</Link>
|
|
1716
|
-
</DropdownMenuItem>
|
|
1717
|
-
|
|
1718
|
-
// ✅ Breadcrumb as Next.js Link
|
|
1719
|
-
<BreadcrumbLink asChild>
|
|
1720
|
-
<Link href="/">Home</Link>
|
|
1721
|
-
</BreadcrumbLink>
|
|
1722
|
-
```
|
|
1663
|
+
import { QuickReply, QuickReplyItem } from '@7onic-ui/react'
|
|
1723
1664
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1665
|
+
{/* Basic suggested replies */}
|
|
1666
|
+
<QuickReply aria-label="Suggested replies">
|
|
1667
|
+
<QuickReplyItem>About payment</QuickReplyItem>
|
|
1668
|
+
<QuickReplyItem>Shipping info</QuickReplyItem>
|
|
1669
|
+
<QuickReplyItem>Return policy</QuickReplyItem>
|
|
1670
|
+
</QuickReply>
|
|
1730
1671
|
|
|
1731
|
-
|
|
1672
|
+
{/* Primary color, filled variant */}
|
|
1673
|
+
<QuickReply color="primary" variant="filled" aria-label="Quick replies">
|
|
1674
|
+
<QuickReplyItem>Payment</QuickReplyItem>
|
|
1675
|
+
<QuickReplyItem>Shipping</QuickReplyItem>
|
|
1676
|
+
</QuickReply>
|
|
1732
1677
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
<
|
|
1678
|
+
{/* Wrap layout for FAQ */}
|
|
1679
|
+
<QuickReply layout="wrap" aria-label="FAQ topics">
|
|
1680
|
+
<QuickReplyItem>Payments</QuickReplyItem>
|
|
1681
|
+
<QuickReplyItem>Shipping</QuickReplyItem>
|
|
1682
|
+
<QuickReplyItem>Returns</QuickReplyItem>
|
|
1683
|
+
<QuickReplyItem>Account</QuickReplyItem>
|
|
1684
|
+
</QuickReply>
|
|
1736
1685
|
|
|
1737
|
-
|
|
1738
|
-
<
|
|
1739
|
-
<
|
|
1740
|
-
<
|
|
1686
|
+
{/* With icon */}
|
|
1687
|
+
<QuickReply aria-label="Actions">
|
|
1688
|
+
<QuickReplyItem icon={<MessageCircle />}>Contact us</QuickReplyItem>
|
|
1689
|
+
<QuickReplyItem icon={<Package />}>Track order</QuickReplyItem>
|
|
1690
|
+
</QuickReply>
|
|
1741
1691
|
```
|
|
1742
1692
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1693
|
+
| Prop (QuickReply) | Type | Default | Description |
|
|
1694
|
+
|---|---|---|---|
|
|
1695
|
+
| layout | `'scroll' \| 'wrap'` | `'scroll'` | Chip layout mode |
|
|
1696
|
+
| variant | `'outline' \| 'filled' \| 'ghost'` | `'outline'` | Visual style |
|
|
1697
|
+
| color | `'default' \| 'primary'` | `'default'` | Color theme |
|
|
1698
|
+
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Chip size |
|
|
1699
|
+
| radius | `'md' \| 'lg' \| 'full'` | `'full'` | Border radius |
|
|
1700
|
+
| gap | `'sm' \| 'default' \| 'lg'` | `'default'` | Gap between chips |
|
|
1750
1701
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1702
|
+
| Prop (QuickReply.Item) | Type | Default | Description |
|
|
1703
|
+
|---|---|---|---|
|
|
1704
|
+
| icon | `ReactNode` | — | Leading icon |
|
|
1705
|
+
| asChild | `boolean` | `false` | Compose with custom element (Radix Slot) |
|
|
1706
|
+
| disabled | `boolean` | `false` | Disable the chip |
|
|
1707
|
+
| onClick | `() => void` | — | Click callback |
|
|
1755
1708
|
|
|
1756
1709
|
---
|
|
1757
1710
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
**Use Field wrapper** for labeled form elements with validation:
|
|
1711
|
+
### ChatInput
|
|
1761
1712
|
|
|
1762
1713
|
```tsx
|
|
1763
|
-
import {
|
|
1764
|
-
<Field error={errors.email}>
|
|
1765
|
-
<FieldLabel required>Email</FieldLabel>
|
|
1766
|
-
<Input placeholder="you@example.com" />
|
|
1767
|
-
<FieldError />
|
|
1768
|
-
</Field>
|
|
1714
|
+
import { ChatInput, ChatInputField, ChatInputSubmit } from '@7onic-ui/react'
|
|
1769
1715
|
|
|
1770
|
-
{/*
|
|
1771
|
-
<
|
|
1716
|
+
{/* Basic uncontrolled */}
|
|
1717
|
+
<ChatInput onSubmit={(value) => console.log(value)}>
|
|
1718
|
+
<ChatInputField placeholder="Ask me anything..." />
|
|
1719
|
+
<ChatInputSubmit />
|
|
1720
|
+
</ChatInput>
|
|
1721
|
+
|
|
1722
|
+
{/* Controlled mode */}
|
|
1723
|
+
const [value, setValue] = useState('')
|
|
1724
|
+
<ChatInput onSubmit={(v) => { handleSend(v); setValue('') }}>
|
|
1725
|
+
<ChatInputField
|
|
1726
|
+
value={value}
|
|
1727
|
+
onChange={(e) => setValue(e.target.value)}
|
|
1728
|
+
placeholder="Ask me anything..."
|
|
1729
|
+
/>
|
|
1730
|
+
<ChatInputSubmit />
|
|
1731
|
+
</ChatInput>
|
|
1732
|
+
|
|
1733
|
+
{/* With loading state + stop */}
|
|
1734
|
+
<ChatInput onSubmit={handleSubmit}>
|
|
1735
|
+
<ChatInputField placeholder="Ask me anything..." />
|
|
1736
|
+
<ChatInputSubmit
|
|
1737
|
+
loading={isLoading}
|
|
1738
|
+
onStop={() => abortController.abort()}
|
|
1739
|
+
/>
|
|
1740
|
+
</ChatInput>
|
|
1741
|
+
|
|
1742
|
+
{/* Character count */}
|
|
1743
|
+
<ChatInput onSubmit={(value) => console.log(value)}>
|
|
1744
|
+
<ChatInputField placeholder="Ask me anything..." showCount maxLength={500} />
|
|
1745
|
+
<ChatInputSubmit />
|
|
1746
|
+
</ChatInput>
|
|
1747
|
+
|
|
1748
|
+
{/* Filled variant, large, custom radius */}
|
|
1749
|
+
<ChatInput variant="filled" size="lg" radius="2xl" onSubmit={(v) => console.log(v)}>
|
|
1750
|
+
<ChatInputField placeholder="Ask me anything..." maxRows={6} />
|
|
1751
|
+
<ChatInputSubmit />
|
|
1752
|
+
</ChatInput>
|
|
1753
|
+
|
|
1754
|
+
{/* Inline layout (single-line field + button side by side) */}
|
|
1755
|
+
<ChatInput layout="inline" radius="full" onSubmit={(value) => console.log(value)}>
|
|
1756
|
+
<ChatInputField placeholder="Message..." />
|
|
1757
|
+
<ChatInputSubmit />
|
|
1758
|
+
</ChatInput>
|
|
1759
|
+
|
|
1760
|
+
{/* Inline with custom button radius */}
|
|
1761
|
+
<ChatInput layout="inline" radius="xl" onSubmit={handleSubmit}>
|
|
1762
|
+
<ChatInputField placeholder="Message..." />
|
|
1763
|
+
<ChatInputSubmit buttonRadius="full" loading={isLoading} onStop={handleStop} />
|
|
1764
|
+
</ChatInput>
|
|
1765
|
+
```
|
|
1766
|
+
|
|
1767
|
+
| Prop (ChatInput) | Type | Default | Description |
|
|
1768
|
+
|---|---|---|---|
|
|
1769
|
+
| variant | `'outline' \| 'filled'` | `'outline'` | Visual style |
|
|
1770
|
+
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale |
|
|
1771
|
+
| radius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Corner radius (`'full'` available in inline layout) |
|
|
1772
|
+
| color | `'default' \| 'primary'` | `'default'` | Submit button color |
|
|
1773
|
+
| layout | `'default' \| 'inline'` | `'default'` | `'inline'` renders field and button side by side |
|
|
1774
|
+
| disabled | `boolean` | `false` | Disable input and submit |
|
|
1775
|
+
| onSubmit | `(value: string) => void` | — | Submit callback |
|
|
1776
|
+
|
|
1777
|
+
| Prop (ChatInput.Field) | Type | Default | Description |
|
|
1778
|
+
|---|---|---|---|
|
|
1779
|
+
| maxRows | `number` | `8` | Max rows before scrolling |
|
|
1780
|
+
| showCount | `boolean` | `false` | Show character counter (default layout only) |
|
|
1781
|
+
| maxLength | `number` | — | Max characters |
|
|
1782
|
+
| placeholder | `string` | — | Placeholder text |
|
|
1783
|
+
|
|
1784
|
+
| Prop (ChatInput.Submit) | Type | Default | Description |
|
|
1785
|
+
|---|---|---|---|
|
|
1786
|
+
| loading | `boolean` | `false` | Switch to stop icon — button stays enabled |
|
|
1787
|
+
| onStop | `() => void` | — | Called on click when loading |
|
|
1788
|
+
| buttonRadius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | — | Override button radius (default: auto from container radius) |
|
|
1789
|
+
| children | `ReactNode` | — | Custom icon (default: send arrow) |
|
|
1790
|
+
|
|
1791
|
+
### ChatMessage
|
|
1792
|
+
|
|
1793
|
+
```tsx
|
|
1794
|
+
import { ChatMessage, ChatMessageAvatar, ChatMessageContent, ChatMessageFooter } from '@7onic-ui/react'
|
|
1795
|
+
|
|
1796
|
+
{/* Assistant message */}
|
|
1797
|
+
<ChatMessage role="assistant">
|
|
1798
|
+
<ChatMessageAvatar />
|
|
1799
|
+
<div className="flex flex-col gap-1">
|
|
1800
|
+
<ChatMessageContent>How can I help you today?</ChatMessageContent>
|
|
1801
|
+
<ChatMessageFooter timestamp="12:34" />
|
|
1802
|
+
</div>
|
|
1803
|
+
</ChatMessage>
|
|
1804
|
+
|
|
1805
|
+
{/* User message with status */}
|
|
1806
|
+
<ChatMessage role="user">
|
|
1807
|
+
<div className="flex flex-col gap-1 items-end">
|
|
1808
|
+
<ChatMessageContent>Thank you for your help!</ChatMessageContent>
|
|
1809
|
+
<ChatMessageFooter timestamp="12:34" status="read" />
|
|
1810
|
+
</div>
|
|
1811
|
+
</ChatMessage>
|
|
1812
|
+
|
|
1813
|
+
{/* Typing animation */}
|
|
1814
|
+
<ChatMessage role="assistant" typing>
|
|
1815
|
+
<ChatMessageAvatar />
|
|
1816
|
+
<ChatMessageContent />
|
|
1817
|
+
</ChatMessage>
|
|
1818
|
+
|
|
1819
|
+
{/* Custom avatar + hover actions */}
|
|
1820
|
+
<ChatMessage
|
|
1821
|
+
role="assistant"
|
|
1822
|
+
actions={<button aria-label="Copy">...</button>}
|
|
1823
|
+
>
|
|
1824
|
+
<ChatMessageAvatar initials="AI" />
|
|
1825
|
+
<div className="flex flex-col gap-1">
|
|
1826
|
+
<ChatMessageContent>Response text here.</ChatMessageContent>
|
|
1827
|
+
<ChatMessageFooter timestamp="12:34" />
|
|
1828
|
+
</div>
|
|
1829
|
+
</ChatMessage>
|
|
1830
|
+
|
|
1831
|
+
{/* User bubble with muted color (common pattern) */}
|
|
1832
|
+
<ChatMessage role="user" color="muted">
|
|
1833
|
+
<div className="flex flex-col gap-1 items-end">
|
|
1834
|
+
<ChatMessageContent>Message text</ChatMessageContent>
|
|
1835
|
+
<ChatMessageFooter timestamp="12:34" status="read" />
|
|
1836
|
+
</div>
|
|
1837
|
+
</ChatMessage>
|
|
1838
|
+
|
|
1839
|
+
{/* History (flat) layout — full-width, no footer */}
|
|
1840
|
+
<div className="flex flex-col gap-3">
|
|
1841
|
+
<ChatMessage role="assistant" variant="flat">
|
|
1842
|
+
<ChatMessageAvatar />
|
|
1843
|
+
<ChatMessageContent className="w-full">Here is the answer.</ChatMessageContent>
|
|
1844
|
+
</ChatMessage>
|
|
1845
|
+
<ChatMessage role="user" variant="flat" color="muted">
|
|
1846
|
+
<ChatMessageContent className="w-full">Thanks!</ChatMessageContent>
|
|
1847
|
+
</ChatMessage>
|
|
1848
|
+
</div>
|
|
1849
|
+
```
|
|
1850
|
+
|
|
1851
|
+
| Prop (ChatMessage) | Type | Default | Description |
|
|
1852
|
+
|---|---|---|---|
|
|
1853
|
+
| role | `'assistant' \| 'user'` | `'assistant'` | Aligns left (assistant) or right (user) |
|
|
1854
|
+
| variant | `'bubble' \| 'flat'` | `'bubble'` | Bubble style with background/border, or flat with no fill |
|
|
1855
|
+
| color | `'default' \| 'muted' \| 'primary' \| 'dark'` | `'default'` | Bubble background color |
|
|
1856
|
+
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale affecting padding and font |
|
|
1857
|
+
| radius | `'md' \| 'lg' \| 'xl' \| '2xl'` | `'2xl'` | Bubble corner radius |
|
|
1858
|
+
| tail | `boolean` | `true` | Asymmetric tail corner (sharp on avatar side) — bubble only |
|
|
1859
|
+
| avatarSize | `'sm' \| 'md' \| 'lg'` | — | Avatar size — also adjusts gap between avatar and bubble |
|
|
1860
|
+
| typing | `boolean` | `false` | Show animated typing dots inside Content |
|
|
1861
|
+
| actions | `ReactNode` | — | Hover-reveal action buttons (copy, react, etc.) |
|
|
1862
|
+
|
|
1863
|
+
| Prop (ChatMessage.Avatar) | Type | Default | Description |
|
|
1864
|
+
|---|---|---|---|
|
|
1865
|
+
| size | `'sm' \| 'md' \| 'lg'` | `'md'` | Avatar size: 24/28/32px |
|
|
1866
|
+
| src | `string` | — | Avatar image URL |
|
|
1867
|
+
| alt | `string` | `'Avatar'` | Alt text |
|
|
1868
|
+
| initials | `string` | — | 1–2 character initials (fallback) |
|
|
1869
|
+
| icon | `ReactNode` | — | Custom icon (fallback) |
|
|
1870
|
+
|
|
1871
|
+
| Prop (ChatMessage.Footer) | Type | Default | Description |
|
|
1872
|
+
|---|---|---|---|
|
|
1873
|
+
| timestamp | `string` | — | Pre-formatted time string |
|
|
1874
|
+
| status | `'sending' \| 'sent' \| 'read' \| 'error' \| ReactNode` | — | Delivery status (built-in presets or custom node) |
|
|
1875
|
+
| size | `'sm' \| 'default' \| 'lg'` | — | Size override (defaults to context value from root) |
|
|
1876
|
+
|
|
1877
|
+
---
|
|
1878
|
+
|
|
1879
|
+
---
|
|
1880
|
+
|
|
1881
|
+
# ═══ SECTION 4: COMPONENT USAGE GUIDE ═══
|
|
1882
|
+
|
|
1883
|
+
## Component Selection
|
|
1884
|
+
|
|
1885
|
+
Before creating custom UI, check if 7onic already has it:
|
|
1886
|
+
|
|
1887
|
+
| Need | Use This Component |
|
|
1888
|
+
|---|---|
|
|
1889
|
+
| Action trigger | Button, IconButton |
|
|
1890
|
+
| Text input | Input (single line), Textarea (multi line) |
|
|
1891
|
+
| Selection (one) | RadioGroup, Select, Segmented |
|
|
1892
|
+
| Selection (many) | Checkbox, ToggleGroup |
|
|
1893
|
+
| Boolean toggle | Switch, Toggle, Checkbox |
|
|
1894
|
+
| Container | Card |
|
|
1895
|
+
| Data table | Table |
|
|
1896
|
+
| Tabs | Tabs |
|
|
1897
|
+
| Collapsible | Accordion |
|
|
1898
|
+
| Dialog | Modal |
|
|
1899
|
+
| Side panel | Drawer |
|
|
1900
|
+
| Hint text | Tooltip |
|
|
1901
|
+
| Rich hint | Popover |
|
|
1902
|
+
| Notification | Toast (imperative), Alert (inline) |
|
|
1903
|
+
| Loading | Spinner (indeterminate), Progress (determinate), Skeleton (placeholder) |
|
|
1904
|
+
| Navigation | Breadcrumb, Pagination, NavigationMenu |
|
|
1905
|
+
| Data visualization | Chart (Line/Area/Bar/Pie), MetricCard |
|
|
1906
|
+
| Metric display | MetricCard |
|
|
1907
|
+
| Tag / chip | Badge (with `removable`) |
|
|
1908
|
+
| Avatar | Avatar |
|
|
1909
|
+
| Separator | Divider |
|
|
1910
|
+
|
|
1911
|
+
**If the component exists, use it.** Don't build custom versions with HTML + classes.
|
|
1912
|
+
|
|
1913
|
+
---
|
|
1914
|
+
|
|
1915
|
+
## Import Pattern
|
|
1916
|
+
|
|
1917
|
+
```tsx
|
|
1918
|
+
// ✅ Single import path
|
|
1919
|
+
import { Button, Card, Input, toast } from '@7onic-ui/react'
|
|
1920
|
+
|
|
1921
|
+
// ✅ Chart components use a separate entry point (recharts is optional)
|
|
1922
|
+
import { ChartBar } from '@7onic-ui/react/chart'
|
|
1923
|
+
|
|
1924
|
+
// ❌ Never import from internal paths
|
|
1925
|
+
import { Button } from '@7onic-ui/react/components/button' // WRONG
|
|
1926
|
+
|
|
1927
|
+
// ❌ Never import Radix directly
|
|
1928
|
+
import * as Dialog from '@radix-ui/react-dialog' // WRONG → use Modal
|
|
1929
|
+
```
|
|
1930
|
+
|
|
1931
|
+
---
|
|
1932
|
+
|
|
1933
|
+
## Compound Component Structure
|
|
1934
|
+
|
|
1935
|
+
Compound components have **required sub-components**. Missing them causes errors or broken UI.
|
|
1936
|
+
|
|
1937
|
+
**Modal — required structure:**
|
|
1938
|
+
```tsx
|
|
1939
|
+
<Modal>
|
|
1940
|
+
<ModalTrigger>...</ModalTrigger>
|
|
1941
|
+
<ModalPortal> {/* ← Required for correct z-index */}
|
|
1942
|
+
<ModalOverlay /> {/* ← Required for backdrop */}
|
|
1943
|
+
<ModalContent>
|
|
1944
|
+
<ModalHeader>
|
|
1945
|
+
<ModalTitle>...</ModalTitle>
|
|
1946
|
+
</ModalHeader>
|
|
1947
|
+
<ModalBody>...</ModalBody>
|
|
1948
|
+
</ModalContent>
|
|
1949
|
+
</ModalPortal>
|
|
1950
|
+
</Modal>
|
|
1951
|
+
```
|
|
1952
|
+
|
|
1953
|
+
**Drawer — same pattern as Modal** (Portal + Overlay + Content required)
|
|
1954
|
+
|
|
1955
|
+
**Tooltip — Provider required:**
|
|
1956
|
+
```tsx
|
|
1957
|
+
<TooltipProvider> {/* ← Required, wrap app once */}
|
|
1958
|
+
<Tooltip>
|
|
1959
|
+
<TooltipTrigger>...</TooltipTrigger>
|
|
1960
|
+
<TooltipPortal>
|
|
1961
|
+
<TooltipContent>...</TooltipContent>
|
|
1962
|
+
</TooltipPortal>
|
|
1963
|
+
</Tooltip>
|
|
1964
|
+
</TooltipProvider>
|
|
1965
|
+
```
|
|
1966
|
+
|
|
1967
|
+
**Toast — imperative API, no compound structure:**
|
|
1968
|
+
```tsx
|
|
1969
|
+
// Place Toaster once in layout
|
|
1970
|
+
<Toaster />
|
|
1971
|
+
// Call toast() anywhere
|
|
1972
|
+
toast.success('Done')
|
|
1973
|
+
```
|
|
1974
|
+
|
|
1975
|
+
---
|
|
1976
|
+
|
|
1977
|
+
## asChild Pattern (Slot)
|
|
1978
|
+
|
|
1979
|
+
`asChild` replaces the component's DOM element with its child, keeping styles and behavior:
|
|
1980
|
+
|
|
1981
|
+
```tsx
|
|
1982
|
+
// ❌ Double <a> — broken HTML
|
|
1983
|
+
<Link href="/about">
|
|
1984
|
+
<Button>About</Button>
|
|
1985
|
+
</Link>
|
|
1986
|
+
|
|
1987
|
+
// ✅ Button renders as <a> with Button styles
|
|
1988
|
+
<Button asChild>
|
|
1989
|
+
<Link href="/about">About</Link>
|
|
1990
|
+
</Button>
|
|
1991
|
+
|
|
1992
|
+
// ✅ DropdownMenu item as link
|
|
1993
|
+
<DropdownMenuItem asChild>
|
|
1994
|
+
<Link href="/settings">Settings</Link>
|
|
1995
|
+
</DropdownMenuItem>
|
|
1996
|
+
|
|
1997
|
+
// ✅ Breadcrumb as Next.js Link
|
|
1998
|
+
<BreadcrumbLink asChild>
|
|
1999
|
+
<Link href="/">Home</Link>
|
|
2000
|
+
</BreadcrumbLink>
|
|
2001
|
+
```
|
|
2002
|
+
|
|
2003
|
+
**Use `asChild` when combining 7onic components with routing `<Link>`.**
|
|
2004
|
+
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
|
|
2005
|
+
|
|
2006
|
+
---
|
|
2007
|
+
|
|
2008
|
+
## Props Usage
|
|
2009
|
+
|
|
2010
|
+
**Always use allowed values.** Don't pass arbitrary strings to variant/size/color props.
|
|
2011
|
+
|
|
2012
|
+
```tsx
|
|
2013
|
+
// ✅ Correct
|
|
2014
|
+
<Button variant="solid" size="default" color="primary" />
|
|
2015
|
+
|
|
2016
|
+
// ❌ Wrong — invalid values
|
|
2017
|
+
<Button variant="primary" /> // 'primary' is a color, not a variant
|
|
2018
|
+
<Button size="medium" /> // Use 'md' or 'default', not 'medium'
|
|
2019
|
+
<Button color="blue" /> // Use 'primary', not raw color names
|
|
2020
|
+
```
|
|
2021
|
+
|
|
2022
|
+
**`className` on components = layout ONLY** (margin, width, flex positioning). All visual styling (color, size, radius, variant) must use Props.
|
|
2023
|
+
|
|
2024
|
+
**Style via Props, not className:**
|
|
2025
|
+
```tsx
|
|
2026
|
+
// ✅ Use Props
|
|
2027
|
+
<Button color="primary" size="lg" />
|
|
2028
|
+
<Badge color="error" variant="subtle" />
|
|
2029
|
+
|
|
2030
|
+
// ❌ Don't override with className
|
|
2031
|
+
<Button className="bg-blue-500 text-white" />
|
|
2032
|
+
<Badge className="bg-red-100" />
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
---
|
|
2036
|
+
|
|
2037
|
+
## Form Patterns
|
|
2038
|
+
|
|
2039
|
+
**Use Field wrapper** for labeled form elements with validation:
|
|
2040
|
+
|
|
2041
|
+
```tsx
|
|
2042
|
+
import { Field, FieldCharCount, FieldError, FieldLabel, Input, Textarea } from '@7onic-ui/react'
|
|
2043
|
+
|
|
2044
|
+
{/* Text input with label + error */}
|
|
2045
|
+
<Field error={errors.email}>
|
|
2046
|
+
<FieldLabel required>Email</FieldLabel>
|
|
2047
|
+
<Input placeholder="you@example.com" />
|
|
2048
|
+
<FieldError />
|
|
2049
|
+
</Field>
|
|
2050
|
+
|
|
2051
|
+
{/* Textarea with character count */}
|
|
2052
|
+
<Field>
|
|
1772
2053
|
<FieldLabel>Bio</FieldLabel>
|
|
1773
2054
|
<Textarea maxLength={200} />
|
|
1774
2055
|
<FieldCharCount />
|
|
@@ -1948,255 +2229,6 @@ But if YOUR code uses React hooks (`useState`, `useEffect`) or event handlers (`
|
|
|
1948
2229
|
| 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 |
|
|
1949
2230
|
---
|
|
1950
2231
|
|
|
1951
|
-
### TypingIndicator
|
|
1952
|
-
|
|
1953
|
-
```tsx
|
|
1954
|
-
import { TypingIndicator } from '@7onic-ui/react'{/* Default — dots, muted, default size */}
|
|
1955
|
-
<TypingIndicator />
|
|
1956
|
-
|
|
1957
|
-
{/* Cursor variant */}
|
|
1958
|
-
<TypingIndicator variant="cursor" />
|
|
1959
|
-
|
|
1960
|
-
{/* Chat bubble */}
|
|
1961
|
-
<TypingIndicator variant="dots" color="muted" />
|
|
1962
|
-
|
|
1963
|
-
{/* AI response — fast with label */}
|
|
1964
|
-
<TypingIndicator
|
|
1965
|
-
variant="dots"
|
|
1966
|
-
color="primary"
|
|
1967
|
-
speed="fast"
|
|
1968
|
-
showLabel
|
|
1969
|
-
label="AI is typing..."
|
|
1970
|
-
/>
|
|
1971
|
-
|
|
1972
|
-
{/* Large cursor, primary color */}
|
|
1973
|
-
<TypingIndicator variant="cursor" size="lg" color="primary" />
|
|
1974
|
-
```
|
|
1975
|
-
|
|
1976
|
-
| Prop | Type | Default | Description |
|
|
1977
|
-
|---|---|---|---|
|
|
1978
|
-
| variant | `'dots' \| 'cursor'` | `'dots'` | Animation style |
|
|
1979
|
-
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size |
|
|
1980
|
-
| color | `'default' \| 'primary' \| 'muted'` | `'muted'` | Color |
|
|
1981
|
-
| speed | `'slow' \| 'default' \| 'fast'` | `'default'` | Speed (dots only) |
|
|
1982
|
-
| label | `string` | `'Typing'` | aria-label and showLabel text |
|
|
1983
|
-
| showLabel | `boolean` | `false` | Show text label alongside indicator |
|
|
1984
|
-
|
|
1985
|
-
---
|
|
1986
|
-
|
|
1987
|
-
### QuickReply
|
|
1988
|
-
|
|
1989
|
-
```tsx
|
|
1990
|
-
import { QuickReply, QuickReplyItem } from '@7onic-ui/react'{/* Basic suggested replies */}
|
|
1991
|
-
<QuickReply aria-label="Suggested replies">
|
|
1992
|
-
<QuickReplyItem>About payment</QuickReplyItem>
|
|
1993
|
-
<QuickReplyItem>Shipping info</QuickReplyItem>
|
|
1994
|
-
<QuickReplyItem>Return policy</QuickReplyItem>
|
|
1995
|
-
</QuickReply>
|
|
1996
|
-
|
|
1997
|
-
{/* Primary color, filled variant */}
|
|
1998
|
-
<QuickReply color="primary" variant="filled" aria-label="Quick replies">
|
|
1999
|
-
<QuickReplyItem>Payment</QuickReplyItem>
|
|
2000
|
-
<QuickReplyItem>Shipping</QuickReplyItem>
|
|
2001
|
-
</QuickReply>
|
|
2002
|
-
|
|
2003
|
-
{/* Wrap layout for FAQ */}
|
|
2004
|
-
<QuickReply layout="wrap" aria-label="FAQ topics">
|
|
2005
|
-
<QuickReplyItem>Payments</QuickReplyItem>
|
|
2006
|
-
<QuickReplyItem>Shipping</QuickReplyItem>
|
|
2007
|
-
<QuickReplyItem>Returns</QuickReplyItem>
|
|
2008
|
-
<QuickReplyItem>Account</QuickReplyItem>
|
|
2009
|
-
</QuickReply>
|
|
2010
|
-
|
|
2011
|
-
{/* With icon */}
|
|
2012
|
-
<QuickReply aria-label="Actions">
|
|
2013
|
-
<QuickReplyItem icon={<MessageCircle />}>Contact us</QuickReplyItem>
|
|
2014
|
-
<QuickReplyItem icon={<Package />}>Track order</QuickReplyItem>
|
|
2015
|
-
</QuickReply>
|
|
2016
|
-
```
|
|
2017
|
-
|
|
2018
|
-
| Prop (QuickReply) | Type | Default | Description |
|
|
2019
|
-
|---|---|---|---|
|
|
2020
|
-
| layout | `'scroll' \| 'wrap'` | `'scroll'` | Chip layout mode |
|
|
2021
|
-
| variant | `'outline' \| 'filled' \| 'ghost'` | `'outline'` | Visual style |
|
|
2022
|
-
| color | `'default' \| 'primary'` | `'default'` | Color theme |
|
|
2023
|
-
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Chip size |
|
|
2024
|
-
| radius | `'md' \| 'lg' \| 'full'` | `'full'` | Border radius |
|
|
2025
|
-
| gap | `'sm' \| 'default' \| 'lg'` | `'default'` | Gap between chips |
|
|
2026
|
-
|
|
2027
|
-
| Prop (QuickReply.Item) | Type | Default | Description |
|
|
2028
|
-
|---|---|---|---|
|
|
2029
|
-
| icon | `ReactNode` | — | Leading icon |
|
|
2030
|
-
| asChild | `boolean` | `false` | Compose with custom element (Radix Slot) |
|
|
2031
|
-
| disabled | `boolean` | `false` | Disable the chip |
|
|
2032
|
-
| onClick | `() => void` | — | Click callback |
|
|
2033
|
-
|
|
2034
|
-
---
|
|
2035
|
-
|
|
2036
|
-
### ChatInput
|
|
2037
|
-
|
|
2038
|
-
```tsx
|
|
2039
|
-
import { ChatInput, ChatInputField, ChatInputSubmit } from '@7onic-ui/react'{/* Basic uncontrolled */}
|
|
2040
|
-
<ChatInput onSubmit={(value) => console.log(value)}>
|
|
2041
|
-
<ChatInputField placeholder="Ask me anything..." />
|
|
2042
|
-
<ChatInputSubmit />
|
|
2043
|
-
</ChatInput>
|
|
2044
|
-
|
|
2045
|
-
{/* Controlled mode */}
|
|
2046
|
-
const [value, setValue] = useState('')
|
|
2047
|
-
<ChatInput onSubmit={(v) => { handleSend(v); setValue('') }}>
|
|
2048
|
-
<ChatInputField
|
|
2049
|
-
value={value}
|
|
2050
|
-
onChange={(e) => setValue(e.target.value)}
|
|
2051
|
-
placeholder="Ask me anything..."
|
|
2052
|
-
/>
|
|
2053
|
-
<ChatInputSubmit />
|
|
2054
|
-
</ChatInput>
|
|
2055
|
-
|
|
2056
|
-
{/* With loading state + stop */}
|
|
2057
|
-
<ChatInput onSubmit={handleSubmit}>
|
|
2058
|
-
<ChatInputField placeholder="Ask me anything..." />
|
|
2059
|
-
<ChatInputSubmit
|
|
2060
|
-
loading={isLoading}
|
|
2061
|
-
onStop={() => abortController.abort()}
|
|
2062
|
-
/>
|
|
2063
|
-
</ChatInput>
|
|
2064
|
-
|
|
2065
|
-
{/* Character count */}
|
|
2066
|
-
<ChatInput onSubmit={(value) => console.log(value)}>
|
|
2067
|
-
<ChatInputField placeholder="Ask me anything..." showCount maxLength={500} />
|
|
2068
|
-
<ChatInputSubmit />
|
|
2069
|
-
</ChatInput>
|
|
2070
|
-
|
|
2071
|
-
{/* Filled variant, large, custom radius */}
|
|
2072
|
-
<ChatInput variant="filled" size="lg" radius="2xl" onSubmit={(v) => console.log(v)}>
|
|
2073
|
-
<ChatInputField placeholder="Ask me anything..." maxRows={6} />
|
|
2074
|
-
<ChatInputSubmit />
|
|
2075
|
-
</ChatInput>
|
|
2076
|
-
|
|
2077
|
-
{/* Inline layout (single-line field + button side by side) */}
|
|
2078
|
-
<ChatInput layout="inline" radius="full" onSubmit={(value) => console.log(value)}>
|
|
2079
|
-
<ChatInputField placeholder="Message..." />
|
|
2080
|
-
<ChatInputSubmit />
|
|
2081
|
-
</ChatInput>
|
|
2082
|
-
|
|
2083
|
-
{/* Inline with custom button radius */}
|
|
2084
|
-
<ChatInput layout="inline" radius="xl" onSubmit={handleSubmit}>
|
|
2085
|
-
<ChatInputField placeholder="Message..." />
|
|
2086
|
-
<ChatInputSubmit buttonRadius="full" loading={isLoading} onStop={handleStop} />
|
|
2087
|
-
</ChatInput>
|
|
2088
|
-
```
|
|
2089
|
-
|
|
2090
|
-
| Prop (ChatInput) | Type | Default | Description |
|
|
2091
|
-
|---|---|---|---|
|
|
2092
|
-
| variant | `'outline' \| 'filled'` | `'outline'` | Visual style |
|
|
2093
|
-
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale |
|
|
2094
|
-
| radius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | `'xl'` | Corner radius (`'full'` available in inline layout) |
|
|
2095
|
-
| color | `'default' \| 'primary'` | `'default'` | Submit button color |
|
|
2096
|
-
| layout | `'default' \| 'inline'` | `'default'` | `'inline'` renders field and button side by side |
|
|
2097
|
-
| disabled | `boolean` | `false` | Disable input and submit |
|
|
2098
|
-
| onSubmit | `(value: string) => void` | — | Submit callback |
|
|
2099
|
-
|
|
2100
|
-
| Prop (ChatInput.Field) | Type | Default | Description |
|
|
2101
|
-
|---|---|---|---|
|
|
2102
|
-
| maxRows | `number` | `8` | Max rows before scrolling |
|
|
2103
|
-
| showCount | `boolean` | `false` | Show character counter (default layout only) |
|
|
2104
|
-
| maxLength | `number` | — | Max characters |
|
|
2105
|
-
| placeholder | `string` | — | Placeholder text |
|
|
2106
|
-
|
|
2107
|
-
| Prop (ChatInput.Submit) | Type | Default | Description |
|
|
2108
|
-
|---|---|---|---|
|
|
2109
|
-
| loading | `boolean` | `false` | Switch to stop icon — button stays enabled |
|
|
2110
|
-
| onStop | `() => void` | — | Called on click when loading |
|
|
2111
|
-
| buttonRadius | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | — | Override button radius (default: auto from container radius) |
|
|
2112
|
-
| children | `ReactNode` | — | Custom icon (default: send arrow) |
|
|
2113
|
-
|
|
2114
|
-
### ChatMessage
|
|
2115
|
-
|
|
2116
|
-
```tsx
|
|
2117
|
-
import { ChatMessage, ChatMessageAvatar, ChatMessageContent, ChatMessageFooter } from '@7onic-ui/react'{/* Assistant message */}
|
|
2118
|
-
<ChatMessage role="assistant">
|
|
2119
|
-
<ChatMessageAvatar />
|
|
2120
|
-
<div className="flex flex-col gap-1">
|
|
2121
|
-
<ChatMessageContent>How can I help you today?</ChatMessageContent>
|
|
2122
|
-
<ChatMessageFooter timestamp="12:34" />
|
|
2123
|
-
</div>
|
|
2124
|
-
</ChatMessage>
|
|
2125
|
-
|
|
2126
|
-
{/* User message with status */}
|
|
2127
|
-
<ChatMessage role="user">
|
|
2128
|
-
<div className="flex flex-col gap-1 items-end">
|
|
2129
|
-
<ChatMessageContent>Thank you for your help!</ChatMessageContent>
|
|
2130
|
-
<ChatMessageFooter timestamp="12:34" status="read" />
|
|
2131
|
-
</div>
|
|
2132
|
-
</ChatMessage>
|
|
2133
|
-
|
|
2134
|
-
{/* Typing animation */}
|
|
2135
|
-
<ChatMessage role="assistant" typing>
|
|
2136
|
-
<ChatMessageAvatar />
|
|
2137
|
-
<ChatMessageContent />
|
|
2138
|
-
</ChatMessage>
|
|
2139
|
-
|
|
2140
|
-
{/* Custom avatar + hover actions */}
|
|
2141
|
-
<ChatMessage
|
|
2142
|
-
role="assistant"
|
|
2143
|
-
actions={<button aria-label="Copy">...</button>}
|
|
2144
|
-
>
|
|
2145
|
-
<ChatMessageAvatar initials="AI" />
|
|
2146
|
-
<div className="flex flex-col gap-1">
|
|
2147
|
-
<ChatMessageContent>Response text here.</ChatMessageContent>
|
|
2148
|
-
<ChatMessageFooter timestamp="12:34" />
|
|
2149
|
-
</div>
|
|
2150
|
-
</ChatMessage>
|
|
2151
|
-
|
|
2152
|
-
{/* User bubble with muted color (common pattern) */}
|
|
2153
|
-
<ChatMessage role="user" color="muted">
|
|
2154
|
-
<div className="flex flex-col gap-1 items-end">
|
|
2155
|
-
<ChatMessageContent>Message text</ChatMessageContent>
|
|
2156
|
-
<ChatMessageFooter timestamp="12:34" status="read" />
|
|
2157
|
-
</div>
|
|
2158
|
-
</ChatMessage>
|
|
2159
|
-
|
|
2160
|
-
{/* History (flat) layout — full-width, no footer */}
|
|
2161
|
-
<div className="flex flex-col gap-3">
|
|
2162
|
-
<ChatMessage role="assistant" variant="flat">
|
|
2163
|
-
<ChatMessageAvatar />
|
|
2164
|
-
<ChatMessageContent className="w-full">Here is the answer.</ChatMessageContent>
|
|
2165
|
-
</ChatMessage>
|
|
2166
|
-
<ChatMessage role="user" variant="flat" color="muted">
|
|
2167
|
-
<ChatMessageContent className="w-full">Thanks!</ChatMessageContent>
|
|
2168
|
-
</ChatMessage>
|
|
2169
|
-
</div>
|
|
2170
|
-
```
|
|
2171
|
-
|
|
2172
|
-
| Prop (ChatMessage) | Type | Default | Description |
|
|
2173
|
-
|---|---|---|---|
|
|
2174
|
-
| role | `'assistant' \| 'user'` | `'assistant'` | Aligns left (assistant) or right (user) |
|
|
2175
|
-
| variant | `'bubble' \| 'flat'` | `'bubble'` | Bubble style with background/border, or flat with no fill |
|
|
2176
|
-
| color | `'default' \| 'muted' \| 'primary' \| 'dark'` | `'default'` | Bubble background color |
|
|
2177
|
-
| size | `'sm' \| 'default' \| 'lg'` | `'default'` | Size scale affecting padding and font |
|
|
2178
|
-
| radius | `'md' \| 'lg' \| 'xl' \| '2xl'` | `'2xl'` | Bubble corner radius |
|
|
2179
|
-
| tail | `boolean` | `true` | Asymmetric tail corner (sharp on avatar side) — bubble only |
|
|
2180
|
-
| avatarSize | `'sm' \| 'md' \| 'lg'` | — | Avatar size — also adjusts gap between avatar and bubble |
|
|
2181
|
-
| typing | `boolean` | `false` | Show animated typing dots inside Content |
|
|
2182
|
-
| actions | `ReactNode` | — | Hover-reveal action buttons (copy, react, etc.) |
|
|
2183
|
-
|
|
2184
|
-
| Prop (ChatMessage.Avatar) | Type | Default | Description |
|
|
2185
|
-
|---|---|---|---|
|
|
2186
|
-
| size | `'sm' \| 'md' \| 'lg'` | `'md'` | Avatar size: 24/28/32px |
|
|
2187
|
-
| src | `string` | — | Avatar image URL |
|
|
2188
|
-
| alt | `string` | `'Avatar'` | Alt text |
|
|
2189
|
-
| initials | `string` | — | 1–2 character initials (fallback) |
|
|
2190
|
-
| icon | `ReactNode` | — | Custom icon (fallback) |
|
|
2191
|
-
|
|
2192
|
-
| Prop (ChatMessage.Footer) | Type | Default | Description |
|
|
2193
|
-
|---|---|---|---|
|
|
2194
|
-
| timestamp | `string` | — | Pre-formatted time string |
|
|
2195
|
-
| status | `'sending' \| 'sent' \| 'read' \| 'error' \| ReactNode` | — | Delivery status (built-in presets or custom node) |
|
|
2196
|
-
| size | `'sm' \| 'default' \| 'lg'` | — | Size override (defaults to context value from root) |
|
|
2197
|
-
|
|
2198
|
-
---
|
|
2199
|
-
|
|
2200
2232
|
## Compound Recipe (opt-in self-wrapper)
|
|
2201
2233
|
|
|
2202
2234
|
v0.3.0+ library exports Named only (`<CardHeader>`). To restore dot-notation (`<Card.Header>`) in your project, add a wrapper file. File location is flexible (`src/lib/card.tsx`, `lib/card.tsx`, `src/components/compound/card.tsx`, etc.) — pick one. Adjust the import source to match your install method:
|