@fragments-sdk/ui 0.15.1 → 0.16.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.
Files changed (34) hide show
  1. package/dist/assets/ui.css +42 -34
  2. package/dist/components/AppShell/AppShell.module.scss.cjs +15 -21
  3. package/dist/components/AppShell/AppShell.module.scss.js +15 -21
  4. package/dist/components/AppShell/index.cjs +52 -13
  5. package/dist/components/AppShell/index.d.ts +55 -27
  6. package/dist/components/AppShell/index.d.ts.map +1 -1
  7. package/dist/components/AppShell/index.js +52 -13
  8. package/dist/components/CodeBlock/index.d.ts.map +1 -1
  9. package/dist/components/DatePicker/index.d.ts.map +1 -1
  10. package/dist/components/Form/index.cjs +1 -1
  11. package/dist/components/Form/index.d.ts +1 -1
  12. package/dist/components/Form/index.d.ts.map +1 -1
  13. package/dist/components/Form/index.js +1 -1
  14. package/dist/components/Menu/index.d.ts +1 -2
  15. package/dist/components/Menu/index.d.ts.map +1 -1
  16. package/dist/components/NavigationMenu/useNavigationMenu.cjs +6 -3
  17. package/dist/components/NavigationMenu/useNavigationMenu.d.ts.map +1 -1
  18. package/dist/components/NavigationMenu/useNavigationMenu.js +6 -3
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/utils/seed-derivation.d.ts.map +1 -1
  22. package/dist/utils/theme-presets.d.ts.map +1 -1
  23. package/fragments.json +1 -1
  24. package/package.json +2 -2
  25. package/src/components/AppShell/AppShell.module.scss +29 -20
  26. package/src/components/AppShell/index.tsx +123 -36
  27. package/src/components/CodeBlock/index.tsx +0 -1
  28. package/src/components/DatePicker/index.tsx +1 -1
  29. package/src/components/Form/index.tsx +1 -1
  30. package/src/components/Menu/index.tsx +1 -1
  31. package/src/components/NavigationMenu/useNavigationMenu.ts +6 -3
  32. package/src/index.ts +1 -0
  33. package/src/utils/seed-derivation.ts +0 -9
  34. package/src/utils/theme-presets.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/ui",
3
- "version": "0.15.1",
3
+ "version": "0.16.0",
4
4
  "license": "MIT",
5
5
  "description": "Customizable UI components built on Base UI headless primitives",
6
6
  "author": "Conan McNicholl",
@@ -230,7 +230,7 @@
230
230
  "vite": "^6.0.0",
231
231
  "vitest": "^2.1.8",
232
232
  "vitest-axe": "^0.1.0",
233
- "@fragments-sdk/core": "0.3.0"
233
+ "@fragments-sdk/core": "1.0.0"
234
234
  },
235
235
  "files": [
236
236
  "src",
@@ -6,9 +6,8 @@
6
6
  // ============================================
7
7
  // Grid areas: header, sidebar, main, aside
8
8
  //
9
- // 'default': header spans full width, sidebar below
10
- // 'sidebar': sidebar spans full height, header beside it
11
- // 'sidebar-floating': like sidebar, but main floats with rounded corners
9
+ // Structure is controlled by the `layout` prop ('default' | 'sidebar').
10
+ // Visual treatment (floating) is controlled per-slot via `variant` props.
12
11
 
13
12
  .root {
14
13
  display: grid;
@@ -48,7 +47,7 @@
48
47
  }
49
48
  }
50
49
 
51
- // Sidebar layout: sidebar spans full height
50
+ // Sidebar structure: sidebar spans full height
52
51
  // sidebar header header
53
52
  // sidebar main aside
54
53
  .sidebarLayout {
@@ -65,11 +64,6 @@
65
64
  }
66
65
  }
67
66
 
68
- // Sidebar-floating layout: shell background frames the floating main area
69
- .sidebarFloatingLayout {
70
- background-color: var(--fui-bg-primary, $fui-bg-primary);
71
- }
72
-
73
67
  // ============================================
74
68
  // Header
75
69
  // ============================================
@@ -83,11 +77,6 @@
83
77
  background-color: var(--fui-bg-primary, $fui-bg-primary);
84
78
  }
85
79
 
86
- // Header in sidebar-floating layout — matches shell bg
87
- .headerFloating {
88
- background-color: var(--fui-bg-primary, $fui-bg-primary);
89
- }
90
-
91
80
  // ============================================
92
81
  // Sidebar
