@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.
Files changed (149) hide show
  1. package/components.css +858 -30
  2. package/dist/cjs/components/_internal/shell-bottom.d.ts +31 -0
  3. package/dist/cjs/components/_internal/shell-bottom.d.ts.map +1 -0
  4. package/dist/cjs/components/_internal/shell-bottom.js +2 -0
  5. package/dist/cjs/components/_internal/shell-bottom.js.map +7 -0
  6. package/dist/cjs/components/_internal/shell-handles.d.ts +7 -0
  7. package/dist/cjs/components/_internal/shell-handles.d.ts.map +1 -0
  8. package/dist/cjs/components/_internal/shell-handles.js +2 -0
  9. package/dist/cjs/components/_internal/shell-handles.js.map +7 -0
  10. package/dist/cjs/components/_internal/shell-inspector.d.ts +31 -0
  11. package/dist/cjs/components/_internal/shell-inspector.d.ts.map +1 -0
  12. package/dist/cjs/components/_internal/shell-inspector.js +2 -0
  13. package/dist/cjs/components/_internal/shell-inspector.js.map +7 -0
  14. package/dist/cjs/components/_internal/shell-resize.d.ts +24 -0
  15. package/dist/cjs/components/_internal/shell-resize.d.ts.map +1 -0
  16. package/dist/cjs/components/_internal/shell-resize.js +2 -0
  17. package/dist/cjs/components/_internal/shell-resize.js.map +7 -0
  18. package/dist/cjs/components/_internal/shell-sidebar.d.ts +37 -0
  19. package/dist/cjs/components/_internal/shell-sidebar.d.ts.map +1 -0
  20. package/dist/cjs/components/_internal/shell-sidebar.js +2 -0
  21. package/dist/cjs/components/_internal/shell-sidebar.js.map +7 -0
  22. package/dist/cjs/components/alert-dialog.d.ts.map +1 -1
  23. package/dist/cjs/components/alert-dialog.js +1 -1
  24. package/dist/cjs/components/alert-dialog.js.map +2 -2
  25. package/dist/cjs/components/dialog.d.ts.map +1 -1
  26. package/dist/cjs/components/dialog.js +1 -1
  27. package/dist/cjs/components/dialog.js.map +2 -2
  28. package/dist/cjs/components/schemas/index.d.ts +2 -0
  29. package/dist/cjs/components/schemas/index.d.ts.map +1 -1
  30. package/dist/cjs/components/schemas/index.js +1 -1
  31. package/dist/cjs/components/schemas/index.js.map +3 -3
  32. package/dist/cjs/components/schemas/shell.schema.d.ts +1025 -0
  33. package/dist/cjs/components/schemas/shell.schema.d.ts.map +1 -0
  34. package/dist/cjs/components/schemas/shell.schema.js +2 -0
  35. package/dist/cjs/components/schemas/shell.schema.js.map +7 -0
  36. package/dist/cjs/components/shell.context.d.ts +37 -0
  37. package/dist/cjs/components/shell.context.d.ts.map +1 -0
  38. package/dist/cjs/components/shell.context.js +2 -0
  39. package/dist/cjs/components/shell.context.js.map +7 -0
  40. package/dist/cjs/components/shell.d.ts +6 -68
  41. package/dist/cjs/components/shell.d.ts.map +1 -1
  42. package/dist/cjs/components/shell.hooks.d.ts +3 -0
  43. package/dist/cjs/components/shell.hooks.d.ts.map +1 -0
  44. package/dist/cjs/components/shell.hooks.js +2 -0
  45. package/dist/cjs/components/shell.hooks.js.map +7 -0
  46. package/dist/cjs/components/shell.js +1 -1
  47. package/dist/cjs/components/shell.js.map +3 -3
  48. package/dist/cjs/components/shell.types.d.ts +20 -0
  49. package/dist/cjs/components/shell.types.d.ts.map +1 -0
  50. package/dist/cjs/components/shell.types.js +2 -0
  51. package/dist/cjs/components/shell.types.js.map +7 -0
  52. package/dist/cjs/components/sidebar.d.ts +1 -1
  53. package/dist/cjs/components/sidebar.d.ts.map +1 -1
  54. package/dist/cjs/components/sidebar.js +1 -1
  55. package/dist/cjs/components/sidebar.js.map +3 -3
  56. package/dist/esm/components/_internal/shell-bottom.d.ts +31 -0
  57. package/dist/esm/components/_internal/shell-bottom.d.ts.map +1 -0
  58. package/dist/esm/components/_internal/shell-bottom.js +2 -0
  59. package/dist/esm/components/_internal/shell-bottom.js.map +7 -0
  60. package/dist/esm/components/_internal/shell-handles.d.ts +7 -0
  61. package/dist/esm/components/_internal/shell-handles.d.ts.map +1 -0
  62. package/dist/esm/components/_internal/shell-handles.js +2 -0
  63. package/dist/esm/components/_internal/shell-handles.js.map +7 -0
  64. package/dist/esm/components/_internal/shell-inspector.d.ts +31 -0
  65. package/dist/esm/components/_internal/shell-inspector.d.ts.map +1 -0
  66. package/dist/esm/components/_internal/shell-inspector.js +2 -0
  67. package/dist/esm/components/_internal/shell-inspector.js.map +7 -0
  68. package/dist/esm/components/_internal/shell-resize.d.ts +24 -0
  69. package/dist/esm/components/_internal/shell-resize.d.ts.map +1 -0
  70. package/dist/esm/components/_internal/shell-resize.js +2 -0
  71. package/dist/esm/components/_internal/shell-resize.js.map +7 -0
  72. package/dist/esm/components/_internal/shell-sidebar.d.ts +37 -0
  73. package/dist/esm/components/_internal/shell-sidebar.d.ts.map +1 -0
  74. package/dist/esm/components/_internal/shell-sidebar.js +2 -0
  75. package/dist/esm/components/_internal/shell-sidebar.js.map +7 -0
  76. package/dist/esm/components/alert-dialog.d.ts.map +1 -1
  77. package/dist/esm/components/alert-dialog.js +1 -1
  78. package/dist/esm/components/alert-dialog.js.map +2 -2
  79. package/dist/esm/components/dialog.d.ts.map +1 -1
  80. package/dist/esm/components/dialog.js +1 -1
  81. package/dist/esm/components/dialog.js.map +2 -2
  82. package/dist/esm/components/schemas/index.d.ts +2 -0
  83. package/dist/esm/components/schemas/index.d.ts.map +1 -1
  84. package/dist/esm/components/schemas/index.js +1 -1
  85. package/dist/esm/components/schemas/index.js.map +3 -3
  86. package/dist/esm/components/schemas/shell.schema.d.ts +1025 -0
  87. package/dist/esm/components/schemas/shell.schema.d.ts.map +1 -0
  88. package/dist/esm/components/schemas/shell.schema.js +2 -0
  89. package/dist/esm/components/schemas/shell.schema.js.map +7 -0
  90. package/dist/esm/components/shell.context.d.ts +37 -0
  91. package/dist/esm/components/shell.context.d.ts.map +1 -0
  92. package/dist/esm/components/shell.context.js +2 -0
  93. package/dist/esm/components/shell.context.js.map +7 -0
  94. package/dist/esm/components/shell.d.ts +6 -68
  95. package/dist/esm/components/shell.d.ts.map +1 -1
  96. package/dist/esm/components/shell.hooks.d.ts +3 -0
  97. package/dist/esm/components/shell.hooks.d.ts.map +1 -0
  98. package/dist/esm/components/shell.hooks.js +2 -0
  99. package/dist/esm/components/shell.hooks.js.map +7 -0
  100. package/dist/esm/components/shell.js +1 -1
  101. package/dist/esm/components/shell.js.map +3 -3
  102. package/dist/esm/components/shell.types.d.ts +20 -0
  103. package/dist/esm/components/shell.types.d.ts.map +1 -0
  104. package/dist/esm/components/shell.types.js +2 -0
  105. package/dist/esm/components/shell.types.js.map +7 -0
  106. package/dist/esm/components/sidebar.d.ts +1 -1
  107. package/dist/esm/components/sidebar.d.ts.map +1 -1
  108. package/dist/esm/components/sidebar.js +1 -1
  109. package/dist/esm/components/sidebar.js.map +2 -2
  110. package/layout/utilities.css +168 -84
  111. package/layout.css +168 -84
  112. package/package.json +2 -1
  113. package/schemas/base-button.json +1 -1
  114. package/schemas/button.json +1 -1
  115. package/schemas/icon-button.json +1 -1
  116. package/schemas/index.json +6 -6
  117. package/schemas/shell-bottom.json +168 -0
  118. package/schemas/shell-content.json +34 -0
  119. package/schemas/shell-handle.json +34 -0
  120. package/schemas/shell-header.json +42 -0
  121. package/schemas/shell-inspector.json +171 -0
  122. package/schemas/shell-panel.json +167 -0
  123. package/schemas/shell-rail.json +132 -0
  124. package/schemas/shell-root.json +54 -0
  125. package/schemas/shell-sidebar.json +182 -0
  126. package/schemas/shell-trigger.json +76 -0
  127. package/schemas/toggle-button.json +1 -1
  128. package/schemas/toggle-icon-button.json +1 -1
  129. package/src/components/_internal/shell-bottom.tsx +251 -0
  130. package/src/components/_internal/shell-handles.tsx +193 -0
  131. package/src/components/_internal/shell-inspector.tsx +242 -0
  132. package/src/components/_internal/shell-resize.tsx +30 -0
  133. package/src/components/_internal/shell-sidebar.tsx +347 -0
  134. package/src/components/alert-dialog.tsx +6 -0
  135. package/src/components/dialog.tsx +6 -0
  136. package/src/components/schemas/index.ts +46 -0
  137. package/src/components/schemas/shell.schema.ts +403 -0
  138. package/src/components/shell.context.tsx +56 -0
  139. package/src/components/shell.css +5 -17
  140. package/src/components/shell.hooks.ts +31 -0
  141. package/src/components/shell.tsx +368 -1684
  142. package/src/components/shell.types.ts +27 -0
  143. package/src/components/sidebar.tsx +1 -1
  144. package/src/styles/tokens/blur.css +2 -2
  145. package/src/styles/tokens/color.css +2 -2
  146. package/styles.css +1031 -116
  147. package/tokens/base.css +5 -2
  148. package/tokens.css +5 -2
  149. 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
+ }
@@ -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
+ }