@kushagradhawan/kookie-ui 0.1.47 → 0.1.49
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/components.css +858 -30
- package/dist/cjs/components/_internal/shell-bottom.d.ts +31 -0
- package/dist/cjs/components/_internal/shell-bottom.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-bottom.js +2 -0
- package/dist/cjs/components/_internal/shell-bottom.js.map +7 -0
- package/dist/cjs/components/_internal/shell-handles.d.ts +7 -0
- package/dist/cjs/components/_internal/shell-handles.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-handles.js +2 -0
- package/dist/cjs/components/_internal/shell-handles.js.map +7 -0
- package/dist/cjs/components/_internal/shell-inspector.d.ts +31 -0
- package/dist/cjs/components/_internal/shell-inspector.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-inspector.js +2 -0
- package/dist/cjs/components/_internal/shell-inspector.js.map +7 -0
- package/dist/cjs/components/_internal/shell-resize.d.ts +24 -0
- package/dist/cjs/components/_internal/shell-resize.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-resize.js +2 -0
- package/dist/cjs/components/_internal/shell-resize.js.map +7 -0
- package/dist/cjs/components/_internal/shell-sidebar.d.ts +37 -0
- package/dist/cjs/components/_internal/shell-sidebar.d.ts.map +1 -0
- package/dist/cjs/components/_internal/shell-sidebar.js +2 -0
- package/dist/cjs/components/_internal/shell-sidebar.js.map +7 -0
- package/dist/cjs/components/alert-dialog.d.ts.map +1 -1
- package/dist/cjs/components/alert-dialog.js +1 -1
- package/dist/cjs/components/alert-dialog.js.map +2 -2
- package/dist/cjs/components/dialog.d.ts.map +1 -1
- package/dist/cjs/components/dialog.js +1 -1
- package/dist/cjs/components/dialog.js.map +2 -2
- package/dist/cjs/components/schemas/index.d.ts +2 -0
- package/dist/cjs/components/schemas/index.d.ts.map +1 -1
- package/dist/cjs/components/schemas/index.js +1 -1
- package/dist/cjs/components/schemas/index.js.map +3 -3
- package/dist/cjs/components/schemas/shell.schema.d.ts +1025 -0
- package/dist/cjs/components/schemas/shell.schema.d.ts.map +1 -0
- package/dist/cjs/components/schemas/shell.schema.js +2 -0
- package/dist/cjs/components/schemas/shell.schema.js.map +7 -0
- package/dist/cjs/components/shell.context.d.ts +37 -0
- package/dist/cjs/components/shell.context.d.ts.map +1 -0
- package/dist/cjs/components/shell.context.js +2 -0
- package/dist/cjs/components/shell.context.js.map +7 -0
- package/dist/cjs/components/shell.d.ts +6 -68
- package/dist/cjs/components/shell.d.ts.map +1 -1
- package/dist/cjs/components/shell.hooks.d.ts +3 -0
- package/dist/cjs/components/shell.hooks.d.ts.map +1 -0
- package/dist/cjs/components/shell.hooks.js +2 -0
- package/dist/cjs/components/shell.hooks.js.map +7 -0
- package/dist/cjs/components/shell.js +1 -1
- package/dist/cjs/components/shell.js.map +3 -3
- package/dist/cjs/components/shell.types.d.ts +20 -0
- package/dist/cjs/components/shell.types.d.ts.map +1 -0
- package/dist/cjs/components/shell.types.js +2 -0
- package/dist/cjs/components/shell.types.js.map +7 -0
- package/dist/cjs/components/sidebar.d.ts +1 -1
- package/dist/cjs/components/sidebar.d.ts.map +1 -1
- package/dist/cjs/components/sidebar.js +1 -1
- package/dist/cjs/components/sidebar.js.map +3 -3
- package/dist/esm/components/_internal/shell-bottom.d.ts +31 -0
- package/dist/esm/components/_internal/shell-bottom.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-bottom.js +2 -0
- package/dist/esm/components/_internal/shell-bottom.js.map +7 -0
- package/dist/esm/components/_internal/shell-handles.d.ts +7 -0
- package/dist/esm/components/_internal/shell-handles.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-handles.js +2 -0
- package/dist/esm/components/_internal/shell-handles.js.map +7 -0
- package/dist/esm/components/_internal/shell-inspector.d.ts +31 -0
- package/dist/esm/components/_internal/shell-inspector.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-inspector.js +2 -0
- package/dist/esm/components/_internal/shell-inspector.js.map +7 -0
- package/dist/esm/components/_internal/shell-resize.d.ts +24 -0
- package/dist/esm/components/_internal/shell-resize.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-resize.js +2 -0
- package/dist/esm/components/_internal/shell-resize.js.map +7 -0
- package/dist/esm/components/_internal/shell-sidebar.d.ts +37 -0
- package/dist/esm/components/_internal/shell-sidebar.d.ts.map +1 -0
- package/dist/esm/components/_internal/shell-sidebar.js +2 -0
- package/dist/esm/components/_internal/shell-sidebar.js.map +7 -0
- package/dist/esm/components/alert-dialog.d.ts.map +1 -1
- package/dist/esm/components/alert-dialog.js +1 -1
- package/dist/esm/components/alert-dialog.js.map +2 -2
- package/dist/esm/components/dialog.d.ts.map +1 -1
- package/dist/esm/components/dialog.js +1 -1
- package/dist/esm/components/dialog.js.map +2 -2
- package/dist/esm/components/schemas/index.d.ts +2 -0
- package/dist/esm/components/schemas/index.d.ts.map +1 -1
- package/dist/esm/components/schemas/index.js +1 -1
- package/dist/esm/components/schemas/index.js.map +3 -3
- package/dist/esm/components/schemas/shell.schema.d.ts +1025 -0
- package/dist/esm/components/schemas/shell.schema.d.ts.map +1 -0
- package/dist/esm/components/schemas/shell.schema.js +2 -0
- package/dist/esm/components/schemas/shell.schema.js.map +7 -0
- package/dist/esm/components/shell.context.d.ts +37 -0
- package/dist/esm/components/shell.context.d.ts.map +1 -0
- package/dist/esm/components/shell.context.js +2 -0
- package/dist/esm/components/shell.context.js.map +7 -0
- package/dist/esm/components/shell.d.ts +6 -68
- package/dist/esm/components/shell.d.ts.map +1 -1
- package/dist/esm/components/shell.hooks.d.ts +3 -0
- package/dist/esm/components/shell.hooks.d.ts.map +1 -0
- package/dist/esm/components/shell.hooks.js +2 -0
- package/dist/esm/components/shell.hooks.js.map +7 -0
- package/dist/esm/components/shell.js +1 -1
- package/dist/esm/components/shell.js.map +3 -3
- package/dist/esm/components/shell.types.d.ts +20 -0
- package/dist/esm/components/shell.types.d.ts.map +1 -0
- package/dist/esm/components/shell.types.js +2 -0
- package/dist/esm/components/shell.types.js.map +7 -0
- package/dist/esm/components/sidebar.d.ts +1 -1
- package/dist/esm/components/sidebar.d.ts.map +1 -1
- package/dist/esm/components/sidebar.js +1 -1
- package/dist/esm/components/sidebar.js.map +2 -2
- package/layout/utilities.css +168 -84
- package/layout.css +168 -84
- package/package.json +2 -1
- package/schemas/base-button.json +1 -1
- package/schemas/button.json +1 -1
- package/schemas/icon-button.json +1 -1
- package/schemas/index.json +6 -6
- package/schemas/shell-bottom.json +168 -0
- package/schemas/shell-content.json +34 -0
- package/schemas/shell-handle.json +34 -0
- package/schemas/shell-header.json +42 -0
- package/schemas/shell-inspector.json +171 -0
- package/schemas/shell-panel.json +167 -0
- package/schemas/shell-rail.json +132 -0
- package/schemas/shell-root.json +54 -0
- package/schemas/shell-sidebar.json +182 -0
- package/schemas/shell-trigger.json +76 -0
- package/schemas/toggle-button.json +1 -1
- package/schemas/toggle-icon-button.json +1 -1
- package/src/components/_internal/shell-bottom.tsx +251 -0
- package/src/components/_internal/shell-handles.tsx +193 -0
- package/src/components/_internal/shell-inspector.tsx +242 -0
- package/src/components/_internal/shell-resize.tsx +30 -0
- package/src/components/_internal/shell-sidebar.tsx +347 -0
- package/src/components/alert-dialog.tsx +6 -0
- package/src/components/dialog.tsx +6 -0
- package/src/components/schemas/index.ts +46 -0
- package/src/components/schemas/shell.schema.ts +403 -0
- package/src/components/shell.context.tsx +56 -0
- package/src/components/shell.css +5 -17
- package/src/components/shell.hooks.ts +31 -0
- package/src/components/shell.tsx +368 -1684
- package/src/components/shell.types.ts +27 -0
- package/src/components/sidebar.tsx +1 -1
- package/src/styles/tokens/blur.css +2 -2
- package/src/styles/tokens/color.css +2 -2
- package/styles.css +1031 -116
- package/tokens/base.css +5 -2
- package/tokens.css +5 -2
- package/utilities.css +168 -84
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shell Zod schema - Single source of truth for Shell component props
|
|
5
|
+
*
|
|
6
|
+
* The Shell component is a layout engine that provides structural patterns for building
|
|
7
|
+
* application interfaces. It manages layout state, composition rules, and responsive
|
|
8
|
+
* behavior across seven core slots.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // Basic shell validation
|
|
13
|
+
* const props = ShellRootSchema.parse({ height: 'full' });
|
|
14
|
+
*
|
|
15
|
+
* // Shell with responsive sidebar
|
|
16
|
+
* const sidebarProps = ShellSidebarSchema.parse({
|
|
17
|
+
* defaultMode: { initial: 'collapsed', md: 'expanded' },
|
|
18
|
+
* presentation: { initial: 'overlay', lg: 'fixed' }
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// Common types
|
|
24
|
+
const PaneModeSchema = z.enum(['expanded', 'collapsed']).describe('Pane state mode');
|
|
25
|
+
const SidebarModeSchema = z.enum(['collapsed', 'thin', 'expanded']).describe('Sidebar state mode');
|
|
26
|
+
const PresentationValueSchema = z
|
|
27
|
+
.enum(['fixed', 'overlay', 'stacked'])
|
|
28
|
+
.describe('Presentation mode');
|
|
29
|
+
const BreakpointSchema = z
|
|
30
|
+
.enum(['initial', 'xs', 'sm', 'md', 'lg', 'xl'])
|
|
31
|
+
.describe('Responsive breakpoint');
|
|
32
|
+
const PaneTargetSchema = z
|
|
33
|
+
.enum(['left', 'rail', 'panel', 'sidebar', 'inspector', 'bottom'])
|
|
34
|
+
.describe('Pane target');
|
|
35
|
+
const TriggerActionSchema = z.enum(['toggle', 'expand', 'collapse']).describe('Trigger action');
|
|
36
|
+
|
|
37
|
+
// Responsive schemas
|
|
38
|
+
const ResponsiveModeSchema = z
|
|
39
|
+
.union([
|
|
40
|
+
PaneModeSchema,
|
|
41
|
+
z.object({
|
|
42
|
+
initial: PaneModeSchema.optional(),
|
|
43
|
+
xs: PaneModeSchema.optional(),
|
|
44
|
+
sm: PaneModeSchema.optional(),
|
|
45
|
+
md: PaneModeSchema.optional(),
|
|
46
|
+
lg: PaneModeSchema.optional(),
|
|
47
|
+
xl: PaneModeSchema.optional(),
|
|
48
|
+
}),
|
|
49
|
+
])
|
|
50
|
+
.describe('Responsive pane mode configuration');
|
|
51
|
+
|
|
52
|
+
const ResponsiveSidebarModeSchema = z
|
|
53
|
+
.union([
|
|
54
|
+
SidebarModeSchema,
|
|
55
|
+
z.object({
|
|
56
|
+
initial: SidebarModeSchema.optional(),
|
|
57
|
+
xs: SidebarModeSchema.optional(),
|
|
58
|
+
sm: SidebarModeSchema.optional(),
|
|
59
|
+
md: SidebarModeSchema.optional(),
|
|
60
|
+
lg: SidebarModeSchema.optional(),
|
|
61
|
+
xl: SidebarModeSchema.optional(),
|
|
62
|
+
}),
|
|
63
|
+
])
|
|
64
|
+
.describe('Responsive sidebar mode configuration');
|
|
65
|
+
|
|
66
|
+
const ResponsivePresentationSchema = z
|
|
67
|
+
.union([
|
|
68
|
+
PresentationValueSchema,
|
|
69
|
+
z.object({
|
|
70
|
+
initial: PresentationValueSchema.optional(),
|
|
71
|
+
xs: PresentationValueSchema.optional(),
|
|
72
|
+
sm: PresentationValueSchema.optional(),
|
|
73
|
+
md: PresentationValueSchema.optional(),
|
|
74
|
+
lg: PresentationValueSchema.optional(),
|
|
75
|
+
xl: PresentationValueSchema.optional(),
|
|
76
|
+
}),
|
|
77
|
+
])
|
|
78
|
+
.describe('Responsive presentation configuration');
|
|
79
|
+
|
|
80
|
+
// Size persistence adapter
|
|
81
|
+
const PaneSizePersistenceSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
load: z
|
|
84
|
+
.function()
|
|
85
|
+
.returns(z.union([z.number(), z.promise(z.number()), z.undefined()]))
|
|
86
|
+
.optional(),
|
|
87
|
+
save: z
|
|
88
|
+
.function()
|
|
89
|
+
.args(z.number())
|
|
90
|
+
.returns(z.union([z.void(), z.promise(z.void())]))
|
|
91
|
+
.optional(),
|
|
92
|
+
})
|
|
93
|
+
.describe('Size persistence adapter');
|
|
94
|
+
|
|
95
|
+
// Common pane props
|
|
96
|
+
const PanePropsSchema = z
|
|
97
|
+
.object({
|
|
98
|
+
presentation: ResponsivePresentationSchema.optional(),
|
|
99
|
+
mode: PaneModeSchema.optional(),
|
|
100
|
+
defaultMode: ResponsiveModeSchema.optional(),
|
|
101
|
+
onModeChange: z.function().args(PaneModeSchema).returns(z.void()).optional(),
|
|
102
|
+
expandedSize: z.number().optional(),
|
|
103
|
+
minSize: z.number().optional(),
|
|
104
|
+
maxSize: z.number().optional(),
|
|
105
|
+
resizable: z.boolean().optional(),
|
|
106
|
+
collapsible: z.boolean().optional(),
|
|
107
|
+
onExpand: z.function().returns(z.void()).optional(),
|
|
108
|
+
onCollapse: z.function().returns(z.void()).optional(),
|
|
109
|
+
onResize: z.function().args(z.number()).returns(z.void()).optional(),
|
|
110
|
+
resizer: z.any().optional(),
|
|
111
|
+
onResizeStart: z.function().args(z.number()).returns(z.void()).optional(),
|
|
112
|
+
onResizeEnd: z.function().args(z.number()).returns(z.void()).optional(),
|
|
113
|
+
snapPoints: z.array(z.number()).optional(),
|
|
114
|
+
snapTolerance: z.number().optional(),
|
|
115
|
+
collapseThreshold: z.number().optional(),
|
|
116
|
+
paneId: z.string().optional(),
|
|
117
|
+
persistence: PaneSizePersistenceSchema.optional(),
|
|
118
|
+
className: z.string().optional(),
|
|
119
|
+
style: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
|
120
|
+
children: z.any().optional(),
|
|
121
|
+
})
|
|
122
|
+
.strict();
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Shell.Root component schema
|
|
126
|
+
*/
|
|
127
|
+
export const ShellRootSchema = z
|
|
128
|
+
.object({
|
|
129
|
+
height: z
|
|
130
|
+
.union([z.literal('full'), z.literal('auto'), z.string(), z.number()])
|
|
131
|
+
.default('full')
|
|
132
|
+
.describe('Height of the shell container'),
|
|
133
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
134
|
+
style: z
|
|
135
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
136
|
+
.optional()
|
|
137
|
+
.describe('Inline styles'),
|
|
138
|
+
children: z.any().optional().describe('Shell components'),
|
|
139
|
+
})
|
|
140
|
+
.strict();
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Shell.Header component schema
|
|
144
|
+
*/
|
|
145
|
+
export const ShellHeaderSchema = z
|
|
146
|
+
.object({
|
|
147
|
+
height: z.union([z.string(), z.number()]).default(64).describe('Height of the header'),
|
|
148
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
149
|
+
style: z
|
|
150
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
151
|
+
.optional()
|
|
152
|
+
.describe('Inline styles'),
|
|
153
|
+
children: z.any().optional().describe('Header content'),
|
|
154
|
+
})
|
|
155
|
+
.strict();
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Shell.Rail component schema
|
|
159
|
+
*/
|
|
160
|
+
export const ShellRailSchema = z
|
|
161
|
+
.object({
|
|
162
|
+
presentation: ResponsivePresentationSchema.optional(),
|
|
163
|
+
mode: PaneModeSchema.optional(),
|
|
164
|
+
defaultMode: ResponsiveModeSchema.optional(),
|
|
165
|
+
onModeChange: z.function().args(PaneModeSchema).returns(z.void()).optional(),
|
|
166
|
+
expandedSize: z.number().default(64).describe('Default width in pixels'),
|
|
167
|
+
collapsible: z.boolean().optional(),
|
|
168
|
+
onExpand: z.function().returns(z.void()).optional(),
|
|
169
|
+
onCollapse: z.function().returns(z.void()).optional(),
|
|
170
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
171
|
+
style: z
|
|
172
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
173
|
+
.optional()
|
|
174
|
+
.describe('Inline styles'),
|
|
175
|
+
children: z.any().optional().describe('Rail content'),
|
|
176
|
+
})
|
|
177
|
+
.strict();
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Shell.Panel component schema
|
|
181
|
+
*/
|
|
182
|
+
export const ShellPanelSchema = PanePropsSchema.extend({
|
|
183
|
+
expandedSize: z.number().default(288).describe('Default width in pixels'),
|
|
184
|
+
minSize: z.number().default(200).describe('Minimum width when resizing'),
|
|
185
|
+
maxSize: z.number().default(800).describe('Maximum width when resizing'),
|
|
186
|
+
resizable: z.boolean().default(false).describe('Whether the panel can be resized'),
|
|
187
|
+
collapsible: z
|
|
188
|
+
.boolean()
|
|
189
|
+
.default(true)
|
|
190
|
+
.describe('Whether the panel can be collapsed via resize handle'),
|
|
191
|
+
}).strict();
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Shell.Sidebar component schema
|
|
195
|
+
*/
|
|
196
|
+
export const ShellSidebarSchema = PanePropsSchema.extend({
|
|
197
|
+
mode: SidebarModeSchema.optional(),
|
|
198
|
+
defaultMode: ResponsiveSidebarModeSchema.default('expanded').describe('Initial sidebar mode'),
|
|
199
|
+
expandedSize: z.number().default(288).describe('Default width in pixels'),
|
|
200
|
+
minSize: z.number().default(200).describe('Minimum width when resizing'),
|
|
201
|
+
maxSize: z.number().default(400).describe('Maximum width when resizing'),
|
|
202
|
+
thinSize: z.number().default(64).describe('Width in thin mode'),
|
|
203
|
+
toggleModes: z.enum(['both', 'single']).optional().describe('Available modes in toggle sequence'),
|
|
204
|
+
resizable: z.boolean().default(false).describe('Whether the sidebar can be resized'),
|
|
205
|
+
collapsible: z
|
|
206
|
+
.boolean()
|
|
207
|
+
.default(true)
|
|
208
|
+
.describe('Whether the sidebar can be collapsed via resize handle'),
|
|
209
|
+
}).strict();
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Shell.Content component schema
|
|
213
|
+
*/
|
|
214
|
+
export const ShellContentSchema = z
|
|
215
|
+
.object({
|
|
216
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
217
|
+
style: z
|
|
218
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
219
|
+
.optional()
|
|
220
|
+
.describe('Inline styles'),
|
|
221
|
+
children: z.any().optional().describe('Main content'),
|
|
222
|
+
})
|
|
223
|
+
.strict();
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Shell.Inspector component schema
|
|
227
|
+
*/
|
|
228
|
+
export const ShellInspectorSchema = PanePropsSchema.extend({
|
|
229
|
+
presentation: ResponsivePresentationSchema.default({ initial: 'overlay', lg: 'fixed' }).describe(
|
|
230
|
+
'Presentation mode',
|
|
231
|
+
),
|
|
232
|
+
expandedSize: z.number().default(320).describe('Default width in pixels'),
|
|
233
|
+
minSize: z.number().default(200).describe('Minimum width when resizing'),
|
|
234
|
+
maxSize: z.number().default(500).describe('Maximum width when resizing'),
|
|
235
|
+
resizable: z.boolean().default(false).describe('Whether the inspector can be resized'),
|
|
236
|
+
collapsible: z
|
|
237
|
+
.boolean()
|
|
238
|
+
.default(true)
|
|
239
|
+
.describe('Whether the inspector can be collapsed via resize handle'),
|
|
240
|
+
}).strict();
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Shell.Bottom component schema
|
|
244
|
+
*/
|
|
245
|
+
export const ShellBottomSchema = PanePropsSchema.extend({
|
|
246
|
+
presentation: ResponsivePresentationSchema.default('fixed').describe('Presentation mode'),
|
|
247
|
+
expandedSize: z.number().default(200).describe('Default height in pixels'),
|
|
248
|
+
minSize: z.number().default(100).describe('Minimum height when resizing'),
|
|
249
|
+
maxSize: z.number().default(400).describe('Maximum height when resizing'),
|
|
250
|
+
resizable: z.boolean().default(false).describe('Whether the bottom panel can be resized'),
|
|
251
|
+
collapsible: z
|
|
252
|
+
.boolean()
|
|
253
|
+
.default(true)
|
|
254
|
+
.describe('Whether the bottom panel can be collapsed via resize handle'),
|
|
255
|
+
}).strict();
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Shell.Trigger component schema
|
|
259
|
+
*/
|
|
260
|
+
export const ShellTriggerSchema = z
|
|
261
|
+
.object({
|
|
262
|
+
target: PaneTargetSchema.describe('Which pane to control'),
|
|
263
|
+
action: TriggerActionSchema.default('toggle').describe('Action to perform'),
|
|
264
|
+
peekOnHover: z
|
|
265
|
+
.boolean()
|
|
266
|
+
.default(false)
|
|
267
|
+
.describe('Whether to show peek preview on hover when collapsed'),
|
|
268
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
269
|
+
style: z
|
|
270
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
271
|
+
.optional()
|
|
272
|
+
.describe('Inline styles'),
|
|
273
|
+
children: z.any().optional().describe('Trigger content'),
|
|
274
|
+
onClick: z.function().optional().describe('Click handler'),
|
|
275
|
+
onMouseEnter: z.function().optional().describe('Mouse enter handler'),
|
|
276
|
+
onMouseLeave: z.function().optional().describe('Mouse leave handler'),
|
|
277
|
+
'aria-label': z.string().optional().describe('ARIA label for accessibility'),
|
|
278
|
+
'aria-labelledby': z.string().optional().describe('ARIA labelled by reference'),
|
|
279
|
+
'aria-describedby': z.string().optional().describe('ARIA described by reference'),
|
|
280
|
+
})
|
|
281
|
+
.strict();
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Shell.Handle component schema (for resize handles)
|
|
285
|
+
*/
|
|
286
|
+
export const ShellHandleSchema = z
|
|
287
|
+
.object({
|
|
288
|
+
className: z.string().optional().describe('Additional CSS class name'),
|
|
289
|
+
style: z
|
|
290
|
+
.record(z.string(), z.union([z.string(), z.number()]))
|
|
291
|
+
.optional()
|
|
292
|
+
.describe('Inline styles'),
|
|
293
|
+
children: z.any().optional().describe('Handle content'),
|
|
294
|
+
})
|
|
295
|
+
.strict();
|
|
296
|
+
|
|
297
|
+
// Type exports
|
|
298
|
+
export type ShellRootProps = z.infer<typeof ShellRootSchema>;
|
|
299
|
+
export type ShellHeaderProps = z.infer<typeof ShellHeaderSchema>;
|
|
300
|
+
export type ShellRailProps = z.infer<typeof ShellRailSchema>;
|
|
301
|
+
export type ShellPanelProps = z.infer<typeof ShellPanelSchema>;
|
|
302
|
+
export type ShellSidebarProps = z.infer<typeof ShellSidebarSchema>;
|
|
303
|
+
export type ShellContentProps = z.infer<typeof ShellContentSchema>;
|
|
304
|
+
export type ShellInspectorProps = z.infer<typeof ShellInspectorSchema>;
|
|
305
|
+
export type ShellBottomProps = z.infer<typeof ShellBottomSchema>;
|
|
306
|
+
export type ShellTriggerProps = z.infer<typeof ShellTriggerSchema>;
|
|
307
|
+
export type ShellHandleProps = z.infer<typeof ShellHandleSchema>;
|
|
308
|
+
|
|
309
|
+
// Common type exports
|
|
310
|
+
export type PaneMode = z.infer<typeof PaneModeSchema>;
|
|
311
|
+
export type SidebarMode = z.infer<typeof SidebarModeSchema>;
|
|
312
|
+
export type PresentationValue = z.infer<typeof PresentationValueSchema>;
|
|
313
|
+
export type Breakpoint = z.infer<typeof BreakpointSchema>;
|
|
314
|
+
export type PaneTarget = z.infer<typeof PaneTargetSchema>;
|
|
315
|
+
export type TriggerAction = z.infer<typeof TriggerActionSchema>;
|
|
316
|
+
export type ResponsiveMode = z.infer<typeof ResponsiveModeSchema>;
|
|
317
|
+
export type ResponsiveSidebarMode = z.infer<typeof ResponsiveSidebarModeSchema>;
|
|
318
|
+
export type ResponsivePresentation = z.infer<typeof ResponsivePresentationSchema>;
|
|
319
|
+
export type PaneSizePersistence = z.infer<typeof PaneSizePersistenceSchema>;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Development-only helper to validate and normalize Shell props
|
|
323
|
+
* This function should only be used in development mode
|
|
324
|
+
*
|
|
325
|
+
* @param props - Props to validate and normalize
|
|
326
|
+
* @returns Validated and normalized props
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```tsx
|
|
330
|
+
* // In development, this will validate props and show helpful errors
|
|
331
|
+
* const validatedProps = parseShellRootProps({ height: 'invalid' });
|
|
332
|
+
* // Throws validation errors for invalid values
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
export function parseShellRootProps(props: unknown): ShellRootProps {
|
|
336
|
+
if (process.env.NODE_ENV === 'development') {
|
|
337
|
+
return ShellRootSchema.parse(props);
|
|
338
|
+
}
|
|
339
|
+
return props as ShellRootProps;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function parseShellHeaderProps(props: unknown): ShellHeaderProps {
|
|
343
|
+
if (process.env.NODE_ENV === 'development') {
|
|
344
|
+
return ShellHeaderSchema.parse(props);
|
|
345
|
+
}
|
|
346
|
+
return props as ShellHeaderProps;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function parseShellRailProps(props: unknown): ShellRailProps {
|
|
350
|
+
if (process.env.NODE_ENV === 'development') {
|
|
351
|
+
return ShellRailSchema.parse(props);
|
|
352
|
+
}
|
|
353
|
+
return props as ShellRailProps;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export function parseShellPanelProps(props: unknown): ShellPanelProps {
|
|
357
|
+
if (process.env.NODE_ENV === 'development') {
|
|
358
|
+
return ShellPanelSchema.parse(props);
|
|
359
|
+
}
|
|
360
|
+
return props as ShellPanelProps;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export function parseShellSidebarProps(props: unknown): ShellSidebarProps {
|
|
364
|
+
if (process.env.NODE_ENV === 'development') {
|
|
365
|
+
return ShellSidebarSchema.parse(props);
|
|
366
|
+
}
|
|
367
|
+
return props as ShellSidebarProps;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function parseShellContentProps(props: unknown): ShellContentProps {
|
|
371
|
+
if (process.env.NODE_ENV === 'development') {
|
|
372
|
+
return ShellContentSchema.parse(props);
|
|
373
|
+
}
|
|
374
|
+
return props as ShellContentProps;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function parseShellInspectorProps(props: unknown): ShellInspectorProps {
|
|
378
|
+
if (process.env.NODE_ENV === 'development') {
|
|
379
|
+
return ShellInspectorSchema.parse(props);
|
|
380
|
+
}
|
|
381
|
+
return props as ShellInspectorProps;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function parseShellBottomProps(props: unknown): ShellBottomProps {
|
|
385
|
+
if (process.env.NODE_ENV === 'development') {
|
|
386
|
+
return ShellBottomSchema.parse(props);
|
|
387
|
+
}
|
|
388
|
+
return props as ShellBottomProps;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export function parseShellTriggerProps(props: unknown): ShellTriggerProps {
|
|
392
|
+
if (process.env.NODE_ENV === 'development') {
|
|
393
|
+
return ShellTriggerSchema.parse(props);
|
|
394
|
+
}
|
|
395
|
+
return props as ShellTriggerProps;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export function parseShellHandleProps(props: unknown): ShellHandleProps {
|
|
399
|
+
if (process.env.NODE_ENV === 'development') {
|
|
400
|
+
return ShellHandleSchema.parse(props);
|
|
401
|
+
}
|
|
402
|
+
return props as ShellHandleProps;
|
|
403
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Breakpoint, PresentationValue, SidebarMode, PaneMode, PaneTarget } from './shell.types.js';
|
|
3
|
+
|
|
4
|
+
export interface ShellContextValue {
|
|
5
|
+
// Pane states
|
|
6
|
+
leftMode: PaneMode;
|
|
7
|
+
setLeftMode: (mode: PaneMode) => void;
|
|
8
|
+
panelMode: PaneMode; // Panel state within left container
|
|
9
|
+
setPanelMode: (mode: PaneMode) => void;
|
|
10
|
+
sidebarMode: SidebarMode;
|
|
11
|
+
setSidebarMode: (mode: SidebarMode) => void;
|
|
12
|
+
inspectorMode: PaneMode;
|
|
13
|
+
setInspectorMode: (mode: PaneMode) => void;
|
|
14
|
+
bottomMode: PaneMode;
|
|
15
|
+
setBottomMode: (mode: PaneMode) => void;
|
|
16
|
+
|
|
17
|
+
// Peek state (layout-only, ephemeral)
|
|
18
|
+
peekTarget: PaneTarget | null;
|
|
19
|
+
setPeekTarget: (target: PaneTarget | null) => void;
|
|
20
|
+
peekPane: (target: PaneTarget) => void;
|
|
21
|
+
clearPeek: () => void;
|
|
22
|
+
|
|
23
|
+
// Composition detection
|
|
24
|
+
hasLeft: boolean;
|
|
25
|
+
setHasLeft: (has: boolean) => void;
|
|
26
|
+
hasSidebar: boolean;
|
|
27
|
+
setHasSidebar: (has: boolean) => void;
|
|
28
|
+
|
|
29
|
+
// Presentation resolution
|
|
30
|
+
currentBreakpoint: Breakpoint;
|
|
31
|
+
currentBreakpointReady: boolean;
|
|
32
|
+
leftResolvedPresentation?: PresentationValue;
|
|
33
|
+
|
|
34
|
+
// Actions
|
|
35
|
+
togglePane: (target: PaneTarget) => void;
|
|
36
|
+
expandPane: (target: PaneTarget) => void;
|
|
37
|
+
collapsePane: (target: PaneTarget) => void;
|
|
38
|
+
// Toggle customization
|
|
39
|
+
setSidebarToggleComputer?: (fn: (current: SidebarMode) => SidebarMode) => void;
|
|
40
|
+
// Dev-only hooks for presentation warnings
|
|
41
|
+
onLeftPres?: (p: PresentationValue) => void;
|
|
42
|
+
// Sizing info for overlay grouping
|
|
43
|
+
onLeftDefaults?: (size: number) => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const ShellContext = React.createContext<ShellContextValue | null>(null);
|
|
47
|
+
|
|
48
|
+
export function useShell() {
|
|
49
|
+
const ctx = React.useContext(ShellContext);
|
|
50
|
+
if (!ctx) throw new Error('Shell components must be used within <Shell.Root>');
|
|
51
|
+
return ctx;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function ShellProvider({ value, children }: { value: ShellContextValue; children: React.ReactNode }) {
|
|
55
|
+
return <ShellContext.Provider value={value}>{children}</ShellContext.Provider>;
|
|
56
|
+
}
|
package/src/components/shell.css
CHANGED
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
z-index: 50;
|
|
34
34
|
height: var(--shell-header-height, 64px);
|
|
35
35
|
min-height: var(--shell-header-height, 64px);
|
|
36
|
-
background-color: var(--color-panel);
|
|
37
36
|
display: flex;
|
|
38
37
|
align-items: center;
|
|
39
38
|
flex-shrink: 0;
|
|
@@ -63,7 +62,6 @@
|
|
|
63
62
|
display: flex;
|
|
64
63
|
flex-direction: column;
|
|
65
64
|
height: 100%;
|
|
66
|
-
background-color: var(--color-surface);
|
|
67
65
|
overflow: hidden;
|
|
68
66
|
|
|
69
67
|
/* Animation setup */
|
|
@@ -97,8 +95,7 @@
|
|
|
97
95
|
|
|
98
96
|
/* Content animation: fade out first, then fade in after width settles */
|
|
99
97
|
opacity: 0;
|
|
100
|
-
transition: opacity var(--motion-duration-small) var(--motion-ease-standard)
|
|
101
|
-
var(--motion-duration-small);
|
|
98
|
+
transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
.rt-ShellRailContent[data-visible] {
|
|
@@ -116,7 +113,6 @@
|
|
|
116
113
|
display: flex;
|
|
117
114
|
flex-direction: column;
|
|
118
115
|
height: 100%;
|
|
119
|
-
background-color: var(--color-panel);
|
|
120
116
|
/* Allow handle to bleed across boundary */
|
|
121
117
|
overflow: visible;
|
|
122
118
|
position: relative;
|
|
@@ -150,8 +146,7 @@
|
|
|
150
146
|
|
|
151
147
|
/* Content animation */
|
|
152
148
|
opacity: 0;
|
|
153
|
-
transition: opacity var(--motion-duration-small) var(--motion-ease-standard)
|
|
154
|
-
var(--motion-duration-small);
|
|
149
|
+
transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
|
|
155
150
|
}
|
|
156
151
|
|
|
157
152
|
.rt-ShellPanelContent[data-visible] {
|
|
@@ -169,7 +164,6 @@
|
|
|
169
164
|
display: flex;
|
|
170
165
|
flex-direction: column;
|
|
171
166
|
height: 100%;
|
|
172
|
-
background-color: var(--color-panel);
|
|
173
167
|
/* Allow handle to bleed across boundary */
|
|
174
168
|
overflow: visible;
|
|
175
169
|
position: relative;
|
|
@@ -212,8 +206,7 @@
|
|
|
212
206
|
|
|
213
207
|
/* Content animation */
|
|
214
208
|
opacity: 0;
|
|
215
|
-
transition: opacity var(--motion-duration-small) var(--motion-ease-standard)
|
|
216
|
-
var(--motion-duration-small);
|
|
209
|
+
transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
|
|
217
210
|
}
|
|
218
211
|
|
|
219
212
|
/* Hide resizer in thin mode */
|
|
@@ -259,7 +252,6 @@
|
|
|
259
252
|
min-width: 0;
|
|
260
253
|
height: 100%;
|
|
261
254
|
overflow: auto;
|
|
262
|
-
background-color: var(--color-surface);
|
|
263
255
|
}
|
|
264
256
|
|
|
265
257
|
/* Inspector - right-side panel */
|
|
@@ -267,7 +259,6 @@
|
|
|
267
259
|
display: flex;
|
|
268
260
|
flex-direction: column;
|
|
269
261
|
height: 100%;
|
|
270
|
-
background-color: var(--color-panel);
|
|
271
262
|
/* Allow handle to bleed across boundary */
|
|
272
263
|
overflow: visible;
|
|
273
264
|
position: relative;
|
|
@@ -300,8 +291,7 @@
|
|
|
300
291
|
|
|
301
292
|
/* Content animation */
|
|
302
293
|
opacity: 0;
|
|
303
|
-
transition: opacity var(--motion-duration-small) var(--motion-ease-standard)
|
|
304
|
-
var(--motion-duration-small);
|
|
294
|
+
transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
|
|
305
295
|
}
|
|
306
296
|
|
|
307
297
|
.rt-ShellInspectorContent[data-visible] {
|
|
@@ -319,7 +309,6 @@
|
|
|
319
309
|
display: flex;
|
|
320
310
|
flex-direction: column;
|
|
321
311
|
width: 100%;
|
|
322
|
-
background-color: var(--color-panel);
|
|
323
312
|
/* Allow handle to bleed across boundary */
|
|
324
313
|
overflow: visible;
|
|
325
314
|
flex-shrink: 0;
|
|
@@ -349,8 +338,7 @@
|
|
|
349
338
|
|
|
350
339
|
/* Content animation */
|
|
351
340
|
opacity: 0;
|
|
352
|
-
transition: opacity var(--motion-duration-small) var(--motion-ease-standard)
|
|
353
|
-
var(--motion-duration-small);
|
|
341
|
+
transition: opacity var(--motion-duration-small) var(--motion-ease-standard) var(--motion-duration-small);
|
|
354
342
|
}
|
|
355
343
|
|
|
356
344
|
.rt-ShellBottomContent[data-visible] {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Breakpoint, PresentationValue, ResponsivePresentation } from './shell.types.js';
|
|
3
|
+
import { BREAKPOINTS } from './shell.types.js';
|
|
4
|
+
import { useShell } from './shell.context.js';
|
|
5
|
+
|
|
6
|
+
export function useResponsivePresentation(presentation: ResponsivePresentation): PresentationValue {
|
|
7
|
+
const { currentBreakpoint } = useShell();
|
|
8
|
+
|
|
9
|
+
return React.useMemo(() => {
|
|
10
|
+
if (typeof presentation === 'string') {
|
|
11
|
+
return presentation;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (presentation[currentBreakpoint]) {
|
|
15
|
+
return presentation[currentBreakpoint]!;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const bpKeys = Object.keys(BREAKPOINTS) as Array<keyof typeof BREAKPOINTS>;
|
|
19
|
+
const order: Breakpoint[] = ([...bpKeys].reverse() as Breakpoint[]).concat('initial' as Breakpoint);
|
|
20
|
+
const startIdx = order.indexOf(currentBreakpoint as Breakpoint);
|
|
21
|
+
|
|
22
|
+
for (let i = startIdx + 1; i < order.length; i++) {
|
|
23
|
+
const bp = order[i];
|
|
24
|
+
if (presentation[bp]) {
|
|
25
|
+
return presentation[bp]!;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return 'fixed';
|
|
30
|
+
}, [presentation, currentBreakpoint]);
|
|
31
|
+
}
|