compote-ui 0.62.1 → 0.63.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 (36) hide show
  1. package/README.md +6 -0
  2. package/dist/components/checkbox/checkbox.svelte +1 -1
  3. package/dist/components/data-table-v9/create-table.svelte.d.ts +3 -1
  4. package/dist/components/data-table-v9/data-table-utils.d.ts +3 -1
  5. package/dist/components/data-table-v9/features.d.ts +3 -1
  6. package/dist/components/data-table-v9/table-view-state.svelte.d.ts +12 -4
  7. package/dist/components/data-table-v9/toolbar/data-table-column-filter.svelte +2 -4
  8. package/dist/components/date-input/date-input.svelte +21 -3
  9. package/dist/components/date-input/types.d.ts +19 -5
  10. package/dist/components/tags-input/tags-input.svelte +83 -0
  11. package/dist/components/tags-input/tags-input.svelte.d.ts +5 -0
  12. package/dist/components/tags-input/types.d.ts +7 -0
  13. package/dist/components/tags-input/types.js +1 -0
  14. package/dist/index.d.ts +4 -1
  15. package/dist/index.js +2 -0
  16. package/dist/utils/date.d.ts +26 -0
  17. package/dist/utils/date.js +64 -0
  18. package/package.json +17 -7
  19. package/skills/component-usage/SKILL.md +202 -0
  20. package/skills/component-usage/references/buttons.md +27 -0
  21. package/skills/component-usage/references/component-export-map.md +54 -0
  22. package/skills/component-usage/references/files-and-images.md +75 -0
  23. package/skills/component-usage/references/forms-and-inputs.md +94 -0
  24. package/skills/component-usage/references/interactive-components.md +33 -0
  25. package/skills/component-usage/references/layout-and-display.md +82 -0
  26. package/skills/component-usage/references/overlays-and-floating-ui.md +80 -0
  27. package/skills/data-table/SKILL.md +247 -0
  28. package/skills/data-table/references/column-options.md +53 -0
  29. package/skills/data-table/references/table-state-and-reactivity.md +45 -0
  30. package/skills/data-table/references/virtual-table.md +44 -0
  31. package/skills/getting-started/SKILL.md +173 -0
  32. package/skills/getting-started/references/install-and-peers.md +45 -0
  33. package/skills/production-checklist/SKILL.md +181 -0
  34. package/skills/production-checklist/references/production-audit.md +40 -0
  35. package/skills/theming/SKILL.md +147 -0
  36. package/skills/theming/references/theme-tokens.md +56 -0
package/README.md CHANGED
@@ -26,6 +26,12 @@ yarn add compote-ui
26
26
  bun add compote-ui
