@classic-homes/theme-svelte 0.1.54 → 0.1.56

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 (36) hide show
  1. package/dist/__tests__/FileUpload.test.js +45 -0
  2. package/dist/lib/components/Button.svelte +17 -1
  3. package/dist/lib/components/Checkbox.svelte +3 -2
  4. package/dist/lib/components/Combobox.svelte +4 -4
  5. package/dist/lib/components/DataPanel.svelte +11 -5
  6. package/dist/lib/components/DateTimePicker.svelte +3 -2
  7. package/dist/lib/components/FileUpload.svelte +39 -4
  8. package/dist/lib/components/FileUpload.svelte.d.ts +6 -0
  9. package/dist/lib/components/HeaderSearch.svelte +5 -0
  10. package/dist/lib/components/RadioGroup.svelte +3 -2
  11. package/dist/lib/components/Select.svelte +3 -2
  12. package/dist/lib/components/Signature.svelte +3 -2
  13. package/dist/lib/components/Tabs.svelte +3 -2
  14. package/dist/lib/components/data-table/DataTableColumnFilter.svelte +2 -2
  15. package/dist/lib/components/data-table/DataTableColumnFilter.svelte.d.ts +33 -13
  16. package/dist/lib/components/data-table/DataTableColumnVisibility.svelte +2 -2
  17. package/dist/lib/components/data-table/DataTableColumnVisibility.svelte.d.ts +27 -7
  18. package/dist/lib/components/data-table/DataTableFacetedFilter.svelte +2 -2
  19. package/dist/lib/components/data-table/DataTableFacetedFilter.svelte.d.ts +36 -17
  20. package/dist/lib/components/data-table/DataTablePagination.svelte +2 -2
  21. package/dist/lib/components/data-table/DataTablePagination.svelte.d.ts +31 -11
  22. package/dist/lib/components/data-table/DataTableSearch.svelte +2 -2
  23. package/dist/lib/components/data-table/DataTableSearch.svelte.d.ts +31 -11
  24. package/dist/lib/components/data-table/DataTableToolbar.svelte +2 -2
  25. package/dist/lib/components/data-table/DataTableToolbar.svelte.d.ts +37 -17
  26. package/dist/lib/composables/useAnnounce.svelte.js +9 -9
  27. package/dist/lib/composables/useArrowNavigation.svelte.js +5 -4
  28. package/dist/lib/composables/useEscapeKey.svelte.d.ts +4 -2
  29. package/dist/lib/composables/useEscapeKey.svelte.js +3 -2
  30. package/dist/lib/composables/useFocusRef.svelte.js +4 -3
  31. package/dist/lib/composables/useFocusTrap.svelte.d.ts +9 -3
  32. package/dist/lib/composables/useFocusTrap.svelte.js +34 -28
  33. package/dist/lib/composables/useRovingTabindex.svelte.js +4 -3
  34. package/dist/lib/utils.d.ts +0 -10
  35. package/dist/lib/utils.js +0 -13
  36. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/svelte';
