sv5ui-plus 5.0.0 → 5.0.2

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 (29) hide show
  1. package/README.md +2 -1
  2. package/dist/components/DatePickerField/DatePickerField.svelte +41 -0
  3. package/dist/components/DatePickerField/DatePickerField.svelte.d.ts +5 -0
  4. package/dist/components/DatePickerField/date-picker-field.types.d.ts +17 -0
  5. package/dist/components/DatePickerField/date-picker-field.types.js +1 -0
  6. package/dist/components/DatePickerField/index.d.ts +2 -0
  7. package/dist/components/DatePickerField/index.js +1 -0
  8. package/dist/components/DateRangePickerField/DateRangePickerField.svelte +87 -0
  9. package/dist/components/DateRangePickerField/DateRangePickerField.svelte.d.ts +5 -0
  10. package/dist/components/DateRangePickerField/date-range-picker-field.types.d.ts +22 -0
  11. package/dist/components/DateRangePickerField/date-range-picker-field.types.js +1 -0
  12. package/dist/components/DateRangePickerField/index.d.ts +2 -0
  13. package/dist/components/DateRangePickerField/index.js +1 -0
  14. package/dist/components/FormSelect/FormSelect.svelte +16 -0
  15. package/dist/components/FormSelect/FormSelect.svelte.d.ts +5 -0
  16. package/dist/components/FormSelect/form-select.types.d.ts +6 -0
  17. package/dist/components/FormSelect/form-select.types.js +1 -0
  18. package/dist/components/FormSelect/index.d.ts +2 -0
  19. package/dist/components/FormSelect/index.js +1 -0
  20. package/dist/components/SafeTable/SafeTable.svelte +85 -0
  21. package/dist/components/SafeTable/SafeTable.svelte.d.ts +26 -0
  22. package/dist/components/SafeTable/index.d.ts +2 -0
  23. package/dist/components/SafeTable/index.js +1 -0
  24. package/dist/components/SafeTable/safe-table.types.d.ts +3 -0
  25. package/dist/components/SafeTable/safe-table.types.js +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.js +4 -0
  28. package/dist/mcp/sv5ui-plus-docs.data.json +2 -2
  29. package/package.json +8 -7
package/README.md CHANGED
@@ -37,7 +37,8 @@ New code should use the explicit `sv5ui` and `sv5ui-plus` imports.
37
37
 
38
38
  - Content and display: `BentoGrid`, `Chart`, `Chat`, `CodeBlock`, `Fonts`, `List`, `Marquee`, `NumberTicker`, `Prose`, `Spotlight`
39
39
  - Forms and overlays: `ColorPicker`, `ConfirmDialog`, `LocaleButton`, `PasswordInput`, `Search`
40
- - Layout and data: `Resizable`, `ScrollArea`, `TableBulkActionBar`, `TreeView`
40
+ - Layout and data: `Resizable`, `ScrollArea`, `SafeTable`, `TableBulkActionBar`, `TreeView`
41
+ - Forms: `FormSelect`, `DatePickerField`, `DateRangePickerField`, `PasswordInput`
41
42
  - Drag and drop: `SortableGroup`, `SortableList`, `useDragDrop`, `useSortable`
42
43
  - SvelteKit adapter: `SvelteKitNavigationMenu`
43
44
  - Feedback adapter: `notify`