93
82
  // ============================================
@@ -129,7 +118,7 @@
129
118
  }
130
119
  }
131
120
 
132
- // Sidebar in sidebar/sidebar-floating layouts: full height
121
+ // Sidebar in sidebar structure: full height
133
122
  .sidebarFullHeight {
134
123
  top: 0;
135
124
  height: 100vh;
@@ -141,11 +130,9 @@
141
130
  }
142
131
  }
143
132
 
144
- // Sidebar in sidebar-floating layout: no borders, primary bg (matches shell)
133
+ // Sidebar variant="floating": blends with shell background (bg applied via inline style on Sidebar)
145
134
  .sidebarFloating {
146
- :global(.root) {
147
- background-color: var(--fui-bg-primary, $fui-bg-primary);
148
- }
135
+ // No additional styles needed — bg prop is passed directly to the Sidebar component
149
136
  }
150
137
 
151
138
  // ============================================
@@ -159,13 +146,15 @@
159
146
  background-color: var(--fui-bg-primary, $fui-bg-primary);
160
147
  }
161
148
 
162
- // Main content in sidebar-floating layout elevated card effect
149
+ // Main variant="floating": elevated card effect with inset from edges
163
150
  .mainFloating {
151
+ margin: var(--fui-space-2, $fui-space-2) var(--fui-space-2, $fui-space-2) var(--fui-space-2, $fui-space-2) 0;
164
152
  border-radius: var(--fui-radius-xl, $fui-radius-xl);
165
153
  background-color: var(--fui-bg-secondary, $fui-bg-secondary);
166
154
  overflow: hidden;
167
155
 
168
156
  @include below-md {
157
+ margin: var(--fui-space-2, $fui-space-2) 0;
169
158
  border-radius: var(--fui-radius-lg, $fui-radius-lg);
170
159
  width: 100%;
171
160
  }
@@ -216,3 +205,23 @@
216
205
  border-top: 1px solid var(--fui-border, $fui-border);
217
206
  }
218
207
  }