3
+ import FileUpload from '../lib/components/FileUpload.svelte';
4
+ describe('FileUpload accepted-types label', () => {
5
+ it('derives a friendly label from MIME types instead of showing raw values', () => {
6
+ render(FileUpload, {
7
+ props: {
8
+ label: 'Upload files',
9
+ acceptedTypes: [
10
+ 'image/jpeg',
11
+ 'image/png',
12
+ 'application/pdf',
13
+ 'video/mp4',
14
+ 'video/quicktime',
15
+ ],
16
+ },
17
+ });
18
+ expect(screen.getByText(/Images, PDF, Videos \(max/)).toBeInTheDocument();
19
+ // Raw MIME types should not be shown
20
+ expect(screen.queryByText(/image\/jpeg/)).not.toBeInTheDocument();
21
+ });
22
+ it('uses the default accepted types (Images, PDF) when none are provided', () => {
23
+ render(FileUpload, { props: { label: 'Upload files' } });
24
+ expect(screen.getByText(/^Images, PDF \(max/)).toBeInTheDocument();
25
+ });
26
+ it('respects an explicit typesLabel override', () => {
27
+ render(FileUpload, {
28
+ props: {
29
+ label: 'Upload files',
30
+ acceptedTypes: ['image/png', 'video/mp4'],
31
+ typesLabel: 'Photos and clips',
32
+ },
33
+ });
34
+ expect(screen.getByText(/^Photos and clips \(max/)).toBeInTheDocument();
35
+ });
36
+ it('falls back to the uppercased subtype for unmapped types', () => {
37
+ render(FileUpload, {
38
+ props: {
39
+ label: 'Upload files',
40
+ acceptedTypes: ['application/zip'],
41
+ },
42
+ });
43
+ expect(screen.getByText(/^ZIP \(max/)).toBeInTheDocument();
44
+ });
45
+ });
@@ -110,7 +110,23 @@
110
110
  {/snippet}
111
111
 
112
112
  {#if href}
113
- <a {href} class={classes} {...restProps}>
113
+ <!-- Anchors can't be natively disabled: remove from tab order, expose
114
+ aria-disabled, drop the href, and block clicks when disabled/loading -->
115
+ <a
116
+ href={disabled || loading ? undefined : href}
117
+ class={classes}
118
+ aria-disabled={disabled || loading || undefined}
119
+ aria-busy={loading || undefined}
120
+ tabindex={disabled || loading ? -1 : undefined}
121
+ onclick={(e) => {
122
+ if (disabled || loading) {
123
+ e.preventDefault();
124
+ return;
125
+ }
126
+ onclick?.(e);
127
+ }}
128
+ {...restProps}
129
+ >
114
130
  {@render buttonContent()}
115
131
  </a>
116
132
  {:else}
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import { Checkbox as CheckboxPrimitive } from 'bits-ui';
4
- import { cn, useId } from '../utils.js';
4
+ import { cn } from '../utils.js';
5
5
 
6
6
  interface Props {
7
7
  checked?: boolean;
@@ -32,7 +32,8 @@
32
32
  }: Props = $props();
33
33
 
34
34
  // Generate a stable unique ID if none provided (for accessibility)
35
- const generatedId = useId('checkbox');
35
+ const uid = $props.id();
36
+ const generatedId = `checkbox-${uid}`;
36
37
  const effectiveId = $derived(id ?? generatedId);
37
38
 
38
39
  function handleCheckedChange(newChecked: boolean | 'indeterminate') {
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { Combobox as ComboboxPrimitive } from 'bits-ui';
3
3
  import { cn } from '../utils.js';
4
- import { generateId, computeDescribedBy } from '../utils/form.js';
4
+ import { computeDescribedBy } from '../utils/form.js';
5
5
  import Spinner from './Spinner.svelte';
6
6
  import Label from './Label.svelte';
7
7
  import LiveRegion from './LiveRegion.svelte';
@@ -66,9 +66,9 @@
66
66
  class: className,
67
67
  }: Props = $props();
68
68
 
69
- // Generate unique IDs for accessibility
70
- const randomSuffix = generateId('combobox').split('-').pop();
71
- const componentId = $derived(id || `combobox-${randomSuffix}`);
69
+ // Generate unique IDs for accessibility ($props.id() is SSR-stable)
70
+ const uid = $props.id();
71
+ const componentId = $derived(id || `combobox-${uid}`);
72
72
  const hintId = $derived(`${componentId}-hint`);
73
73
  const errorId = $derived(`${componentId}-error`);
74
74
 
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../utils.js';
3
- import { onMount } from 'svelte';
3
+ import { onMount, onDestroy } from 'svelte';
4
4
  import type { Snippet } from 'svelte';
5
5
  import type {
6
6
  PanelEdge,
@@ -222,11 +222,13 @@
222
222
  }
223
223
 
224
224
  saveTimeout = setTimeout(() => {
225
+ // Persist the resolved values so controlled mode saves what's shown,
226
+ // not the untouched internal defaults
225
227
  savePanelState(persistKey, {
226
- mode: internalMode,
227
- variant: internalVariant,
228
- edge: internalEdge,
229
- isExpanded: internalExpanded,
228
+ mode,
229
+ variant,
230
+ edge,
231
+ isExpanded,
230
232
  detachedPosition,
231
233
  detachedSize,
232
234
  pinnedSize,
@@ -236,6 +238,10 @@
236
238
  }, 300);
237
239
  }
238
240
 
241
+ onDestroy(() => {
242
+ if (saveTimeout) clearTimeout(saveTimeout);
243
+ });
244
+
239
245
  // Initialize from persistence on mount
240
246
  onMount(() => {
241
247
  // Update viewport dimensions
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { Popover, Calendar } from 'bits-ui';
3
3
  import { tick } from 'svelte';
4
- import { cn, useId } from '../utils.js';
4
+ import { cn } from '../utils.js';
5
5
  import { parseDate, toISOString, parseDateInput } from '../utils/date.js';
6
6
  import Label from './Label.svelte';
7
7
 
@@ -69,7 +69,8 @@
69
69
  }: Props = $props();
70
70
 
71
71
  // Generate unique IDs for accessibility using sequential counter
72
- const generatedId = useId('datetimepicker');
72
+ const uid = $props.id();
73
+ const generatedId = `datetimepicker-${uid}`;
73
74
  const componentId = $derived(id || generatedId);
74
75
  const hintId = $derived(`${componentId}-hint`);
75
76
  const errorId = $derived(`${componentId}-error`);
@@ -12,7 +12,7 @@
12
12
  * - Accessible with keyboard navigation
13
13
  */
14
14
  import type { FileMetadata } from '../types/components.js';
15
- import { cn, useId } from '../utils.js';
15
+ import { cn } from '../utils.js';
16
16
  import Button from './Button.svelte';
17
17
 
18
18
  interface Props {
@@ -38,11 +38,18 @@
38
38
  label?: string;
39
39
  /** Hint text shown below the drop zone */
40
40
  hint?: string;
41
+ /**
42
+ * Human-friendly label for the accepted file types shown in the drop zone.
43
+ * When omitted, a readable label is derived from `acceptedTypes`
44
+ * (e.g. "Images, PDF, Videos") instead of showing raw MIME types.
45
+ */
46
+ typesLabel?: string;
41
47
  /** Additional classes */
42
48
  class?: string;
43
49
  }
44
50
 
45
- const generatedId = useId('file-upload');
51
+ const uid = $props.id();
52
+ const generatedId = `file-upload-${uid}`;
46
53
 
47
54
  let {
48
55
  id = generatedId,
@@ -56,6 +63,7 @@
56
63
  onUpload,
57
64
  label,
58
65
  hint,
66
+ typesLabel,
59
67
  class: className,
60
68
  }: Props = $props();
61
69
 
@@ -68,6 +76,33 @@
68
76
 
69
77
  const displayError = $derived(externalError || internalError);
70
78
 
79
+ /**
80
+ * Readable label for the accepted types shown in the drop zone.
81
+ * Uses the explicit `typesLabel` when provided, otherwise groups the
82
+ * accepted MIME types into friendly names (Images, PDF, Videos, ...).
83
+ */
84
+ const acceptedTypesLabel = $derived.by(() => {
85
+ if (typesLabel) return typesLabel;
86
+
87
+ const groups: string[] = [];
88
+ const add = (name: string) => {
89
+ if (!groups.includes(name)) groups.push(name);
90
+ };
91
+
92
+ for (const type of acceptedTypes) {
93
+ if (type.startsWith('image/')) add('Images');
94
+ else if (type === 'application/pdf') add('PDF');
95
+ else if (type.startsWith('video/')) add('Videos');
96
+ else if (type.startsWith('audio/')) add('Audio');
97
+ else {
98
+ const subtype = type.split('/')[1];
99
+ add(subtype ? subtype.toUpperCase() : type);
100
+ }
101
+ }
102
+
103
+ return groups.join(', ');
104
+ });
105
+
71
106
  // Helper to generate unique ID
72
107
  function generateId(): string {
73
108
  return `file-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
@@ -302,7 +337,7 @@
302
337
  for={id}
303
338
  aria-describedby={displayError ? `${id}-error` : undefined}
304
339
  class={cn(
305
- 'relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6 transition-colors',
340
+ 'relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6',
306
341
  'cursor-pointer focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',
307
342
  isDragging && !disabled && 'border-primary bg-primary/5',
308
343
  disabled && 'cursor-not-allowed opacity-50',
@@ -337,7 +372,7 @@
337
372
  <span class="font-medium text-foreground">Click to upload</span> or drag and drop
338
373
  </p>
339
374
  <p class="mt-1 text-xs text-muted-foreground">
340
- {acceptedTypes.join(', ')} (max {formatSize(maxSizeBytes)})
375
+ {acceptedTypesLabel} (max {formatSize(maxSizeBytes)})
341
376
  </p>
342
377
 
343
378
  <!-- Hidden file input -->
@@ -34,6 +34,12 @@ interface Props {
34
34
  label?: string;
35
35
  /** Hint text shown below the drop zone */
36
36
  hint?: string;
37
+ /**
38
+ * Human-friendly label for the accepted file types shown in the drop zone.
39
+ * When omitted, a readable label is derived from `acceptedTypes`
40
+ * (e.g. "Images, PDF, Videos") instead of showing raw MIME types.
41
+ */
42
+ typesLabel?: string;
37
43
  /** Additional classes */
38
44
  class?: string;
39
45
  }
@@ -25,6 +25,7 @@
25
25
  * ```
26
26
  */
27
27
  import { Dialog as DialogPrimitive } from 'bits-ui';
28
+ import { onDestroy } from 'svelte';
28
29
  import { cn } from '../utils.js';
29
30
  import type { Snippet } from 'svelte';
30
31
  import type { SearchResultItem, SearchResultGroup } from '../types/layout.js';
@@ -131,6 +132,10 @@
131
132
  }, 200);
132
133
  }
133
134
 
135
+ onDestroy(() => {
136
+ if (debounceTimer) clearTimeout(debounceTimer);
137
+ });
138
+
134
139
  // Keyboard navigation within results
135
140
  function handleKeydown(e: KeyboardEvent) {
136
141
  switch (e.key) {
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { RadioGroup as RadioGroupPrimitive } from 'bits-ui';
3
- import { cn, useId } from '../utils.js';
3
+ import { cn } from '../utils.js';
4
4
  import { computeDescribedBy } from '../utils/form.js';
5
5
  import { validateNonEmptyArray } from '../validation.js';
6
6
  import Label from './Label.svelte';
@@ -52,7 +52,8 @@
52
52
  }: Props = $props();
53
53
 
54
54
  // Generate unique IDs for accessibility (sequential counter, SSR-safe)
55
- const generatedId = useId('radio-group');
55
+ const uid = $props.id();
56
+ const generatedId = `radio-group-${uid}`;
56
57
  const componentName = $derived(name || generatedId);
57
58
  const labelId = $derived(`${componentName}-label`);
58
59
  const hintId = $derived(`${componentName}-hint`);
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { Select as SelectPrimitive } from 'bits-ui';
3
- import { cn, useId } from '../utils.js';
3
+ import { cn } from '../utils.js';
4
4
  import { validateNonEmptyArray } from '../validation.js';
5
5
  import { DEV } from 'esm-env';
6
6
  import Label from './Label.svelte';
@@ -59,7 +59,8 @@
59
59
  }: Props = $props();
60
60
 
61
61
  // Generate unique IDs for accessibility using sequential counter
62
- const generatedId = useId('select');
62
+ const uid = $props.id();
63
+ const generatedId = `select-${uid}`;
63
64
  const componentId = $derived(id || generatedId);
64
65
  const hintId = $derived(`${componentId}-hint`);
65
66
  const errorId = $derived(`${componentId}-error`);
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { untrack } from 'svelte';
3
- import { cn, useId } from '../utils.js';
3
+ import { cn } from '../utils.js';
4
4
  import { tv, type VariantProps } from 'tailwind-variants';
5
5
  import type {
6
6
  SignatureData,
@@ -842,7 +842,8 @@
842
842
  });
843
843
 
844
844
  // Computed IDs (using stable sequential ID generation)
845
- const generatedInputId = useId('signature');
845
+ const uid = $props.id();
846
+ const generatedInputId = `signature-${uid}`;
846
847
  const inputId = $derived(id || generatedInputId);
847
848
  const errorId = $derived(`${inputId}-error`);
848
849
  const hintId = $derived(`${inputId}-hint`);
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import { setContext } from 'svelte';
4
- import { cn, useId } from '../utils.js';
4
+ import { cn } from '../utils.js';
5
5
  import type { Tab } from '../types/components.js';
6
6
 
7
7
  interface Props {
@@ -25,7 +25,8 @@
25
25
  onValueChange?: (value: string) => void;
26
26
  }
27
27
 
28
- const generatedId = useId('tabs');
28
+ const uid = $props.id();
29
+ const generatedId = `tabs-${uid}`;
29
30
 
30
31
  let {
31
32
  tabs,
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTableColumnFilter - Per-column text filter input
4
4
  *
@@ -12,7 +12,7 @@
12
12
 
13
13
  interface Props {
14
14
  /** The native DataTable instance */
15
- table: DataTableInstance<any>;
15
+ table: DataTableInstance<TData>;
16
16
  /** Column ID to filter */
17
17
  columnId: string;
18
18
  /** Placeholder text */
@@ -5,18 +5,38 @@
5
5
  * Works with the native Svelte 5 DataTable implementation.
6
6
  */
7
7
  import type { DataTableInstance } from './createDataTable.svelte.js';
8
- interface Props {
9
- /** The native DataTable instance */
10
- table: DataTableInstance<any>;
11
- /** Column ID to filter */
12
- columnId: string;
13
- /** Placeholder text */
14
- placeholder?: string;
15
- /** Debounce delay in ms */
16
- debounceMs?: number;
17
- /** Additional classes */
18
- class?: string;
8
+ declare function $$render<TData extends object>(): {
9
+ props: {
10
+ /** The native DataTable instance */
11
+ table: DataTableInstance<TData>;
12
+ /** Column ID to filter */
13
+ columnId: string;
14
+ /** Placeholder text */
15
+ placeholder?: string;
16
+ /** Debounce delay in ms */
17
+ debounceMs?: number;
18
+ /** Additional classes */
19
+ class?: string;
20
+ };
21
+ exports: {};
22
+ bindings: "";
23
+ slots: {};
24
+ events: {};
25
+ };
26
+ declare class __sveltets_Render<TData extends object> {
27
+ props(): ReturnType<typeof $$render<TData>>['props'];
28
+ events(): ReturnType<typeof $$render<TData>>['events'];
29
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
30
+ bindings(): "";
31
+ exports(): {};
19
32
  }
20
- declare const DataTableColumnFilter: import("svelte").Component<Props, {}, "">;
21
- type DataTableColumnFilter = ReturnType<typeof DataTableColumnFilter>;
33
+ interface $$IsomorphicComponent {
34
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
35
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
36
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
37
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
38
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
39
+ }
40
+ declare const DataTableColumnFilter: $$IsomorphicComponent;
41
+ type DataTableColumnFilter<TData extends object> = InstanceType<typeof DataTableColumnFilter<TData>>;
22
42
  export default DataTableColumnFilter;
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTableColumnVisibility - Column visibility toggle dropdown
4
4
  *
@@ -12,7 +12,7 @@
12
12
 
13
13
  interface Props {
14
14
  /** The native DataTable instance */
15
- table: DataTableInstance<any>;
15
+ table: DataTableInstance<TData>;
16
16
  /** Additional classes */
17
17
  class?: string;
18
18
  }
@@ -5,12 +5,32 @@
5
5
  * Works with the native Svelte 5 DataTable implementation.
6
6
  */
7
7
  import type { DataTableInstance } from './createDataTable.svelte.js';
8
- interface Props {
9
- /** The native DataTable instance */
10
- table: DataTableInstance<any>;
11
- /** Additional classes */
12
- class?: string;
8
+ declare function $$render<TData extends object>(): {
9
+ props: {
10
+ /** The native DataTable instance */
11
+ table: DataTableInstance<TData>;
12
+ /** Additional classes */
13
+ class?: string;
14
+ };
15
+ exports: {};
16
+ bindings: "";
17
+ slots: {};
18
+ events: {};
19
+ };
20
+ declare class __sveltets_Render<TData extends object> {
21
+ props(): ReturnType<typeof $$render<TData>>['props'];
22
+ events(): ReturnType<typeof $$render<TData>>['events'];
23
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
24
+ bindings(): "";
25
+ exports(): {};
13
26
  }
14
- declare const DataTableColumnVisibility: import("svelte").Component<Props, {}, "">;
15
- type DataTableColumnVisibility = ReturnType<typeof DataTableColumnVisibility>;
27
+ interface $$IsomorphicComponent {
28
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
29
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
30
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
31
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
32
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
33
+ }
34
+ declare const DataTableColumnVisibility: $$IsomorphicComponent;
35
+ type DataTableColumnVisibility<TData extends object> = InstanceType<typeof DataTableColumnVisibility<TData>>;
16
36
  export default DataTableColumnVisibility;
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTableFacetedFilter - Multi-select filter for categorical columns
4
4
  *
@@ -23,7 +23,7 @@
23
23
 
24
24
  interface Props {
25
25
  /** The native DataTable instance */
26
- table: DataTableInstance<any>;
26
+ table: DataTableInstance<TData>;
27
27
  /** Column ID to filter */
28
28
  columnId: string;
29
29
  /** Title for the filter */
@@ -9,23 +9,42 @@
9
9
  * from the main table's column filter state.
10
10
  */
11
11
  import type { DataTableInstance } from './createDataTable.svelte.js';
12
- interface FilterOption {
13
- value: string;
14
- label: string;
15
- count?: number;
12
+ declare function $$render<TData extends object>(): {
13
+ props: {
14
+ /** The native DataTable instance */
15
+ table: DataTableInstance<TData>;
16
+ /** Column ID to filter */
17
+ columnId: string;
18
+ /** Title for the filter */
19
+ title: string;
20
+ /** Available filter options */
21
+ options: {
22
+ value: string;
23
+ label: string;
24
+ count?: number;
25
+ }[];
26
+ /** Additional classes */
27
+ class?: string;
28
+ };
29
+ exports: {};
30
+ bindings: "";
31
+ slots: {};
32
+ events: {};
33
+ };
34
+ declare class __sveltets_Render<TData extends object> {
35
+ props(): ReturnType<typeof $$render<TData>>['props'];
36
+ events(): ReturnType<typeof $$render<TData>>['events'];
37
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
38
+ bindings(): "";
39
+ exports(): {};
16
40
  }
17
- interface Props {
18
- /** The native DataTable instance */
19
- table: DataTableInstance<any>;
20
- /** Column ID to filter */
21
- columnId: string;
22
- /** Title for the filter */
23
- title: string;
24
- /** Available filter options */
25
- options: FilterOption[];
26
- /** Additional classes */
27
- class?: string;
41
+ interface $$IsomorphicComponent {
42
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
43
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
44
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
45
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
46
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
28
47
  }
29
- declare const DataTableFacetedFilter: import("svelte").Component<Props, {}, "">;
30
- type DataTableFacetedFilter = ReturnType<typeof DataTableFacetedFilter>;
48
+ declare const DataTableFacetedFilter: $$IsomorphicComponent;
49
+ type DataTableFacetedFilter<TData extends object> = InstanceType<typeof DataTableFacetedFilter<TData>>;
31
50
  export default DataTableFacetedFilter;
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTablePagination - Pagination controls for DataTable
4
4
  *
@@ -12,7 +12,7 @@
12
12
 
13
13
  interface Props {
14
14
  /** The native DataTable instance */
15
- table: DataTableInstance<any>;
15
+ table: DataTableInstance<TData>;
16
16
  /** Available page sizes */
17
17
  pageSizeOptions?: number[];
18
18
  /** Show selected row count */
@@ -5,16 +5,36 @@
5
5
  * Works with the native Svelte 5 DataTable implementation.
6
6
  */
7
7
  import type { DataTableInstance } from './createDataTable.svelte.js';
8
- interface Props {
9
- /** The native DataTable instance */
10
- table: DataTableInstance<any>;
11
- /** Available page sizes */
12
- pageSizeOptions?: number[];
13
- /** Show selected row count */
14
- showSelectedCount?: boolean;
15
- /** Additional classes */
16
- class?: string;
8
+ declare function $$render<TData extends object>(): {
9
+ props: {
10
+ /** The native DataTable instance */
11
+ table: DataTableInstance<TData>;
12
+ /** Available page sizes */
13
+ pageSizeOptions?: number[];
14
+ /** Show selected row count */
15
+ showSelectedCount?: boolean;
16
+ /** Additional classes */
17
+ class?: string;
18
+ };
19
+ exports: {};
20
+ bindings: "";
21
+ slots: {};
22
+ events: {};
23
+ };
24
+ declare class __sveltets_Render<TData extends object> {
25
+ props(): ReturnType<typeof $$render<TData>>['props'];
26
+ events(): ReturnType<typeof $$render<TData>>['events'];
27
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
28
+ bindings(): "";
29
+ exports(): {};
17
30
  }
18
- declare const DataTablePagination: import("svelte").Component<Props, {}, "">;
19
- type DataTablePagination = ReturnType<typeof DataTablePagination>;
31
+ interface $$IsomorphicComponent {
32
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
33
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
34
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
35
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
36
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
37
+ }
38
+ declare const DataTablePagination: $$IsomorphicComponent;
39
+ type DataTablePagination<TData extends object> = InstanceType<typeof DataTablePagination<TData>>;
20
40
  export default DataTablePagination;
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTableSearch - Global search input for DataTable
4
4
  *
@@ -11,7 +11,7 @@
11
11
 
12
12
  interface Props {
13
13
  /** The native DataTable instance */
14
- table: DataTableInstance<any>;
14
+ table: DataTableInstance<TData>;
15
15
  /** Placeholder text */
16
16
  placeholder?: string;
17
17
  /** Debounce delay in ms */
@@ -5,16 +5,36 @@
5
5
  * Works with the native Svelte 5 DataTable implementation.
6
6
  */
7
7
  import type { DataTableInstance } from './createDataTable.svelte.js';
8
- interface Props {
9
- /** The native DataTable instance */
10
- table: DataTableInstance<any>;
11
- /** Placeholder text */
12
- placeholder?: string;
13
- /** Debounce delay in ms */
14
- debounceMs?: number;
15
- /** Additional classes */
16
- class?: string;
8
+ declare function $$render<TData extends object>(): {
9
+ props: {
10
+ /** The native DataTable instance */
11
+ table: DataTableInstance<TData>;
12
+ /** Placeholder text */
13
+ placeholder?: string;
14
+ /** Debounce delay in ms */
15
+ debounceMs?: number;
16
+ /** Additional classes */
17
+ class?: string;
18
+ };
19
+ exports: {};
20
+ bindings: "";
21
+ slots: {};
22
+ events: {};
23
+ };
24
+ declare class __sveltets_Render<TData extends object> {
25
+ props(): ReturnType<typeof $$render<TData>>['props'];
26
+ events(): ReturnType<typeof $$render<TData>>['events'];
27
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
28
+ bindings(): "";
29
+ exports(): {};
17
30
  }
18
- declare const DataTableSearch: import("svelte").Component<Props, {}, "">;
19
- type DataTableSearch = ReturnType<typeof DataTableSearch>;
31
+ interface $$IsomorphicComponent {
32
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
33
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
34
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
35
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
36
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
37
+ }
38
+ declare const DataTableSearch: $$IsomorphicComponent;
39
+ type DataTableSearch<TData extends object> = InstanceType<typeof DataTableSearch<TData>>;
20
40
  export default DataTableSearch;
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="TData extends object">
2
2
  /**
3
3
  * DataTableToolbar - Combined toolbar with search and controls
4
4
  *
@@ -14,7 +14,7 @@
14
14
 
15
15
  interface Props {
16
16
  /** The native DataTable instance */
17
- table: DataTableInstance<any>;
17
+ table: DataTableInstance<TData>;
18
18
  /** Show global search */
19
19
  showSearch?: boolean;
20
20
  /** Show column visibility toggle */
@@ -6,22 +6,42 @@
6
6
  */
7
7
  import type { Snippet } from 'svelte';
8
8
  import type { DataTableInstance } from './createDataTable.svelte.js';
9
- interface Props {
10
- /** The native DataTable instance */
11
- table: DataTableInstance<any>;
12
- /** Show global search */
13
- showSearch?: boolean;
14
- /** Show column visibility toggle */
15
- showColumnVisibility?: boolean;
16
- /** Search placeholder */
17
- searchPlaceholder?: string;
18
- /** Custom filters slot */
19
- filters?: Snippet;
20
- /** Custom actions slot */
21
- actions?: Snippet;
22
- /** Additional classes */
23
- class?: string;
9
+ declare function $$render<TData extends object>(): {
10
+ props: {
11
+ /** The native DataTable instance */
12
+ table: DataTableInstance<TData>;
13
+ /** Show global search */
14
+ showSearch?: boolean;
15
+ /** Show column visibility toggle */
16
+ showColumnVisibility?: boolean;
17
+ /** Search placeholder */
18
+ searchPlaceholder?: string;
19
+ /** Custom filters slot */
20
+ filters?: Snippet;
21
+ /** Custom actions slot */
22
+ actions?: Snippet;
23
+ /** Additional classes */
24
+ class?: string;
25
+ };
26
+ exports: {};
27
+ bindings: "";
28
+ slots: {};
29
+ events: {};
30
+ };
31
+ declare class __sveltets_Render<TData extends object> {
32
+ props(): ReturnType<typeof $$render<TData>>['props'];
33
+ events(): ReturnType<typeof $$render<TData>>['events'];
34
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
35
+ bindings(): "";
36
+ exports(): {};
24
37
  }
25
- declare const DataTableToolbar: import("svelte").Component<Props, {}, "">;
26
- type DataTableToolbar = ReturnType<typeof DataTableToolbar>;
38
+ interface $$IsomorphicComponent {
39
+ new <TData extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
40
+ $$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
41
+ } & ReturnType<__sveltets_Render<TData>['exports']>;
42
+ <TData extends object>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
43
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
44
+ }
45
+ declare const DataTableToolbar: $$IsomorphicComponent;
46
+ type DataTableToolbar<TData extends object> = InstanceType<typeof DataTableToolbar<TData>>;
27
47
  export default DataTableToolbar;
@@ -28,18 +28,18 @@
28
28
  export function useAnnounce(defaultOptions) {
29
29
  let message = $state('');
30
30
  let politeness = $state(defaultOptions?.politeness ?? 'polite');
31
- let clearTimeout = null;
31
+ let clearTimer = null;
32
32
  function clear() {
33
33
  message = '';
34
- if (clearTimeout) {
35
- globalThis.clearTimeout(clearTimeout);
36
- clearTimeout = null;
34
+ if (clearTimer) {
35
+ clearTimeout(clearTimer);
36
+ clearTimer = null;
37
37
  }
38
38
  }
39
39
  function announce(newMessage, options) {
40
40
  // Clear any pending timeout
41
- if (clearTimeout) {
42
- globalThis.clearTimeout(clearTimeout);
41
+ if (clearTimer) {
42
+ clearTimeout(clearTimer);
43
43
  }
44
44
  // Update politeness if provided
45
45
  if (options?.politeness) {
@@ -50,7 +50,7 @@ export function useAnnounce(defaultOptions) {
50
50
  // Set up auto-clear if delay > 0
51
51
  const delay = options?.clearDelay ?? defaultOptions?.clearDelay ?? 1000;
52
52
  if (delay > 0) {
53
- clearTimeout = globalThis.setTimeout(() => {
53
+ clearTimer = setTimeout(() => {
54
54
  message = '';
55
55
  }, delay);
56
56
  }
@@ -58,8 +58,8 @@ export function useAnnounce(defaultOptions) {
58
58
  // Cleanup on destroy
59
59
  $effect(() => {
60
60
  return () => {
61
- if (clearTimeout) {
62
- globalThis.clearTimeout(clearTimeout);
61
+ if (clearTimer) {
62
+ clearTimeout(clearTimer);
63
63
  }
64
64
  };
65
65
  });
@@ -23,10 +23,11 @@ const DEFAULT_SELECTOR = '[role="menuitem"], [role="option"], [role="tab"], butt
23
23
  * ```
24
24
  */
25
25
  export function useArrowNavigation(options = {}) {
26
- let orientation = $state(options.orientation ?? 'vertical');
27
- let loop = $state(options.loop ?? true);
28
- let itemSelector = $state(options.itemSelector ?? DEFAULT_SELECTOR);
29
- let onFocusChange = $state(options.onFocusChange);
26
+ // Plain locals: only read imperatively (handlers/action update), never tracked
27
+ let orientation = options.orientation ?? 'vertical';
28
+ let loop = options.loop ?? true;
29
+ let itemSelector = options.itemSelector ?? DEFAULT_SELECTOR;
30
+ let onFocusChange = options.onFocusChange;
30
31
  let container = null;
31
32
  let focusedIndex = $state(-1);
32
33
  function getFocusableItems() {
@@ -5,9 +5,11 @@ export interface UseEscapeKeyOptions {
5
5
  /**
6
6
  * Whether the escape key handler is enabled.
7
7
  * Useful for conditionally enabling based on component state (e.g., dialog open).
8
+ * Pass a getter (`() => isOpen`) for a value that should stay reactive —
9
+ * a plain boolean is captured once when the composable is called.
8
10
  * Default: true
9
11
  */
10
- enabled?: boolean;
12
+ enabled?: boolean | (() => boolean);
11
13
  /**
12
14
  * Whether to prevent default behavior when Escape is pressed.
13
15
  * Default: true
@@ -37,7 +39,7 @@ export interface UseEscapeKeyOptions {
37
39
  * useEscapeKey(() => {
38
40
  * isOpen = false;
39
41
  * onClose?.();
40
- * }, { enabled: isOpen });
42
+ * }, { enabled: () => isOpen });
41
43
  * </script>
42
44
  *
43
45
  * {#if isOpen}
@@ -16,7 +16,7 @@
16
16
  * useEscapeKey(() => {
17
17
  * isOpen = false;
18
18
  * onClose?.();
19
- * }, { enabled: isOpen });
19
+ * }, { enabled: () => isOpen });
20
20
  * </script>
21
21
  *
22
22
  * {#if isOpen}
@@ -25,10 +25,11 @@
25
25
  * ```
26
26
  */
27
27
  export function useEscapeKey(callback, options) {
28
- const enabled = $derived(options?.enabled ?? true);
29
28
  const preventDefault = options?.preventDefault ?? true;
30
29
  const stopPropagation = options?.stopPropagation ?? false;
31
30
  $effect(() => {
31
+ // Resolve inside the effect so a getter's reactive reads are tracked
32
+ const enabled = typeof options?.enabled === 'function' ? options.enabled() : (options?.enabled ?? true);
32
33
  if (!enabled)
33
34
  return;
34
35
  function handleKeyDown(event) {
@@ -27,9 +27,10 @@
27
27
  * ```
28
28
  */
29
29
  export function useFocusRef(options = {}) {
30
- let focusOnMount = $state(options.focusOnMount ?? false);
31
- let preventScroll = $state(options.preventScroll ?? false);
32
- let delay = $state(options.delay ?? 0);
30
+ // Plain locals: only read imperatively (action lifecycle), never tracked
31
+ let focusOnMount = options.focusOnMount ?? false;
32
+ let preventScroll = options.preventScroll ?? false;
33
+ let delay = options.delay ?? 0;
33
34
  let element = null;
34
35
  let timeoutId = null;
35
36
  let frameId = null;
@@ -1,6 +1,10 @@
1
1
  export interface UseFocusTrapOptions {
2
- /** Whether the focus trap is active */
3
- active?: boolean;
2
+ /**
3
+ * Whether the focus trap is active.
4
+ * Pass a getter (`() => isOpen`) for a value that should stay reactive —
5
+ * a plain boolean is captured once when the composable is called.
6
+ */
7
+ active?: boolean | (() => boolean);
4
8
  /** Element to return focus to when trap is deactivated */
5
9
  returnFocusTo?: HTMLElement | null;
6
10
  /** Selector for the element to focus initially (defaults to first focusable) */
@@ -15,12 +19,14 @@ export interface UseFocusTrapOptions {
15
19
  * focusable elements without escaping. Useful for modals, dialogs,
16
20
  * and dropdown menus.
17
21
  *
22
+ * Must be called during component initialization (it registers a `$effect`).
23
+ *
18
24
  * @example
19
25
  * ```svelte
20
26
  * <script>
21
27
  * import { useFocusTrap } from '@classic-homes/theme-svelte';
22
28
  *
23
- * const { action } = useFocusTrap({ active: isOpen });
29
+ * const { action } = useFocusTrap({ active: () => isOpen });
24
30
  * </script>
25
31
  *
26
32
  * {#if isOpen}
@@ -22,12 +22,14 @@ function getFocusableElements(container) {
22
22
  * focusable elements without escaping. Useful for modals, dialogs,
23
23
  * and dropdown menus.
24
24
  *
25
+ * Must be called during component initialization (it registers a `$effect`).
26
+ *
25
27
  * @example
26
28
  * ```svelte
27
29
  * <script>
28
30
  * import { useFocusTrap } from '@classic-homes/theme-svelte';
29
31
  *
30
- * const { action } = useFocusTrap({ active: isOpen });
32
+ * const { action } = useFocusTrap({ active: () => isOpen });
31
33
  * </script>
32
34
  *
33
35
  * {#if isOpen}
@@ -40,15 +42,18 @@ function getFocusableElements(container) {
40
42
  * ```
41
43
  */
42
44
  export function useFocusTrap(options = {}) {
43
- let active = $state(options.active ?? true);
44
- let returnFocusTo = $state(options.returnFocusTo ?? null);
45
- let initialFocus = $state(options.initialFocus);
46
- let preventScroll = $state(options.preventScroll ?? false);
47
- let container = null;
45
+ let currentOptions = $state(options);
46
+ let container = $state(null);
48
47
  let previousActiveElement = null;
48
+ let trapped = false;
49
+ function isActive() {
50
+ const active = currentOptions.active;
51
+ return typeof active === 'function' ? active() : (active ?? true);
52
+ }
49
53
  function handleKeyDown(event) {
50
- if (!active || event.key !== 'Tab' || !container)
54
+ if (!trapped || event.key !== 'Tab' || !container)
51
55
  return;
56
+ const preventScroll = currentOptions.preventScroll ?? false;
52
57
  const focusableElements = getFocusableElements(container);
53
58
  if (focusableElements.length === 0)
54
59
  return;
@@ -70,16 +75,18 @@ export function useFocusTrap(options = {}) {
70
75
  }
71
76
  }
72
77
  function activate() {
73
- if (!container)
78
+ if (!container || trapped)
74
79
  return;
80
+ trapped = true;
75
81
  // Save current active element to return focus later
76
82
  previousActiveElement = document.activeElement;
77
83
  // Focus initial element
84
+ const preventScroll = currentOptions.preventScroll ?? false;
78
85
  const focusableElements = getFocusableElements(container);
79
86
  if (focusableElements.length > 0) {
80
87
  let elementToFocus = null;
81
- if (initialFocus) {
82
- elementToFocus = container.querySelector(initialFocus);
88
+ if (currentOptions.initialFocus) {
89
+ elementToFocus = container.querySelector(currentOptions.initialFocus);
83
90
  }
84
91
  if (!elementToFocus) {
85
92
  elementToFocus = focusableElements[0];
@@ -91,39 +98,38 @@ export function useFocusTrap(options = {}) {
91
98
  document.addEventListener('keydown', handleKeyDown);
92
99
  }
93
100
  function deactivate() {
101
+ if (!trapped)
102
+ return;
103
+ trapped = false;
94
104
  document.removeEventListener('keydown', handleKeyDown);
95
105
  // Return focus when trap is deactivated
96
- const elementToReturn = returnFocusTo ?? previousActiveElement;
106
+ const preventScroll = currentOptions.preventScroll ?? false;
107
+ const elementToReturn = currentOptions.returnFocusTo ?? previousActiveElement;
97
108
  if (elementToReturn && typeof elementToReturn.focus === 'function') {
98
109
  elementToReturn.focus({ preventScroll });
99
110
  }
100
111
  }
112
+ // Activate/deactivate as the container attaches/detaches, `active` changes
113
+ // (via getter or action update), or the component is destroyed.
114
+ $effect(() => {
115
+ if (container !== null && isActive()) {
116
+ activate();
117
+ }
118
+ else {
119
+ deactivate();
120
+ }
121
+ });
101
122
  /**
102
123
  * Svelte action to apply focus trap to an element
103
124
  */
104
125
  function action(node) {
105
126
  container = node;
106
- if (active) {
107
- activate();
108
- }
109
127
  return {
110
128
  update(newOptions) {
111
- const wasActive = active;
112
- active = newOptions.active ?? true;
113
- returnFocusTo = newOptions.returnFocusTo ?? null;
114
- initialFocus = newOptions.initialFocus;
115
- preventScroll = newOptions.preventScroll ?? false;
116
- if (!wasActive && active) {
117
- activate();
118
- }
119
- else if (wasActive && !active) {
120
- deactivate();
121
- }
129
+ currentOptions = newOptions;
122
130
  },
123
131
  destroy() {
124
- if (active) {
125
- deactivate();
126
- }
132
+ deactivate();
127
133
  container = null;
128
134
  },
129
135
  };
@@ -32,10 +32,11 @@ const DEFAULT_SELECTOR = '[data-roving-tabindex-item]';
32
32
  * ```
33
33
  */
34
34
  export function useRovingTabindex(options = {}) {
35
- let loop = $state(options.loop ?? true);
36
- let itemSelector = $state(options.itemSelector ?? DEFAULT_SELECTOR);
35
+ // Plain locals: only read imperatively (handlers/action update), never tracked
36
+ let loop = options.loop ?? true;
37
+ let itemSelector = options.itemSelector ?? DEFAULT_SELECTOR;
37
38
  let activeIndex = $state(options.initialIndex ?? 0);
38
- let onIndexChange = $state(options.onIndexChange);
39
+ let onIndexChange = options.onIndexChange;
39
40
  let container = null;
40
41
  function getItems() {
41
42
  if (!container)
@@ -4,13 +4,3 @@ import { type ClassValue } from 'clsx';
4
4
  * Uses clsx for conditional classes and tailwind-merge to handle conflicts
5
5
  */
6
6
  export declare function cn(...inputs: ClassValue[]): string;
7
- /**
8
- * Generate a unique ID with an optional prefix.
9
- * Uses crypto.randomUUID() to avoid SSR hydration mismatches caused by
10
- * sequential counters (where server and client counts can diverge).
11
- * The short suffix is derived from the UUID for compact, readable IDs.
12
- *
13
- * @param prefix - Optional prefix for the ID (e.g., 'checkbox', 'tabs')
14
- * @returns A unique ID string like 'checkbox-a1b2c3d4' or 'ct-a1b2c3d4'
15
- */
16
- export declare function useId(prefix?: string): string;
package/dist/lib/utils.js CHANGED
@@ -7,16 +7,3 @@ import { twMerge } from 'tailwind-merge';
7
7
  export function cn(...inputs) {
8
8
  return twMerge(clsx(inputs));
9
9
  }
10
- /**
11
- * Generate a unique ID with an optional prefix.
12
- * Uses crypto.randomUUID() to avoid SSR hydration mismatches caused by
13
- * sequential counters (where server and client counts can diverge).
14
- * The short suffix is derived from the UUID for compact, readable IDs.
15
- *
16
- * @param prefix - Optional prefix for the ID (e.g., 'checkbox', 'tabs')
17
- * @returns A unique ID string like 'checkbox-a1b2c3d4' or 'ct-a1b2c3d4'
18
- */
19
- export function useId(prefix) {
20
- const id = crypto.randomUUID().slice(0, 8);
21
- return prefix ? `${prefix}-${id}` : `ct-${id}`;
22
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/theme-svelte",
3
- "version": "0.1.54",
3
+ "version": "0.1.56",
4
4
  "description": "Svelte components for the Classic theme system",
5
5
  "type": "module",
6
6
  "svelte": "./dist/lib/index.js",