@@ -0,0 +1,41 @@
1
+ <script lang="ts" module>export {};
2
+ </script>
3
+
4
+ <script lang="ts">import { parseDate, parseDateTime } from "@internationalized/date";
5
+ import { DatePicker } from "sv5ui";
6
+ let { value = $bindable(""), name, granularity = "day", required = false, disabled = false, readonly = false, class: className, locale = "th-TH", weekStartsOn = 1, hourCycle = 24, onValueChange } = $props();
7
+ const hasTime = $derived(granularity !== "day");
8
+ const pickerValue = $derived(toDateValue(value, hasTime));
9
+ function toDateValue(raw, withTime) {
10
+ const normalized = raw.trim();
11
+ if (!normalized) return undefined;
12
+ try {
13
+ return withTime ? parseDateTime(normalized.slice(0, 19)) : parseDate(normalized.slice(0, 10));
14
+ } catch {
15
+ return undefined;
16
+ }
17
+ }
18
+ function toFormValue(next) {
19
+ if (!next) return "";
20
+ const date = next.toString();
21
+ return hasTime ? date.slice(0, granularity === "second" ? 19 : 16) : date.slice(0, 10);
22
+ }
23
+ function handleValueChange(next) {
24
+ value = toFormValue(next);
25
+ onValueChange?.(value);
26
+ }
27
+ </script>
28
+
29
+ <DatePicker
30
+ value={pickerValue}
31
+ onValueChange={handleValueChange}
32
+ {name}
33
+ {granularity}
34
+ {hourCycle}
35
+ {locale}
36
+ {weekStartsOn}
37
+ {required}
38
+ {disabled}
39
+ {readonly}
40
+ class={className}
41
+ />
@@ -0,0 +1,5 @@
1
+ export type { DatePickerFieldProps as Props } from './date-picker-field.types.js';
2
+ import type { DatePickerFieldProps } from './date-picker-field.types.js';
3
+ declare const DatePickerField: import("svelte").Component<DatePickerFieldProps, {}, "value">;
4
+ type DatePickerField = ReturnType<typeof DatePickerField>;
5
+ export default DatePickerField;
@@ -0,0 +1,17 @@
1
+ export type DateFieldGranularity = 'day' | 'hour' | 'minute' | 'second';
2
+ export type DatePickerFieldProps = {
3
+ value?: string;
4
+ name?: string;
5
+ granularity?: DateFieldGranularity;
6
+ required?: boolean;
7
+ disabled?: boolean;
8
+ readonly?: boolean;
9
+ class?: string;
10
+ /** @default 'th-TH' */
11
+ locale?: string;
12
+ /** @default 1 (Monday) */
13
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
14
+ /** @default 24 */
15
+ hourCycle?: 12 | 24;
16
+ onValueChange?: (value: string) => void;
17
+ };
@@ -0,0 +1,2 @@
1
+ export { default as DatePickerField } from './DatePickerField.svelte';
2
+ export type { DateFieldGranularity, DatePickerFieldProps } from './date-picker-field.types.js';
@@ -0,0 +1 @@
1
+ export { default as DatePickerField } from './DatePickerField.svelte';
@@ -0,0 +1,87 @@
1
+ <script lang="ts" module>export {};
2
+ </script>
3
+
4
+ <script lang="ts">import { parseDate, parseDateTime } from "@internationalized/date";
5
+ import { Button, DateRangePicker } from "sv5ui";
6
+ let { start = $bindable(""), end = $bindable(""), startName, endName, granularity = "day", required = false, disabled = false, readonly = false, clearable = true, timeInput, class: className, locale = "th-TH", weekStartsOn = 1, hourCycle = 24, clearLabel = "Clear dates" } = $props();
7
+ const hasTime = $derived(granularity !== "day");
8
+ const showTimeInput = $derived(timeInput ?? hasTime);
9
+ function toDateValue(raw, withTime) {
10
+ const normalized = raw.trim();
11
+ if (!normalized) return undefined;
12
+ try {
13
+ return withTime ? parseDateTime(normalized.slice(0, 19)) : parseDate(normalized.slice(0, 10));
14
+ } catch {
15
+ return undefined;
16
+ }
17
+ }
18
+ function toFormValue(next) {
19
+ if (!next) return "";
20
+ const date = next.toString();
21
+ return hasTime ? date.slice(0, granularity === "second" ? 19 : 16) : date.slice(0, 10);
22
+ }
23
+ let pickerValue = $state(undefined);
24
+ $effect(() => {
25
+ const s = toDateValue(start, hasTime);
26
+ const e = toDateValue(end, hasTime);
27
+ const curStart = pickerValue?.start?.toString();
28
+ const curEnd = pickerValue?.end?.toString();
29
+ const nextStart = s?.toString();
30
+ const nextEnd = e?.toString();
31
+ if (curStart !== nextStart || curEnd !== nextEnd) {
32
+ pickerValue = s || e ? {
33
+ start: s,
34
+ end: e
35
+ } : undefined;
36
+ }
37
+ });
38
+ function handleValueChange(next) {
39
+ pickerValue = next;
40
+ start = toFormValue(next?.start);
41
+ end = toFormValue(next?.end);
42
+ }
43
+ function handleStartValueChange(next) {
44
+ if (!next) return;
45
+ start = toFormValue(next);
46
+ }
47
+ function handleEndValueChange(next) {
48
+ if (!next) return;
49
+ end = toFormValue(next);
50
+ }
51
+ function handleClear() {
52
+ pickerValue = undefined;
53
+ start = "";
54
+ end = "";
55
+ }
56
+ </script>
57
+
58
+ <div class="flex items-center gap-2">
59
+ <DateRangePicker
60
+ bind:value={pickerValue}
61
+ onValueChange={handleValueChange}
62
+ onStartValueChange={handleStartValueChange}
63
+ onEndValueChange={handleEndValueChange}
64
+ {granularity}
65
+ timeInput={showTimeInput}
66
+ {hourCycle}
67
+ {locale}
68
+ {weekStartsOn}
69
+ {required}
70
+ {disabled}
71
+ {readonly}
72
+ class={className}
73
+ />
74
+ {#if clearable && (start || end) && !disabled && !readonly}
75
+ <Button
76
+ type="button"
77
+ variant="ghost"
78
+ color="secondary"
79
+ size="sm"
80
+ icon="lucide:x"
81
+ onclick={handleClear}
82
+ aria-label={clearLabel}
83
+ />
84
+ {/if}
85
+ </div>
86
+ <input type="hidden" name={startName} value={start} />
87
+ <input type="hidden" name={endName} value={end} />
@@ -0,0 +1,5 @@
1
+ export type { DateRangePickerFieldProps as Props } from './date-range-picker-field.types.js';
2
+ import type { DateRangePickerFieldProps } from './date-range-picker-field.types.js';
3
+ declare const DateRangePickerField: import("svelte").Component<DateRangePickerFieldProps, {}, "start" | "end">;
4
+ type DateRangePickerField = ReturnType<typeof DateRangePickerField>;
5
+ export default DateRangePickerField;
@@ -0,0 +1,22 @@
1
+ import type { DateFieldGranularity } from '../DatePickerField/date-picker-field.types.js';
2
+ export type DateRangePickerFieldProps = {
3
+ start?: string;
4
+ end?: string;
5
+ startName: string;
6
+ endName: string;
7
+ granularity?: DateFieldGranularity;
8
+ required?: boolean;
9
+ disabled?: boolean;
10
+ readonly?: boolean;
11
+ clearable?: boolean;
12
+ timeInput?: boolean;
13
+ class?: string;
14
+ /** @default 'th-TH' */
15
+ locale?: string;
16
+ /** @default 1 (Monday) */
17
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
18
+ /** @default 24 */
19
+ hourCycle?: 12 | 24;
20
+ /** Accessible label for the clear button. @default 'Clear dates' */
21
+ clearLabel?: string;
22
+ };
@@ -0,0 +1,2 @@
1
+ export { default as DateRangePickerField } from './DateRangePickerField.svelte';
2
+ export type { DateRangePickerFieldProps } from './date-range-picker-field.types.js';
@@ -0,0 +1 @@
1
+ export { default as DateRangePickerField } from './DateRangePickerField.svelte';
@@ -0,0 +1,16 @@
1
+ <script lang="ts" module>export {};
2
+ </script>
3
+
4
+ <script lang="ts">import { Select } from "sv5ui";
5
+ let { name, value = $bindable(), disabled = false, ...selectProps } = $props();
6
+ </script>
7
+
8
+ <Select {...selectProps} bind:value {disabled} />
9
+
10
+ {#if Array.isArray(value)}
11
+ {#each value as item (item)}
12
+ <input type="hidden" {name} value={item} {disabled} />
13
+ {/each}
14
+ {:else}
15
+ <input type="hidden" {name} value={value ?? ''} {disabled} />
16
+ {/if}
@@ -0,0 +1,5 @@
1
+ export type { FormSelectProps as Props } from './form-select.types.js';
2
+ import type { FormSelectProps } from './form-select.types.js';
3
+ declare const FormSelect: import("svelte").Component<FormSelectProps, {}, "value">;
4
+ type FormSelect = ReturnType<typeof FormSelect>;
5
+ export default FormSelect;
@@ -0,0 +1,6 @@
1
+ import type { ComponentProps } from 'svelte';
2
+ import type { Select } from 'sv5ui';
3
+ export type FormSelectProps = Omit<ComponentProps<typeof Select>, 'name'> & {
4
+ /** Native form field name (written to hidden inputs). */
5
+ name: string;
6
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { default as FormSelect } from './FormSelect.svelte';
2
+ export type { FormSelectProps } from './form-select.types.js';
@@ -0,0 +1 @@
1
+ export { default as FormSelect } from './FormSelect.svelte';
@@ -0,0 +1,85 @@
1
+ <script lang="ts" module>export {};
2
+ </script>
3
+
4
+ <!--
5
+ Thin wrapper around sv5ui Table.
6
+ Owns $state for bindable arrays so Table never falls back to $bindable([])
7
+ which can surface Symbol(UNINITIALIZED) under Svelte experimental.async / fork.
8
+ -->
9
+ <script lang="ts" generics="T extends Record<string, any>">import { Table } from "sv5ui";
10
+ let localSorting = $state([]);
11
+ let localSelectedRows = $state([]);
12
+ let localPinnedRows = $state([]);
13
+ let localExpandedRows = $state([]);
14
+ let localColumnFilters = $state({});
15
+ let localColumnSizing = $state({});
16
+ let localGlobalFilter = $state("");
17
+ let localPage = $state(0);
18
+ let localRef = $state(null);
19
+ let localColumnVisibility = $state(undefined);
20
+ let localColumnPinning = $state(undefined);
21
+ let { ref = $bindable(localRef), sorting = $bindable(localSorting), selectedRows = $bindable(localSelectedRows), pinnedRows = $bindable(localPinnedRows), expandedRows = $bindable(localExpandedRows), columnFilters = $bindable(localColumnFilters), columnSizing = $bindable(localColumnSizing), globalFilter = $bindable(localGlobalFilter), page = $bindable(localPage), columnVisibility = $bindable(localColumnVisibility), columnPinning = $bindable(localColumnPinning), ...rest } = $props();
22
+ </script>
23
+
24
+ <Table
25
+ bind:ref
26
+ bind:sorting={
27
+ () => (Array.isArray(sorting) ? sorting : localSorting),
28
+ (value) => {
29
+ const next = Array.isArray(value) ? value : []
30
+ sorting = next
31
+ }
32
+ }
33
+ bind:selectedRows={
34
+ () => (Array.isArray(selectedRows) ? selectedRows : localSelectedRows),
35
+ (value) => {
36
+ const next = (Array.isArray(value) ? value : []) as T[]
37
+ selectedRows = next
38
+ }
39
+ }
40
+ bind:pinnedRows={
41
+ () => (Array.isArray(pinnedRows) ? pinnedRows : localPinnedRows),
42
+ (value) => {
43
+ const next = Array.isArray(value) ? value : []
44
+ pinnedRows = next
45
+ }
46
+ }
47
+ bind:expandedRows={
48
+ () => (Array.isArray(expandedRows) ? expandedRows : localExpandedRows),
49
+ (value) => {
50
+ const next = Array.isArray(value) ? value : []
51
+ expandedRows = next
52
+ }
53
+ }
54
+ bind:columnFilters={
55
+ () =>
56
+ columnFilters && typeof columnFilters === 'object' && !Array.isArray(columnFilters)
57
+ ? columnFilters
58
+ : localColumnFilters,
59
+ (value) => {
60
+ const next =
61
+ value && typeof value === 'object' && !Array.isArray(value)
62
+ ? value
63
+ : ({} as Record<string, string>)
64
+ columnFilters = next
65
+ }
66
+ }
67
+ bind:columnSizing={
68
+ () =>
69
+ columnSizing && typeof columnSizing === 'object' && !Array.isArray(columnSizing)
70
+ ? columnSizing
71
+ : localColumnSizing,
72
+ (value) => {
73
+ const next =
74
+ value && typeof value === 'object' && !Array.isArray(value)
75
+ ? value
76
+ : ({} as Record<string, number>)
77
+ columnSizing = next
78
+ }
79
+ }
80
+ bind:globalFilter
81
+ bind:page
82
+ bind:columnVisibility
83
+ bind:columnPinning
84
+ {...rest}
85
+ />
@@ -0,0 +1,26 @@
1
+ export type { SafeTableProps as Props } from './safe-table.types.js';
2
+ import type { SafeTableProps } from './safe-table.types.js';
3
+ declare function $$render<T extends Record<string, any>>(): {
4
+ props: SafeTableProps<T>;
5
+ exports: {};
6
+ bindings: "page" | "ref" | "sorting" | "selectedRows" | "pinnedRows" | "expandedRows" | "columnFilters" | "columnSizing" | "globalFilter" | "columnVisibility" | "columnPinning";
7
+ slots: {};
8
+ events: {};
9
+ };
10
+ declare class __sveltets_Render<T extends Record<string, any>> {
11
+ props(): ReturnType<typeof $$render<T>>['props'];
12
+ events(): ReturnType<typeof $$render<T>>['events'];
13
+ slots(): ReturnType<typeof $$render<T>>['slots'];
14
+ bindings(): "page" | "ref" | "sorting" | "selectedRows" | "pinnedRows" | "expandedRows" | "columnFilters" | "columnSizing" | "globalFilter" | "columnVisibility" | "columnPinning";
15
+ exports(): {};
16
+ }
17
+ interface $$IsomorphicComponent {
18
+ new <T extends Record<string, any>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
19
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
20
+ } & ReturnType<__sveltets_Render<T>['exports']>;
21
+ <T extends Record<string, any>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
22
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
23
+ }
24
+ declare const SafeTable: $$IsomorphicComponent;
25
+ type SafeTable<T extends Record<string, any>> = InstanceType<typeof SafeTable<T>>;
26
+ export default SafeTable;
@@ -0,0 +1,2 @@
1
+ export { default as SafeTable } from './SafeTable.svelte';
2
+ export type { SafeTableProps } from './safe-table.types.js';
@@ -0,0 +1 @@
1
+ export { default as SafeTable } from './SafeTable.svelte';
@@ -0,0 +1,3 @@
1
+ import type { TableProps } from 'sv5ui';
2
+ /** Same surface as `sv5ui` Table — wrapper only hardens bindable array defaults. */
3
+ export type SafeTableProps<T extends Record<string, any> = Record<string, any>> = TableProps<T>;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -4,7 +4,10 @@ export * from './components/Chat/index.js';
4
4
  export * from './components/CodeBlock/index.js';
5
5
  export * from './components/ColorPicker/index.js';
6
6
  export * from './components/ConfirmDialog/index.js';
7
+ export * from './components/DatePickerField/index.js';
8
+ export * from './components/DateRangePickerField/index.js';
7
9
  export * from './components/Fonts/index.js';
10
+ export * from './components/FormSelect/index.js';
8
11
  export * from './components/List/index.js';
9
12
  export * from './components/LocaleButton/index.js';
10
13
  export * from './components/Marquee/index.js';
@@ -18,6 +21,7 @@ export * from './components/Search/index.js';
18
21
  export * from './components/SortableGroup/index.js';
19
22
  export * from './components/SortableList/index.js';
20
23
  export * from './components/Spotlight/index.js';
24
+ export * from './components/SafeTable/index.js';
21
25
  export * from './components/TableBulkActionBar/index.js';
22
26
  export * from './components/TreeView/index.js';
23
27
  export * from './hooks/useSortable/index.js';
package/dist/index.js CHANGED
@@ -5,7 +5,10 @@ export * from './components/Chat/index.js';
5
5
  export * from './components/CodeBlock/index.js';
6
6
  export * from './components/ColorPicker/index.js';
7
7
  export * from './components/ConfirmDialog/index.js';
8
+ export * from './components/DatePickerField/index.js';
9
+ export * from './components/DateRangePickerField/index.js';
8
10
  export * from './components/Fonts/index.js';
11
+ export * from './components/FormSelect/index.js';
9
12
  export * from './components/List/index.js';
10
13
  export * from './components/LocaleButton/index.js';
11
14
  export * from './components/Marquee/index.js';
@@ -19,6 +22,7 @@ export * from './components/Search/index.js';
19
22
  export * from './components/SortableGroup/index.js';
20
23
  export * from './components/SortableList/index.js';
21
24
  export * from './components/Spotlight/index.js';
25
+ export * from './components/SafeTable/index.js';
22
26
  export * from './components/TableBulkActionBar/index.js';
23
27
  export * from './components/TreeView/index.js';
24
28
  // SV5UI Plus-exclusive hooks
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": 1,
3
3
  "packageName": "sv5ui-plus",
4
- "packageVersion": "5.0.0",
5
- "generatedAt": "2026-08-09T08:52:11.840Z",
4
+ "packageVersion": "5.0.2",
5
+ "generatedAt": "2026-08-16T09:25:54.305Z",
6
6
  "slugs": {
7
7
  "components": [],
8
8
  "hooks": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv5ui-plus",
3
- "version": "5.0.0",
3
+ "version": "5.0.2",
4
4
  "description": "Community companion components and hooks for SV5UI and Svelte 5",
5
5
  "packageManager": "bun@1.3.14",
6
6
  "author": "asphum",
@@ -120,8 +120,8 @@
120
120
  }
121
121
  },
122
122
  "devDependencies": {
123
- "@biomejs/biome": "2.5.7",
124
- "@inlang/paraglide-js": "^2.23.2",
123
+ "@biomejs/biome": "2.5.8",
124
+ "@inlang/paraglide-js": "^2.24.1",
125
125
  "@sveltejs/adapter-vercel": "^6.3.4",
126
126
  "@sveltejs/kit": "^2.70.2",
127
127
  "@sveltejs/package": "^2.5.8",
@@ -132,8 +132,8 @@
132
132
  "playwright": "^1.62.1",
133
133
  "publint": "^0.3.23",
134
134
  "sv5ui": "^2.5.0",
135
- "svelte": "^5.56.8",
136
- "svelte-check": "^4.7.5",
135
+ "svelte": "^5.56.9",
136
+ "svelte-check": "^4.7.6",
137
137
  "tailwindcss": "^4.3.3",
138
138
  "typescript": "6.0.3",
139
139
  "vite": "^8.2.1",
@@ -161,10 +161,11 @@
161
161
  "@dnd-kit/dom": "^0.5.0",
162
162
  "@dnd-kit/helpers": "^0.5.0",
163
163
  "@dnd-kit/svelte": "^0.5.0",
164
+ "@internationalized/date": "^3.12.3",
164
165
  "@modelcontextprotocol/sdk": "^1.30.0",
165
- "apexcharts": "^6.7.0",
166
+ "apexcharts": "^6.8.0",
166
167
  "bits-ui": "^2.18.1",
167
- "shiki": "^4.4.2",
168
+ "shiki": "^4.4.3",
168
169
  "tailwind-merge": "^3.6.0",
169
170
  "tailwind-variants": "^3.3.1",
170
171
  "zod": "^4.4.3"