ai-design-system 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/components/blocks/SectionLayout/SectionLayout.stories.tsx +276 -0
  2. package/components/blocks/SectionLayout/SectionLayout.tsx +82 -0
  3. package/components/blocks/SectionLayout/index.ts +2 -0
  4. package/components/blocks/index.ts +3 -1
  5. package/components/composites/AdjustableLayout/AdjustableLayout.stories.tsx +203 -0
  6. package/components/composites/AdjustableLayout/AdjustableLayout.tsx +229 -0
  7. package/components/composites/AdjustableLayout/index.ts +2 -0
  8. package/components/composites/AppHeader/AppHeader.mocks.ts +26 -0
  9. package/components/composites/AppHeader/AppHeader.stories.tsx +102 -2
  10. package/components/composites/AppHeader/AppHeader.tsx +38 -5
  11. package/components/composites/AppHeader/index.ts +1 -1
  12. package/components/composites/NavigationList/NavigationList.tsx +1 -0
  13. package/components/composites/index.ts +4 -1
  14. package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +44 -1
  15. package/components/features/PageLayout/PageLayout.mocks.ts +9 -0
  16. package/components/features/PageLayout/PageLayout.stories.tsx +144 -43
  17. package/components/features/PageLayout/PageLayout.tsx +52 -2
  18. package/components/features/PageLayout/usePageLayout.d.ts +5 -1
  19. package/components/features/PageLayout/usePageLayout.mock.ts +18 -3
  20. package/components/features/RefinementPanel/RefinementPanel.tsx +1 -1
  21. package/components/features/WorkflowBuilder/WorkflowBuilder.tsx +1 -1
  22. package/components/ui/sidebar.tsx +2 -2
  23. package/dist/index.cjs +251 -11
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.css +156 -10
  26. package/dist/index.d.ts +25 -0
  27. package/dist/index.js +250 -12
  28. package/dist/index.js.map +1 -1
  29. package/package.json +2 -2
