compote-ui 0.49.3 → 0.50.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.
- package/dist/components/date-field/date-field.svelte +109 -0
- package/dist/components/date-field/date-field.svelte.d.ts +4 -0
- package/dist/components/date-field/types.d.ts +9 -0
- package/dist/components/date-field/types.js +1 -0
- package/dist/components/date-input/date-input.svelte +50 -0
- package/dist/components/date-input/date-input.svelte.d.ts +5 -0
- package/dist/components/date-input/types.d.ts +8 -0
- package/dist/components/date-input/types.js +1 -0
- package/dist/components/date-picker/date-picker-calendar.svelte +174 -0
- package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +6 -0
- package/dist/components/date-picker/date-picker.svelte +69 -0
- package/dist/components/date-picker/date-picker.svelte.d.ts +5 -0
- package/dist/components/date-picker/types.d.ts +10 -0
- package/dist/components/date-picker/types.js +1 -0
- package/dist/components/date-range-field/date-range-field.svelte +106 -0
- package/dist/components/date-range-field/date-range-field.svelte.d.ts +4 -0
- package/dist/components/date-range-field/types.d.ts +8 -0
- package/dist/components/date-range-field/types.js +1 -0
- package/dist/components/tabs/tabs.svelte +1 -1
- package/dist/components/tree-view/tree-view.svelte +19 -8
- package/dist/icons/PhCalendarBlank.svelte +19 -0
- package/dist/icons/PhCalendarBlank.svelte.d.ts +5 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4 -0
- package/package.json +2 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DatePicker, useDatePicker } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
import { DateInput, useDateInput } from '@ark-ui/svelte/date-input';
|
|
4
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
5
|
+
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
6
|
+
import { CalendarDateTime } from '@internationalized/date';
|
|
7
|
+
import { PhCalendarBlank } from '../../icons';
|
|
8
|
+
import type { DateFieldProps } from './types';
|
|
9
|
+
import DatePickerCalendar from '../date-picker/date-picker-calendar.svelte';
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
value = $bindable(),
|
|
13
|
+
defaultValue,
|
|
14
|
+
label,
|
|
15
|
+
name,
|
|
16
|
+
min,
|
|
17
|
+
max,
|
|
18
|
+
disabled,
|
|
19
|
+
readOnly,
|
|
20
|
+
required,
|
|
21
|
+
invalid,
|
|
22
|
+
timeZone,
|
|
23
|
+
granularity,
|
|
24
|
+
onValueChange
|
|
25
|
+
}: DateFieldProps = $props();
|
|
26
|
+
|
|
27
|
+
const locale = useLocaleContext();
|
|
28
|
+
const id = $props.id();
|
|
29
|
+
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
30
|
+
|
|
31
|
+
const datePicker = useDatePicker(() => ({
|
|
32
|
+
id,
|
|
33
|
+
locale: locale().locale,
|
|
34
|
+
closeOnSelect: !showTimeInput,
|
|
35
|
+
value: value ? [value] : [],
|
|
36
|
+
defaultValue: defaultValue ? [defaultValue] : undefined,
|
|
37
|
+
min,
|
|
38
|
+
max,
|
|
39
|
+
disabled,
|
|
40
|
+
readOnly,
|
|
41
|
+
required,
|
|
42
|
+
invalid,
|
|
43
|
+
timeZone,
|
|
44
|
+
onValueChange(details) {
|
|
45
|
+
const picked = details.value[0] ?? null;
|
|
46
|
+
if (picked && showTimeInput && !('hour' in picked)) {
|
|
47
|
+
const h = value && 'hour' in value ? (value as CalendarDateTime).hour : 0;
|
|
48
|
+
const m = value && 'hour' in value ? (value as CalendarDateTime).minute : 0;
|
|
49
|
+
const merged = new CalendarDateTime(picked.year, picked.month, picked.day, h, m);
|
|
50
|
+
value = merged;
|
|
51
|
+
datePicker().setValue([merged]);
|
|
52
|
+
} else {
|
|
53
|
+
value = picked;
|
|
54
|
+
}
|
|
55
|
+
onValueChange?.(details);
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
const dateInput = useDateInput(() => ({
|
|
60
|
+
id,
|
|
61
|
+
locale: locale().locale,
|
|
62
|
+
granularity: granularity ?? 'day',
|
|
63
|
+
value: datePicker().value,
|
|
64
|
+
min,
|
|
65
|
+
max,
|
|
66
|
+
disabled,
|
|
67
|
+
readOnly,
|
|
68
|
+
required,
|
|
69
|
+
invalid,
|
|
70
|
+
timeZone,
|
|
71
|
+
onValueChange(details) {
|
|
72
|
+
datePicker().setValue(details.value);
|
|
73
|
+
}
|
|
74
|
+
}));
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<DateInput.RootProvider value={dateInput}>
|
|
78
|
+
{#if label}
|
|
79
|
+
<DateInput.Label class="text-sm font-medium leading-none">
|
|
80
|
+
{label}
|
|
81
|
+
<Field.RequiredIndicator />
|
|
82
|
+
</DateInput.Label>
|
|
83
|
+
{/if}
|
|
84
|
+
<DateInput.Control>
|
|
85
|
+
<DatePicker.RootProvider value={datePicker}>
|
|
86
|
+
<DatePicker.Control class="flex flex-row gap-1.5">
|
|
87
|
+
<DateInput.SegmentGroup
|
|
88
|
+
class="inline-flex h-9 items-center rounded-md border border-border bg-surface-1 px-3 text-sm shadow-sm focus-within:ring-1 focus-within:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50 data-invalid:border-danger"
|
|
89
|
+
>
|
|
90
|
+
<DateInput.SegmentContext>
|
|
91
|
+
{#snippet render(segment)}
|
|
92
|
+
<DateInput.Segment
|
|
93
|
+
{segment}
|
|
94
|
+
class="rounded px-0.5 text-ink outline-none focus:bg-primary focus:text-ink-inverse data-placeholder-shown:text-ink-dim"
|
|
95
|
+
/>
|
|
96
|
+
{/snippet}
|
|
97
|
+
</DateInput.SegmentContext>
|
|
98
|
+
</DateInput.SegmentGroup>
|
|
99
|
+
<DatePicker.Trigger
|
|
100
|
+
class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-border bg-surface-1 shadow-sm hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50"
|
|
101
|
+
>
|
|
102
|
+
<PhCalendarBlank class="size-4" />
|
|
103
|
+
</DatePicker.Trigger>
|
|
104
|
+
</DatePicker.Control>
|
|
105
|
+
<DatePickerCalendar {showTimeInput} />
|
|
106
|
+
</DatePicker.RootProvider>
|
|
107
|
+
</DateInput.Control>
|
|
108
|
+
<DateInput.HiddenInput {name} />
|
|
109
|
+
</DateInput.RootProvider>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DatePickerRootBaseProps } from '@ark-ui/svelte/date-picker';
|
|
2
|
+
import type { DateValue } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
export interface DateFieldProps extends Omit<DatePickerRootBaseProps, 'value' | 'defaultValue'> {
|
|
4
|
+
value?: DateValue | null;
|
|
5
|
+
defaultValue?: DateValue;
|
|
6
|
+
label?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
granularity?: 'day' | 'hour' | 'minute' | 'second';
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DateInput } from '@ark-ui/svelte/date-input';
|
|
3
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
4
|
+
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
5
|
+
import type { DateInputProps } from './types';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
value = $bindable(),
|
|
9
|
+
defaultValue,
|
|
10
|
+
label,
|
|
11
|
+
name,
|
|
12
|
+
onValueChange,
|
|
13
|
+
...restProps
|
|
14
|
+
}: DateInputProps = $props();
|
|
15
|
+
|
|
16
|
+
const locale = useLocaleContext();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<DateInput.Root
|
|
20
|
+
{...restProps}
|
|
21
|
+
locale={locale().locale}
|
|
22
|
+
value={value ? [value] : []}
|
|
23
|
+
defaultValue={defaultValue ? [defaultValue] : undefined}
|
|
24
|
+
onValueChange={(details) => {
|
|
25
|
+
value = details.value[0] ?? null;
|
|
26
|
+
onValueChange?.(details);
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
{#if label}
|
|
30
|
+
<DateInput.Label class="text-sm font-medium leading-none">
|
|
31
|
+
{label}
|
|
32
|
+
<Field.RequiredIndicator />
|
|
33
|
+
</DateInput.Label>
|
|
34
|
+
{/if}
|
|
35
|
+
<DateInput.Control>
|
|
36
|
+
<DateInput.SegmentGroup
|
|
37
|
+
class="inline-flex h-9 items-center rounded-md border border-border bg-surface-1 px-3 text-sm shadow-sm focus-within:ring-1 focus-within:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50 data-invalid:border-danger"
|
|
38
|
+
>
|
|
39
|
+
<DateInput.SegmentContext>
|
|
40
|
+
{#snippet render(segment)}
|
|
41
|
+
<DateInput.Segment
|
|
42
|
+
{segment}
|
|
43
|
+
class="rounded px-0.5 text-ink outline-none focus:bg-primary focus:text-ink-inverse data-placeholder-shown:text-ink-dim"
|
|
44
|
+
/>
|
|
45
|
+
{/snippet}
|
|
46
|
+
</DateInput.SegmentContext>
|
|
47
|
+
</DateInput.SegmentGroup>
|
|
48
|
+
</DateInput.Control>
|
|
49
|
+
<DateInput.HiddenInput {name} />
|
|
50
|
+
</DateInput.Root>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DateInputRootBaseProps } from '@ark-ui/svelte/date-input';
|
|
2
|
+
import type { DateInputDateValue as DateValue } from '@ark-ui/svelte/date-input';
|
|
3
|
+
export interface DateInputProps extends Omit<DateInputRootBaseProps, 'value' | 'defaultValue'> {
|
|
4
|
+
value?: DateValue | null;
|
|
5
|
+
defaultValue?: DateValue;
|
|
6
|
+
label?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DatePicker } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
import { Portal } from '@ark-ui/svelte/portal';
|
|
4
|
+
import { CalendarDateTime } from '@internationalized/date';
|
|
5
|
+
import { PhArrowLeft, PhArrowRight } from '../../icons';
|
|
6
|
+
import type { DateValue } from '@ark-ui/svelte/date-picker';
|
|
7
|
+
|
|
8
|
+
let { showTimeInput = false }: { showTimeInput?: boolean } = $props();
|
|
9
|
+
|
|
10
|
+
function getTimeValue(v: DateValue | undefined): string {
|
|
11
|
+
if (!v || !('hour' in v)) return '';
|
|
12
|
+
const dt = v as CalendarDateTime;
|
|
13
|
+
return `${String(dt.hour).padStart(2, '0')}:${String(dt.minute).padStart(2, '0')}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function setTime(v: DateValue | undefined, hours: number, minutes: number): CalendarDateTime {
|
|
17
|
+
if (v && 'hour' in v) return (v as CalendarDateTime).set({ hour: hours, minute: minutes });
|
|
18
|
+
const d = v ?? new CalendarDateTime(new Date().getFullYear(), 1, 1, 0, 0);
|
|
19
|
+
return new CalendarDateTime(d.year, d.month, d.day, hours, minutes);
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Portal>
|
|
24
|
+
<DatePicker.Positioner>
|
|
25
|
+
<DatePicker.Content
|
|
26
|
+
class="z-50 min-w-70 rounded-lg border border-border bg-surface-document p-4 shadow-lg outline-none data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
27
|
+
>
|
|
28
|
+
<DatePicker.View view="day">
|
|
29
|
+
<DatePicker.Context>
|
|
30
|
+
{#snippet render(datePicker)}
|
|
31
|
+
<DatePicker.ViewControl class="mb-3 flex items-center justify-between">
|
|
32
|
+
<DatePicker.PrevTrigger
|
|
33
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
34
|
+
>
|
|
35
|
+
<PhArrowLeft class="size-4" />
|
|
36
|
+
</DatePicker.PrevTrigger>
|
|
37
|
+
<DatePicker.ViewTrigger
|
|
38
|
+
class="flex-1 rounded-md py-1 text-center text-sm font-semibold text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
39
|
+
>
|
|
40
|
+
<DatePicker.RangeText />
|
|
41
|
+
</DatePicker.ViewTrigger>
|
|
42
|
+
<DatePicker.NextTrigger
|
|
43
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
44
|
+
>
|
|
45
|
+
<PhArrowRight class="size-4" />
|
|
46
|
+
</DatePicker.NextTrigger>
|
|
47
|
+
</DatePicker.ViewControl>
|
|
48
|
+
<DatePicker.Table class="w-full border-collapse">
|
|
49
|
+
<DatePicker.TableHead>
|
|
50
|
+
<DatePicker.TableRow>
|
|
51
|
+
{#each datePicker().weekDays as weekDay (weekDay.short)}
|
|
52
|
+
<DatePicker.TableHeader
|
|
53
|
+
class="pb-2 text-center text-xs font-medium uppercase text-ink-dim"
|
|
54
|
+
>
|
|
55
|
+
{weekDay.short}
|
|
56
|
+
</DatePicker.TableHeader>
|
|
57
|
+
{/each}
|
|
58
|
+
</DatePicker.TableRow>
|
|
59
|
+
</DatePicker.TableHead>
|
|
60
|
+
<DatePicker.TableBody>
|
|
61
|
+
{#each datePicker().weeks as week, weekIdx (weekIdx)}
|
|
62
|
+
<DatePicker.TableRow>
|
|
63
|
+
{#each week as day (day.toString())}
|
|
64
|
+
<DatePicker.TableCell value={day}>
|
|
65
|
+
<DatePicker.TableCellTrigger
|
|
66
|
+
class="inline-flex h-9 w-9 items-center justify-center rounded-md text-sm text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40 data-in-range:rounded-none data-in-range:bg-primary/15 data-outside-range:opacity-40 data-outside-range:text-ink-dim data-range-end:rounded-r-md data-range-end:bg-primary data-range-end:text-ink-inverse data-range-start:rounded-l-md data-range-start:bg-primary data-range-start:text-ink-inverse data-selected:bg-primary data-selected:text-ink-inverse data-today:font-semibold data-today:text-primary data-unavailable:line-through data-unavailable:opacity-40 data-selected:data-today:text-ink-inverse"
|
|
67
|
+
>
|
|
68
|
+
{day.day}
|
|
69
|
+
</DatePicker.TableCellTrigger>
|
|
70
|
+
</DatePicker.TableCell>
|
|
71
|
+
{/each}
|
|
72
|
+
</DatePicker.TableRow>
|
|
73
|
+
{/each}
|
|
74
|
+
</DatePicker.TableBody>
|
|
75
|
+
</DatePicker.Table>
|
|
76
|
+
{#if showTimeInput}
|
|
77
|
+
<input
|
|
78
|
+
type="time"
|
|
79
|
+
value={getTimeValue(datePicker().value[0])}
|
|
80
|
+
oninput={(e) => {
|
|
81
|
+
const [h, m] = e.currentTarget.value.split(':').map(Number);
|
|
82
|
+
datePicker().setValue([setTime(datePicker().value[0], h, m)]);
|
|
83
|
+
}}
|
|
84
|
+
class="mt-3 h-9 w-full rounded-md border border-border bg-surface-1 px-3 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
85
|
+
/>
|
|
86
|
+
{/if}
|
|
87
|
+
{/snippet}
|
|
88
|
+
</DatePicker.Context>
|
|
89
|
+
</DatePicker.View>
|
|
90
|
+
|
|
91
|
+
<DatePicker.View view="month">
|
|
92
|
+
<DatePicker.Context>
|
|
93
|
+
{#snippet render(datePicker)}
|
|
94
|
+
<DatePicker.ViewControl class="mb-3 flex items-center justify-between">
|
|
95
|
+
<DatePicker.PrevTrigger
|
|
96
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
97
|
+
>
|
|
98
|
+
<PhArrowLeft class="size-4" />
|
|
99
|
+
</DatePicker.PrevTrigger>
|
|
100
|
+
<DatePicker.ViewTrigger
|
|
101
|
+
class="flex-1 rounded-md py-1 text-center text-sm font-semibold text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
102
|
+
>
|
|
103
|
+
<DatePicker.RangeText />
|
|
104
|
+
</DatePicker.ViewTrigger>
|
|
105
|
+
<DatePicker.NextTrigger
|
|
106
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
107
|
+
>
|
|
108
|
+
<PhArrowRight class="size-4" />
|
|
109
|
+
</DatePicker.NextTrigger>
|
|
110
|
+
</DatePicker.ViewControl>
|
|
111
|
+
<DatePicker.Table class="w-full border-collapse">
|
|
112
|
+
<DatePicker.TableBody>
|
|
113
|
+
{#each datePicker().getMonthsGrid( { columns: 4, format: 'short' } ) as monthRow, rowIdx (rowIdx)}
|
|
114
|
+
<DatePicker.TableRow>
|
|
115
|
+
{#each monthRow as month (month.value)}
|
|
116
|
+
<DatePicker.TableCell value={month.value}>
|
|
117
|
+
<DatePicker.TableCellTrigger
|
|
118
|
+
class="inline-flex h-10 w-full items-center justify-center rounded-md px-2 text-sm text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-outside-range:invisible data-selected:bg-primary data-selected:text-ink-inverse"
|
|
119
|
+
>
|
|
120
|
+
{month.label}
|
|
121
|
+
</DatePicker.TableCellTrigger>
|
|
122
|
+
</DatePicker.TableCell>
|
|
123
|
+
{/each}
|
|
124
|
+
</DatePicker.TableRow>
|
|
125
|
+
{/each}
|
|
126
|
+
</DatePicker.TableBody>
|
|
127
|
+
</DatePicker.Table>
|
|
128
|
+
{/snippet}
|
|
129
|
+
</DatePicker.Context>
|
|
130
|
+
</DatePicker.View>
|
|
131
|
+
|
|
132
|
+
<DatePicker.View view="year">
|
|
133
|
+
<DatePicker.Context>
|
|
134
|
+
{#snippet render(datePicker)}
|
|
135
|
+
<DatePicker.ViewControl class="mb-3 flex items-center justify-between">
|
|
136
|
+
<DatePicker.PrevTrigger
|
|
137
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
138
|
+
>
|
|
139
|
+
<PhArrowLeft class="size-4" />
|
|
140
|
+
</DatePicker.PrevTrigger>
|
|
141
|
+
<DatePicker.ViewTrigger
|
|
142
|
+
class="flex-1 rounded-md py-1 text-center text-sm font-semibold text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
143
|
+
>
|
|
144
|
+
<DatePicker.RangeText />
|
|
145
|
+
</DatePicker.ViewTrigger>
|
|
146
|
+
<DatePicker.NextTrigger
|
|
147
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-ink-dim hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-40"
|
|
148
|
+
>
|
|
149
|
+
<PhArrowRight class="size-4" />
|
|
150
|
+
</DatePicker.NextTrigger>
|
|
151
|
+
</DatePicker.ViewControl>
|
|
152
|
+
<DatePicker.Table class="w-full border-collapse">
|
|
153
|
+
<DatePicker.TableBody>
|
|
154
|
+
{#each datePicker().getYearsGrid({ columns: 4 }) as yearRow, rowIdx (rowIdx)}
|
|
155
|
+
<DatePicker.TableRow>
|
|
156
|
+
{#each yearRow as year (year.value)}
|
|
157
|
+
<DatePicker.TableCell value={year.value}>
|
|
158
|
+
<DatePicker.TableCellTrigger
|
|
159
|
+
class="inline-flex h-10 w-full items-center justify-center rounded-md px-2 text-sm text-ink hover:bg-surface-1 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-outside-range:invisible data-selected:bg-primary data-selected:text-ink-inverse"
|
|
160
|
+
>
|
|
161
|
+
{year.label}
|
|
162
|
+
</DatePicker.TableCellTrigger>
|
|
163
|
+
</DatePicker.TableCell>
|
|
164
|
+
{/each}
|
|
165
|
+
</DatePicker.TableRow>
|
|
166
|
+
{/each}
|
|
167
|
+
</DatePicker.TableBody>
|
|
168
|
+
</DatePicker.Table>
|
|
169
|
+
{/snippet}
|
|
170
|
+
</DatePicker.Context>
|
|
171
|
+
</DatePicker.View>
|
|
172
|
+
</DatePicker.Content>
|
|
173
|
+
</DatePicker.Positioner>
|
|
174
|
+
</Portal>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DatePicker } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
4
|
+
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
5
|
+
import { CalendarDateTime } from '@internationalized/date';
|
|
6
|
+
import { PhCalendarBlank, PhX } from '../../icons';
|
|
7
|
+
import type { DatePickerProps } from './types';
|
|
8
|
+
import DatePickerCalendar from './date-picker-calendar.svelte';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
value = $bindable(),
|
|
12
|
+
defaultValue,
|
|
13
|
+
label,
|
|
14
|
+
placeholder,
|
|
15
|
+
name,
|
|
16
|
+
granularity,
|
|
17
|
+
onValueChange,
|
|
18
|
+
...restProps
|
|
19
|
+
}: DatePickerProps = $props();
|
|
20
|
+
|
|
21
|
+
const locale = useLocaleContext();
|
|
22
|
+
const showTimeInput = $derived(!!granularity && granularity !== 'day');
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<DatePicker.Root
|
|
26
|
+
{...restProps}
|
|
27
|
+
locale={locale().locale}
|
|
28
|
+
closeOnSelect={!showTimeInput}
|
|
29
|
+
value={value ? [value] : []}
|
|
30
|
+
defaultValue={defaultValue ? [defaultValue] : undefined}
|
|
31
|
+
onValueChange={(details) => {
|
|
32
|
+
const picked = details.value[0] ?? null;
|
|
33
|
+
if (picked && showTimeInput) {
|
|
34
|
+
const h = value && 'hour' in value ? (value as CalendarDateTime).hour : 0;
|
|
35
|
+
const m = value && 'hour' in value ? (value as CalendarDateTime).minute : 0;
|
|
36
|
+
value = new CalendarDateTime(picked.year, picked.month, picked.day, h, m);
|
|
37
|
+
} else {
|
|
38
|
+
value = picked;
|
|
39
|
+
}
|
|
40
|
+
onValueChange?.(details);
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
{#if label}
|
|
44
|
+
<DatePicker.Label class="text-sm font-medium leading-none">
|
|
45
|
+
{label}
|
|
46
|
+
<Field.RequiredIndicator />
|
|
47
|
+
</DatePicker.Label>
|
|
48
|
+
{/if}
|
|
49
|
+
<DatePicker.Control class="flex flex-row gap-1.5">
|
|
50
|
+
<DatePicker.Input
|
|
51
|
+
{placeholder}
|
|
52
|
+
class="h-9 min-w-0 flex-1 rounded-md border border-border bg-surface-1 px-3 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50 data-invalid:border-danger"
|
|
53
|
+
/>
|
|
54
|
+
<DatePicker.Trigger
|
|
55
|
+
class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-border bg-surface-1 shadow-sm hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50"
|
|
56
|
+
>
|
|
57
|
+
<PhCalendarBlank class="size-4" />
|
|
58
|
+
</DatePicker.Trigger>
|
|
59
|
+
<DatePicker.ClearTrigger
|
|
60
|
+
class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-border bg-surface-1 text-ink-dim shadow-sm hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
61
|
+
>
|
|
62
|
+
<PhX class="size-3.5" />
|
|
63
|
+
</DatePicker.ClearTrigger>
|
|
64
|
+
</DatePicker.Control>
|
|
65
|
+
<DatePickerCalendar {showTimeInput} />
|
|
66
|
+
{#if name}
|
|
67
|
+
<input type="hidden" {name} value={value ?? ''} />
|
|
68
|
+
{/if}
|
|
69
|
+
</DatePicker.Root>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DatePicker } from '@ark-ui/svelte/date-picker';
|
|
2
|
+
import type { DatePickerProps } from './types';
|
|
3
|
+
declare const DatePicker: import("svelte").Component<DatePickerProps, {}, "value">;
|
|
4
|
+
type DatePicker = ReturnType<typeof DatePicker>;
|
|
5
|
+
export default DatePicker;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DatePickerRootBaseProps } from '@ark-ui/svelte/date-picker';
|
|
2
|
+
import type { DateValue } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
export interface DatePickerProps extends Omit<DatePickerRootBaseProps, 'value' | 'defaultValue'> {
|
|
4
|
+
value?: DateValue | null;
|
|
5
|
+
defaultValue?: DateValue;
|
|
6
|
+
label?: string;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
granularity?: 'day' | 'hour' | 'minute' | 'second';
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DatePicker, useDatePicker } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
import { DateInput, useDateInput } from '@ark-ui/svelte/date-input';
|
|
4
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
5
|
+
import { useLocaleContext } from '@ark-ui/svelte/locale';
|
|
6
|
+
import { PhCalendarBlank } from '../../icons';
|
|
7
|
+
import type { DateRangeFieldProps } from './types';
|
|
8
|
+
import DatePickerCalendar from '../date-picker/date-picker-calendar.svelte';
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
value = $bindable([]),
|
|
12
|
+
defaultValue,
|
|
13
|
+
label,
|
|
14
|
+
name,
|
|
15
|
+
min,
|
|
16
|
+
max,
|
|
17
|
+
disabled,
|
|
18
|
+
readOnly,
|
|
19
|
+
required,
|
|
20
|
+
invalid,
|
|
21
|
+
timeZone,
|
|
22
|
+
onValueChange
|
|
23
|
+
}: DateRangeFieldProps = $props();
|
|
24
|
+
|
|
25
|
+
const locale = useLocaleContext();
|
|
26
|
+
const id = $props.id();
|
|
27
|
+
|
|
28
|
+
const datePicker = useDatePicker(() => ({
|
|
29
|
+
id,
|
|
30
|
+
locale: locale().locale,
|
|
31
|
+
selectionMode: 'range',
|
|
32
|
+
value,
|
|
33
|
+
defaultValue,
|
|
34
|
+
min,
|
|
35
|
+
max,
|
|
36
|
+
disabled,
|
|
37
|
+
readOnly,
|
|
38
|
+
required,
|
|
39
|
+
invalid,
|
|
40
|
+
timeZone,
|
|
41
|
+
onValueChange(details) {
|
|
42
|
+
value = details.value;
|
|
43
|
+
onValueChange?.(details);
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const dateInput = useDateInput(() => ({
|
|
48
|
+
id,
|
|
49
|
+
locale: locale().locale,
|
|
50
|
+
selectionMode: 'range',
|
|
51
|
+
value: datePicker().value,
|
|
52
|
+
min,
|
|
53
|
+
max,
|
|
54
|
+
disabled,
|
|
55
|
+
readOnly,
|
|
56
|
+
required,
|
|
57
|
+
invalid,
|
|
58
|
+
timeZone,
|
|
59
|
+
onValueChange(details) {
|
|
60
|
+
datePicker().setValue(details.value);
|
|
61
|
+
}
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
const segmentGroupClass =
|
|
65
|
+
'inline-flex h-9 items-center rounded-md border border-border bg-surface-1 px-3 text-sm shadow-sm focus-within:ring-1 focus-within:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50 data-invalid:border-danger';
|
|
66
|
+
|
|
67
|
+
const segmentClass =
|
|
68
|
+
'rounded px-0.5 text-ink outline-none focus:bg-primary focus:text-ink-inverse data-placeholder-shown:text-ink-dim';
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<DateInput.RootProvider value={dateInput}>
|
|
72
|
+
{#if label}
|
|
73
|
+
<DateInput.Label class="text-sm font-medium leading-none">
|
|
74
|
+
{label}
|
|
75
|
+
<Field.RequiredIndicator />
|
|
76
|
+
</DateInput.Label>
|
|
77
|
+
{/if}
|
|
78
|
+
<DateInput.Control>
|
|
79
|
+
<DatePicker.RootProvider value={datePicker}>
|
|
80
|
+
<DatePicker.Control class="flex flex-row items-center gap-1.5">
|
|
81
|
+
<DateInput.SegmentGroup index={0} class={segmentGroupClass}>
|
|
82
|
+
<DateInput.SegmentContext>
|
|
83
|
+
{#snippet render(segment)}
|
|
84
|
+
<DateInput.Segment {segment} class={segmentClass} />
|
|
85
|
+
{/snippet}
|
|
86
|
+
</DateInput.SegmentContext>
|
|
87
|
+
</DateInput.SegmentGroup>
|
|
88
|
+
<span class="text-ink-dim">–</span>
|
|
89
|
+
<DateInput.SegmentGroup index={1} class={segmentGroupClass}>
|
|
90
|
+
<DateInput.SegmentContext>
|
|
91
|
+
{#snippet render(segment)}
|
|
92
|
+
<DateInput.Segment {segment} class={segmentClass} />
|
|
93
|
+
{/snippet}
|
|
94
|
+
</DateInput.SegmentContext>
|
|
95
|
+
</DateInput.SegmentGroup>
|
|
96
|
+
<DatePicker.Trigger
|
|
97
|
+
class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md border border-border bg-surface-1 shadow-sm hover:bg-surface-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring data-disabled:cursor-not-allowed data-disabled:opacity-50"
|
|
98
|
+
>
|
|
99
|
+
<PhCalendarBlank class="size-4" />
|
|
100
|
+
</DatePicker.Trigger>
|
|
101
|
+
</DatePicker.Control>
|
|
102
|
+
<DatePickerCalendar />
|
|
103
|
+
</DatePicker.RootProvider>
|
|
104
|
+
</DateInput.Control>
|
|
105
|
+
<DateInput.HiddenInput {name} />
|
|
106
|
+
</DateInput.RootProvider>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DatePickerRootBaseProps } from '@ark-ui/svelte/date-picker';
|
|
2
|
+
import type { DateValue } from '@ark-ui/svelte/date-picker';
|
|
3
|
+
export interface DateRangeFieldProps extends Omit<DatePickerRootBaseProps, 'value' | 'defaultValue' | 'selectionMode'> {
|
|
4
|
+
value?: DateValue[];
|
|
5
|
+
defaultValue?: DateValue[];
|
|
6
|
+
label?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
bind:value
|
|
19
19
|
{defaultValue}
|
|
20
20
|
{orientation}
|
|
21
|
-
class="flex data-[orientation='horizontal']:flex-col data-[orientation='vertical']:flex-row"
|
|
21
|
+
class="flex h-full data-[orientation='horizontal']:flex-col data-[orientation='vertical']:flex-row"
|
|
22
22
|
>
|
|
23
23
|
{@render children?.()}
|
|
24
24
|
</Tabs.Root>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
PhMinus,
|
|
13
13
|
PhX
|
|
14
14
|
} from '../../icons';
|
|
15
|
-
import { Button, Field } from '../..';
|
|
15
|
+
import { Button, Field, ScrollArea } from '../..';
|
|
16
16
|
import { SvelteSet } from 'svelte/reactivity';
|
|
17
17
|
|
|
18
18
|
import Icon from '@iconify/svelte';
|
|
@@ -137,13 +137,24 @@
|
|
|
137
137
|
</div>
|
|
138
138
|
</div>
|
|
139
139
|
|
|
140
|
-
<
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
140
|
+
<ScrollArea.Root class="flex-1">
|
|
141
|
+
<ScrollArea.Viewport>
|
|
142
|
+
<ScrollArea.Content class="p-0">
|
|
143
|
+
<TreeView.Tree class="flex flex-col text-sm">
|
|
144
|
+
{#each collection.rootNode.children ?? [] as node, index (node.value)}
|
|
145
|
+
{@render renderNode(node as T, [index])}
|
|
146
|
+
{/each}
|
|
147
|
+
</TreeView.Tree>
|
|
148
|
+
</ScrollArea.Content>
|
|
149
|
+
</ScrollArea.Viewport>
|
|
150
|
+
<ScrollArea.Scrollbar orientation="vertical">
|
|
151
|
+
<ScrollArea.Thumb />
|
|
152
|
+
</ScrollArea.Scrollbar>
|
|
153
|
+
<ScrollArea.Scrollbar orientation="horizontal">
|
|
154
|
+
<ScrollArea.Thumb />
|
|
155
|
+
</ScrollArea.Scrollbar>
|
|
156
|
+
<ScrollArea.Corner />
|
|
157
|
+
</ScrollArea.Root>
|
|
147
158
|
</TreeView.Root>
|
|
148
159
|
|
|
149
160
|
{#snippet nodeCheckbox()}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let { class: className = '', ...restProps } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<svg
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
width="1em"
|
|
8
|
+
height="1em"
|
|
9
|
+
viewBox="0 0 256 256"
|
|
10
|
+
class={className}
|
|
11
|
+
{...restProps}
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
fill="currentColor"
|
|
15
|
+
d="M208 32h-24v-8a8 8 0 0 0-16 0v8H88v-8a8 8 0 0 0-16 0v8H48a16 16 0 0 0-16 16v160a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16M72 48v8a8 8 0 0 0 16 0v-8h80v8a8 8 0 0 0 16 0v-8h24v32H48V48Zm136 160H48V96h160z"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
|
|
19
|
+
<!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
|
package/dist/icons/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as PhArrowClockwise } from './PhArrowClockwise.svelte';
|
|
2
2
|
export { default as PhArrowCounterClockwise } from './PhArrowCounterClockwise.svelte';
|
|
3
|
+
export { default as PhCalendarBlank } from './PhCalendarBlank.svelte';
|
|
3
4
|
export { default as PhArrowLeft } from './PhArrowLeft.svelte';
|
|
4
5
|
export { default as PhArrowRight } from './PhArrowRight.svelte';
|
|
5
6
|
export { default as PhArrowSquareOut } from './PhArrowSquareOut.svelte';
|
package/dist/icons/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as PhArrowClockwise } from './PhArrowClockwise.svelte';
|
|
2
2
|
export { default as PhArrowCounterClockwise } from './PhArrowCounterClockwise.svelte';
|
|
3
|
+
export { default as PhCalendarBlank } from './PhCalendarBlank.svelte';
|
|
3
4
|
export { default as PhArrowLeft } from './PhArrowLeft.svelte';
|
|
4
5
|
export { default as PhArrowRight } from './PhArrowRight.svelte';
|
|
5
6
|
export { default as PhArrowSquareOut } from './PhArrowSquareOut.svelte';
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,14 @@ export * as Carousel from './components/carousel';
|
|
|
12
12
|
export { default as Checkbox } from './components/checkbox/checkbox.svelte';
|
|
13
13
|
export { default as CheckboxGroup } from './components/checkbox/checkbox-group.svelte';
|
|
14
14
|
export { default as Combobox } from './components/combobox/combobox.svelte';
|
|
15
|
+
export { default as DateField } from './components/date-field/date-field.svelte';
|
|
16
|
+
export type { DateFieldProps } from './components/date-field/types';
|
|
17
|
+
export { default as DateRangeField } from './components/date-range-field/date-range-field.svelte';
|
|
18
|
+
export type { DateRangeFieldProps } from './components/date-range-field/types';
|
|
19
|
+
export { default as DateInput } from './components/date-input/date-input.svelte';
|
|
20
|
+
export type { DateInputProps } from './components/date-input/types';
|
|
21
|
+
export { default as DatePicker } from './components/date-picker/date-picker.svelte';
|
|
22
|
+
export type { DatePickerProps } from './components/date-picker/types';
|
|
15
23
|
export * as Dialog from './components/dialog';
|
|
16
24
|
export { default as AlertDialog } from './components/dialog/alert-dialog.svelte';
|
|
17
25
|
export type { AlertDialogProps } from './components/dialog/dialog.types';
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,10 @@ export * as Carousel from './components/carousel';
|
|
|
11
11
|
export { default as Checkbox } from './components/checkbox/checkbox.svelte';
|
|
12
12
|
export { default as CheckboxGroup } from './components/checkbox/checkbox-group.svelte';
|
|
13
13
|
export { default as Combobox } from './components/combobox/combobox.svelte';
|
|
14
|
+
export { default as DateField } from './components/date-field/date-field.svelte';
|
|
15
|
+
export { default as DateRangeField } from './components/date-range-field/date-range-field.svelte';
|
|
16
|
+
export { default as DateInput } from './components/date-input/date-input.svelte';
|
|
17
|
+
export { default as DatePicker } from './components/date-picker/date-picker.svelte';
|
|
14
18
|
export * as Dialog from './components/dialog';
|
|
15
19
|
export { default as AlertDialog } from './components/dialog/alert-dialog.svelte';
|
|
16
20
|
export * as Drawer from './components/drawer';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compote-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev --open",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"svelte"
|
|
89
89
|
],
|
|
90
90
|
"dependencies": {
|
|
91
|
-
"@ark-ui/svelte": "^5.
|
|
91
|
+
"@ark-ui/svelte": "^5.22.0",
|
|
92
92
|
"@fontsource-variable/nunito-sans": "^5.2.7",
|
|
93
93
|
"@iconify/svelte": "^5.2.1",
|
|
94
94
|
"runed": "^0.37.1",
|