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
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent } from './Chart'
|
|
3
|
+
import type { ChartConfig } from './Chart'
|
|
4
|
+
import { BarChart, Bar, LineChart, Line, AreaChart, Area, XAxis, YAxis, CartesianGrid } from 'recharts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Chart Primitive Stories
|
|
8
|
+
*
|
|
9
|
+
* The Chart component is a foundational primitive for data visualizations.
|
|
10
|
+
* It extends shadcn/ui's Chart with design system-specific enhancements and maintains
|
|
11
|
+
* full accessibility compliance (WCAG 2.1 Level AA).
|
|
12
|
+
*
|
|
13
|
+
* ## Features
|
|
14
|
+
* - Built on Recharts for powerful visualizations
|
|
15
|
+
* - Automatic theming with design tokens
|
|
16
|
+
* - Responsive container
|
|
17
|
+
* - Accessible tooltips and legends
|
|
18
|
+
* - Dark mode support
|
|
19
|
+
*
|
|
20
|
+
* ## Accessibility
|
|
21
|
+
* - Proper ARIA labels for charts
|
|
22
|
+
* - Keyboard navigation support
|
|
23
|
+
* - Screen reader compatible tooltips
|
|
24
|
+
* - Color-blind friendly palettes
|
|
25
|
+
*
|
|
26
|
+
* ## Usage Guidelines
|
|
27
|
+
*
|
|
28
|
+
* ### Do's
|
|
29
|
+
* - Use ChartConfig to define data series
|
|
30
|
+
* - Provide meaningful labels
|
|
31
|
+
* - Use appropriate chart types for data
|
|
32
|
+
* - Include tooltips for data points
|
|
33
|
+
*
|
|
34
|
+
* ### Don'ts
|
|
35
|
+
* - Don't use too many data series
|
|
36
|
+
* - Don't omit axis labels
|
|
37
|
+
* - Don't use charts for simple data
|
|
38
|
+
* - Don't rely solely on color to convey meaning
|
|
39
|
+
*/
|
|
40
|
+
const meta = {
|
|
41
|
+
title: 'Primitives/Chart',
|
|
42
|
+
component: ChartContainer,
|
|
43
|
+
tags: ['autodocs'],
|
|
44
|
+
parameters: {
|
|
45
|
+
layout: 'padded',
|
|
46
|
+
docs: {
|
|
47
|
+
description: {
|
|
48
|
+
component: 'A chart component for data visualizations, built on Recharts and shadcn/ui foundation.',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
} satisfies Meta<typeof ChartContainer>
|
|
53
|
+
|
|
54
|
+
export default meta
|
|
55
|
+
type Story = StoryObj<typeof meta>
|
|
56
|
+
|
|
57
|
+
const chartData = [
|
|
58
|
+
{ month: 'January', desktop: 186, mobile: 80 },
|
|
59
|
+
{ month: 'February', desktop: 305, mobile: 200 },
|
|
60
|
+
{ month: 'March', desktop: 237, mobile: 120 },
|
|
61
|
+
{ month: 'April', desktop: 73, mobile: 190 },
|
|
62
|
+
{ month: 'May', desktop: 209, mobile: 130 },
|
|
63
|
+
{ month: 'June', desktop: 214, mobile: 140 },
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
const chartConfig = {
|
|
67
|
+
desktop: {
|
|
68
|
+
label: 'Desktop',
|
|
69
|
+
color: 'hsl(var(--chart-1))',
|
|
70
|
+
},
|
|
71
|
+
mobile: {
|
|
72
|
+
label: 'Mobile',
|
|
73
|
+
color: 'hsl(var(--chart-2))',
|
|
74
|
+
},
|
|
75
|
+
} satisfies ChartConfig
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Bar Chart
|
|
79
|
+
*
|
|
80
|
+
* Basic bar chart with two data series.
|
|
81
|
+
*/
|
|
82
|
+
export const BarChartExample: Story = {
|
|
83
|
+
render: () => (
|
|
84
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '300px', width: '100%' }}>
|
|
85
|
+
<BarChart data={chartData}>
|
|
86
|
+
<CartesianGrid vertical={false} />
|
|
87
|
+
<XAxis
|
|
88
|
+
dataKey="month"
|
|
89
|
+
tickLine={false}
|
|
90
|
+
tickMargin={10}
|
|
91
|
+
axisLine={false}
|
|
92
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
93
|
+
/>
|
|
94
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
95
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
96
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
97
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
98
|
+
</BarChart>
|
|
99
|
+
</ChartContainer>
|
|
100
|
+
),
|
|
101
|
+
parameters: {
|
|
102
|
+
docs: {
|
|
103
|
+
description: {
|
|
104
|
+
story: 'A bar chart comparing desktop and mobile usage across months.',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Line Chart
|
|
112
|
+
*
|
|
113
|
+
* Line chart showing trends over time.
|
|
114
|
+
*/
|
|
115
|
+
export const LineChartExample: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '300px', width: '100%' }}>
|
|
118
|
+
<LineChart data={chartData}>
|
|
119
|
+
<CartesianGrid vertical={false} />
|
|
120
|
+
<XAxis
|
|
121
|
+
dataKey="month"
|
|
122
|
+
tickLine={false}
|
|
123
|
+
axisLine={false}
|
|
124
|
+
tickMargin={8}
|
|
125
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
126
|
+
/>
|
|
127
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
128
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
129
|
+
<Line
|
|
130
|
+
dataKey="desktop"
|
|
131
|
+
type="monotone"
|
|
132
|
+
stroke="var(--color-desktop)"
|
|
133
|
+
strokeWidth={2}
|
|
134
|
+
dot={false}
|
|
135
|
+
/>
|
|
136
|
+
<Line
|
|
137
|
+
dataKey="mobile"
|
|
138
|
+
type="monotone"
|
|
139
|
+
stroke="var(--color-mobile)"
|
|
140
|
+
strokeWidth={2}
|
|
141
|
+
dot={false}
|
|
142
|
+
/>
|
|
143
|
+
</LineChart>
|
|
144
|
+
</ChartContainer>
|
|
145
|
+
),
|
|
146
|
+
parameters: {
|
|
147
|
+
docs: {
|
|
148
|
+
description: {
|
|
149
|
+
story: 'A line chart showing trends in desktop and mobile usage.',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Area Chart
|
|
157
|
+
*
|
|
158
|
+
* Area chart with filled regions.
|
|
159
|
+
*/
|
|
160
|
+
export const AreaChartExample: Story = {
|
|
161
|
+
render: () => (
|
|
162
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '300px', width: '100%' }}>
|
|
163
|
+
<AreaChart data={chartData}>
|
|
164
|
+
<CartesianGrid vertical={false} />
|
|
165
|
+
<XAxis
|
|
166
|
+
dataKey="month"
|
|
167
|
+
tickLine={false}
|
|
168
|
+
axisLine={false}
|
|
169
|
+
tickMargin={8}
|
|
170
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
171
|
+
/>
|
|
172
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
173
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
174
|
+
<Area
|
|
175
|
+
dataKey="desktop"
|
|
176
|
+
type="monotone"
|
|
177
|
+
fill="var(--color-desktop)"
|
|
178
|
+
fillOpacity={0.4}
|
|
179
|
+
stroke="var(--color-desktop)"
|
|
180
|
+
/>
|
|
181
|
+
<Area
|
|
182
|
+
dataKey="mobile"
|
|
183
|
+
type="monotone"
|
|
184
|
+
fill="var(--color-mobile)"
|
|
185
|
+
fillOpacity={0.4}
|
|
186
|
+
stroke="var(--color-mobile)"
|
|
187
|
+
/>
|
|
188
|
+
</AreaChart>
|
|
189
|
+
</ChartContainer>
|
|
190
|
+
),
|
|
191
|
+
parameters: {
|
|
192
|
+
docs: {
|
|
193
|
+
description: {
|
|
194
|
+
story: 'An area chart with filled regions showing cumulative data.',
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* With Y Axis
|
|
202
|
+
*
|
|
203
|
+
* Chart with both X and Y axes.
|
|
204
|
+
*/
|
|
205
|
+
export const WithYAxis: Story = {
|
|
206
|
+
render: () => (
|
|
207
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '300px', width: '100%' }}>
|
|
208
|
+
<BarChart data={chartData}>
|
|
209
|
+
<CartesianGrid vertical={false} />
|
|
210
|
+
<XAxis
|
|
211
|
+
dataKey="month"
|
|
212
|
+
tickLine={false}
|
|
213
|
+
tickMargin={10}
|
|
214
|
+
axisLine={false}
|
|
215
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
216
|
+
/>
|
|
217
|
+
<YAxis tickLine={false} axisLine={false} tickMargin={8} />
|
|
218
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
219
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
220
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
221
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
222
|
+
</BarChart>
|
|
223
|
+
</ChartContainer>
|
|
224
|
+
),
|
|
225
|
+
parameters: {
|
|
226
|
+
docs: {
|
|
227
|
+
description: {
|
|
228
|
+
story: 'Chart with Y axis for better value reference.',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Single Series
|
|
236
|
+
*
|
|
237
|
+
* Chart with a single data series.
|
|
238
|
+
*/
|
|
239
|
+
export const SingleSeries: Story = {
|
|
240
|
+
render: () => {
|
|
241
|
+
const singleConfig = {
|
|
242
|
+
desktop: {
|
|
243
|
+
label: 'Desktop',
|
|
244
|
+
color: 'hsl(var(--chart-1))',
|
|
245
|
+
},
|
|
246
|
+
} satisfies ChartConfig
|
|
247
|
+
|
|
248
|
+
return (
|
|
249
|
+
<ChartContainer config={singleConfig} style={{ minHeight: '300px', width: '100%' }}>
|
|
250
|
+
<BarChart data={chartData}>
|
|
251
|
+
<CartesianGrid vertical={false} />
|
|
252
|
+
<XAxis
|
|
253
|
+
dataKey="month"
|
|
254
|
+
tickLine={false}
|
|
255
|
+
tickMargin={10}
|
|
256
|
+
axisLine={false}
|
|
257
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
258
|
+
/>
|
|
259
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
260
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
261
|
+
</BarChart>
|
|
262
|
+
</ChartContainer>
|
|
263
|
+
)
|
|
264
|
+
},
|
|
265
|
+
parameters: {
|
|
266
|
+
docs: {
|
|
267
|
+
description: {
|
|
268
|
+
story: 'Chart with a single data series for simpler visualizations.',
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Dark Mode Preview
|
|
276
|
+
*
|
|
277
|
+
* Charts in dark mode to verify theming compatibility.
|
|
278
|
+
*/
|
|
279
|
+
export const DarkMode: Story = {
|
|
280
|
+
render: () => (
|
|
281
|
+
<div className="dark" style={{ padding: '24px', background: 'hsl(222.2 84% 4.9%)', borderRadius: '8px' }}>
|
|
282
|
+
<div style={{ marginBottom: '24px' }}>
|
|
283
|
+
<h3 style={{ fontSize: '16px', fontWeight: 600, marginBottom: '16px', color: 'hsl(var(--foreground))' }}>
|
|
284
|
+
Bar Chart
|
|
285
|
+
</h3>
|
|
286
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '250px', width: '100%' }}>
|
|
287
|
+
<BarChart data={chartData}>
|
|
288
|
+
<CartesianGrid vertical={false} />
|
|
289
|
+
<XAxis
|
|
290
|
+
dataKey="month"
|
|
291
|
+
tickLine={false}
|
|
292
|
+
tickMargin={10}
|
|
293
|
+
axisLine={false}
|
|
294
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
295
|
+
/>
|
|
296
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
297
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
298
|
+
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
|
299
|
+
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
|
300
|
+
</BarChart>
|
|
301
|
+
</ChartContainer>
|
|
302
|
+
</div>
|
|
303
|
+
<div>
|
|
304
|
+
<h3 style={{ fontSize: '16px', fontWeight: 600, marginBottom: '16px', color: 'hsl(var(--foreground))' }}>
|
|
305
|
+
Line Chart
|
|
306
|
+
</h3>
|
|
307
|
+
<ChartContainer config={chartConfig} style={{ minHeight: '250px', width: '100%' }}>
|
|
308
|
+
<LineChart data={chartData}>
|
|
309
|
+
<CartesianGrid vertical={false} />
|
|
310
|
+
<XAxis
|
|
311
|
+
dataKey="month"
|
|
312
|
+
tickLine={false}
|
|
313
|
+
axisLine={false}
|
|
314
|
+
tickMargin={8}
|
|
315
|
+
tickFormatter={(value) => value.slice(0, 3)}
|
|
316
|
+
/>
|
|
317
|
+
<ChartTooltip content={<ChartTooltipContent />} />
|
|
318
|
+
<ChartLegend content={<ChartLegendContent />} />
|
|
319
|
+
<Line
|
|
320
|
+
dataKey="desktop"
|
|
321
|
+
type="monotone"
|
|
322
|
+
stroke="var(--color-desktop)"
|
|
323
|
+
strokeWidth={2}
|
|
324
|
+
dot={false}
|
|
325
|
+
/>
|
|
326
|
+
<Line
|
|
327
|
+
dataKey="mobile"
|
|
328
|
+
type="monotone"
|
|
329
|
+
stroke="var(--color-mobile)"
|
|
330
|
+
strokeWidth={2}
|
|
331
|
+
dot={false}
|
|
332
|
+
/>
|
|
333
|
+
</LineChart>
|
|
334
|
+
</ChartContainer>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
),
|
|
338
|
+
parameters: {
|
|
339
|
+
docs: {
|
|
340
|
+
description: {
|
|
341
|
+
story: 'Charts automatically adapt to dark mode with appropriate contrast and visibility.',
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
backgrounds: { disable: true },
|
|
345
|
+
},
|
|
346
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
ChartContainer as ShadcnChartContainer,
|
|
4
|
+
ChartTooltip as ShadcnChartTooltip,
|
|
5
|
+
ChartTooltipContent as ShadcnChartTooltipContent,
|
|
6
|
+
ChartLegend as ShadcnChartLegend,
|
|
7
|
+
ChartLegendContent as ShadcnChartLegendContent,
|
|
8
|
+
ChartStyle as ShadcnChartStyle,
|
|
9
|
+
} from "../../ui/chart"
|
|
10
|
+
import type { ChartConfig } from "../../ui/chart"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Chart Primitive
|
|
14
|
+
*
|
|
15
|
+
* A foundational chart component that wraps shadcn/ui Chart with design system
|
|
16
|
+
* enhancements. This primitive serves as the single source of truth for all data
|
|
17
|
+
* visualizations across the application.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const chartConfig = {
|
|
22
|
+
* desktop: { label: "Desktop", color: "var(--chart-1)" },
|
|
23
|
+
* mobile: { label: "Mobile", color: "var(--chart-2)" },
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* <ChartContainer config={chartConfig}>
|
|
27
|
+
* <BarChart data={data}>
|
|
28
|
+
* <Bar dataKey="desktop" fill="var(--color-desktop)" />
|
|
29
|
+
* <Bar dataKey="mobile" fill="var(--color-mobile)" />
|
|
30
|
+
* </BarChart>
|
|
31
|
+
* </ChartContainer>
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @see https://ui.shadcn.com/docs/components/chart - shadcn/ui Chart documentation
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* ChartContainer component props
|
|
39
|
+
*/
|
|
40
|
+
export type ChartContainerProps = React.ComponentProps<typeof ShadcnChartContainer>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ChartContainer component
|
|
44
|
+
*
|
|
45
|
+
* Container for chart components with configuration and theming.
|
|
46
|
+
*/
|
|
47
|
+
export const ChartContainer = React.memo(
|
|
48
|
+
React.forwardRef<HTMLDivElement, ChartContainerProps>((props, ref) => {
|
|
49
|
+
return <ShadcnChartContainer ref={ref} {...props} />
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
ChartContainer.displayName = "ChartContainer"
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* ChartTooltip component
|
|
57
|
+
*
|
|
58
|
+
* Tooltip component for charts from Recharts.
|
|
59
|
+
*/
|
|
60
|
+
export const ChartTooltip = ShadcnChartTooltip
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* ChartTooltipContent component props
|
|
64
|
+
*/
|
|
65
|
+
export type ChartTooltipContentProps = React.ComponentProps<typeof ShadcnChartTooltipContent>
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* ChartTooltipContent component
|
|
69
|
+
*
|
|
70
|
+
* Styled tooltip content for charts.
|
|
71
|
+
*/
|
|
72
|
+
export const ChartTooltipContent = React.memo(
|
|
73
|
+
React.forwardRef<HTMLDivElement, ChartTooltipContentProps>((props, ref) => {
|
|
74
|
+
return <ShadcnChartTooltipContent ref={ref} {...props} />
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
ChartTooltipContent.displayName = "ChartTooltipContent"
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* ChartLegend component
|
|
82
|
+
*
|
|
83
|
+
* Legend component for charts from Recharts.
|
|
84
|
+
*/
|
|
85
|
+
export const ChartLegend = ShadcnChartLegend
|
|
86
|
+
|
|
87
|
+
ChartLegend.displayName = "ChartLegend"
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* ChartLegendContent component props
|
|
91
|
+
*/
|
|
92
|
+
export type ChartLegendContentProps = React.ComponentProps<typeof ShadcnChartLegendContent>
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* ChartLegendContent component
|
|
96
|
+
*
|
|
97
|
+
* Styled legend content for charts.
|
|
98
|
+
*/
|
|
99
|
+
export const ChartLegendContent = React.memo(
|
|
100
|
+
React.forwardRef<HTMLDivElement, ChartLegendContentProps>((props, ref) => {
|
|
101
|
+
return <ShadcnChartLegendContent ref={ref} {...props} />
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
ChartLegendContent.displayName = "ChartLegendContent"
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* ChartStyle component
|
|
109
|
+
*
|
|
110
|
+
* Internal component for injecting chart color styles.
|
|
111
|
+
*/
|
|
112
|
+
export const ChartStyle = ShadcnChartStyle
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Re-export ChartConfig type for chart configuration
|
|
116
|
+
*/
|
|
117
|
+
export type { ChartConfig }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart Primitive
|
|
3
|
+
*
|
|
4
|
+
* Central export point for the Chart primitive component and its related types.
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
ChartContainer,
|
|
8
|
+
ChartTooltip,
|
|
9
|
+
ChartTooltipContent,
|
|
10
|
+
ChartLegend,
|
|
11
|
+
ChartLegendContent,
|
|
12
|
+
ChartStyle,
|
|
13
|
+
} from './Chart'
|
|
14
|
+
|
|
15
|
+
export type {
|
|
16
|
+
ChartContainerProps,
|
|
17
|
+
ChartTooltipContentProps,
|
|
18
|
+
ChartLegendContentProps,
|
|
19
|
+
ChartConfig,
|
|
20
|
+
} from './Chart'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react"
|
|
2
|
+
import { Checkbox } from "./Checkbox"
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Primitives/Checkbox",
|
|
7
|
+
component: Checkbox,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
} satisfies Meta<typeof Checkbox>
|
|
13
|
+
|
|
14
|
+
export default meta
|
|
15
|
+
type Story = StoryObj<typeof meta>
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
render: () => <Checkbox />,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const Checked: Story = {
|
|
22
|
+
render: () => <Checkbox checked />,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Disabled: Story = {
|
|
26
|
+
render: () => (
|
|
27
|
+
<div className="flex gap-4">
|
|
28
|
+
<Checkbox disabled />
|
|
29
|
+
<Checkbox disabled checked />
|
|
30
|
+
</div>
|
|
31
|
+
),
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const Indeterminate: Story = {
|
|
35
|
+
render: () => <Checkbox checked="indeterminate" />,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const WithLabel: Story = {
|
|
39
|
+
render: () => (
|
|
40
|
+
<div className="flex items-center gap-2">
|
|
41
|
+
<Checkbox id="terms" />
|
|
42
|
+
<label
|
|
43
|
+
htmlFor="terms"
|
|
44
|
+
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
45
|
+
>
|
|
46
|
+
Accept terms and conditions
|
|
47
|
+
</label>
|
|
48
|
+
</div>
|
|
49
|
+
),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const Controlled: Story = {
|
|
53
|
+
render: () => {
|
|
54
|
+
const [checked, setChecked] = React.useState(false)
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div className="flex flex-col gap-4">
|
|
58
|
+
<div className="flex items-center gap-2">
|
|
59
|
+
<Checkbox
|
|
60
|
+
id="controlled"
|
|
61
|
+
checked={checked}
|
|
62
|
+
onCheckedChange={setChecked}
|
|
63
|
+
/>
|
|
64
|
+
<label htmlFor="controlled" className="text-sm">
|
|
65
|
+
Controlled checkbox
|
|
66
|
+
</label>
|
|
67
|
+
</div>
|
|
68
|
+
<p className="text-sm text-muted-foreground">
|
|
69
|
+
Status: {checked ? "Checked" : "Unchecked"}
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const DarkMode: Story = {
|
|
77
|
+
parameters: {
|
|
78
|
+
backgrounds: { default: "dark" },
|
|
79
|
+
},
|
|
80
|
+
render: () => (
|
|
81
|
+
<div className="dark flex gap-4">
|
|
82
|
+
<Checkbox />
|
|
83
|
+
<Checkbox checked />
|
|
84
|
+
<Checkbox checked="indeterminate" />
|
|
85
|
+
</div>
|
|
86
|
+
),
|
|
87
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Checkbox as ShadcnCheckbox } from "../../ui/checkbox"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checkbox Primitive
|
|
6
|
+
*
|
|
7
|
+
* A checkbox input component with support for checked, unchecked, and indeterminate states.
|
|
8
|
+
* Built on Radix UI Checkbox primitive with WCAG 2.1 Level AA compliance.
|
|
9
|
+
*
|
|
10
|
+
* @see https://ui.shadcn.com/docs/components/checkbox
|
|
11
|
+
* @see https://www.radix-ui.com/primitives/docs/components/checkbox
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type CheckboxProps = React.ComponentProps<typeof ShadcnCheckbox>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Checkbox component
|
|
18
|
+
*
|
|
19
|
+
* A checkbox input component with support for checked, unchecked, and indeterminate states.
|
|
20
|
+
* Optimized with React.memo for performance in high-frequency rendering scenarios.
|
|
21
|
+
*
|
|
22
|
+
* Features:
|
|
23
|
+
* - Three states: checked, unchecked, indeterminate
|
|
24
|
+
* - Full keyboard navigation support
|
|
25
|
+
* - ARIA attributes for screen readers
|
|
26
|
+
* - Dark mode support
|
|
27
|
+
* - Accessible label association
|
|
28
|
+
*/
|
|
29
|
+
export const Checkbox = React.memo(
|
|
30
|
+
React.forwardRef<
|
|
31
|
+
React.ElementRef<typeof ShadcnCheckbox>,
|
|
32
|
+
CheckboxProps
|
|
33
|
+
>((props, ref) => {
|
|
34
|
+
return <ShadcnCheckbox ref={ref} {...props} />
|
|
35
|
+
})
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
Checkbox.displayName = "Checkbox"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./Collapsible";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Button } from "../Button";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Collapsible> = {
|
|
7
|
+
title: "Primitives/Collapsible",
|
|
8
|
+
component: Collapsible,
|
|
9
|
+
parameters: { layout: "centered" },
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof Collapsible>;
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
render: () => {
|
|
18
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="w-[350px] space-y-2">
|
|
22
|
+
<div className="flex items-center justify-between">
|
|
23
|
+
<h4 className="text-sm font-semibold">@username starred 3 repositories</h4>
|
|
24
|
+
<CollapsibleTrigger asChild>
|
|
25
|
+
<Button variant="ghost" size="sm">
|
|
26
|
+
{isOpen ? "Hide" : "Show"}
|
|
27
|
+
</Button>
|
|
28
|
+
</CollapsibleTrigger>
|
|
29
|
+
</div>
|
|
30
|
+
<CollapsibleContent className="space-y-2">
|
|
31
|
+
<div className="rounded-md border px-4 py-2 text-sm">@radix-ui/primitives</div>
|
|
32
|
+
<div className="rounded-md border px-4 py-2 text-sm">@radix-ui/colors</div>
|
|
33
|
+
<div className="rounded-md border px-4 py-2 text-sm">@stitches/react</div>
|
|
34
|
+
</CollapsibleContent>
|
|
35
|
+
</Collapsible>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
Collapsible as ShadcnCollapsible,
|
|
6
|
+
CollapsibleContent as ShadcnCollapsibleContent,
|
|
7
|
+
CollapsibleTrigger as ShadcnCollapsibleTrigger,
|
|
8
|
+
} from "@/components/ui/collapsible";
|
|
9
|
+
|
|
10
|
+
export type CollapsibleProps = React.ComponentProps<typeof ShadcnCollapsible>;
|
|
11
|
+
export type CollapsibleTriggerProps = React.ComponentProps<typeof ShadcnCollapsibleTrigger>;
|
|
12
|
+
export type CollapsibleContentProps = React.ComponentProps<typeof ShadcnCollapsibleContent>;
|
|
13
|
+
|
|
14
|
+
export const Collapsible = React.memo<CollapsibleProps>(
|
|
15
|
+
React.forwardRef<React.ElementRef<typeof ShadcnCollapsible>, CollapsibleProps>(
|
|
16
|
+
(props, ref) => {
|
|
17
|
+
return <ShadcnCollapsible {...props} />;
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
Collapsible.displayName = "Collapsible";
|
|
22
|
+
|
|
23
|
+
export const CollapsibleTrigger = React.memo<CollapsibleTriggerProps>(
|
|
24
|
+
React.forwardRef<React.ElementRef<typeof ShadcnCollapsibleTrigger>, CollapsibleTriggerProps>(
|
|
25
|
+
(props, ref) => {
|
|
26
|
+
return <ShadcnCollapsibleTrigger ref={ref} {...props} />;
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
CollapsibleTrigger.displayName = "CollapsibleTrigger";
|
|
31
|
+
|
|
32
|
+
export const CollapsibleContent = React.memo<CollapsibleContentProps>(
|
|
33
|
+
React.forwardRef<React.ElementRef<typeof ShadcnCollapsibleContent>, CollapsibleContentProps>(
|
|
34
|
+
(props, ref) => {
|
|
35
|
+
return <ShadcnCollapsibleContent ref={ref} {...props} />;
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
CollapsibleContent.displayName = "CollapsibleContent";
|