@@ -0,0 +1,276 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { SectionLayout } from './SectionLayout'
3
+
4
+ /**
5
+ * SectionLayout Block Stories
6
+ *
7
+ * A layout block that provides adjustable panels with headers.
8
+ * Uses AdjustableLayout composite for panel management and AppHeader composite for headers.
9
+ *
10
+ * ## Features
11
+ * - Adjustable panel sizing with drag handles
12
+ * - Optional headers with tabs in each panel
13
+ * - Horizontal and vertical orientation support
14
+ * - Panel size persistence via localStorage
15
+ *
16
+ * ## Usage
17
+ * Perfect for creating multi-panel layouts with independent headers,
18
+ * such as code editors, chat interfaces, or dashboard layouts.
19
+ */
20
+ const meta = {
21
+ title: 'Blocks/SectionLayout',
22
+ component: SectionLayout,
23
+ tags: ['autodocs'],
24
+ parameters: { layout: 'fullscreen' },
25
+ } satisfies Meta<typeof SectionLayout>
26
+
27
+ export default meta
28
+ type Story = StoryObj<typeof meta>
29
+
30
+ /**
31
+ * Default SectionLayout
32
+ *
33
+ * 4-panel adjustable layout with headers using AppHeader composite.
34
+ */
35
+ export const Default: Story = {
36
+ render: () => {
37
+ const sections = [
38
+ {
39
+ id: 'top-left',
40
+ content: (
41
+ <div className="h-full bg-muted rounded-lg border p-4">
42
+ <h3 className="font-medium mb-2">Top Left Content</h3>
43
+ <p className="text-sm text-muted-foreground">Content area with AppHeader composite</p>
44
+ </div>
45
+ ),
46
+ defaultSize: 25,
47
+ header: {
48
+ tabs: [
49
+ { value: 'view', label: 'View' },
50
+ { value: 'edit', label: 'Edit' },
51
+ ],
52
+ defaultTab: 'view',
53
+ showSidebarToggle: false,
54
+ showTitle: false,
55
+ },
56
+ },
57
+ {
58
+ id: 'top-right',
59
+ content: (
60
+ <div className="h-full bg-muted rounded-lg border p-4">
61
+ <h3 className="font-medium mb-2">Top Right Content</h3>
62
+ <p className="text-sm text-muted-foreground">Content area with AppHeader composite</p>
63
+ </div>
64
+ ),
65
+ defaultSize: 25,
66
+ header: {
67
+ tabs: [
68
+ { value: 'tab1', label: 'Tab 1' },
69
+ { value: 'tab2', label: 'Tab 2' },
70
+ { value: 'tab3', label: 'Tab 3' },
71
+ ],
72
+ defaultTab: 'tab1',
73
+ showSidebarToggle: false,
74
+ showTitle: false,
75
+ },
76
+ },
77
+ {
78
+ id: 'bottom-left',
79
+ content: (
80
+ <div className="h-full bg-muted rounded-lg border p-4">
81
+ <h3 className="font-medium mb-2">Bottom Left Content</h3>
82
+ <p className="text-sm text-muted-foreground">Content area with minimal AppHeader</p>
83
+ </div>
84
+ ),
85
+ defaultSize: 25,
86
+ header: {
87
+ showSidebarToggle: false,
88
+ showTitle: false,
89
+ },
90
+ },
91
+ {
92
+ id: 'bottom-right',
93
+ content: (
94
+ <div className="h-full bg-muted rounded-lg border p-4">
95
+ <h3 className="font-medium mb-2">Bottom Right Content</h3>
96
+ <p className="text-sm text-muted-foreground">Content area with AppHeader composite</p>
97
+ </div>
98
+ ),
99
+ defaultSize: 25,
100
+ header: {
101
+ tabs: [
102
+ { value: 'log', label: 'Log' },
103
+ { value: 'console', label: 'Console' },
104
+ ],
105
+ defaultTab: 'log',
106
+ showSidebarToggle: false,
107
+ showTitle: false,
108
+ },
109
+ },
110
+ ]
111
+
112
+ return (
113
+ <div className="h-screen p-4">
114
+ <SectionLayout
115
+ sections={sections}
116
+ storageKey="section-layout-default"
117
+ />
118
+ </div>
119
+ )
120
+ },
121
+ }
122
+
123
+ /**
124
+ * Single Panel Layout
125
+ *
126
+ * Single panel with header using AppHeader composite.
127
+ */
128
+ export const SinglePanel: Story = {
129
+ render: () => {
130
+ const sections = [
131
+ {
132
+ id: 'main-panel',
133
+ content: (
134
+ <div className="h-full bg-muted rounded-lg border p-4">
135
+ <h3 className="font-medium mb-2">Single Panel Content</h3>
136
+ <p className="text-sm text-muted-foreground">Single panel with AppHeader composite</p>
137
+ </div>
138
+ ),
139
+ defaultSize: 100,
140
+ header: {
141
+ tabs: [
142
+ { value: 'overview', label: 'Overview' },
143
+ { value: 'details', label: 'Details' },
144
+ { value: 'settings', label: 'Settings' },
145
+ ],
146
+ defaultTab: 'overview',
147
+ showSidebarToggle: false,
148
+ showTitle: false,
149
+ },
150
+ },
151
+ ]
152
+
153
+ return (
154
+ <div className="h-screen p-4">
155
+ <SectionLayout
156
+ sections={sections}
157
+ storageKey="section-layout-single"
158
+ />
159
+ </div>
160
+ )
161
+ },
162
+ }
163
+
164
+ /**
165
+ * Primary Drag Handles
166
+ *
167
+ * Demonstrates primary colored drag handles.
168
+ */
169
+ export const PrimaryDragHandles: Story = {
170
+ render: () => {
171
+ const sections = [
172
+ {
173
+ id: 'left',
174
+ content: (
175
+ <div className="h-full bg-muted rounded-lg border p-4">
176
+ <h3 className="font-medium mb-2">Left Panel</h3>
177
+ <p className="text-sm text-muted-foreground">Primary drag handles</p>
178
+ </div>
179
+ ),
180
+ defaultSize: 50,
181
+ header: {
182
+ showSidebarToggle: false,
183
+ showTitle: false,
184
+ },
185
+ },
186
+ {
187
+ id: 'right',
188
+ content: (
189
+ <div className="h-full bg-muted rounded-lg border p-4">
190
+ <h3 className="font-medium mb-2">Right Panel</h3>
191
+ <p className="text-sm text-muted-foreground">Primary drag handles</p>
192
+ </div>
193
+ ),
194
+ defaultSize: 50,
195
+ header: {
196
+ showSidebarToggle: false,
197
+ showTitle: false,
198
+ },
199
+ },
200
+ ]
201
+
202
+ return (
203
+ <div className="h-screen p-4">
204
+ <SectionLayout
205
+ sections={sections}
206
+ dragHandleColor="primary"
207
+ storageKey="section-layout-primary"
208
+ />
209
+ </div>
210
+ )
211
+ },
212
+ }
213
+
214
+ /**
215
+ * Accent Drag Handles
216
+ *
217
+ * Demonstrates accent colored drag handles.
218
+ */
219
+ export const AccentDragHandles: Story = {
220
+ render: () => {
221
+ const sections = [
222
+ {
223
+ id: 'panel1',
224
+ content: (
225
+ <div className="h-full bg-muted rounded-lg border p-4">
226
+ <h3 className="font-medium mb-2">Panel 1</h3>
227
+ <p className="text-sm text-muted-foreground">Accent drag handles</p>
228
+ </div>
229
+ ),
230
+ defaultSize: 33,
231
+ header: {
232
+ showSidebarToggle: false,
233
+ showTitle: false,
234
+ },
235
+ },
236
+ {
237
+ id: 'panel2',
238
+ content: (
239
+ <div className="h-full bg-muted rounded-lg border p-4">
240
+ <h3 className="font-medium mb-2">Panel 2</h3>
241
+ <p className="text-sm text-muted-foreground">Accent drag handles</p>
242
+ </div>
243
+ ),
244
+ defaultSize: 34,
245
+ header: {
246
+ showSidebarToggle: false,
247
+ showTitle: false,
248
+ },
249
+ },
250
+ {
251
+ id: 'panel3',
252
+ content: (
253
+ <div className="h-full bg-muted rounded-lg border p-4">
254
+ <h3 className="font-medium mb-2">Panel 3</h3>
255
+ <p className="text-sm text-muted-foreground">Accent drag handles</p>
256
+ </div>
257
+ ),
258
+ defaultSize: 33,
259
+ header: {
260
+ showSidebarToggle: false,
261
+ showTitle: false,
262
+ },
263
+ },
264
+ ]
265
+
266
+ return (
267
+ <div className="h-screen p-4">
268
+ <SectionLayout
269
+ sections={sections}
270
+ dragHandleColor="accent"
271
+ storageKey="section-layout-accent"
272
+ />
273
+ </div>
274
+ )
275
+ },
276
+ }
@@ -0,0 +1,82 @@
1
+ import * as React from "react"
2
+ import { AdjustableLayout, type AdjustableLayoutSection } from "@/components/composites/AdjustableLayout"
3
+ import { AppHeader, type AppHeaderProps } from "@/components/composites/AppHeader"
4
+
5
+ export interface SectionLayoutSection extends AdjustableLayoutSection {
6
+ header?: AppHeaderProps
7
+ }
8
+
9
+ export interface SectionLayoutProps extends React.ComponentPropsWithoutRef<"div"> {
10
+ /**
11
+ * Layout sections with optional headers
12
+ */
13
+ sections: SectionLayoutSection[]
14
+ /**
15
+ * Layout orientation for adjustable layout
16
+ * @default "horizontal"
17
+ */
18
+ orientation?: "horizontal" | "vertical"
19
+ /**
20
+ * Storage key for layout panel sizes persistence
21
+ */
22
+ storageKey?: string
23
+ /**
24
+ * Callback for section resize events
25
+ */
26
+ onSectionResize?: (sectionId: string, newSize: number) => void
27
+ /**
28
+ * Color theme for drag handles
29
+ * @default "border"
30
+ */
31
+ dragHandleColor?: "primary" | "secondary" | "accent" | "border" | "muted"
32
+ }
33
+
34
+ /**
35
+ * SectionLayout Block
36
+ *
37
+ * A layout block that provides adjustable panels with headers.
38
+ * Uses AdjustableLayout composite for panel management and AppHeader composite for headers.
39
+ *
40
+ * This is a Block component that composites multiple Composite components
41
+ * to provide higher-level layout functionality.
42
+ */
43
+ export const SectionLayout = React.memo<SectionLayoutProps>(
44
+ ({
45
+ sections,
46
+ orientation = "horizontal",
47
+ storageKey,
48
+ onSectionResize,
49
+ dragHandleColor = "border",
50
+ className,
51
+ ...props
52
+ }) => {
53
+ // Transform sections to include headers
54
+ const transformedSections = sections.map(section => ({
55
+ ...section,
56
+ content: (
57
+ <div className="h-full flex flex-col">
58
+ {section.header && (
59
+ <AppHeader {...section.header} />
60
+ )}
61
+ <div className="flex-1">
62
+ {section.content}
63
+ </div>
64
+ </div>
65
+ ),
66
+ }))
67
+
68
+ return (
69
+ <AdjustableLayout
70
+ sections={transformedSections}
71
+ orientation={orientation}
72
+ storageKey={storageKey}
73
+ onSectionResize={onSectionResize}
74
+ dragHandleColor={dragHandleColor}
75
+ className={className}
76
+ {...props}
77
+ />
78
+ )
79
+ }
80
+ )
81
+
82
+ SectionLayout.displayName = "SectionLayout"
@@ -0,0 +1,2 @@
1
+ export { SectionLayout } from './SectionLayout'
2
+ export type { SectionLayoutProps } from './SectionLayout'
@@ -10,7 +10,9 @@ export type { DocumentEditorWithCommentsProps } from './DocumentEditorWithCommen
10
10
  export { FileChangeQueue } from './FileChangeQueue'
