@joewinke/jatui 0.41.0 → 0.42.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/CLAUDE.md +9 -3
- package/dist/components/AnimatedNumber.svelte +22 -4
- package/dist/components/BookingScheduler.svelte +412 -0
- package/dist/components/BookingScheduler.svelte.d.ts +66 -0
- package/dist/components/CalendarPicker.svelte +190 -205
- package/dist/components/CalendarPicker.svelte.d.ts +19 -1
- package/dist/components/DatePicker.svelte +419 -0
- package/dist/components/DatePicker.svelte.d.ts +44 -0
- package/dist/components/DateRangePicker.svelte +471 -5
- package/dist/components/DateRangePicker.svelte.d.ts +32 -3
- package/dist/components/EventCalendar.svelte +1324 -0
- package/dist/components/EventCalendar.svelte.d.ts +101 -0
- package/dist/components/TimeSlotPicker.svelte +174 -108
- package/dist/components/TimeSlotPicker.svelte.d.ts +27 -0
- package/dist/components/calendar/CalendarHeader.svelte +98 -0
- package/dist/components/calendar/CalendarHeader.svelte.d.ts +24 -0
- package/dist/components/calendar/MonthGrid.svelte +361 -0
- package/dist/components/calendar/MonthGrid.svelte.d.ts +55 -0
- package/dist/components/calendar/calendarGrid.d.ts +219 -0
- package/dist/components/calendar/calendarGrid.js +494 -0
- package/dist/components/calendar/createCalendarGrid.d.ts +25 -0
- package/dist/components/calendar/createCalendarGrid.js +57 -0
- package/dist/components/calendar/dayOverlap.d.ts +92 -0
- package/dist/components/calendar/dayOverlap.js +147 -0
- package/dist/components/calendar/eventCalendar.d.ts +75 -0
- package/dist/components/calendar/eventCalendar.js +187 -0
- package/dist/components/calendar/index.d.ts +32 -0
- package/dist/components/calendar/index.js +25 -0
- package/dist/components/calendar/monthPacking.d.ts +97 -0
- package/dist/components/calendar/monthPacking.js +254 -0
- package/dist/components/calendar/timeSlots.d.ts +57 -0
- package/dist/components/calendar/timeSlots.js +163 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +11 -0
- package/dist/showcase/Globe.svelte +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* DatePicker — a date field: trigger button + popover month grid + typed entry.
|
|
4
|
+
*
|
|
5
|
+
* The drop-in replacement for a native `<input type="date">`: `value` is the
|
|
6
|
+
* same `YYYY-MM-DD` string (bindable), `name` posts it with a form, and
|
|
7
|
+
* `min`/`max` take the same strings. On top of that it adds the shared
|
|
8
|
+
* calendar grid (APG keys, locale week start), a typed field that reads the
|
|
9
|
+
* locale's own order (MM/DD/YYYY in en-US, DD/MM/YYYY in en-GB — commits on
|
|
10
|
+
* Enter/blur, reverts on Escape or input it can't read) and an optional
|
|
11
|
+
* pending/Apply step (`commit="apply"`).
|
|
12
|
+
*
|
|
13
|
+
* Built from BoardUI's public date-picker behaviour (jatui-lfxyy); no BoardUI
|
|
14
|
+
* source is copied. The popover rides `use:floating`.
|
|
15
|
+
*/
|
|
16
|
+
import { tick } from 'svelte';
|
|
17
|
+
import { floating, type Placement } from '../actions/floating';
|
|
18
|
+
import MonthGrid from './calendar/MonthGrid.svelte';
|
|
19
|
+
import CalendarHeader from './calendar/CalendarHeader.svelte';
|
|
20
|
+
import IconButton from './IconButton.svelte';
|
|
21
|
+
import { createCalendarGrid } from './calendar/createCalendarGrid';
|
|
22
|
+
import {
|
|
23
|
+
calendarAccentStyle,
|
|
24
|
+
datePlaceholder,
|
|
25
|
+
formatMonthYear,
|
|
26
|
+
formatTypedDate,
|
|
27
|
+
makeIsDisabled,
|
|
28
|
+
parseTypedDate,
|
|
29
|
+
resolveWeekStart,
|
|
30
|
+
startOfDay,
|
|
31
|
+
toDay,
|
|
32
|
+
toIsoDate,
|
|
33
|
+
type Weekday
|
|
34
|
+
} from './calendar/calendarGrid';
|
|
35
|
+
|
|
36
|
+
type Size = 'sm' | 'md' | 'lg';
|
|
37
|
+
|
|
38
|
+
let {
|
|
39
|
+
value = $bindable(null),
|
|
40
|
+
open = $bindable(false),
|
|
41
|
+
onChange,
|
|
42
|
+
label,
|
|
43
|
+
id = `jatui-date-${Math.random().toString(36).slice(2, 9)}`,
|
|
44
|
+
name,
|
|
45
|
+
placeholder = 'Pick a date',
|
|
46
|
+
min,
|
|
47
|
+
max,
|
|
48
|
+
isDateEnabled,
|
|
49
|
+
weekdaysOnly = false,
|
|
50
|
+
weekStart = 'locale',
|
|
51
|
+
locale,
|
|
52
|
+
format = { month: 'short', day: 'numeric', year: 'numeric' },
|
|
53
|
+
commit = 'instant',
|
|
54
|
+
typed = true,
|
|
55
|
+
clearable = true,
|
|
56
|
+
showToday = true,
|
|
57
|
+
disabled = false,
|
|
58
|
+
required = false,
|
|
59
|
+
error,
|
|
60
|
+
helpText,
|
|
61
|
+
size = 'md',
|
|
62
|
+
accentColor,
|
|
63
|
+
placement = 'bottom-start',
|
|
64
|
+
zIndex = 60,
|
|
65
|
+
class: className = ''
|
|
66
|
+
}: {
|
|
67
|
+
/** `YYYY-MM-DD` (local calendar day) or null. */
|
|
68
|
+
value?: string | null;
|
|
69
|
+
/** Popover open state (bindable). */
|
|
70
|
+
open?: boolean;
|
|
71
|
+
/** Fires on every committed change, with the parsed local-midnight Date. */
|
|
72
|
+
onChange?: (value: string | null, date: Date | null) => void;
|
|
73
|
+
label?: string;
|
|
74
|
+
id?: string;
|
|
75
|
+
/** Posts `value` with the enclosing form (a native date input's `name`). */
|
|
76
|
+
name?: string;
|
|
77
|
+
placeholder?: string;
|
|
78
|
+
min?: string | Date | null;
|
|
79
|
+
max?: string | Date | null;
|
|
80
|
+
isDateEnabled?: (date: Date) => boolean;
|
|
81
|
+
weekdaysOnly?: boolean;
|
|
82
|
+
/** 0 = Sunday … 6 = Saturday, or `'locale'` (default). */
|
|
83
|
+
weekStart?: Weekday | 'locale';
|
|
84
|
+
locale?: string;
|
|
85
|
+
/** Intl options for the trigger label. */
|
|
86
|
+
format?: Intl.DateTimeFormatOptions;
|
|
87
|
+
/** `instant`: a click commits and closes. `apply`: pick, then Apply / Cancel. */
|
|
88
|
+
commit?: 'instant' | 'apply';
|
|
89
|
+
/** Show the typed-entry field in the popover. */
|
|
90
|
+
typed?: boolean;
|
|
91
|
+
clearable?: boolean;
|
|
92
|
+
showToday?: boolean;
|
|
93
|
+
disabled?: boolean;
|
|
94
|
+
required?: boolean;
|
|
95
|
+
error?: string;
|
|
96
|
+
helpText?: string;
|
|
97
|
+
size?: Size;
|
|
98
|
+
/** primary | secondary | accent | info | success | warning | error | neutral */
|
|
99
|
+
accentColor?: string;
|
|
100
|
+
placement?: Placement;
|
|
101
|
+
zIndex?: number;
|
|
102
|
+
class?: string;
|
|
103
|
+
} = $props();
|
|
104
|
+
|
|
105
|
+
const SIZE: Record<Size, string> = { sm: 'input-sm', md: '', lg: 'input-lg' };
|
|
106
|
+
|
|
107
|
+
const firstDay = $derived(resolveWeekStart(weekStart, locale));
|
|
108
|
+
const minDay = $derived(toDay(min ?? null));
|
|
109
|
+
const maxDay = $derived(toDay(max ?? null));
|
|
110
|
+
const isDisabled = $derived(makeIsDisabled({ min: minDay, max: maxDay, isDateEnabled, weekdaysOnly }));
|
|
111
|
+
const committed = $derived(toDay(value));
|
|
112
|
+
const display = $derived(committed ? new Intl.DateTimeFormat(locale, format).format(committed) : '');
|
|
113
|
+
const popId = $derived(`${id}-calendar`);
|
|
114
|
+
|
|
115
|
+
let triggerEl = $state<HTMLButtonElement | null>(null);
|
|
116
|
+
let popEl = $state<HTMLDivElement | null>(null);
|
|
117
|
+
let pending = $state<Date | null>(null);
|
|
118
|
+
const cal = createCalendarGrid({ initial: () => committed, min: () => minDay, max: () => maxDay });
|
|
119
|
+
let typedText = $state('');
|
|
120
|
+
let typedMessage = $state('');
|
|
121
|
+
let lastDismiss = 0;
|
|
122
|
+
|
|
123
|
+
// Re-key the panel every time it opens, so the visible month follows the value.
|
|
124
|
+
async function openPopover() {
|
|
125
|
+
pending = committed;
|
|
126
|
+
cal.reset(committed);
|
|
127
|
+
typedText = formatTypedDate(pending, locale);
|
|
128
|
+
typedMessage = '';
|
|
129
|
+
open = true;
|
|
130
|
+
await tick();
|
|
131
|
+
popEl?.querySelector<HTMLElement>('.jatui-month-grid__day[tabindex="0"]')?.focus();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function close() {
|
|
135
|
+
open = false;
|
|
136
|
+
lastDismiss = performance.now();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function toggle() {
|
|
140
|
+
if (disabled) return;
|
|
141
|
+
if (open) return close();
|
|
142
|
+
// The outside-click dismiss runs (capture phase) before this click; don't reopen.
|
|
143
|
+
if (performance.now() - lastDismiss < 250) return;
|
|
144
|
+
void openPopover();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function commitValue(date: Date | null) {
|
|
148
|
+
const next = date ? toIsoDate(date) : null;
|
|
149
|
+
if (next !== value) {
|
|
150
|
+
value = next;
|
|
151
|
+
onChange?.(next, date);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function choose(date: Date) {
|
|
156
|
+
pending = date;
|
|
157
|
+
typedText = formatTypedDate(date, locale);
|
|
158
|
+
typedMessage = '';
|
|
159
|
+
if (commit === 'instant') {
|
|
160
|
+
commitValue(date);
|
|
161
|
+
close();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function apply() {
|
|
166
|
+
commitValue(pending);
|
|
167
|
+
close();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function clear() {
|
|
171
|
+
commitValue(null);
|
|
172
|
+
triggerEl?.focus();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Commit what was typed, or revert it. Returns true when a date was accepted. */
|
|
176
|
+
function commitTyped(): boolean {
|
|
177
|
+
const current = formatTypedDate(pending, locale);
|
|
178
|
+
if (typedText.trim() === current) return false;
|
|
179
|
+
if (!typedText.trim()) {
|
|
180
|
+
pending = null;
|
|
181
|
+
if (commit === 'instant') commitValue(null);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
const parsed = parseTypedDate(typedText, locale);
|
|
185
|
+
if (!parsed || isDisabled(parsed)) {
|
|
186
|
+
typedMessage = parsed ? 'That date is not available.' : `Couldn't read that date — use ${datePlaceholder(locale)}.`;
|
|
187
|
+
typedText = current;
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
typedMessage = '';
|
|
191
|
+
pending = parsed;
|
|
192
|
+
cal.focus(parsed);
|
|
193
|
+
if (commit === 'instant') commitValue(parsed);
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function handleTypedKeydown(e: KeyboardEvent) {
|
|
198
|
+
if (e.key === 'Enter') {
|
|
199
|
+
e.preventDefault();
|
|
200
|
+
if (commitTyped() && commit === 'instant') close();
|
|
201
|
+
} else if (e.key === 'Escape') {
|
|
202
|
+
const current = formatTypedDate(pending, locale);
|
|
203
|
+
if (typedText !== current) {
|
|
204
|
+
// First Escape reverts the field; the next one closes the popover.
|
|
205
|
+
e.stopPropagation();
|
|
206
|
+
typedText = current;
|
|
207
|
+
typedMessage = '';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const today = startOfDay(new Date());
|
|
213
|
+
const todayEnabled = $derived(!isDisabled(today));
|
|
214
|
+
const describedBy = $derived(error ? `${id}-error` : helpText ? `${id}-help` : undefined);
|
|
215
|
+
</script>
|
|
216
|
+
|
|
217
|
+
<div class="form-control jatui-date-picker {className}">
|
|
218
|
+
{#if label}
|
|
219
|
+
<label for={id} class="label">
|
|
220
|
+
<span class="text-[0.8125rem] font-medium text-base-content/85">
|
|
221
|
+
{label}
|
|
222
|
+
{#if required}<span class="text-error ml-1" aria-hidden="true">*</span>{/if}
|
|
223
|
+
</span>
|
|
224
|
+
</label>
|
|
225
|
+
{/if}
|
|
226
|
+
|
|
227
|
+
<div class="jatui-date-picker__field">
|
|
228
|
+
<button
|
|
229
|
+
bind:this={triggerEl}
|
|
230
|
+
{id}
|
|
231
|
+
type="button"
|
|
232
|
+
class="input {SIZE[size]} {error ? 'input-error' : ''} jatui-date-picker__trigger"
|
|
233
|
+
aria-haspopup="dialog"
|
|
234
|
+
aria-expanded={open}
|
|
235
|
+
aria-controls={open ? popId : undefined}
|
|
236
|
+
aria-describedby={describedBy}
|
|
237
|
+
{disabled}
|
|
238
|
+
onclick={toggle}
|
|
239
|
+
>
|
|
240
|
+
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" class="jatui-date-picker__icon">
|
|
241
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />
|
|
242
|
+
</svg>
|
|
243
|
+
<span class="jatui-date-picker__value" class:is-placeholder={!display}>{display || placeholder}</span>
|
|
244
|
+
</button>
|
|
245
|
+
{#if clearable && value && !disabled}
|
|
246
|
+
<span class="jatui-date-picker__clear">
|
|
247
|
+
<IconButton label="Clear date" size="xs" shape="circle" onclick={clear}>
|
|
248
|
+
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
|
249
|
+
<path stroke-linecap="round" d="M6 6l12 12M18 6L6 18" />
|
|
250
|
+
</svg>
|
|
251
|
+
</IconButton>
|
|
252
|
+
</span>
|
|
253
|
+
{/if}
|
|
254
|
+
{#if name || required}
|
|
255
|
+
<!-- Form value + native required validation (hidden inputs skip both). -->
|
|
256
|
+
<input
|
|
257
|
+
class="jatui-date-picker__native"
|
|
258
|
+
type="text"
|
|
259
|
+
tabindex="-1"
|
|
260
|
+
aria-hidden="true"
|
|
261
|
+
{name}
|
|
262
|
+
value={value ?? ''}
|
|
263
|
+
{required}
|
|
264
|
+
{disabled}
|
|
265
|
+
onfocus={() => triggerEl?.focus()}
|
|
266
|
+
/>
|
|
267
|
+
{/if}
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
{#if error}
|
|
271
|
+
<div class="label"><span id="{id}-error" class="text-[0.8125rem] text-error">{error}</span></div>
|
|
272
|
+
{:else if helpText}
|
|
273
|
+
<div class="label"><span id="{id}-help" class="text-[0.8125rem] text-base-content/55">{helpText}</span></div>
|
|
274
|
+
{/if}
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
{#if open}
|
|
278
|
+
<div
|
|
279
|
+
bind:this={popEl}
|
|
280
|
+
id={popId}
|
|
281
|
+
role="dialog"
|
|
282
|
+
aria-label={label ? `Choose ${label.toLowerCase()}` : 'Choose date'}
|
|
283
|
+
class="jatui-date-picker__pop bg-base-100 rounded-box border border-base-300"
|
|
284
|
+
style="z-index: {zIndex}; {calendarAccentStyle(accentColor)}"
|
|
285
|
+
data-calendar-root
|
|
286
|
+
use:floating={{ anchor: triggerEl, placement, offset: 6, onDismiss: close }}
|
|
287
|
+
>
|
|
288
|
+
{#if typed}
|
|
289
|
+
<div class="jatui-date-picker__typed">
|
|
290
|
+
<input
|
|
291
|
+
type="text"
|
|
292
|
+
inputmode="numeric"
|
|
293
|
+
autocomplete="off"
|
|
294
|
+
dir="ltr"
|
|
295
|
+
class="input input-sm w-full font-mono"
|
|
296
|
+
aria-label="Type a date, {datePlaceholder(locale)}"
|
|
297
|
+
placeholder={datePlaceholder(locale)}
|
|
298
|
+
bind:value={typedText}
|
|
299
|
+
onkeydown={handleTypedKeydown}
|
|
300
|
+
onblur={() => commitTyped()}
|
|
301
|
+
/>
|
|
302
|
+
<p class="jatui-date-picker__msg" role="status" aria-live="polite">{typedMessage}</p>
|
|
303
|
+
</div>
|
|
304
|
+
{/if}
|
|
305
|
+
|
|
306
|
+
<CalendarHeader
|
|
307
|
+
label={formatMonthYear(cal.viewMonth, locale)}
|
|
308
|
+
onPrev={() => cal.shift(-1)}
|
|
309
|
+
onNext={() => cal.shift(1)}
|
|
310
|
+
canPrev={cal.canPrev}
|
|
311
|
+
canNext={cal.canNext}
|
|
312
|
+
size="sm"
|
|
313
|
+
/>
|
|
314
|
+
<MonthGrid
|
|
315
|
+
month={cal.viewMonth}
|
|
316
|
+
focusedDate={cal.focusedDate}
|
|
317
|
+
weekStart={firstDay}
|
|
318
|
+
{locale}
|
|
319
|
+
selected={pending}
|
|
320
|
+
{isDisabled}
|
|
321
|
+
min={minDay}
|
|
322
|
+
max={maxDay}
|
|
323
|
+
fixedWeeks
|
|
324
|
+
size="sm"
|
|
325
|
+
onSelect={choose}
|
|
326
|
+
onFocusDate={cal.focus}
|
|
327
|
+
/>
|
|
328
|
+
|
|
329
|
+
{#if showToday || commit === 'apply'}
|
|
330
|
+
<div class="jatui-date-picker__footer">
|
|
331
|
+
{#if showToday}
|
|
332
|
+
<button type="button" class="btn btn-ghost btn-xs" disabled={!todayEnabled} onclick={() => choose(today)}>Today</button>
|
|
333
|
+
{/if}
|
|
334
|
+
{#if commit === 'apply'}
|
|
335
|
+
<span class="jatui-date-picker__actions">
|
|
336
|
+
<button type="button" class="btn btn-ghost btn-sm" onclick={close}>Cancel</button>
|
|
337
|
+
<button type="button" class="btn btn-primary btn-sm" onclick={apply}>Apply</button>
|
|
338
|
+
</span>
|
|
339
|
+
{/if}
|
|
340
|
+
</div>
|
|
341
|
+
{/if}
|
|
342
|
+
</div>
|
|
343
|
+
{/if}
|
|
344
|
+
|
|
345
|
+
<style>
|
|
346
|
+
.jatui-date-picker {
|
|
347
|
+
position: relative;
|
|
348
|
+
}
|
|
349
|
+
.jatui-date-picker__field {
|
|
350
|
+
position: relative;
|
|
351
|
+
display: flex;
|
|
352
|
+
align-items: center;
|
|
353
|
+
}
|
|
354
|
+
.jatui-date-picker__trigger {
|
|
355
|
+
display: flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
gap: 0.5rem;
|
|
358
|
+
width: 100%;
|
|
359
|
+
text-align: start;
|
|
360
|
+
cursor: pointer;
|
|
361
|
+
padding-inline-end: 2.25rem;
|
|
362
|
+
}
|
|
363
|
+
.jatui-date-picker__icon {
|
|
364
|
+
flex-shrink: 0;
|
|
365
|
+
color: color-mix(in oklab, var(--color-base-content) 55%, transparent);
|
|
366
|
+
}
|
|
367
|
+
.jatui-date-picker__value {
|
|
368
|
+
flex: 1;
|
|
369
|
+
min-width: 0;
|
|
370
|
+
overflow: hidden;
|
|
371
|
+
text-overflow: ellipsis;
|
|
372
|
+
white-space: nowrap;
|
|
373
|
+
font-variant-numeric: tabular-nums;
|
|
374
|
+
}
|
|
375
|
+
.jatui-date-picker__value.is-placeholder {
|
|
376
|
+
color: color-mix(in oklab, var(--color-base-content) 45%, transparent);
|
|
377
|
+
}
|
|
378
|
+
.jatui-date-picker__clear {
|
|
379
|
+
position: absolute;
|
|
380
|
+
inset-inline-end: 0.375rem;
|
|
381
|
+
}
|
|
382
|
+
.jatui-date-picker__native {
|
|
383
|
+
position: absolute;
|
|
384
|
+
inset: 0;
|
|
385
|
+
opacity: 0;
|
|
386
|
+
pointer-events: none;
|
|
387
|
+
}
|
|
388
|
+
.jatui-date-picker__pop {
|
|
389
|
+
width: max-content;
|
|
390
|
+
min-width: 17rem;
|
|
391
|
+
padding: 0.75rem;
|
|
392
|
+
}
|
|
393
|
+
.jatui-date-picker__typed {
|
|
394
|
+
margin-block-end: 0.5rem;
|
|
395
|
+
}
|
|
396
|
+
.jatui-date-picker__msg {
|
|
397
|
+
margin: 0.25rem 0 0;
|
|
398
|
+
min-height: 0;
|
|
399
|
+
font-size: 0.75rem;
|
|
400
|
+
color: var(--color-error);
|
|
401
|
+
}
|
|
402
|
+
.jatui-date-picker__msg:empty {
|
|
403
|
+
margin: 0;
|
|
404
|
+
}
|
|
405
|
+
.jatui-date-picker__footer {
|
|
406
|
+
display: flex;
|
|
407
|
+
align-items: center;
|
|
408
|
+
justify-content: space-between;
|
|
409
|
+
gap: 0.5rem;
|
|
410
|
+
margin-block-start: 0.5rem;
|
|
411
|
+
padding-block-start: 0.5rem;
|
|
412
|
+
border-block-start: 1px solid var(--jatui-separator, var(--color-base-300));
|
|
413
|
+
}
|
|
414
|
+
.jatui-date-picker__actions {
|
|
415
|
+
display: inline-flex;
|
|
416
|
+
gap: 0.375rem;
|
|
417
|
+
margin-inline-start: auto;
|
|
418
|
+
}
|
|
419
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Placement } from '../actions/floating';
|
|
2
|
+
import { type Weekday } from './calendar/calendarGrid';
|
|
3
|
+
type Size = 'sm' | 'md' | 'lg';
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
/** `YYYY-MM-DD` (local calendar day) or null. */
|
|
6
|
+
value?: string | null;
|
|
7
|
+
/** Popover open state (bindable). */
|
|
8
|
+
open?: boolean;
|
|
9
|
+
/** Fires on every committed change, with the parsed local-midnight Date. */
|
|
10
|
+
onChange?: (value: string | null, date: Date | null) => void;
|
|
11
|
+
label?: string;
|
|
12
|
+
id?: string;
|
|
13
|
+
/** Posts `value` with the enclosing form (a native date input's `name`). */
|
|
14
|
+
name?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
min?: string | Date | null;
|
|
17
|
+
max?: string | Date | null;
|
|
18
|
+
isDateEnabled?: (date: Date) => boolean;
|
|
19
|
+
weekdaysOnly?: boolean;
|
|
20
|
+
/** 0 = Sunday … 6 = Saturday, or `'locale'` (default). */
|
|
21
|
+
weekStart?: Weekday | 'locale';
|
|
22
|
+
locale?: string;
|
|
23
|
+
/** Intl options for the trigger label. */
|
|
24
|
+
format?: Intl.DateTimeFormatOptions;
|
|
25
|
+
/** `instant`: a click commits and closes. `apply`: pick, then Apply / Cancel. */
|
|
26
|
+
commit?: 'instant' | 'apply';
|
|
27
|
+
/** Show the typed-entry field in the popover. */
|
|
28
|
+
typed?: boolean;
|
|
29
|
+
clearable?: boolean;
|
|
30
|
+
showToday?: boolean;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
required?: boolean;
|
|
33
|
+
error?: string;
|
|
34
|
+
helpText?: string;
|
|
35
|
+
size?: Size;
|
|
36
|
+
/** primary | secondary | accent | info | success | warning | error | neutral */
|
|
37
|
+
accentColor?: string;
|
|
38
|
+
placement?: Placement;
|
|
39
|
+
zIndex?: number;
|
|
40
|
+
class?: string;
|
|
41
|
+
};
|
|
42
|
+
declare const DatePicker: import("svelte").Component<$$ComponentProps, {}, "value" | "open">;
|
|
43
|
+
type DatePicker = ReturnType<typeof DatePicker>;
|
|
44
|
+
export default DatePicker;
|