27
27
  ```
28
28
 
29
+ If you use an AI agent, run:
30
+
31
+ ```bash
32
+ npx @tanstack/intent@latest install
33
+ ```
34
+
29
35
  ## Peer Dependencies
30
36
 
31
37
  Compote UI requires Svelte 5 or later:
@@ -50,7 +50,7 @@
50
50
  </Checkbox.Control>
51
51
  {#if label}
52
52
  <div class="flex flex-col gap-0.5">
53
- <Checkbox.Label class="text-base select-none data-disabled:opacity-50">
53
+ <Checkbox.Label class="text-sm select-none data-disabled:opacity-50">
54
54
  {label}
55
55
  </Checkbox.Label>
56
56
  {#if children}
@@ -58,7 +58,9 @@ export declare function createTable<T extends RowData>(options: CreateDataTableO
58
58
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
59
59
  autoRemove: (val: any) => boolean;
60
60
  };
61
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
61
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
62
+ autoRemove: (val: any) => boolean;
63
+ };
62
64
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
63
65
  autoRemove: (val: any) => boolean;
64
66
  };
@@ -52,7 +52,9 @@ export declare function getRowCells<T extends RowData>(row: Row<DataTableFeature
52
52
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
53
53
  autoRemove: (val: any) => boolean;
54
54
  };
55
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
55
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
56
+ autoRemove: (val: any) => boolean;
57
+ };
56
58
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
57
59
  autoRemove: (val: any) => boolean;
58
60
  };
@@ -29,7 +29,9 @@ export declare const dataTableFeatures: {
29
29
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends import("@tanstack/table-core").RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
30
30
  autoRemove: (val: any) => boolean;
31
31
  };
32
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends import("@tanstack/table-core").RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
32
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends import("@tanstack/table-core").RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
33
+ autoRemove: (val: any) => boolean;
34
+ };
33
35
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends import("@tanstack/table-core").RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
34
36
  autoRemove: (val: any) => boolean;
35
37
  };
@@ -49,7 +49,9 @@ export declare function createTableViewState<T extends RowData>(getTable: () =>
49
49
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
50
50
  autoRemove: (val: any) => boolean;
51
51
  };
52
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
52
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
53
+ autoRemove: (val: any) => boolean;
54
+ };
53
55
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
54
56
  autoRemove: (val: any) => boolean;
55
57
  };
@@ -111,7 +113,9 @@ export declare function createTableViewState<T extends RowData>(getTable: () =>
111
113
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
112
114
  autoRemove: (val: any) => boolean;
113
115
  };
114
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
116
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
117
+ autoRemove: (val: any) => boolean;
118
+ };
115
119
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
116
120
  autoRemove: (val: any) => boolean;
117
121
  };
@@ -174,7 +178,9 @@ export declare function createTableViewState<T extends RowData>(getTable: () =>
174
178
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
175
179
  autoRemove: (val: any) => boolean;
176
180
  };
177
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
181
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
182
+ autoRemove: (val: any) => boolean;
183
+ };
178
184
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
179
185
  autoRemove: (val: any) => boolean;
180
186
  };
@@ -236,7 +242,9 @@ export declare function createTableViewState<T extends RowData>(getTable: () =>
236
242
  arrIncludesAll: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
237
243
  autoRemove: (val: any) => boolean;
238
244
  };
239
- arrHas: <TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean;
245
+ arrHas: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
246
+ autoRemove: (val: any) => boolean;
247
+ };
240
248
  arrIncludesSome: (<TFeatures extends import("@tanstack/table-core").TableFeatures, TData extends RowData>(row: import("@tanstack/table-core").Row<TFeatures, TData>, columnId: string, filterValue: Array<unknown>) => boolean) & {
241
249
  autoRemove: (val: any) => boolean;
242
250
  };
@@ -66,8 +66,7 @@
66
66
 
67
67
  function getColumnType(column: Column<DataTableFeatures, T, unknown>): string | undefined {
68
68
  return (column.columnDef.meta as Record<string, unknown> | undefined)?.type as
69
- | string
70
- | undefined;
69
+ string | undefined;
71
70
  }
72
71
 
73
72
  function getColumnLabel(column: Column<DataTableFeatures, T, unknown>): string {
@@ -162,8 +161,7 @@
162
161
  column: Column<DataTableFeatures, T, unknown>
163
162
  ): Intl.NumberFormatOptions | undefined {
164
163
  return (column.columnDef.meta as Record<string, unknown> | undefined)?.formatOptions as
165
- | Intl.NumberFormatOptions
166
- | undefined;
164
+ Intl.NumberFormatOptions | undefined;
167
165
  }
168
166
  </script>
169
167
 
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { DateInput } from '@ark-ui/svelte/date-input';
3
3
  import { Field, useFieldContext } from '@ark-ui/svelte/field';
4
+ import { toDateValue, fromDateValue, dateValueShape } from '../../utils/date';
5
+ import type { DateValueShape } from '../../utils/date';
4
6
  import type { DateInputProps } from './types';
5
7
 
6
8
  let {
@@ -8,6 +10,9 @@
8
10
  defaultValue,
9
11
  label,
10
12
  name,
13
+ granularity = 'day',
14
+ hourCycle,
15
+ timeZone,
11
16
  onValueChange,
12
17
  invalid,
13
18
  readOnly,
@@ -21,12 +26,25 @@
21
26
  const isReadOnly = $derived(readOnly ?? field?.()?.readOnly ?? false);
22
27
  const isDisabled = $derived(disabled ?? field?.()?.disabled ?? false);
23
28
 
24
- const arkValue = $derived(value ?? null);
25
- const arkDefault = $derived(defaultValue ?? null);
29
+ // Remember the shape the consumer bound the value as, so changes are emitted
30
+ // back in the same shape (string in → string out, Date in → Date out).
31
+ // When the bound value starts null (e.g. a nullable DB column), default to
32
+ // string output since that's the common case binding to database values.
33
+ let shape: DateValueShape = 'string';
34
+
35
+ const arkValue = $derived.by(() => {
36
+ const s = dateValueShape(value) ?? dateValueShape(defaultValue);
37
+ if (s) shape = s;
38
+ return toDateValue(value, timeZone);
39
+ });
40
+ const arkDefault = $derived(toDateValue(defaultValue, timeZone));
26
41
  </script>
27
42
 
28
43
  <DateInput.Root
29
44
  {...restProps}
45
+ {granularity}
46
+ {hourCycle}
47
+ {timeZone}
30
48
  {hideTimeZone}
31
49
  invalid={isInvalid}
32
50
  readOnly={isReadOnly}
@@ -37,7 +55,7 @@
37
55
  const dv = details.value[0] ?? null;
38
56
  // Guard: skip if Ark UI echoes back the same date (prevents reactive loop)
39
57
  if (dv?.toString() === arkValue?.toString()) return;
40
- value = dv;
58
+ value = fromDateValue(dv, shape, timeZone);
41
59
  onValueChange?.(details);
42
60
  }}
43
61
  >
@@ -1,9 +1,23 @@
1
1
  import type { DateInputRootBaseProps } from '@ark-ui/svelte/date-input';
2
- import type { DateValue } from '@internationalized/date';
3
- export type { DateValue };
4
- export interface DateInputProps extends Omit<DateInputRootBaseProps, 'value' | 'defaultValue'> {
5
- value?: DateValue | null;
6
- defaultValue?: DateValue | null;
2
+ import type { DateValue, DateInputValue } from '../../utils/date';
3
+ export type { DateValue, DateInputValue };
4
+ export interface DateInputProps extends Omit<DateInputRootBaseProps, 'value' | 'defaultValue' | 'granularity' | 'hourCycle'> {
5
+ /**
6
+ * Bound value. Accepts a `DateValue`, an ISO/DB string, or a native `Date` —
7
+ * no manual conversion needed. The value is emitted back in the same shape it
8
+ * was provided (string in → string out, `Date` in → `Date` out). When the
9
+ * value starts `null`, changes are emitted as a string by default.
10
+ *
11
+ * For UTC values from a database, bind the ISO string with its `Z`/offset and
12
+ * leave `timeZone` unset: the segments display in the user's local zone and the
13
+ * emitted string is UTC (e.g. `"2024-01-15T10:30:00.000Z"`).
14
+ */
15
+ value?: DateInputValue;
16
+ defaultValue?: DateInputValue;
7
17
  label?: string;
8
18
  name?: string;
19
+ granularity?: 'day' | 'hour' | 'minute' | 'second';
20
+ hourCycle?: 12 | 24;
21
+ /** BCP-47 locale (e.g. `'de-DE'`). Overrides the `LocaleProvider` / browser locale. */
22
+ locale?: string;
9
23
  }
@@ -0,0 +1,83 @@
1
+ <script lang="ts">
2
+ import { TagsInput } from '@ark-ui/svelte/tags-input';
3
+ import { useFieldContext } from '@ark-ui/svelte/field';
4
+ import { cn } from 'tailwind-variants';
5
+ import type { TagsInputProps } from './types';
6
+ import { PhX } from '../../icons';
7
+
8
+ let {
9
+ value = $bindable(),
10
+ label,
11
+ placeholder,
12
+ invalid,
13
+ readOnly,
14
+ disabled,
15
+ class: className,
16
+ ...restProps
17
+ }: TagsInputProps = $props();
18
+
19
+ const field = useFieldContext();
20
+ const isInvalid = $derived(invalid ?? field?.()?.invalid ?? false);
21
+ const isReadOnly = $derived(readOnly ?? field?.()?.readOnly ?? false);
22
+ const isDisabled = $derived(disabled ?? field?.()?.disabled ?? false);
23
+ </script>
24
+
25
+ <TagsInput.Root
26
+ bind:value
27
+ invalid={isInvalid}
28
+ readOnly={isReadOnly}
29
+ disabled={isDisabled}
30
+ {...restProps}
31
+ class={cn('grid gap-1.5', className)}
32
+ >
33
+ <TagsInput.Context>
34
+ {#snippet render(tagsInput)}
35
+ {#if label}
36
+ <TagsInput.Label class="text-sm font-medium leading-none data-disabled:opacity-50">
37
+ {label}
38
+ </TagsInput.Label>
39
+ {/if}
40
+
41
+ <TagsInput.Control
42
+ class={cn(
43
+ 'flex min-h-9 flex-wrap items-center gap-1 rounded border bg-surface-1 px-2 py-1 shadow-sm',
44
+ 'focus-within:ring-1 focus-within:ring-ring',
45
+ 'data-disabled:pointer-events-none data-disabled:opacity-50',
46
+ 'data-invalid:border-danger data-invalid:focus-within:ring-danger'
47
+ )}
48
+ >
49
+ {#each tagsInput().value as value, index (index)}
50
+ <TagsInput.Item
51
+ {index}
52
+ {value}
53
+ class="inline-flex cursor-default items-center outline-none"
54
+ >
55
+ <TagsInput.ItemPreview
56
+ class={cn(
57
+ 'inline-flex items-center gap-1 rounded bg-surface-2 py-0.5 pr-1 pl-2 text-sm',
58
+ 'data-highlighted:bg-primary/10 data-disabled:opacity-50'
59
+ )}
60
+ >
61
+ <TagsInput.ItemText>{value}</TagsInput.ItemText>
62
+ {#if !isReadOnly}
63
+ <TagsInput.ItemDeleteTrigger
64
+ class="rounded p-0.5 text-ink-dim transition-colors hover:text-ink"
65
+ >
66
+ <PhX class="size-3" />
67
+ </TagsInput.ItemDeleteTrigger>
68
+ {/if}
69
+ </TagsInput.ItemPreview>
70
+ <TagsInput.ItemInput
71
+ class="rounded border bg-surface-1 px-2 py-0.5 text-sm outline-none"
72
+ />
73
+ </TagsInput.Item>
74
+ {/each}
75
+ <TagsInput.Input
76
+ {placeholder}
77
+ class="min-w-12 flex-1 bg-transparent text-sm outline-none placeholder:text-ink-dim disabled:cursor-not-allowed"
78
+ />
79
+ </TagsInput.Control>
80
+ {/snippet}
81
+ </TagsInput.Context>
82
+ <TagsInput.HiddenInput />
83
+ </TagsInput.Root>
@@ -0,0 +1,5 @@
1
+ import { TagsInput } from '@ark-ui/svelte/tags-input';
2
+ import type { TagsInputProps } from './types';
3
+ declare const TagsInput: import("svelte").Component<TagsInputProps, {}, "value">;
4
+ type TagsInput = ReturnType<typeof TagsInput>;
5
+ export default TagsInput;
@@ -0,0 +1,7 @@
1
+ import type { TagsInputRootProps } from '@ark-ui/svelte/tags-input';
2
+ import type { ClassValue } from 'tailwind-variants';
3
+ export interface TagsInputProps extends Omit<TagsInputRootProps, 'class'> {
4
+ class?: ClassValue;
5
+ label?: string;
6
+ placeholder?: string;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -17,7 +17,8 @@ export type { DateFieldProps } from './components/date-field/types';
17
17
  export { default as DateRangeField } from './components/date-range-field/date-range-field.svelte';
18
18
  export type { DateRangeFieldProps } from './components/date-range-field/types';
19
19
  export { default as DateInput } from './components/date-input/date-input.svelte';
20
- export type { DateInputProps, DateValue as DateInputDateValue } from './components/date-input/types';
20
+ export type { DateInputProps, DateInputValue, DateValue as DateInputDateValue } from './components/date-input/types';
21
+ export { toDateValue, dateValueToString, dateValueToDate } from './utils/date';
21
22
  export { default as DatePicker } from './components/date-picker/date-picker.svelte';
22
23
  export type { DatePickerProps } from './components/date-picker/types';
23
24
  export * as Dialog from './components/dialog';
@@ -48,6 +49,8 @@ export { default as Splitter } from './components/splitter/splitter.svelte';
48
49
  export type { SplitterPanelConfig, SplitterProps } from './components/splitter/types';
49
50
  export { default as Switch } from './components/switch/switch.svelte';
50
51
  export * as Tabs from './components/tabs';
52
+ export { default as TagsInput } from './components/tags-input/tags-input.svelte';
53
+ export type { TagsInputProps } from './components/tags-input/types';
51
54
  export * as Toast from './components/toast';
52
55
  export { toast } from './components/toast';
53
56
  export type { ToastOptions, ToastType } from './components/toast';
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export { default as Combobox } from './components/combobox/combobox.svelte';
14
14
  export { default as DateField } from './components/date-field/date-field.svelte';
15
15
  export { default as DateRangeField } from './components/date-range-field/date-range-field.svelte';
16
16
  export { default as DateInput } from './components/date-input/date-input.svelte';
17
+ export { toDateValue, dateValueToString, dateValueToDate } from './utils/date';
17
18
  export { default as DatePicker } from './components/date-picker/date-picker.svelte';
18
19
  export * as Dialog from './components/dialog';
19
20
  export { default as AlertDialog } from './components/dialog/alert-dialog.svelte';
@@ -35,6 +36,7 @@ export { default as Select } from './components/select/select.svelte';
35
36
  export { default as Splitter } from './components/splitter/splitter.svelte';
36
37
  export { default as Switch } from './components/switch/switch.svelte';
37
38
  export * as Tabs from './components/tabs';
39
+ export { default as TagsInput } from './components/tags-input/tags-input.svelte';
38
40
  export * as Toast from './components/toast';
39
41
  export { toast } from './components/toast';
40
42
  export { createToaster } from '@ark-ui/svelte/toast';
@@ -0,0 +1,26 @@
1
+ import { type DateValue } from '@internationalized/date';
2
+ export type { DateValue };
3
+ /**
4
+ * Anything the date components accept for a single value: an
5
+ * `@internationalized/date` value, an ISO/DB string, a native `Date`, or null.
6
+ */
7
+ export type DateInputValue = DateValue | string | Date | null | undefined;
8
+ /** The runtime shape a bound value was provided in, used to round-trip on change. */
9
+ export type DateValueShape = 'string' | 'date' | 'date-value';
10
+ /** Report the runtime shape of a value so a change can be emitted in the same shape. */
11
+ export declare function dateValueShape(value: DateInputValue): DateValueShape | null;
12
+ /**
13
+ * Coerce a string / `Date` / `DateValue` into a `DateValue` for Ark UI.
14
+ *
15
+ * String auto-detection:
16
+ * - `"2024-01-15"` → {@link parseDate} (date-only)
17
+ * - `"2024-01-15T10:30:00"` → {@link parseDateTime} (local datetime)
18
+ * - `"2024-01-15T10:30:00Z"` / `"…+02:00"` → zoned (in `timeZone`, else local)
19
+ */
20
+ export declare function toDateValue(value: DateInputValue, timeZone?: string): DateValue | null;
21
+ /** Serialize a `DateValue` to an ISO string (absolute `…Z` for zoned values). */
22
+ export declare function dateValueToString(value: DateValue): string;
23
+ /** Convert a `DateValue` to a native `Date`. */
24
+ export declare function dateValueToDate(value: DateValue, timeZone?: string): Date;
25
+ /** Emit a `DateValue` back in the original `shape` it was bound as. */
26
+ export declare function fromDateValue(value: DateValue | null, shape: DateValueShape, timeZone?: string): DateValue | string | Date | null;
@@ -0,0 +1,64 @@
1
+ import { parseDate, parseDateTime, parseAbsolute, parseAbsoluteToLocal, fromDate, getLocalTimeZone } from '@internationalized/date';
2
+ const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
3
+ // Trailing `Z`, or a `+HH`, `+HH:MM`, `+HHMM` offset.
4
+ const HAS_OFFSET = /(?:[zZ]|[+-]\d{2}(?::?\d{2})?)$/;
5
+ /** Normalize a DB datetime string to ISO 8601: space → `T`, bare `+HH` offset → `+HH:00`. */
6
+ function normalizeIso(value) {
7
+ return value.replace(' ', 'T').replace(/([+-]\d{2})$/, '$1:00');
8
+ }
9
+ /** Report the runtime shape of a value so a change can be emitted in the same shape. */
10
+ export function dateValueShape(value) {
11
+ if (value == null)
12
+ return null;
13
+ if (typeof value === 'string')
14
+ return 'string';
15
+ if (value instanceof Date)
16
+ return 'date';
17
+ return 'date-value';
18
+ }
19
+ /**
20
+ * Coerce a string / `Date` / `DateValue` into a `DateValue` for Ark UI.
21
+ *
22
+ * String auto-detection:
23
+ * - `"2024-01-15"` → {@link parseDate} (date-only)
24
+ * - `"2024-01-15T10:30:00"` → {@link parseDateTime} (local datetime)
25
+ * - `"2024-01-15T10:30:00Z"` / `"…+02:00"` → zoned (in `timeZone`, else local)
26
+ */
27
+ export function toDateValue(value, timeZone) {
28
+ if (value == null)
29
+ return null;
30
+ if (value instanceof Date)
31
+ return fromDate(value, timeZone ?? getLocalTimeZone());
32
+ if (typeof value !== 'string')
33
+ return value;
34
+ const raw = value.trim();
35
+ if (!raw)
36
+ return null;
37
+ if (DATE_ONLY.test(raw))
38
+ return parseDate(raw);
39
+ const iso = normalizeIso(raw);
40
+ if (HAS_OFFSET.test(iso)) {
41
+ return timeZone ? parseAbsolute(iso, timeZone) : parseAbsoluteToLocal(iso);
42
+ }
43
+ return parseDateTime(iso);
44
+ }
45
+ /** Serialize a `DateValue` to an ISO string (absolute `…Z` for zoned values). */
46
+ export function dateValueToString(value) {
47
+ return 'timeZone' in value ? value.toAbsoluteString() : value.toString();
48
+ }
49
+ /** Convert a `DateValue` to a native `Date`. */
50
+ export function dateValueToDate(value, timeZone) {
51
+ return 'timeZone' in value
52
+ ? value.toDate()
53
+ : value.toDate(timeZone ?? getLocalTimeZone());
54
+ }
55
+ /** Emit a `DateValue` back in the original `shape` it was bound as. */
56
+ export function fromDateValue(value, shape, timeZone) {
57
+ if (value == null)
58
+ return null;
59
+ if (shape === 'string')
60
+ return dateValueToString(value);
61
+ if (shape === 'date')
62
+ return dateValueToDate(value, timeZone);
63
+ return value;
64
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compote-ui",
3
- "version": "0.62.1",
3
+ "version": "0.63.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev --open",
@@ -19,7 +19,9 @@
19
19
  "files": [
20
20
  "dist",
21
21
  "!dist/**/*.test.*",
22
- "!dist/**/*.spec.*"
22
+ "!dist/**/*.spec.*",
23
+ "skills",
24
+ "!skills/_artifacts"
23
25
  ],
24
26
  "sideEffects": [
25
27
  "**/*.css"
@@ -61,9 +63,10 @@
61
63
  "@sveltejs/kit": "^2.66.0",
62
64
  "@sveltejs/package": "^2.5.8",
63
65
  "@sveltejs/vite-plugin-svelte": "7.1.2",
64
- "@tailwindcss/vite": "^4.3.1",
66
+ "@tailwindcss/vite": "^4.3.2",
67
+ "@tanstack/intent": "^0.3.2",
65
68
  "@tanstack/svelte-table": "^9.0.0-beta.17",
66
- "@tanstack/svelte-virtual": "^3.13.29",
69
+ "@tanstack/svelte-virtual": "^3.13.30",
67
70
  "@types/node": "^22.20.0",
68
71
  "eslint": "^10.5.0",
69
72
  "eslint-config-prettier": "^10.1.8",
@@ -73,9 +76,9 @@
73
76
  "prettier-plugin-svelte": "^4.1.1",
74
77
  "prettier-plugin-tailwindcss": "^0.8.0",
75
78
  "publint": "^0.3.21",
76
- "svelte": "^5.56.3",
79
+ "svelte": "^5.56.4",
77
80
  "svelte-check": "^4.6.0",
78
- "tailwindcss": "^4.3.1",
81
+ "tailwindcss": "^4.3.2",
79
82
  "tw-animate-css": "^1.4.0",
80
83
  "typescript": "^6.0.3",
81
84
  "typescript-eslint": "^8.61.1",
@@ -83,7 +86,8 @@
83
86
  "vite": "^8.0.16"
84
87
  },
85
88
  "keywords": [
86
- "svelte"
89
+ "svelte",
90
+ "tanstack-intent"
87
91
  ],
88
92
  "dependencies": {
89
93
  "@ark-ui/svelte": "^5.22.1",
@@ -93,5 +97,11 @@
93
97
  "svelte-tel-input": "^4.2.0",
94
98
  "tailwind-merge": "^3.6.0",
95
99
  "tailwind-variants": "^3.2.2"
100
+ },
101
+ "intent": {
102
+ "skills": [
103
+ "compote-ui",
104
+ "@tanstack/svelte-table"
105
+ ]
96
106
  }
97
107
  }