208
+
209
+ // Aside variant="floating": elevated card effect with inset from edges
210
+ .asideFloating {
211
+ // Override the explicit width so the aside fills its grid cell
212
+ // and the margin creates visible inset space from the viewport edge.
213
+ width: auto;
214
+ height: calc(100vh - var(--appshell-header-height, 56px) - var(--fui-space-2, $fui-space-2) * 2);
215
+ height: calc(100dvh - var(--appshell-header-height, 56px) - var(--fui-space-2, $fui-space-2) * 2);
216
+ margin: var(--fui-space-2, $fui-space-2) var(--fui-space-2, $fui-space-2) var(--fui-space-2, $fui-space-2) 0;
217
+ border-radius: var(--fui-radius-xl, $fui-radius-xl);
218
+ background-color: var(--fui-bg-secondary, $fui-bg-secondary);
219
+ overflow: hidden;
220
+
221
+ @include below-md {
222
+ margin: var(--fui-space-2, $fui-space-2) 0;
223
+ border-radius: var(--fui-radius-lg, $fui-radius-lg);
224
+ width: 100%;
225
+ height: auto;
226
+ }
227
+ }
@@ -14,46 +14,62 @@ import {
14
14
  // ============================================
15
15
 
16
16
  /**
17
+ * Structural layout — controls CSS grid areas.
18
+ *
17
19
  * ```
18
- * 'default' 'sidebar' 'sidebar-floating'
19
- * ┌──────────────┐ ┌────┬─────────┐ ┌────┬─────────┐
20
- * │ Header │ │ │ Header │ │ │ Header │
21
- * ├────┬─────────┤ │Side├─────────┤ │Side├╌╌╌╌╌╌╌╌╌┤
22
- * │ │ │ │bar │ │ │bar │┌───────┐│
23
- * │Side│ Main │ │ │ Main │ │ ││ Main ││
24
- * │bar │ │ │ │ │ │ │└───────┘│
25
- * └────┴─────────┘ └────┴─────────┘ └────┴─────────┘
20
+ * 'default' 'sidebar'
21
+ * ┌──────────────┐ ┌────┬─────────┐
22
+ * │ Header │ │ │ Header │
23
+ * ├────┬─────────┤ │Side├─────────┤
24
+ * │ │ │ │bar │ │
25
+ * │Side│ Main │ │ │ Main │
26
+ * │bar │ │ │ │ │
27
+ * └────┴─────────┘ └────┴─────────┘
26
28
  * ```
29
+ *
30
+ * Combine with `variant="floating"` on individual slots for floating effects:
31
+ *
32
+ * ```tsx
33
+ * <AppShell layout="sidebar">
34
+ * <AppShell.Sidebar variant="floating" />
35
+ * <AppShell.Main variant="floating" />
36
+ * <AppShell.Aside variant="floating" />
37
+ * </AppShell>
38
+ * ```
39
+ *
40
+ * Legacy values `'sidebar-floating'` and `'floating'` are still accepted
41
+ * for backwards compatibility and internally expand to the appropriate
42
+ * per-slot variants.
27
43
  */
28
- export type AppShellLayout = 'default' | 'sidebar' | 'sidebar-floating';
44
+ export type AppShellLayout = 'default' | 'sidebar' | 'sidebar-floating' | 'floating';
45
+
46
+ /** Visual treatment for individual layout slots. */
47
+ export type AppShellSlotVariant = 'default' | 'floating';
29
48
 
30
49
  export interface AppShellProps extends React.HTMLAttributes<HTMLDivElement> {
31
50
  children: React.ReactNode;
32
51
  /**
33
- * Layout mode:
34
- *
35
- * ```
36
- * 'default' 'sidebar' 'sidebar-floating'
37
- * ┌──────────────┐ ┌────┬─────────┐ ┌────┬─────────┐
38
- * │ Header │ │ │ Header │ │ │ Header │
39
- * ├────┬─────────┤ │Side├─────────┤ │Side├╌╌╌╌╌╌╌╌╌┤
40
- * │ │ │ │bar │ │ │bar │┌───────┐│
41
- * │Side│ Main │ │ │ Main │ │ ││ Main ││
42
- * │bar │ │ │ │ │ │ │└───────┘│
43
- * └────┴─────────┘ └────┴─────────┘ └────┴─────────┘
44
- * ```
52
+ * Layout structure:
45
53
  *
46
54
  * - `'default'`: Header spans full width, sidebar below (default)
47
55
  * - `'sidebar'`: Sidebar is full height, header sits beside it
48
- * - `'sidebar-floating'`: Like `sidebar` but main content floats with rounded corners and a distinct background
56
+ *
57
+ * Legacy presets (still work, prefer per-slot `variant` props instead):
58
+ *
59
+ * - `'sidebar-floating'`: Expands to `layout="sidebar"` with floating sidebar + main
60
+ * - `'floating'`: Expands to `layout="sidebar"` with floating sidebar + main + aside
49
61
  */
50
62
  layout?: AppShellLayout;
63
+ /** Background color for the shell container (accepts any CSS color value or token) */
64
+ bg?: string;
51
65
  }
52
66
 
53
67
  export interface AppShellHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
54
68
  children: React.ReactNode;
55
69
  /** Header height (default: '56px') */
56
70
  height?: string;
71
+ /** Background color override (accepts any CSS color value or token) */
72
+ bg?: string;
57
73
  }
58
74
 
59
75
  export interface AppShellSidebarProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -68,12 +84,20 @@ export interface AppShellSidebarProps extends React.HTMLAttributes<HTMLDivElemen
68
84
  position?: 'left' | 'right';
69
85
  /** Default collapsed state */
70
86
  defaultCollapsed?: boolean;
87
+ /** Visual treatment: `'floating'` blends sidebar with the shell background */
88
+ variant?: AppShellSlotVariant;
89
+ /** Background color override (accepts any CSS color value or token) */
90
+ bg?: string;
71
91
  }
72
92
 
73
93
  export interface AppShellMainProps extends React.HTMLAttributes<HTMLElement> {
74
94
  children: React.ReactNode;
75
95
  /** Content padding */
76
96
  padding?: 'none' | 'sm' | 'md' | 'lg';
97
+ /** Visual treatment: `'floating'` adds rounded corners and elevated background */
98
+ variant?: AppShellSlotVariant;
99
+ /** Background color override (accepts any CSS color value or token) */
100
+ bg?: string;
77
101
  }
78
102
 