11
11
  export type { FileChangeQueueProps } from './FileChangeQueue'
12
12
 
13
- export { LayoutProvider } from './LayoutProvider'
13
+ // Blocks
14
+ export * from './LayoutProvider'
15
+ export * from './SectionLayout'
14
16
  export type { LayoutProviderProps } from './LayoutProvider'
15
17
 
16
18
  export { WorkflowCanvas } from './WorkflowCanvas'
@@ -0,0 +1,203 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { AdjustableLayout, type AdjustableLayoutSection } from './AdjustableLayout'
3
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/primitives/Card'
4
+
5
+ const meta = {
6
+ title: 'Composites/AdjustableLayout',
7
+ component: AdjustableLayout,
8
+ tags: ['autodocs'],
9
+ parameters: { layout: 'fullscreen' },
10
+ } satisfies Meta<typeof AdjustableLayout>
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof meta>
14
+
15
+ /**
16
+ * Default AdjustableLayout
17
+ *
18
+ * 4-section layout with equal default sizes.
19
+ */
20
+ export const Default: Story = {
21
+ render: () => {
22
+ const sections: AdjustableLayoutSection[] = [
23
+ {
24
+ id: 'left',
25
+ content: (
26
+ <Card className="h-full">
27
+ <CardHeader>
28
+ <CardTitle className="text-blue-600">Left Panel</CardTitle>
29
+ </CardHeader>
30
+ <CardContent>
31
+ <p className="text-sm text-muted-foreground">Resizeable panel content</p>
32
+ </CardContent>
33
+ </Card>
34
+ ),
35
+ defaultSize: 25,
36
+ },
37
+ {
38
+ id: 'center',
39
+ content: (
40
+ <Card className="h-full">
41
+ <CardHeader>
42
+ <CardTitle className="text-green-600">Center Panel</CardTitle>
43
+ </CardHeader>
44
+ <CardContent>
45
+ <p className="text-sm text-muted-foreground">Resizeable panel content</p>
46
+ </CardContent>
47
+ </Card>
48
+ ),
49
+ defaultSize: 25,
50
+ },
51
+ {
52
+ id: 'right',
53
+ content: (
54
+ <Card className="h-full">
55
+ <CardHeader>
56
+ <CardTitle className="text-purple-600">Right Panel</CardTitle>
57
+ </CardHeader>
58
+ <CardContent>
59
+ <p className="text-sm text-muted-foreground">Resizeable panel content</p>
60
+ </CardContent>
61
+ </Card>
62
+ ),
63
+ defaultSize: 25,
64
+ },
65
+ {
66
+ id: 'logs',
67
+ content: (
68
+ <Card className="h-full">
69
+ <CardHeader>
70
+ <CardTitle className="text-orange-600">Logs Panel</CardTitle>
71
+ </CardHeader>
72
+ <CardContent>
73
+ <p className="text-sm text-muted-foreground">Resizeable panel content</p>
74
+ </CardContent>
75
+ </Card>
76
+ ),
77
+ defaultSize: 25,
78
+ },
79
+ ]
80
+
81
+ return (
82
+ <div className="h-screen p-4">
83
+ <AdjustableLayout
84
+ sections={sections}
85
+ storageKey="adjustable-layout-default"
86
+ />
87
+ </div>
88
+ )
89
+ },
90
+ }
91
+
92
+ /**
93
+ * Two Panels
94
+ *
95
+ * Simple 2-panel layout with resizable divider.
96
+ */
97
+ export const TwoPanels: Story = {
98
+ render: () => {
99
+ const sections: AdjustableLayoutSection[] = [
100
+ {
101
+ id: 'main',
102
+ content: (
103
+ <Card className="h-full">
104
+ <CardHeader>
105
+ <CardTitle className="text-blue-600">Main Content</CardTitle>
106
+ </CardHeader>
107
+ <CardContent>
108
+ <p className="text-sm text-muted-foreground">Primary content area</p>
109
+ </CardContent>
110
+ </Card>
111
+ ),
112
+ defaultSize: 70,
113
+ },
114
+ {
115
+ id: 'sidebar',
116
+ content: (
117
+ <Card className="h-full">
118
+ <CardHeader>
119
+ <CardTitle className="text-gray-600">Sidebar</CardTitle>
120
+ </CardHeader>
121
+ <CardContent>
122
+ <p className="text-sm text-muted-foreground">Secondary content area</p>
123
+ </CardContent>
124
+ </Card>
125
+ ),
126
+ defaultSize: 30,
127
+ },
128
+ ]
129
+
130
+ return (
131
+ <div className="h-screen p-4">
132
+ <AdjustableLayout
133
+ sections={sections}
134
+ storageKey="adjustable-layout-two-panels"
135
+ />
136
+ </div>
137
+ )
138
+ },
139
+ }
140
+
141
+ /**
142
+ * Vertical Orientation
143
+ *
144
+ * Vertical layout with horizontal dividers.
145
+ */
146
+ export const VerticalOrientation: Story = {
147
+ render: () => {
148
+ const sections: AdjustableLayoutSection[] = [
149
+ {
150
+ id: 'header',
151
+ content: (
152
+ <Card className="h-full">
153
+ <CardHeader>
154
+ <CardTitle className="text-blue-600">Header Section</CardTitle>
155
+ </CardHeader>
156
+ <CardContent>
157
+ <p className="text-sm text-muted-foreground">Top content area</p>
158
+ </CardContent>
159
+ </Card>
160
+ ),
161
+ defaultSize: 20,
162
+ },
163
+ {
164
+ id: 'main',
165
+ content: (
166
+ <Card className="h-full">
167
+ <CardHeader>
168
+ <CardTitle className="text-green-600">Main Content</CardTitle>
169
+ </CardHeader>
170
+ <CardContent>
171
+ <p className="text-sm text-muted-foreground">Middle content area</p>
172
+ </CardContent>
173
+ </Card>
174
+ ),
175
+ defaultSize: 60,
176
+ },
177
+ {
178
+ id: 'footer',
179
+ content: (
180
+ <Card className="h-full">
181
+ <CardHeader>
182
+ <CardTitle className="text-gray-600">Footer Section</CardTitle>
183
+ </CardHeader>
184
+ <CardContent>
185
+ <p className="text-sm text-muted-foreground">Bottom content area</p>
186
+ </CardContent>
187
+ </Card>
188
+ ),
189
+ defaultSize: 20,
190
+ },
191
+ ]
192
+
193
+ return (
194
+ <div className="h-screen p-4">
195
+ <AdjustableLayout
196
+ sections={sections}
197
+ orientation="vertical"
198
+ storageKey="adjustable-layout-vertical"
199
+ />
200
+ </div>
201
+ )
202
+ },
203
+ }