compote-ui 0.63.1 → 0.63.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.
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import { DateInput, useDateInput } from '@ark-ui/svelte/date-input';
|
|
4
4
|
import { Field } from '@ark-ui/svelte/field';
|
|
5
5
|
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
6
|
-
import { CalendarDateTime } from '@internationalized/date';
|
|
6
|
+
import { CalendarDateTime, getLocalTimeZone } from '@internationalized/date';
|
|
7
|
+
import { toDateValue, fromDateValue, dateValueShape } from '../../utils/date';
|
|
8
|
+
import type { DateValueShape } from '../../utils/date';
|
|
7
9
|
import { PhCalendarBlank } from '../../icons';
|
|
8
10
|
import type { DateFieldProps } from './types';
|
|
9
11
|
import DatePickerCalendar from '../date-picker/date-picker-calendar.svelte';
|
|
@@ -20,54 +22,71 @@
|
|
|
20
22
|
required,
|
|
21
23
|
invalid,
|
|
22
24
|
timeZone,
|
|
25
|
+
locale: localeProp,
|
|
23
26
|
granularity,
|
|
24
27
|
hourCycle,
|
|
25
28
|
onValueChange
|
|
26
29
|
}: DateFieldProps = $props();
|
|
27
30
|
|
|
28
|
-
const
|
|
31
|
+
const localeContext = useLocaleContext();
|
|
32
|
+
const resolvedLocale = $derived(localeProp ?? localeContext().locale);
|
|
29
33
|
const id = $props.id();
|
|
30
34
|
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
31
35
|
const resolvedHourCycle = $derived(
|
|
32
36
|
hourCycle ??
|
|
33
|
-
(new Intl.DateTimeFormat(
|
|
37
|
+
(new Intl.DateTimeFormat(resolvedLocale, { hour: 'numeric' })
|
|
34
38
|
.formatToParts(new Date(2024, 0, 1, 14))
|
|
35
39
|
.some((p) => p.type === 'dayPeriod')
|
|
36
40
|
? 12
|
|
37
41
|
: 24)
|
|
38
42
|
);
|
|
39
43
|
|
|
44
|
+
// Default the display zone to the user's local zone. Without this Ark/zag
|
|
45
|
+
// formats segments in UTC, so a UTC value would show shifted hours.
|
|
46
|
+
const tz = $derived(timeZone ?? getLocalTimeZone());
|
|
47
|
+
|
|
48
|
+
// Remember the shape the consumer bound the value as, so changes are emitted
|
|
49
|
+
// back in the same shape (string in → string out, Date in → Date out).
|
|
50
|
+
// When the bound value starts null, default to string output.
|
|
51
|
+
let shape: DateValueShape = 'string';
|
|
52
|
+
|
|
53
|
+
const arkValue = $derived.by(() => {
|
|
54
|
+
const s = dateValueShape(value) ?? dateValueShape(defaultValue);
|
|
55
|
+
if (s) shape = s;
|
|
56
|
+
return toDateValue(value, tz);
|
|
57
|
+
});
|
|
58
|
+
const arkDefault = $derived(toDateValue(defaultValue, tz));
|
|
59
|
+
|
|
40
60
|
const datePicker = useDatePicker(() => ({
|
|
41
61
|
id,
|
|
42
|
-
locale:
|
|
62
|
+
locale: resolvedLocale,
|
|
43
63
|
closeOnSelect: !showTimeInput,
|
|
44
|
-
value:
|
|
45
|
-
defaultValue:
|
|
64
|
+
value: arkValue ? [arkValue] : [],
|
|
65
|
+
defaultValue: arkDefault ? [arkDefault] : undefined,
|
|
46
66
|
min,
|
|
47
67
|
max,
|
|
48
68
|
disabled,
|
|
49
69
|
readOnly,
|
|
50
70
|
required,
|
|
51
71
|
invalid,
|
|
52
|
-
timeZone,
|
|
72
|
+
timeZone: tz,
|
|
53
73
|
onValueChange(details) {
|
|
54
74
|
const picked = details.value[0] ?? null;
|
|
75
|
+
let next = picked;
|
|
55
76
|
if (picked && showTimeInput && !('hour' in picked)) {
|
|
56
|
-
const h =
|
|
57
|
-
const m =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
datePicker().setValue([merged]);
|
|
61
|
-
} else {
|
|
62
|
-
value = picked;
|
|
77
|
+
const h = arkValue && 'hour' in arkValue ? (arkValue as CalendarDateTime).hour : 0;
|
|
78
|
+
const m = arkValue && 'hour' in arkValue ? (arkValue as CalendarDateTime).minute : 0;
|
|
79
|
+
next = new CalendarDateTime(picked.year, picked.month, picked.day, h, m);
|
|
80
|
+
datePicker().setValue(next ? [next] : []);
|
|
63
81
|
}
|
|
82
|
+
value = fromDateValue(next, shape, tz);
|
|
64
83
|
onValueChange?.(details);
|
|
65
84
|
}
|
|
66
85
|
}));
|
|
67
86
|
|
|
68
87
|
const dateInput = useDateInput(() => ({
|
|
69
88
|
id,
|
|
70
|
-
locale:
|
|
89
|
+
locale: resolvedLocale,
|
|
71
90
|
granularity: granularity ?? 'day',
|
|
72
91
|
hourCycle,
|
|
73
92
|
value: datePicker().value,
|
|
@@ -77,7 +96,7 @@
|
|
|
77
96
|
readOnly,
|
|
78
97
|
required,
|
|
79
98
|
invalid,
|
|
80
|
-
timeZone,
|
|
99
|
+
timeZone: tz,
|
|
81
100
|
onValueChange(details) {
|
|
82
101
|
datePicker().setValue(details.value);
|
|
83
102
|
}
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import type { DatePickerRootBaseProps } from '@ark-ui/svelte/date-picker';
|
|
2
|
-
import type { DateValue } from '
|
|
2
|
+
import type { DateValue, DateInputValue } from '../../utils/date';
|
|
3
|
+
export type { DateValue };
|
|
3
4
|
export interface DateFieldProps extends Omit<DatePickerRootBaseProps, 'value' | 'defaultValue'> {
|
|
4
|
-
|
|
5
|
-
|
|
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 field displays the user's local zone and the
|
|
13
|
+
* emitted string is UTC.
|
|
14
|
+
*/
|
|
15
|
+
value?: DateInputValue;
|
|
16
|
+
defaultValue?: DateInputValue;
|
|
6
17
|
label?: string;
|
|
7
18
|
name?: string;
|
|
8
19
|
granularity?: 'day' | 'hour' | 'minute' | 'second';
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { DatePicker } from '@ark-ui/svelte/date-picker';
|
|
3
3
|
import { Field } from '@ark-ui/svelte/field';
|
|
4
4
|
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
5
|
-
import { CalendarDateTime } from '@internationalized/date';
|
|
5
|
+
import { CalendarDateTime, getLocalTimeZone } from '@internationalized/date';
|
|
6
|
+
import { toDateValue, fromDateValue, dateValueShape } from '../../utils/date';
|
|
7
|
+
import type { DateValueShape } from '../../utils/date';
|
|
6
8
|
import { PhCalendarBlank, PhX } from '../../icons';
|
|
7
9
|
import type { DatePickerProps } from './types';
|
|
8
10
|
import DatePickerCalendar from './date-picker-calendar.svelte';
|
|
@@ -15,37 +17,57 @@
|
|
|
15
17
|
name,
|
|
16
18
|
granularity,
|
|
17
19
|
hourCycle,
|
|
20
|
+
locale: localeProp,
|
|
21
|
+
timeZone,
|
|
18
22
|
onValueChange,
|
|
19
23
|
...restProps
|
|
20
24
|
}: DatePickerProps = $props();
|
|
21
25
|
|
|
22
|
-
const
|
|
26
|
+
const localeContext = useLocaleContext();
|
|
27
|
+
const resolvedLocale = $derived(localeProp ?? localeContext().locale);
|
|
23
28
|
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
24
29
|
const resolvedHourCycle = $derived(
|
|
25
30
|
hourCycle ??
|
|
26
|
-
(new Intl.DateTimeFormat(
|
|
31
|
+
(new Intl.DateTimeFormat(resolvedLocale, { hour: 'numeric' })
|
|
27
32
|
.formatToParts(new Date(2024, 0, 1, 14))
|
|
28
33
|
.some((p) => p.type === 'dayPeriod')
|
|
29
34
|
? 12
|
|
30
35
|
: 24)
|
|
31
36
|
);
|
|
37
|
+
|
|
38
|
+
// Default the display zone to the user's local zone. Without this Ark/zag
|
|
39
|
+
// formats segments in UTC, so a UTC value would show shifted hours.
|
|
40
|
+
const tz = $derived(timeZone ?? getLocalTimeZone());
|
|
41
|
+
|
|
42
|
+
// Remember the shape the consumer bound the value as, so changes are emitted
|
|
43
|
+
// back in the same shape (string in → string out, Date in → Date out).
|
|
44
|
+
// When the bound value starts null, default to string output.
|
|
45
|
+
let shape: DateValueShape = 'string';
|
|
46
|
+
|
|
47
|
+
const arkValue = $derived.by(() => {
|
|
48
|
+
const s = dateValueShape(value) ?? dateValueShape(defaultValue);
|
|
49
|
+
if (s) shape = s;
|
|
50
|
+
return toDateValue(value, tz);
|
|
51
|
+
});
|
|
52
|
+
const arkDefault = $derived(toDateValue(defaultValue, tz));
|
|
32
53
|
</script>
|
|
33
54
|
|
|
34
55
|
<DatePicker.Root
|
|
35
56
|
{...restProps}
|
|
36
|
-
locale={
|
|
57
|
+
locale={resolvedLocale}
|
|
58
|
+
timeZone={tz}
|
|
37
59
|
closeOnSelect={!showTimeInput}
|
|
38
|
-
value={
|
|
39
|
-
defaultValue={
|
|
60
|
+
value={arkValue ? [arkValue] : []}
|
|
61
|
+
defaultValue={arkDefault ? [arkDefault] : undefined}
|
|
40
62
|
onValueChange={(details) => {
|
|
41
63
|
const picked = details.value[0] ?? null;
|
|
64
|
+
let next = picked;
|
|
42
65
|
if (picked && showTimeInput && !('hour' in picked)) {
|
|
43
|
-
const h =
|
|
44
|
-
const m =
|
|
45
|
-
|
|
46
|
-
} else {
|
|
47
|
-
value = picked;
|
|
66
|
+
const h = arkValue && 'hour' in arkValue ? (arkValue as CalendarDateTime).hour : 0;
|
|
67
|
+
const m = arkValue && 'hour' in arkValue ? (arkValue as CalendarDateTime).minute : 0;
|
|
68
|
+
next = new CalendarDateTime(picked.year, picked.month, picked.day, h, m);
|
|
48
69
|
}
|
|
70
|
+
value = fromDateValue(next, shape, tz);
|
|
49
71
|
onValueChange?.(details);
|
|
50
72
|
}}
|
|
51
73
|
>
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import type { DatePickerRootBaseProps } from '@ark-ui/svelte/date-picker';
|
|
2
|
-
import type { DateValue } from '
|
|
2
|
+
import type { DateValue, DateInputValue } from '../../utils/date';
|
|
3
|
+
export type { DateValue };
|
|
3
4
|
export interface DatePickerProps extends Omit<DatePickerRootBaseProps, 'value' | 'defaultValue'> {
|
|
4
|
-
|
|
5
|
-
|
|
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 picker displays the user's local zone and the
|
|
13
|
+
* emitted string is UTC.
|
|
14
|
+
*/
|
|
15
|
+
value?: DateInputValue;
|
|
16
|
+
defaultValue?: DateInputValue;
|
|
6
17
|
label?: string;
|
|
7
18
|
placeholder?: string;
|
|
8
19
|
name?: string;
|