79
103
  export interface AppShellAsideProps extends React.HTMLAttributes<HTMLElement> {
@@ -82,6 +106,35 @@ export interface AppShellAsideProps extends React.HTMLAttributes<HTMLElement> {
82
106
  width?: string;
83
107
  /** Control visibility */
84
108
  visible?: boolean;
109
+ /** Visual treatment: `'floating'` adds rounded corners and elevated background */
110
+ variant?: AppShellSlotVariant;
111
+ /** Background color override (accepts any CSS color value or token) */
112
+ bg?: string;
113
+ }
114
+
115
+ // ============================================
116
+ // Layout resolution helpers
117
+ // ============================================
118
+
119
+ /** Resolve a layout value to its structural grid mode. */
120
+ function resolveStructure(layout: AppShellLayout): 'default' | 'sidebar' {
121
+ if (layout === 'sidebar' || layout === 'sidebar-floating' || layout === 'floating') return 'sidebar';
122
+ return 'default';
123
+ }
124
+
125
+ /**
126
+ * Resolve a slot's visual variant.
127
+ * Explicit `variant` prop always wins. Otherwise, infer from legacy layout values.
128
+ */
129
+ function resolveSlotVariant(
130
+ explicit: AppShellSlotVariant | undefined,
131
+ layout: AppShellLayout,
132
+ slot: 'main' | 'aside' | 'sidebar',
133
+ ): AppShellSlotVariant {
134
+ if (explicit !== undefined) return explicit;
135
+ if ((layout === 'sidebar-floating' || layout === 'floating') && (slot === 'main' || slot === 'sidebar')) return 'floating';
136
+ if (layout === 'floating' && slot === 'aside') return 'floating';
137
+ return 'default';
85
138
  }
86
139
 
87
140
  // ============================================
@@ -90,6 +143,7 @@ export interface AppShellAsideProps extends React.HTMLAttributes<HTMLElement> {
90
143
 
91
144
  interface AppShellContextValue {
92
145
  layout: AppShellLayout;
146
+ structure: 'default' | 'sidebar';
93
147
  headerHeight: string;
94
148
  sidebarWidth: string;
95
149
  sidebarCollapsedWidth: string;
@@ -99,6 +153,7 @@ interface AppShellContextValue {
99
153
 
100
154
  const AppShellContext = React.createContext<AppShellContextValue>({
101
155
  layout: 'default',
156
+ structure: 'default',
102
157
  headerHeight: '56px',
103
158
  sidebarWidth: '240px',
104
159
  sidebarCollapsedWidth: '64px',
@@ -190,20 +245,21 @@ function AppShellInner({
190
245
  children,
191
246
  className,
192
247
  layout,
248
+ structure,
193
249
  style: styleProp,
194
250
  ...htmlProps
195
251
  }: {
196
252
  children: React.ReactNode;
197
253
  className?: string;
198
254
  layout: AppShellLayout;
255
+ structure: 'default' | 'sidebar';
199
256
  } & React.HTMLAttributes<HTMLDivElement>) {
200
257
  const appShell = useAppShell();
201
258
  const { collapsed, isMobile, collapsible } = useSidebar();
202
259
 
203
260
  const classes = [
204
261
  styles.root,
205
- (layout === 'sidebar' || layout === 'sidebar-floating') && styles.sidebarLayout,
206
- layout === 'sidebar-floating' && styles.sidebarFloatingLayout,
262
+ structure === 'sidebar' && styles.sidebarLayout,
207
263
  className,
208
264
  ].filter(Boolean).join(' ');
209
265
 
@@ -243,14 +299,19 @@ function AppShellInner({
243
299
  function AppShellRoot({
244
300
  children,
245
301
  layout = 'default',
302
+ bg,
246
303
  className,
304
+ style: styleProp,
247
305
  ...htmlProps
248
306
  }: AppShellProps) {
307
+ const structure = resolveStructure(layout);
308
+
249
309
  // Extract config from children using useMemo to avoid re-renders
250
310
  const config = React.useMemo(() => extractConfigFromChildren(children), [children]);
251
311
 
252
312
  const contextValue: AppShellContextValue = {
253
313
  layout,
314
+ structure,
254
315
  headerHeight: config.headerHeight,
255
316
  sidebarWidth: config.sidebarWidth,
256
317
  sidebarCollapsedWidth: config.sidebarCollapsedWidth,
@@ -266,7 +327,7 @@ function AppShellRoot({
266
327
  collapsible={config.sidebarCollapsible}
267
328
  defaultCollapsed={config.sidebarDefaultCollapsed}
268
329
  >
269
- <AppShellInner className={className} layout={layout} {...htmlProps}>
330
+ <AppShellInner className={className} layout={layout} structure={structure} style={{ ...(bg ? { backgroundColor: bg } : {}), ...styleProp }} {...htmlProps}>
270
331
  {children}
271
332
  </AppShellInner>
272
333
  </SidebarProvider>
@@ -280,21 +341,19 @@ function AppShellRoot({
280
341
  function AppShellHeader({
281
342
  children,
282
343
  height = '56px',
344
+ bg,
283
345
  className,
284
346
  style: styleProp,
285
347
  ...htmlProps
286
348
  }: AppShellHeaderProps) {
287
- const { layout } = useAppShell();
288
-
289
349
  const classes = [
290
350
  styles.header,
291
- (layout === 'sidebar' || layout === 'sidebar-floating') && styles.headerSidebar,
292
- layout === 'sidebar-floating' && styles.headerFloating,
293
351
  className,
294
352
  ].filter(Boolean).join(' ');
295
353
 
296
354
  const style: React.CSSProperties = {
297
355
  '--header-height': height,
356
+ ...(bg ? { backgroundColor: bg } : {}),
298
357
  ...styleProp,
299
358
  } as React.CSSProperties;
300
359
 
@@ -315,22 +374,30 @@ function AppShellSidebar({
315
374
  collapsible = 'icon',
316
375
  position = 'left',
317
376
  defaultCollapsed = false,
377
+ variant,
378
+ bg,
318
379
  'aria-label': ariaLabel,
319
380
  className,
381
+ style: styleProp,
320
382
  ...htmlProps
321
383
  }: AppShellSidebarProps) {
322
384
  const isMobile = useIsMobile();
323
- const { layout } = useAppShell();
385
+ const { layout, structure } = useAppShell();
386
+ const resolvedVariant = resolveSlotVariant(variant, layout, 'sidebar');
324
387
 
325
388
  const classes = [
326
389
  styles.sidebar,
327
- (layout === 'sidebar' || layout === 'sidebar-floating') && styles.sidebarFullHeight,
328
- layout === 'sidebar-floating' && styles.sidebarFloating,
390
+ structure === 'sidebar' && styles.sidebarFullHeight,
391
+ resolvedVariant === 'floating' && styles.sidebarFloating,
329
392
  className,
330
393
  ].filter(Boolean).join(' ');
331
394
 
395
+ const style: React.CSSProperties = {
396
+ ...styleProp,
397
+ } as React.CSSProperties;
398
+
332
399
  return (
333
- <div {...htmlProps} className={classes}>
400
+ <div {...htmlProps} className={classes} style={style}>
334
401
  <Sidebar
335
402
  width={width}
336
403
  collapsedWidth={collapsedWidth}
@@ -338,6 +405,7 @@ function AppShellSidebar({
338
405
  collapsible={collapsible}
339
406
  defaultCollapsed={defaultCollapsed}
340
407
  aria-label={ariaLabel}
408
+ style={bg ? { backgroundColor: bg } : undefined}
341
409
  >
342
410
  {children}
343
411
  </Sidebar>
@@ -352,21 +420,30 @@ function AppShellSidebar({
352
420
  function AppShellMain({
353
421
  children,
354
422
  padding = 'md',
423
+ variant,
424
+ bg,
355
425
  className,
426
+ style: styleProp,
356
427
  id = 'main-content',
357
428
  ...htmlProps
358
429
  }: AppShellMainProps) {
359
430
  const { layout } = useAppShell();
431
+ const resolvedVariant = resolveSlotVariant(variant, layout, 'main');
360
432
 
361
433
  const classes = [
362
434
  styles.main,
363
435
  padding !== 'none' && styles[`padding${padding.charAt(0).toUpperCase() + padding.slice(1)}`],
364
- layout === 'sidebar-floating' && styles.mainFloating,
436
+ resolvedVariant === 'floating' && styles.mainFloating,
365
437
  className,
366
438
  ].filter(Boolean).join(' ');
367
439
 
440
+ const style: React.CSSProperties = {
441
+ ...(bg ? { backgroundColor: bg } : {}),
442
+ ...styleProp,
443
+ } as React.CSSProperties;
444
+
368
445
  return (
369
- <main {...htmlProps} className={classes} id={id}>
446
+ <main {...htmlProps} className={classes} style={style} id={id}>
370
447
  {children}
371
448
  </main>
372
449
  );
@@ -379,18 +456,28 @@ function AppShellAside({
379
456
  children,
380
457
  width = '280px',
381
458
  visible = true,
459
+ variant,
460
+ bg,
382
461
  className,
383
462
  style: styleProp,
384
463
  ...htmlProps
385
464
  }: AppShellAsideProps) {
465
+ const { layout } = useAppShell();
466
+ const resolvedVariant = resolveSlotVariant(variant, layout, 'aside');
467
+
386
468
  if (!visible) {
387
469
  return null;
388
470
  }
389
471
 
390
- const classes = [styles.aside, className].filter(Boolean).join(' ');
472
+ const classes = [
473
+ styles.aside,
474
+ resolvedVariant === 'floating' && styles.asideFloating,
475
+ className,
476
+ ].filter(Boolean).join(' ');
391
477
 
392
478
  const style: React.CSSProperties = {
393
479
  '--aside-width': width,
480
+ ...(bg ? { backgroundColor: bg } : {}),
394
481
  ...styleProp,
395
482
  } as React.CSSProperties;
396
483
 
@@ -28,7 +28,6 @@ async function loadShikiDeps() {
28
28
  await _shikiLoadPromise;
29
29
  }
30
30
  import { TabsRoot, TabsList, Tab, TabsPanel } from "../Tabs";
31
- import { Button } from "../Button";
32
31
  import styles from "./CodeBlock.module.scss";
33
32
  import "../../styles/globals.scss";
34
33
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  import { Popover as BasePopover } from '@base-ui/react/popover';
5
- import { mergeAriaIds, useFormFieldIds, type FormFieldProps } from '../../utils/aria';
5
+ import { useFormFieldIds, type FormFieldProps } from '../../utils/aria';
6
6
  import styles from './DatePicker.module.scss';
7
7
  // Import globals to ensure CSS variables are defined
8
8
  import '../../styles/globals.scss';
@@ -28,7 +28,7 @@ function FormRoot({
28
28
  errors,
29
29
  onSubmit,
30
30
  onFormSubmit,
31
- onClearErrors,
31
+ onClearErrors: _onClearErrors,
32
32
  validationMode,
33
33
  className,
34
34
  ...htmlProps
@@ -73,7 +73,7 @@ export interface MenuGroupLabelProps extends React.HTMLAttributes<HTMLElement> {
73
73
  children: React.ReactNode;
74
74
  }
75
75
 
76
- export interface MenuSeparatorProps extends React.HTMLAttributes<HTMLElement> {}
76
+ export type MenuSeparatorProps = React.HTMLAttributes<HTMLElement>;
77
77
 
78
78
  export interface MenuSubmenuProps {
79
79
  children: React.ReactNode;
@@ -64,10 +64,13 @@ export function useNavigationMenu({
64
64
 
65
65
  // Clean up timers on unmount
66
66
  React.useEffect(() => {
67
+ const openTimer = openTimerRef.current;
68
+ const closeTimer = closeTimerRef.current;
69
+ const skipDelayTimer = skipDelayTimerRef.current;
67
70
  return () => {
68
- if (openTimerRef.current) clearTimeout(openTimerRef.current);
69
- if (closeTimerRef.current) clearTimeout(closeTimerRef.current);
70
- if (skipDelayTimerRef.current) clearTimeout(skipDelayTimerRef.current);
71
+ if (openTimer) clearTimeout(openTimer);
72
+ if (closeTimer) clearTimeout(closeTimer);
73
+ if (skipDelayTimer) clearTimeout(skipDelayTimer);
71
74
  };
72
75
  }, []);
73
76
 
package/src/index.ts CHANGED
@@ -341,6 +341,7 @@ export {
341
341
  AppShell,
342
342
  type AppShellProps,
343
343
  type AppShellLayout,
344
+ type AppShellSlotVariant,
344
345
  type AppShellHeaderProps,
345
346
  type AppShellSidebarProps,
346
347
  type AppShellMainProps,
@@ -266,15 +266,6 @@ function rgbToHex(r: number, g: number, b: number): string {
266
266
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
267
267
  }
268
268
 
269
- /**
270
- * Check if a color is considered "dark" (luminance < 0.5)
271
- */
272
- function isDarkColor(hex: string): boolean {
273
- const { r, g, b } = hexToRgb(hex);
274
- const luminance = 0.2126 * (r / 255) + 0.7152 * (g / 255) + 0.0722 * (b / 255);
275
- return luminance < 0.5;
276
- }
277
-
278
269
  /**
279
270
  * Lighten a color by a percentage
280
271
  */
@@ -8,7 +8,6 @@
8
8
 
9
9
  import {
10
10
  type SeedConfig,
11
- type NeutralPalette,
12
11
  PALETTES,
13
12
  RADIUS_STYLES,
14
13
  getSemanticColors,