ai-design-system 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +307 -0
- package/components/ai-elements/actions.tsx +65 -0
- package/components/ai-elements/artifact.tsx +147 -0
- package/components/ai-elements/branch.tsx +212 -0
- package/components/ai-elements/canvas.tsx +24 -0
- package/components/ai-elements/chain-of-thought.tsx +228 -0
- package/components/ai-elements/code-block.tsx +179 -0
- package/components/ai-elements/confirmation.tsx +169 -0
- package/components/ai-elements/connection.tsx +28 -0
- package/components/ai-elements/context.tsx +408 -0
- package/components/ai-elements/controls.tsx +18 -0
- package/components/ai-elements/conversation.tsx +97 -0
- package/components/ai-elements/edge.tsx +140 -0
- package/components/ai-elements/image.tsx +24 -0
- package/components/ai-elements/inline-citation.tsx +287 -0
- package/components/ai-elements/loader.tsx +96 -0
- package/components/ai-elements/message.tsx +80 -0
- package/components/ai-elements/node.tsx +71 -0
- package/components/ai-elements/open-in-chat.tsx +363 -0
- package/components/ai-elements/panel.tsx +15 -0
- package/components/ai-elements/plan.tsx +142 -0
- package/components/ai-elements/prompt-input.tsx +1352 -0
- package/components/ai-elements/queue.tsx +274 -0
- package/components/ai-elements/reasoning.tsx +178 -0
- package/components/ai-elements/response.tsx +22 -0
- package/components/ai-elements/shimmer.tsx +64 -0
- package/components/ai-elements/sources.tsx +77 -0
- package/components/ai-elements/suggestion.tsx +56 -0
- package/components/ai-elements/task.tsx +87 -0
- package/components/ai-elements/tool.tsx +179 -0
- package/components/ai-elements/toolbar.tsx +16 -0
- package/components/ai-elements/web-preview.tsx +263 -0
- package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
- package/components/blocks/AIConversation/AIConversation.tsx +186 -0
- package/components/blocks/AIConversation/index.ts +8 -0
- package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
- package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
- package/components/blocks/AppSidebar/index.ts +2 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
- package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
- package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
- package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
- package/components/blocks/FileChangeQueue/index.ts +7 -0
- package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
- package/components/blocks/LayoutProvider/index.ts +1 -0
- package/components/blocks/index.ts +2 -0
- package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
- package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
- package/components/composites/AgentIndicator/index.ts +8 -0
- package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
- package/components/composites/AppHeader/AppHeader.tsx +24 -0
- package/components/composites/AppHeader/index.ts +2 -0
- package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
- package/components/composites/CommentBox/CommentBox.tsx +364 -0
- package/components/composites/CommentBox/index.ts +8 -0
- package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
- package/components/composites/Confirmation/Confirmation.tsx +93 -0
- package/components/composites/Confirmation/index.ts +7 -0
- package/components/composites/DataTable/DataTable.stories.tsx +35 -0
- package/components/composites/DataTable/DataTable.tsx +95 -0
- package/components/composites/DataTable/index.ts +2 -0
- package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
- package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
- package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
- package/components/composites/DocumentEditor/index.ts +8 -0
- package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
- package/components/composites/FileQueue/FileQueue.tsx +161 -0
- package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
- package/components/composites/FileQueue/index.ts +24 -0
- package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
- package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
- package/components/composites/InteractiveChart/index.ts +2 -0
- package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
- package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
- package/components/composites/ModeToggle/index.ts +7 -0
- package/components/composites/NavUser/NavUser.stories.tsx +50 -0
- package/components/composites/NavUser/NavUser.tsx +60 -0
- package/components/composites/NavUser/index.ts +2 -0
- package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
- package/components/composites/NavigationList/NavigationList.tsx +46 -0
- package/components/composites/NavigationList/index.ts +2 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
- package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
- package/components/composites/OrchestratorMessage/index.ts +8 -0
- package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
- package/components/composites/PageContainer/PageContainer.tsx +24 -0
- package/components/composites/PageContainer/index.ts +2 -0
- package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
- package/components/composites/PromptInput/PromptInput.tsx +129 -0
- package/components/composites/PromptInput/index.ts +8 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
- package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
- package/components/composites/SpecialistMessage/index.ts +8 -0
- package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
- package/components/composites/StatsCard/StatsCard.tsx +81 -0
- package/components/composites/StatsCard/index.ts +2 -0
- package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
- package/components/composites/TablePagination/TablePagination.tsx +119 -0
- package/components/composites/TablePagination/index.ts +2 -0
- package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
- package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
- package/components/composites/TableToolbar/index.ts +2 -0
- package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
- package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
- package/components/composites/ThemeSelector/index.ts +2 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
- package/components/composites/ToolCallDisplay/index.ts +8 -0
- package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
- package/components/composites/UserMessage/UserMessage.tsx +52 -0
- package/components/composites/UserMessage/index.ts +8 -0
- package/components/composites/index.ts +90 -0
- package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
- package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
- package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
- package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
- package/components/features/AIDocEditor/index.ts +8 -0
- package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
- package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
- package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
- package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
- package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
- package/components/features/PageLayout/PageLayout.tsx +94 -0
- package/components/features/PageLayout/index.ts +4 -0
- package/components/features/PageLayout/usePageLayout.d.ts +24 -0
- package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
- package/components/features/RefinementPanel/README.md +189 -0
- package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
- package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
- package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
- package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
- package/components/features/RefinementPanel/index.ts +25 -0
- package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
- package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
- package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
- package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
- package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
- package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
- package/components/features/SpecNavigator/index.ts +2 -0
- package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
- package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
- package/components/features/index.ts +18 -0
- package/components/index.ts +14 -0
- package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
- package/components/primitives/Accordion/Accordion.tsx +66 -0
- package/components/primitives/Accordion/index.ts +13 -0
- package/components/primitives/Alert/Alert.stories.tsx +422 -0
- package/components/primitives/Alert/Alert.tsx +61 -0
- package/components/primitives/Alert/index.ts +8 -0
- package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
- package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
- package/components/primitives/AlertDialog/index.ts +25 -0
- package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
- package/components/primitives/Avatar/Avatar.tsx +63 -0
- package/components/primitives/Avatar/index.ts +8 -0
- package/components/primitives/Badge/Badge.stories.tsx +74 -0
- package/components/primitives/Badge/Badge.tsx +49 -0
- package/components/primitives/Badge/index.ts +2 -0
- package/components/primitives/Button/Button.stories.tsx +445 -0
- package/components/primitives/Button/Button.tsx +89 -0
- package/components/primitives/Button/index.ts +7 -0
- package/components/primitives/Card/Card.stories.tsx +831 -0
- package/components/primitives/Card/Card.tsx +242 -0
- package/components/primitives/Card/index.ts +30 -0
- package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
- package/components/primitives/Carousel/Carousel.tsx +63 -0
- package/components/primitives/Carousel/index.ts +13 -0
- package/components/primitives/Chart/Chart.stories.tsx +346 -0
- package/components/primitives/Chart/Chart.tsx +117 -0
- package/components/primitives/Chart/index.ts +20 -0
- package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
- package/components/primitives/Checkbox/Checkbox.tsx +38 -0
- package/components/primitives/Checkbox/index.ts +2 -0
- package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
- package/components/primitives/Collapsible/Collapsible.tsx +39 -0
- package/components/primitives/Collapsible/index.ts +8 -0
- package/components/primitives/Command/Command.stories.tsx +150 -0
- package/components/primitives/Command/Command.tsx +147 -0
- package/components/primitives/Command/index.ts +20 -0
- package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
- package/components/primitives/Dialog/Dialog.tsx +140 -0
- package/components/primitives/Dialog/index.ts +22 -0
- package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
- package/components/primitives/Drawer/Drawer.tsx +208 -0
- package/components/primitives/Drawer/index.ts +27 -0
- package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
- package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
- package/components/primitives/DropdownMenu/index.ts +1 -0
- package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
- package/components/primitives/HoverCard/HoverCard.tsx +39 -0
- package/components/primitives/HoverCard/index.ts +8 -0
- package/components/primitives/Icon/Icon.stories.tsx +281 -0
- package/components/primitives/Icon/Icon.tsx +87 -0
- package/components/primitives/Icon/index.ts +8 -0
- package/components/primitives/Input/Input.stories.tsx +370 -0
- package/components/primitives/Input/Input.tsx +88 -0
- package/components/primitives/Input/index.ts +7 -0
- package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
- package/components/primitives/InputGroup/InputGroup.tsx +72 -0
- package/components/primitives/InputGroup/index.ts +14 -0
- package/components/primitives/Label/Label.stories.tsx +227 -0
- package/components/primitives/Label/Label.tsx +53 -0
- package/components/primitives/Label/index.ts +7 -0
- package/components/primitives/Popover/Popover.stories.tsx +42 -0
- package/components/primitives/Popover/Popover.tsx +107 -0
- package/components/primitives/Popover/index.ts +2 -0
- package/components/primitives/Progress/Progress.stories.tsx +340 -0
- package/components/primitives/Progress/Progress.tsx +31 -0
- package/components/primitives/Progress/index.ts +1 -0
- package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
- package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
- package/components/primitives/ScrollArea/index.ts +6 -0
- package/components/primitives/Select/Select.stories.tsx +288 -0
- package/components/primitives/Select/Select.tsx +162 -0
- package/components/primitives/Select/index.ts +22 -0
- package/components/primitives/Separator/Separator.stories.tsx +264 -0
- package/components/primitives/Separator/Separator.tsx +48 -0
- package/components/primitives/Separator/index.ts +7 -0
- package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
- package/components/primitives/Sidebar/Sidebar.tsx +317 -0
- package/components/primitives/Sidebar/index.ts +41 -0
- package/components/primitives/Table/Table.stories.tsx +389 -0
- package/components/primitives/Table/Table.tsx +191 -0
- package/components/primitives/Table/index.ts +26 -0
- package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
- package/components/primitives/Tabs/Tabs.tsx +70 -0
- package/components/primitives/Tabs/index.ts +13 -0
- package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
- package/components/primitives/Textarea/Textarea.tsx +91 -0
- package/components/primitives/Textarea/index.ts +7 -0
- package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
- package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
- package/components/primitives/ToggleGroup/index.ts +6 -0
- package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
- package/components/primitives/Tooltip/Tooltip.tsx +78 -0
- package/components/primitives/Tooltip/index.ts +10 -0
- package/components/primitives/index.ts +34 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +157 -0
- package/components/ui/alert.tsx +66 -0
- package/components/ui/avatar.tsx +53 -0
- package/components/ui/badge.tsx +46 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/card.tsx +117 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +334 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +184 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/drawer.tsx +118 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/input-group.tsx +170 -0
- package/components/ui/input.tsx +48 -0
- package/components/ui/label.tsx +26 -0
- package/components/ui/popover.tsx +33 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/select.tsx +187 -0
- package/components/ui/separator.tsx +31 -0
- package/components/ui/sidebar.tsx +577 -0
- package/components/ui/table.tsx +120 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +46 -0
- package/components/ui/toggle-group.tsx +83 -0
- package/components/ui/toggle.tsx +47 -0
- package/components/ui/tooltip.tsx +61 -0
- package/dist/index.cjs +7389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +75 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +7160 -0
- package/dist/index.js.map +1 -0
- package/hooks/useAIDocReviewer.d.ts +0 -0
- package/lib/utils.ts +6 -0
- package/package.json +140 -0
- package/tokens/color/base.json +14 -0
- package/tokens/color/dark.json +40 -0
- package/tokens/color/green.json +21 -0
- package/tokens/color/light.json +52 -0
- package/tokens/color/neutral.json +20 -0
- package/tokens/color/violet.json +21 -0
- package/tokens/spacing.json +22 -0
- package/utils/ai-editor/format-date.ts +41 -0
- package/utils/ai-editor/index.ts +22 -0
- package/utils/ai-editor/type-guards.ts +72 -0
- package/utils/ai-editor/validation.ts +130 -0
- package/utils/editor-annotations.ts +122 -0
package/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# UI Library - Design System
|
|
2
|
+
|
|
3
|
+
The official design system and component library for Bizmatters, built with Next.js, React, Tailwind CSS, and shadcn/ui.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Initial Setup
|
|
8
|
+
|
|
9
|
+
After cloning the repository, set up the git hooks for design system governance:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd packages/ui-lib
|
|
13
|
+
./scripts/setup-hooks.sh
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This will install pre-commit hooks that enforce:
|
|
17
|
+
- Layer import architecture validation
|
|
18
|
+
- Storybook coverage validation
|
|
19
|
+
|
|
20
|
+
### Development Server
|
|
21
|
+
|
|
22
|
+
Run the development server:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm dev
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Open [http://localhost:3000](http://localhost:3000) to see the result.
|
|
29
|
+
|
|
30
|
+
### Storybook
|
|
31
|
+
|
|
32
|
+
Run Storybook for component development and documentation:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm storybook
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Open [http://localhost:6006](http://localhost:6006) to view the component library.
|
|
39
|
+
|
|
40
|
+
## Design System Governance
|
|
41
|
+
|
|
42
|
+
### Pre-Commit Hooks
|
|
43
|
+
|
|
44
|
+
The design system enforces strict quality standards through automated pre-commit hooks:
|
|
45
|
+
|
|
46
|
+
**Master Validation Script**
|
|
47
|
+
- Runs all design system validations in a single command
|
|
48
|
+
- Run manually: `bash scripts/run-all-validations.sh` or `pnpm run prebuild`
|
|
49
|
+
|
|
50
|
+
**Layer Import Architecture**
|
|
51
|
+
- Validates that components follow the layered architecture pattern
|
|
52
|
+
- Ensures primitives don't import from patterns or features
|
|
53
|
+
- Ensures patterns don't import from features
|
|
54
|
+
- Run manually: `python3 scripts/validate-layer-imports.py`
|
|
55
|
+
|
|
56
|
+
**Storybook Coverage**
|
|
57
|
+
- Ensures every component has a corresponding `.stories.tsx` file
|
|
58
|
+
- Validates story file naming conventions
|
|
59
|
+
- Run manually: `node scripts/validate-storybook-coverage.js`
|
|
60
|
+
|
|
61
|
+
**Adding New Validations**
|
|
62
|
+
To add a new validation to the master script, edit `scripts/run-all-validations.sh`:
|
|
63
|
+
1. Add a new section with clear header and description
|
|
64
|
+
2. Run your validation script and capture exit code
|
|
65
|
+
3. Add the exit code to the final results check
|
|
66
|
+
4. The script provides clear guidance with comments for adding new validations
|
|
67
|
+
|
|
68
|
+
**Bypassing Hooks (Not Recommended)**
|
|
69
|
+
```bash
|
|
70
|
+
git commit --no-verify
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Only bypass hooks if you have a valid reason and plan to fix violations immediately.
|
|
74
|
+
|
|
75
|
+
## Project Structure
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
packages/ui-lib/
|
|
79
|
+
├── components/
|
|
80
|
+
│ ├── primitives/ # Base components (buttons, inputs, etc.)
|
|
81
|
+
│ ├── patterns/ # Composite components (cards, forms, etc.)
|
|
82
|
+
│ └── features/ # Feature-specific components
|
|
83
|
+
├── scripts/
|
|
84
|
+
│ ├── hooks/ # Git hooks (tracked in version control)
|
|
85
|
+
│ │ └── pre-commit # Pre-commit validation hook
|
|
86
|
+
│ ├── setup-hooks.sh # Hook installation script
|
|
87
|
+
│ ├── run-all-validations.sh # Master validation script
|
|
88
|
+
│ ├── validate-layer-imports.py
|
|
89
|
+
│ └── validate-storybook-coverage.js
|
|
90
|
+
├── styles/ # Global styles and themes
|
|
91
|
+
└── tokens/ # Design tokens
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Layer Architecture
|
|
95
|
+
|
|
96
|
+
The design system follows a strict three-layer architecture:
|
|
97
|
+
|
|
98
|
+
1. **Primitives** - Base components with no dependencies on other layers
|
|
99
|
+
- Examples: Button, Input, Textarea, Badge
|
|
100
|
+
- Can only import from external libraries and utilities
|
|
101
|
+
|
|
102
|
+
2. **Patterns** - Composite components built from primitives
|
|
103
|
+
- Examples: Card, Form, Dialog
|
|
104
|
+
- Can import from primitives and external libraries
|
|
105
|
+
|
|
106
|
+
3. **Features** - Feature-specific components
|
|
107
|
+
- Examples: AIConversation, RefinementPanel
|
|
108
|
+
- Can import from primitives, patterns, and external libraries
|
|
109
|
+
|
|
110
|
+
**Import Rules:**
|
|
111
|
+
- Primitives → No internal imports
|
|
112
|
+
- Patterns → Can import Primitives
|
|
113
|
+
- Features → Can import Primitives + Patterns
|
|
114
|
+
|
|
115
|
+
## Available Scripts
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pnpm dev # Start development server
|
|
119
|
+
pnpm build # Build for production
|
|
120
|
+
pnpm start # Start production server
|
|
121
|
+
pnpm lint # Run ESLint
|
|
122
|
+
pnpm tokens:build # Build design tokens
|
|
123
|
+
pnpm tokens:watch # Watch design tokens
|
|
124
|
+
pnpm storybook # Start Storybook dev server
|
|
125
|
+
pnpm build-storybook # Build Storybook for production
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Creating New Components
|
|
129
|
+
|
|
130
|
+
### 1. Choose the Correct Layer
|
|
131
|
+
|
|
132
|
+
Determine which layer your component belongs to:
|
|
133
|
+
- **Primitive**: Standalone, reusable UI element
|
|
134
|
+
- **Pattern**: Combination of primitives
|
|
135
|
+
- **Feature**: Domain-specific component
|
|
136
|
+
|
|
137
|
+
### 2. Create Component File
|
|
138
|
+
|
|
139
|
+
Create your component following the established structure:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
// components/primitives/YourComponent/YourComponent.tsx
|
|
143
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
144
|
+
import { cn } from "@/lib/utils";
|
|
145
|
+
|
|
146
|
+
const yourComponentVariants = cva(
|
|
147
|
+
"base-classes",
|
|
148
|
+
{
|
|
149
|
+
variants: {
|
|
150
|
+
variant: {
|
|
151
|
+
default: "variant-classes",
|
|
152
|
+
secondary: "variant-classes",
|
|
153
|
+
},
|
|
154
|
+
size: {
|
|
155
|
+
default: "size-classes",
|
|
156
|
+
sm: "size-classes",
|
|
157
|
+
lg: "size-classes",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
defaultVariants: {
|
|
161
|
+
variant: "default",
|
|
162
|
+
size: "default",
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
export interface YourComponentProps
|
|
168
|
+
extends React.HTMLAttributes<HTMLElement>,
|
|
169
|
+
VariantProps<typeof yourComponentVariants> {
|
|
170
|
+
// Additional props
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function YourComponent({
|
|
174
|
+
className,
|
|
175
|
+
variant,
|
|
176
|
+
size,
|
|
177
|
+
...props
|
|
178
|
+
}: YourComponentProps) {
|
|
179
|
+
return (
|
|
180
|
+
<div
|
|
181
|
+
className={cn(yourComponentVariants({ variant, size, className }))}
|
|
182
|
+
{...props}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 3. Create Index File
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
// components/primitives/YourComponent/index.ts
|
|
192
|
+
export { YourComponent } from "./YourComponent";
|
|
193
|
+
export type { YourComponentProps } from "./YourComponent";
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 4. Create Storybook Story (REQUIRED)
|
|
197
|
+
|
|
198
|
+
Every component must have a `.stories.tsx` file:
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
// components/primitives/YourComponent/YourComponent.stories.tsx
|
|
202
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
203
|
+
import { YourComponent } from "./YourComponent";
|
|
204
|
+
|
|
205
|
+
const meta = {
|
|
206
|
+
title: "Primitives/YourComponent",
|
|
207
|
+
component: YourComponent,
|
|
208
|
+
tags: ["autodocs"],
|
|
209
|
+
parameters: {
|
|
210
|
+
layout: "centered",
|
|
211
|
+
},
|
|
212
|
+
} satisfies Meta<typeof YourComponent>;
|
|
213
|
+
|
|
214
|
+
export default meta;
|
|
215
|
+
type Story = StoryObj<typeof meta>;
|
|
216
|
+
|
|
217
|
+
export const Default: Story = {
|
|
218
|
+
args: {
|
|
219
|
+
// default props
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export const Variant: Story = {
|
|
224
|
+
args: {
|
|
225
|
+
variant: "secondary",
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 5. Validate
|
|
231
|
+
|
|
232
|
+
Run validation scripts to ensure compliance:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Run all validations (recommended)
|
|
236
|
+
bash scripts/run-all-validations.sh
|
|
237
|
+
# or
|
|
238
|
+
pnpm run prebuild
|
|
239
|
+
|
|
240
|
+
# Run individual validations
|
|
241
|
+
python3 scripts/validate-layer-imports.py # Layer architecture
|
|
242
|
+
node scripts/validate-storybook-coverage.js # Storybook coverage
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Design Tokens
|
|
246
|
+
|
|
247
|
+
The design system uses Style Dictionary for design tokens management:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Build tokens once
|
|
251
|
+
pnpm tokens:build
|
|
252
|
+
|
|
253
|
+
# Watch for changes
|
|
254
|
+
pnpm tokens:watch
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Tokens are defined in the `tokens/` directory and compiled to CSS custom properties.
|
|
258
|
+
|
|
259
|
+
## Technology Stack
|
|
260
|
+
|
|
261
|
+
- **Framework**: Next.js 16 with App Router
|
|
262
|
+
- **UI**: React 19
|
|
263
|
+
- **Styling**: Tailwind CSS 4
|
|
264
|
+
- **Component Variants**: Class Variance Authority (CVA)
|
|
265
|
+
- **Component Foundation**: Radix UI primitives
|
|
266
|
+
- **Documentation**: Storybook 10
|
|
267
|
+
- **Type Safety**: TypeScript 5 (strict mode)
|
|
268
|
+
- **Icons**: Lucide React
|
|
269
|
+
- **Animation**: Motion (Framer Motion)
|
|
270
|
+
|
|
271
|
+
## Accessibility
|
|
272
|
+
|
|
273
|
+
All components must meet WCAG 2.1 Level AA standards:
|
|
274
|
+
- Keyboard navigation support
|
|
275
|
+
- Screen reader compatibility
|
|
276
|
+
- Proper ARIA attributes
|
|
277
|
+
- Focus management
|
|
278
|
+
- Color contrast requirements
|
|
279
|
+
|
|
280
|
+
## Theming
|
|
281
|
+
|
|
282
|
+
The design system supports:
|
|
283
|
+
- Light and dark modes
|
|
284
|
+
- Design token-based theming
|
|
285
|
+
- CSS custom properties
|
|
286
|
+
- Responsive design across all breakpoints
|
|
287
|
+
|
|
288
|
+
## Contributing
|
|
289
|
+
|
|
290
|
+
1. Set up git hooks: `./scripts/setup-hooks.sh`
|
|
291
|
+
2. Create components following the layer architecture
|
|
292
|
+
3. Include Storybook stories for all components
|
|
293
|
+
4. Ensure all validations pass before committing
|
|
294
|
+
5. Document accessibility features and keyboard shortcuts
|
|
295
|
+
|
|
296
|
+
## Learn More
|
|
297
|
+
|
|
298
|
+
- [Next.js Documentation](https://nextjs.org/docs)
|
|
299
|
+
- [Tailwind CSS](https://tailwindcss.com)
|
|
300
|
+
- [Radix UI](https://www.radix-ui.com)
|
|
301
|
+
- [shadcn/ui](https://ui.shadcn.com)
|
|
302
|
+
- [Storybook](https://storybook.js.org)
|
|
303
|
+
- [CVA](https://cva.style)
|
|
304
|
+
|
|
305
|
+
## Support
|
|
306
|
+
|
|
307
|
+
For questions or issues with the design system, contact the Design System Guardian or open an issue in the repository.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import {
|
|
5
|
+
Tooltip,
|
|
6
|
+
TooltipContent,
|
|
7
|
+
TooltipProvider,
|
|
8
|
+
TooltipTrigger,
|
|
9
|
+
} from "@/components/ui/tooltip";
|
|
10
|
+
import { cn } from "@/lib/utils";
|
|
11
|
+
import type { ComponentProps } from "react";
|
|
12
|
+
|
|
13
|
+
export type ActionsProps = ComponentProps<"div">;
|
|
14
|
+
|
|
15
|
+
export const Actions = ({ className, children, ...props }: ActionsProps) => (
|
|
16
|
+
<div className={cn("flex items-center gap-1", className)} {...props}>
|
|
17
|
+
{children}
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export type ActionProps = ComponentProps<typeof Button> & {
|
|
22
|
+
tooltip?: string;
|
|
23
|
+
label?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Action = ({
|
|
27
|
+
tooltip,
|
|
28
|
+
children,
|
|
29
|
+
label,
|
|
30
|
+
className,
|
|
31
|
+
variant = "ghost",
|
|
32
|
+
size = "sm",
|
|
33
|
+
...props
|
|
34
|
+
}: ActionProps) => {
|
|
35
|
+
const button = (
|
|
36
|
+
<Button
|
|
37
|
+
className={cn(
|
|
38
|
+
"relative size-9 p-1.5 text-muted-foreground hover:text-foreground",
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
size={size}
|
|
42
|
+
type="button"
|
|
43
|
+
variant={variant}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
<span className="sr-only">{label || tooltip}</span>
|
|
48
|
+
</Button>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (tooltip) {
|
|
52
|
+
return (
|
|
53
|
+
<TooltipProvider>
|
|
54
|
+
<Tooltip>
|
|
55
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
56
|
+
<TooltipContent>
|
|
57
|
+
<p>{tooltip}</p>
|
|
58
|
+
</TooltipContent>
|
|
59
|
+
</Tooltip>
|
|
60
|
+
</TooltipProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return button;
|
|
65
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import {
|
|
5
|
+
Tooltip,
|
|
6
|
+
TooltipContent,
|
|
7
|
+
TooltipProvider,
|
|
8
|
+
TooltipTrigger,
|
|
9
|
+
} from "@/components/ui/tooltip";
|
|
10
|
+
import { cn } from "@/lib/utils";
|
|
11
|
+
import { type LucideIcon, XIcon } from "lucide-react";
|
|
12
|
+
import type { ComponentProps, HTMLAttributes } from "react";
|
|
13
|
+
|
|
14
|
+
export type ArtifactProps = HTMLAttributes<HTMLDivElement>;
|
|
15
|
+
|
|
16
|
+
export const Artifact = ({ className, ...props }: ArtifactProps) => (
|
|
17
|
+
<div
|
|
18
|
+
className={cn(
|
|
19
|
+
"flex flex-col overflow-hidden rounded-lg border bg-background shadow-sm",
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export type ArtifactHeaderProps = HTMLAttributes<HTMLDivElement>;
|
|
27
|
+
|
|
28
|
+
export const ArtifactHeader = ({
|
|
29
|
+
className,
|
|
30
|
+
...props
|
|
31
|
+
}: ArtifactHeaderProps) => (
|
|
32
|
+
<div
|
|
33
|
+
className={cn(
|
|
34
|
+
"flex items-center justify-between border-b bg-muted/50 px-4 py-3",
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export type ArtifactCloseProps = ComponentProps<typeof Button>;
|
|
42
|
+
|
|
43
|
+
export const ArtifactClose = ({
|
|
44
|
+
className,
|
|
45
|
+
children,
|
|
46
|
+
size = "sm",
|
|
47
|
+
variant = "ghost",
|
|
48
|
+
...props
|
|
49
|
+
}: ArtifactCloseProps) => (
|
|
50
|
+
<Button
|
|
51
|
+
className={cn(
|
|
52
|
+
"size-8 p-0 text-muted-foreground hover:text-foreground",
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
size={size}
|
|
56
|
+
type="button"
|
|
57
|
+
variant={variant}
|
|
58
|
+
{...props}
|
|
59
|
+
>
|
|
60
|
+
{children ?? <XIcon className="size-4" />}
|
|
61
|
+
<span className="sr-only">Close</span>
|
|
62
|
+
</Button>
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
export type ArtifactTitleProps = HTMLAttributes<HTMLParagraphElement>;
|
|
66
|
+
|
|
67
|
+
export const ArtifactTitle = ({ className, ...props }: ArtifactTitleProps) => (
|
|
68
|
+
<p
|
|
69
|
+
className={cn("font-medium text-foreground text-sm", className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
export type ArtifactDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
|
|
75
|
+
|
|
76
|
+
export const ArtifactDescription = ({
|
|
77
|
+
className,
|
|
78
|
+
...props
|
|
79
|
+
}: ArtifactDescriptionProps) => (
|
|
80
|
+
<p className={cn("text-muted-foreground text-sm", className)} {...props} />
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
export type ArtifactActionsProps = HTMLAttributes<HTMLDivElement>;
|
|
84
|
+
|
|
85
|
+
export const ArtifactActions = ({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: ArtifactActionsProps) => (
|
|
89
|
+
<div className={cn("flex items-center gap-1", className)} {...props} />
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
export type ArtifactActionProps = ComponentProps<typeof Button> & {
|
|
93
|
+
tooltip?: string;
|
|
94
|
+
label?: string;
|
|
95
|
+
icon?: LucideIcon;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const ArtifactAction = ({
|
|
99
|
+
tooltip,
|
|
100
|
+
label,
|
|
101
|
+
icon: Icon,
|
|
102
|
+
children,
|
|
103
|
+
className,
|
|
104
|
+
size = "sm",
|
|
105
|
+
variant = "ghost",
|
|
106
|
+
...props
|
|
107
|
+
}: ArtifactActionProps) => {
|
|
108
|
+
const button = (
|
|
109
|
+
<Button
|
|
110
|
+
className={cn(
|
|
111
|
+
"size-8 p-0 text-muted-foreground hover:text-foreground",
|
|
112
|
+
className
|
|
113
|
+
)}
|
|
114
|
+
size={size}
|
|
115
|
+
type="button"
|
|
116
|
+
variant={variant}
|
|
117
|
+
{...props}
|
|
118
|
+
>
|
|
119
|
+
{Icon ? <Icon className="size-4" /> : children}
|
|
120
|
+
<span className="sr-only">{label || tooltip}</span>
|
|
121
|
+
</Button>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
if (tooltip) {
|
|
125
|
+
return (
|
|
126
|
+
<TooltipProvider>
|
|
127
|
+
<Tooltip>
|
|
128
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
129
|
+
<TooltipContent>
|
|
130
|
+
<p>{tooltip}</p>
|
|
131
|
+
</TooltipContent>
|
|
132
|
+
</Tooltip>
|
|
133
|
+
</TooltipProvider>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return button;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export type ArtifactContentProps = HTMLAttributes<HTMLDivElement>;
|
|
141
|
+
|
|
142
|
+
export const ArtifactContent = ({
|
|
143
|
+
className,
|
|
144
|
+
...props
|
|
145
|
+
}: ArtifactContentProps) => (
|
|
146
|
+
<div className={cn("flex-1 overflow-auto p-4", className)} {...props} />
|
|
147
|
+
);
|