compote-ui 0.50.0 → 0.51.1
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.
- package/dist/components/data-table-v8/column-helper.js +3 -3
- package/dist/components/data-table-v8/toolbar/data-table-column-filter.svelte +26 -28
- package/dist/components/date-field/date-field.svelte +11 -1
- package/dist/components/date-field/types.d.ts +1 -0
- package/dist/components/date-picker/date-picker-calendar.svelte +80 -14
- package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +1 -0
- package/dist/components/date-picker/date-picker.svelte +11 -2
- package/dist/components/date-picker/types.d.ts +1 -0
- package/dist/components/date-range-field/date-range-field.svelte +2 -0
- package/dist/components/date-range-field/types.d.ts +2 -0
- package/package.json +9 -9
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const TYPE_DEFAULTS = {
|
|
2
|
-
number: { align: 'right' },
|
|
3
|
-
currency: { align: 'right' },
|
|
4
|
-
percent: { align: 'right' },
|
|
2
|
+
number: { align: 'right', size: 120 },
|
|
3
|
+
currency: { align: 'right', size: 120 },
|
|
4
|
+
percent: { align: 'right', size: 100 },
|
|
5
5
|
date: { align: 'center', size: 110 },
|
|
6
6
|
time: { align: 'center', size: 80 },
|
|
7
7
|
'date-time': { align: 'center', size: 160 },
|
|
@@ -267,12 +267,12 @@
|
|
|
267
267
|
</button>
|
|
268
268
|
</div>
|
|
269
269
|
{:else if getColumnType(column) === 'select'}
|
|
270
|
-
{
|
|
271
|
-
{
|
|
272
|
-
{
|
|
270
|
+
{const allOptions = getFacetedValues(column)}
|
|
271
|
+
{const search = localSelectSearch[column.id] ?? ''}
|
|
272
|
+
{const options = search
|
|
273
273
|
? allOptions.filter((o) => o.toLowerCase().includes(search.toLowerCase()))
|
|
274
274
|
: allOptions}
|
|
275
|
-
{
|
|
275
|
+
{const selected = getSelectValues(column)}
|
|
276
276
|
<div class="flex flex-col gap-1">
|
|
277
277
|
<Field.Root>
|
|
278
278
|
<Field.Input
|
|
@@ -285,30 +285,28 @@
|
|
|
285
285
|
}}
|
|
286
286
|
/>
|
|
287
287
|
</Field.Root>
|
|
288
|
-
<
|
|
289
|
-
<ScrollArea.
|
|
290
|
-
<ScrollArea.
|
|
291
|
-
<
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
<ScrollArea.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
</ScrollArea.Root>
|
|
311
|
-
</div>
|
|
288
|
+
<ScrollArea.Root class="max-h-44">
|
|
289
|
+
<ScrollArea.Viewport>
|
|
290
|
+
<ScrollArea.Content>
|
|
291
|
+
<div class="flex flex-col gap-0.5">
|
|
292
|
+
{#each options as option (option)}
|
|
293
|
+
<Checkbox
|
|
294
|
+
size="sm"
|
|
295
|
+
label={option}
|
|
296
|
+
class="min-h-7 rounded-sm px-2 hover:bg-surface-2"
|
|
297
|
+
checked={selected.includes(option)}
|
|
298
|
+
onCheckedChange={({ checked }) =>
|
|
299
|
+
handleSelectChange(column, option, checked === true)}
|
|
300
|
+
/>
|
|
301
|
+
{/each}
|
|
302
|
+
</div>
|
|
303
|
+
</ScrollArea.Content>
|
|
304
|
+
</ScrollArea.Viewport>
|
|
305
|
+
<ScrollArea.Scrollbar orientation="vertical">
|
|
306
|
+
<ScrollArea.Thumb />
|
|
307
|
+
</ScrollArea.Scrollbar>
|
|
308
|
+
<ScrollArea.Corner />
|
|
309
|
+
</ScrollArea.Root>
|
|
312
310
|
</div>
|
|
313
311
|
{:else}
|
|
314
312
|
<Field.Root>
|
|
@@ -21,12 +21,21 @@
|
|
|
21
21
|
invalid,
|
|
22
22
|
timeZone,
|
|
23
23
|
granularity,
|
|
24
|
+
hourCycle,
|
|
24
25
|
onValueChange
|
|
25
26
|
}: DateFieldProps = $props();
|
|
26
27
|
|
|
27
28
|
const locale = useLocaleContext();
|
|
28
29
|
const id = $props.id();
|
|
29
30
|
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
31
|
+
const resolvedHourCycle = $derived(
|
|
32
|
+
hourCycle ??
|
|
33
|
+
(new Intl.DateTimeFormat(locale().locale, { hour: 'numeric' })
|
|
34
|
+
.formatToParts(new Date(2024, 0, 1, 14))
|
|
35
|
+
.some((p) => p.type === 'dayPeriod')
|
|
36
|
+
? 12
|
|
37
|
+
: 24)
|
|
38
|
+
);
|
|
30
39
|
|
|
31
40
|
const datePicker = useDatePicker(() => ({
|
|
32
41
|
id,
|
|
@@ -60,6 +69,7 @@
|
|
|
60
69
|
id,
|
|
61
70
|
locale: locale().locale,
|
|
62
71
|
granularity: granularity ?? 'day',
|
|
72
|
+
hourCycle,
|
|
63
73
|
value: datePicker().value,
|
|
64
74
|
min,
|
|
65
75
|
max,
|
|
@@ -102,7 +112,7 @@
|
|
|
102
112
|
<PhCalendarBlank class="size-4" />
|
|
103
113
|
</DatePicker.Trigger>
|
|
104
114
|
</DatePicker.Control>
|
|
105
|
-
<DatePickerCalendar {showTimeInput} />
|
|
115
|
+
<DatePickerCalendar {showTimeInput} hourCycle={resolvedHourCycle} />
|
|
106
116
|
</DatePicker.RootProvider>
|
|
107
117
|
</DateInput.Control>
|
|
108
118
|
<DateInput.HiddenInput {name} />
|
|
@@ -4,13 +4,25 @@
|
|
|
4
4
|
import { CalendarDateTime } from '@internationalized/date';
|
|
5
5
|
import { PhArrowLeft, PhArrowRight } from '../../icons';
|
|
6
6
|
import type { DateValue } from '@ark-ui/svelte/date-picker';
|
|
7
|
+
import Select from '../select/select.svelte';
|
|
7
8
|
|
|
8
|
-
let { showTimeInput = false }: { showTimeInput?: boolean } =
|
|
9
|
+
let { showTimeInput = false, hourCycle = 24 }: { showTimeInput?: boolean; hourCycle?: 12 | 24 } =
|
|
10
|
+
$props();
|
|
9
11
|
|
|
10
|
-
function
|
|
11
|
-
if (!v || !('hour' in v)) return
|
|
12
|
-
const
|
|
13
|
-
return
|
|
12
|
+
function getHour(v: DateValue | undefined): number {
|
|
13
|
+
if (!v || !('hour' in v)) return 0;
|
|
14
|
+
const h = (v as CalendarDateTime).hour;
|
|
15
|
+
return hourCycle === 12 ? h % 12 || 12 : h;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getMinute(v: DateValue | undefined): number {
|
|
19
|
+
if (!v || !('hour' in v)) return 0;
|
|
20
|
+
return (v as CalendarDateTime).minute;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isPM(v: DateValue | undefined): boolean {
|
|
24
|
+
if (!v || !('hour' in v)) return false;
|
|
25
|
+
return (v as CalendarDateTime).hour >= 12;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
function setTime(v: DateValue | undefined, hours: number, minutes: number): CalendarDateTime {
|
|
@@ -18,6 +30,32 @@
|
|
|
18
30
|
const d = v ?? new CalendarDateTime(new Date().getFullYear(), 1, 1, 0, 0);
|
|
19
31
|
return new CalendarDateTime(d.year, d.month, d.day, hours, minutes);
|
|
20
32
|
}
|
|
33
|
+
|
|
34
|
+
function updateHour(v: DateValue | undefined, displayHour: number): CalendarDateTime {
|
|
35
|
+
let h = displayHour;
|
|
36
|
+
if (hourCycle === 12) {
|
|
37
|
+
const pm = isPM(v);
|
|
38
|
+
h = pm ? (displayHour % 12) + 12 : displayHour % 12;
|
|
39
|
+
}
|
|
40
|
+
return setTime(v, h, getMinute(v));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function togglePeriod(v: DateValue | undefined): CalendarDateTime {
|
|
44
|
+
const cur = v && 'hour' in v ? (v as CalendarDateTime).hour : 0;
|
|
45
|
+
return setTime(v, cur >= 12 ? cur - 12 : cur + 12, getMinute(v));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const minuteItems = Array.from({ length: 60 }, (_, m) => ({
|
|
49
|
+
value: m,
|
|
50
|
+
label: String(m).padStart(2, '0')
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
const hourItems = $derived(
|
|
54
|
+
Array.from({ length: hourCycle === 12 ? 12 : 24 }, (_, i) => {
|
|
55
|
+
const h = hourCycle === 12 ? i + 1 : i;
|
|
56
|
+
return { value: h, label: String(h).padStart(2, '0') };
|
|
57
|
+
})
|
|
58
|
+
);
|
|
21
59
|
</script>
|
|
22
60
|
|
|
23
61
|
<Portal>
|
|
@@ -74,15 +112,43 @@
|
|
|
74
112
|
</DatePicker.TableBody>
|
|
75
113
|
</DatePicker.Table>
|
|
76
114
|
{#if showTimeInput}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
{@const cur = datePicker().value[0]}
|
|
116
|
+
<div class="mt-3 flex items-center justify-center gap-1">
|
|
117
|
+
<Select
|
|
118
|
+
items={hourItems}
|
|
119
|
+
value={getHour(cur)}
|
|
120
|
+
size="sm"
|
|
121
|
+
placeholder="HH"
|
|
122
|
+
onValueChange={(d) =>
|
|
123
|
+
datePicker().setValue([updateHour(cur, Number(d.items[0]?.value))])}
|
|
124
|
+
/>
|
|
125
|
+
<span class="text-ink-dim">:</span>
|
|
126
|
+
<Select
|
|
127
|
+
items={minuteItems}
|
|
128
|
+
value={getMinute(cur)}
|
|
129
|
+
size="sm"
|
|
130
|
+
placeholder="mm"
|
|
131
|
+
onValueChange={(d) => {
|
|
132
|
+
const m = Number(d.items[0]?.value);
|
|
133
|
+
const h24 =
|
|
134
|
+
hourCycle === 12
|
|
135
|
+
? isPM(cur)
|
|
136
|
+
? (getHour(cur) % 12) + 12
|
|
137
|
+
: getHour(cur) % 12
|
|
138
|
+
: getHour(cur);
|
|
139
|
+
datePicker().setValue([setTime(cur, h24, m)]);
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
{#if hourCycle === 12}
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
onclick={() => datePicker().setValue([togglePeriod(cur)])}
|
|
146
|
+
class="h-8 rounded-md border border-border bg-surface-1 px-2 text-sm shadow-sm hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
147
|
+
>
|
|
148
|
+
{isPM(cur) ? 'PM' : 'AM'}
|
|
149
|
+
</button>
|
|
150
|
+
{/if}
|
|
151
|
+
</div>
|
|
86
152
|
{/if}
|
|
87
153
|
{/snippet}
|
|
88
154
|
</DatePicker.Context>
|
|
@@ -14,12 +14,21 @@
|
|
|
14
14
|
placeholder,
|
|
15
15
|
name,
|
|
16
16
|
granularity,
|
|
17
|
+
hourCycle,
|
|
17
18
|
onValueChange,
|
|
18
19
|
...restProps
|
|
19
20
|
}: DatePickerProps = $props();
|
|
20
21
|
|
|
21
22
|
const locale = useLocaleContext();
|
|
22
23
|
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
24
|
+
const resolvedHourCycle = $derived(
|
|
25
|
+
hourCycle ??
|
|
26
|
+
(new Intl.DateTimeFormat(locale().locale, { hour: 'numeric' })
|
|
27
|
+
.formatToParts(new Date(2024, 0, 1, 14))
|
|
28
|
+
.some((p) => p.type === 'dayPeriod')
|
|
29
|
+
? 12
|
|
30
|
+
: 24)
|
|
31
|
+
);
|
|
23
32
|
</script>
|
|
24
33
|
|
|
25
34
|
<DatePicker.Root
|
|
@@ -30,7 +39,7 @@
|
|
|
30
39
|
defaultValue={defaultValue ? [defaultValue] : undefined}
|
|
31
40
|
onValueChange={(details) => {
|
|
32
41
|
const picked = details.value[0] ?? null;
|
|
33
|
-
if (picked && showTimeInput) {
|
|
42
|
+
if (picked && showTimeInput && !('hour' in picked)) {
|
|
34
43
|
const h = value && 'hour' in value ? (value as CalendarDateTime).hour : 0;
|
|
35
44
|
const m = value && 'hour' in value ? (value as CalendarDateTime).minute : 0;
|
|
36
45
|
value = new CalendarDateTime(picked.year, picked.month, picked.day, h, m);
|
|
@@ -62,7 +71,7 @@
|
|
|
62
71
|
<PhX class="size-3.5" />
|
|
63
72
|
</DatePicker.ClearTrigger>
|
|
64
73
|
</DatePicker.Control>
|
|
65
|
-
<DatePickerCalendar {showTimeInput} />
|
|
74
|
+
<DatePickerCalendar {showTimeInput} hourCycle={resolvedHourCycle} />
|
|
66
75
|
{#if name}
|
|
67
76
|
<input type="hidden" {name} value={value ?? ''} />
|
|
68
77
|
{/if}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
required,
|
|
20
20
|
invalid,
|
|
21
21
|
timeZone,
|
|
22
|
+
hourCycle,
|
|
22
23
|
onValueChange
|
|
23
24
|
}: DateRangeFieldProps = $props();
|
|
24
25
|
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
id,
|
|
49
50
|
locale: locale().locale,
|
|
50
51
|
selectionMode: 'range',
|
|
52
|
+
hourCycle,
|
|
51
53
|
value: datePicker().value,
|
|
52
54
|
min,
|
|
53
55
|
max,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compote-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev --open",
|
|
@@ -64,25 +64,25 @@
|
|
|
64
64
|
"@sveltejs/package": "^2.5.7",
|
|
65
65
|
"@sveltejs/vite-plugin-svelte": "7.1.2",
|
|
66
66
|
"@tailwindcss/vite": "^4.2.4",
|
|
67
|
-
"@tanstack/svelte-virtual": "^3.13.
|
|
67
|
+
"@tanstack/svelte-virtual": "^3.13.28",
|
|
68
68
|
"@tanstack/table-core": "^8.21.3",
|
|
69
69
|
"@types/node": "^22.19.18",
|
|
70
|
-
"eslint": "^10.4.
|
|
70
|
+
"eslint": "^10.4.1",
|
|
71
71
|
"eslint-config-prettier": "^10.1.8",
|
|
72
|
-
"eslint-plugin-svelte": "^3.
|
|
72
|
+
"eslint-plugin-svelte": "^3.19.0",
|
|
73
73
|
"globals": "^17.5.0",
|
|
74
74
|
"prettier": "^3.8.3",
|
|
75
|
-
"prettier-plugin-svelte": "^4.0
|
|
75
|
+
"prettier-plugin-svelte": "^4.1.0",
|
|
76
76
|
"prettier-plugin-tailwindcss": "^0.8.0",
|
|
77
77
|
"publint": "^0.3.21",
|
|
78
|
-
"svelte": "^5.
|
|
79
|
-
"svelte-check": "^4.
|
|
78
|
+
"svelte": "^5.56.1",
|
|
79
|
+
"svelte-check": "^4.5.0",
|
|
80
80
|
"tailwindcss": "^4.2.4",
|
|
81
81
|
"tw-animate-css": "^1.4.0",
|
|
82
82
|
"typescript": "^6.0.3",
|
|
83
|
-
"typescript-eslint": "^8.60.
|
|
83
|
+
"typescript-eslint": "^8.60.1",
|
|
84
84
|
"unplugin-icons": "^23.0.1",
|
|
85
|
-
"vite": "^8.0.
|
|
85
|
+
"vite": "^8.0.16"
|
|
86
86
|
},
|
|
87
87
|
"keywords": [
|
|
88
88
|
"svelte"
|