@nepdatejs/vanilla 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +124 -2
- package/dist/auto-define.cjs +11 -0
- package/dist/auto-define.cjs.map +1 -0
- package/dist/auto-define.d.cts +2 -0
- package/dist/auto-define.d.ts +2 -0
- package/dist/auto-define.js +9 -0
- package/dist/auto-define.js.map +1 -0
- package/dist/calendar-BAcO-jYq.js +142 -0
- package/dist/calendar-BAcO-jYq.js.map +1 -0
- package/dist/calendar-BNdN8qJv.d.ts +87 -0
- package/dist/calendar-C1LZI7XN.cjs +159 -0
- package/dist/calendar-C1LZI7XN.cjs.map +1 -0
- package/dist/calendar-QWPX0IfD.d.cts +87 -0
- package/dist/calendar.cjs +7 -0
- package/dist/calendar.d.cts +2 -0
- package/dist/calendar.d.ts +2 -0
- package/dist/calendar.js +3 -0
- package/dist/date-picker-BidCGOz0.d.cts +74 -0
- package/dist/date-picker-CQoabjlj.cjs +600 -0
- package/dist/date-picker-CQoabjlj.cjs.map +1 -0
- package/dist/date-picker-DyvpYe29.d.ts +74 -0
- package/dist/date-picker-ucoEFnMW.js +577 -0
- package/dist/date-picker-ucoEFnMW.js.map +1 -0
- package/dist/date-picker.cjs +6 -0
- package/dist/date-picker.d.cts +3 -0
- package/dist/date-picker.d.ts +3 -0
- package/dist/date-picker.js +1 -0
- package/dist/date-range-picker-BQKcZeqG.cjs +489 -0
- package/dist/date-range-picker-BQKcZeqG.cjs.map +1 -0
- package/dist/date-range-picker-D3eNvlgv.d.ts +98 -0
- package/dist/date-range-picker-DAkCzVgT.js +466 -0
- package/dist/date-range-picker-DAkCzVgT.js.map +1 -0
- package/dist/date-range-picker-SIl0vhUV.d.cts +98 -0
- package/dist/date-range-picker.cjs +6 -0
- package/dist/date-range-picker.d.cts +2 -0
- package/dist/date-range-picker.d.ts +2 -0
- package/dist/date-range-picker.js +1 -0
- package/dist/date-time-picker-BqweOP2u.js +487 -0
- package/dist/date-time-picker-BqweOP2u.js.map +1 -0
- package/dist/date-time-picker-Bxfn-a9T.cjs +510 -0
- package/dist/date-time-picker-Bxfn-a9T.cjs.map +1 -0
- package/dist/date-time-picker-BzSyQxrf.d.cts +92 -0
- package/dist/date-time-picker-DzDpzLMZ.d.ts +92 -0
- package/dist/date-time-picker.cjs +6 -0
- package/dist/date-time-picker.d.cts +2 -0
- package/dist/date-time-picker.d.ts +2 -0
- package/dist/date-time-picker.js +1 -0
- package/dist/define-7natoEH4.js +18 -0
- package/dist/define-7natoEH4.js.map +1 -0
- package/dist/define-B8NUA3yj.d.cts +16 -0
- package/dist/define-B8NUA3yj.d.ts +16 -0
- package/dist/define-DTTdLfIM.cjs +23 -0
- package/dist/define-DTTdLfIM.cjs.map +1 -0
- package/dist/element-utils-BVye8UQq.d.cts +82 -0
- package/dist/element-utils-C-r5gPlk.d.ts +82 -0
- package/dist/index.cjs +30 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/multi-date-picker-B2mQbjZM.d.ts +105 -0
- package/dist/multi-date-picker-BMEYUPBa.cjs +462 -0
- package/dist/multi-date-picker-BMEYUPBa.cjs.map +1 -0
- package/dist/multi-date-picker-BUNf5zyJ.d.cts +105 -0
- package/dist/multi-date-picker-XCg8Y0sF.js +439 -0
- package/dist/multi-date-picker-XCg8Y0sF.js.map +1 -0
- package/dist/multi-date-picker.cjs +6 -0
- package/dist/multi-date-picker.d.cts +2 -0
- package/dist/multi-date-picker.d.ts +2 -0
- package/dist/multi-date-picker.js +1 -0
- package/dist/nepdate-picker.global.js +3 -0
- package/dist/nepdate-picker.global.js.map +1 -0
- package/dist/preset-list-CASwnwmS.js +45 -0
- package/dist/preset-list-CASwnwmS.js.map +1 -0
- package/dist/preset-list-Cs8H12Wp.cjs +50 -0
- package/dist/preset-list-Cs8H12Wp.cjs.map +1 -0
- package/dist/registry-3qzdVB7H.cjs +591 -0
- package/dist/registry-3qzdVB7H.cjs.map +1 -0
- package/dist/registry-BvkGnkvV.js +466 -0
- package/dist/registry-BvkGnkvV.js.map +1 -0
- package/package.json +162 -3
- package/src/auto-define.ts +6 -0
- package/src/calendar-element.ts +129 -0
- package/src/calendar-view.ts +406 -0
- package/src/calendar.ts +45 -0
- package/src/date-picker-element.ts +249 -0
- package/src/date-picker.ts +91 -0
- package/src/date-range-picker-element.ts +201 -0
- package/src/date-range-picker.ts +20 -0
- package/src/date-time-picker-element.ts +191 -0
- package/src/date-time-picker.ts +20 -0
- package/src/datetime-view.ts +459 -0
- package/src/define.ts +16 -0
- package/src/dom.ts +109 -0
- package/src/element-utils.ts +86 -0
- package/src/global.ts +7 -0
- package/src/index.ts +15 -0
- package/src/multi-date-picker-element.ts +187 -0
- package/src/multi-date-picker.ts +53 -0
- package/src/multi-view.ts +345 -0
- package/src/picker-view.ts +448 -0
- package/src/preset-list.ts +51 -0
- package/src/range-view.ts +393 -0
- package/src/registry.ts +27 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { i as DatePickerViewOptions, n as RichProps, r as DatePickerView, t as Base } from "./element-utils-C-r5gPlk.js";
|
|
2
|
+
import { DatePickerState, SinglePreset } from "@nepdatejs/datepicker";
|
|
3
|
+
//#region src/date-picker-element.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* <nep-date-picker name="dob" min="2020-01-01"></nep-date-picker>
|
|
6
|
+
*
|
|
7
|
+
* A form-associated BS/AD date field: the form receives the AD "YYYY-MM-DD"
|
|
8
|
+
* value under `name`. Fires `change` with { value, ad, bs }, plus `nep-open`,
|
|
9
|
+
* `nep-close` and `nep-calendar-change`.
|
|
10
|
+
*/
|
|
11
|
+
declare class NepDatePickerElement extends Base {
|
|
12
|
+
static readonly formAssociated = true;
|
|
13
|
+
static readonly observedAttributes: readonly string[];
|
|
14
|
+
/** The view, once connected. */
|
|
15
|
+
view: DatePickerView | null;
|
|
16
|
+
private readonly internals;
|
|
17
|
+
private rich;
|
|
18
|
+
private customPresets;
|
|
19
|
+
private unsubscribe;
|
|
20
|
+
constructor();
|
|
21
|
+
get value(): string;
|
|
22
|
+
set value(next: string);
|
|
23
|
+
get holidays(): RichProps["holidays"];
|
|
24
|
+
set holidays(next: RichProps["holidays"]);
|
|
25
|
+
get events(): RichProps["events"];
|
|
26
|
+
set events(next: RichProps["events"]);
|
|
27
|
+
get isDateDisabled(): RichProps["isDateDisabled"];
|
|
28
|
+
set isDateDisabled(next: RichProps["isDateDisabled"]);
|
|
29
|
+
/** Shortcuts, including custom { id, label, resolve } ones. Overrides the presets attribute. */
|
|
30
|
+
get presets(): readonly SinglePreset[] | undefined;
|
|
31
|
+
set presets(next: readonly SinglePreset[] | undefined);
|
|
32
|
+
get form(): HTMLFormElement | null;
|
|
33
|
+
get validity(): ValidityState | undefined;
|
|
34
|
+
get validationMessage(): string;
|
|
35
|
+
checkValidity(): boolean;
|
|
36
|
+
reportValidity(): boolean;
|
|
37
|
+
connectedCallback(): void;
|
|
38
|
+
disconnectedCallback(): void;
|
|
39
|
+
attributeChangedCallback(name: string, previous: string | null, next: string | null): void;
|
|
40
|
+
formResetCallback(): void;
|
|
41
|
+
formDisabledCallback(disabled: boolean): void;
|
|
42
|
+
formStateRestoreCallback(state: string | File | FormData | null): void;
|
|
43
|
+
override focus(options?: FocusOptions): void;
|
|
44
|
+
open(): void;
|
|
45
|
+
close(): void;
|
|
46
|
+
private setRich;
|
|
47
|
+
private readOptions;
|
|
48
|
+
private syncForm;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/date-picker.d.ts
|
|
52
|
+
/** Register <nep-date-picker> (skipped if already defined). */
|
|
53
|
+
declare function defineDatePicker(registry?: CustomElementRegistry): void;
|
|
54
|
+
interface DatePickerHandle {
|
|
55
|
+
readonly view: DatePickerView;
|
|
56
|
+
getValue(): string;
|
|
57
|
+
getState(): DatePickerState;
|
|
58
|
+
setValue(value: string): void;
|
|
59
|
+
setOptions(changes: Partial<DatePickerViewOptions>): void;
|
|
60
|
+
open(): void;
|
|
61
|
+
close(): void;
|
|
62
|
+
destroy(): void;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Mount a date picker without custom elements.
|
|
66
|
+
*
|
|
67
|
+
* - Given a container, renders the field into it.
|
|
68
|
+
* - Given an <input>, hides it and keeps its value in step with the picker
|
|
69
|
+
* (AD "YYYY-MM-DD"), so existing forms and server code keep working.
|
|
70
|
+
*/
|
|
71
|
+
declare function createDatePicker$1(target: HTMLElement, options?: DatePickerViewOptions): DatePickerHandle;
|
|
72
|
+
//#endregion
|
|
73
|
+
export { NepDatePickerElement as i, createDatePicker$1 as n, defineDatePicker as r, DatePickerHandle as t };
|
|
74
|
+
//# sourceMappingURL=date-picker-DyvpYe29.d.ts.map
|
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { _ as icon, a as calendarAttr, b as setText, c as onUnlessFalse, d as str, f as swallowInnerChange, g as el, h as CalendarView, i as bool, l as panelLayout, m as weekday, n as defineElement, p as theme, r as Base, s as isoOf, t as ELEMENT_NAMES, u as presetIds, v as setAttrs, x as uid, y as setPopupMode } from "./registry-BvkGnkvV.js";
|
|
2
|
+
import { t as PresetList } from "./preset-list-CASwnwmS.js";
|
|
3
|
+
import { fromIsoDate, getLocale } from "@nepdatejs/core";
|
|
4
|
+
import { createDatePicker } from "@nepdatejs/datepicker";
|
|
5
|
+
import { onBackdropPointer, onEscape, onOutsidePointer, restoreFocus, trackPosition } from "@nepdatejs/dom";
|
|
6
|
+
//#region src/picker-view.ts
|
|
7
|
+
const VIEW_KEYS = /* @__PURE__ */ new Set([
|
|
8
|
+
"name",
|
|
9
|
+
"hiddenInput",
|
|
10
|
+
"id",
|
|
11
|
+
"placeholder",
|
|
12
|
+
"required",
|
|
13
|
+
"disabled",
|
|
14
|
+
"clearable",
|
|
15
|
+
"showEquivalent",
|
|
16
|
+
"theme",
|
|
17
|
+
"panelLayout",
|
|
18
|
+
"persistCalendar",
|
|
19
|
+
"ariaLabel",
|
|
20
|
+
"onOpenChange",
|
|
21
|
+
"onInput"
|
|
22
|
+
]);
|
|
23
|
+
/**
|
|
24
|
+
* The date picker field and panel, rendered with the @nepdatejs/styles markup
|
|
25
|
+
* into `host`. Used by <nep-date-picker> and by createDatePicker().
|
|
26
|
+
*/
|
|
27
|
+
var DatePickerView = class {
|
|
28
|
+
constructor(host, options = {}) {
|
|
29
|
+
this.closePanel = null;
|
|
30
|
+
this.wasOpen = false;
|
|
31
|
+
this.onTextInput = () => {
|
|
32
|
+
this.store.actions.type(this.input.value);
|
|
33
|
+
this.options.onInput?.(this.input.value);
|
|
34
|
+
};
|
|
35
|
+
this.onInputKeyDown = (event) => {
|
|
36
|
+
if (event.key === "ArrowDown" && (event.altKey || this.input.value === "")) {
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
this.open();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
this.onClick = (event) => {
|
|
42
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
43
|
+
if (!target || this.calendarView.element.contains(target)) return;
|
|
44
|
+
const calendar = target.closest("[data-calendar]")?.dataset["calendar"];
|
|
45
|
+
if (calendar === "BS" || calendar === "AD") {
|
|
46
|
+
this.store.actions.switchCalendar(calendar);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
switch (target.closest("[data-action]")?.dataset["action"]) {
|
|
50
|
+
case "clear":
|
|
51
|
+
this.store.actions.clear();
|
|
52
|
+
this.input.focus();
|
|
53
|
+
break;
|
|
54
|
+
case "switch":
|
|
55
|
+
this.store.actions.switchCalendar(this.store.getState().calendar === "BS" ? "AD" : "BS");
|
|
56
|
+
break;
|
|
57
|
+
case "toggle":
|
|
58
|
+
if (this.store.getState().open) this.close();
|
|
59
|
+
else this.open();
|
|
60
|
+
break;
|
|
61
|
+
case "today": if (this.store.actions.selectToday()) restoreFocus(this.input);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
this.options = { ...options };
|
|
65
|
+
this.store = createDatePicker({
|
|
66
|
+
...storeOptions(options),
|
|
67
|
+
onChange: (value, detail) => {
|
|
68
|
+
this.options.onChange?.(value, detail);
|
|
69
|
+
},
|
|
70
|
+
onCalendarChange: (calendar) => {
|
|
71
|
+
this.remember(calendar);
|
|
72
|
+
this.options.onCalendarChange?.(calendar);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const inputId = options.id ?? uid("ndp-input");
|
|
76
|
+
const panelId = `${inputId}-panel`;
|
|
77
|
+
this.input = el("input", {
|
|
78
|
+
class: "ndp-input__control",
|
|
79
|
+
id: inputId,
|
|
80
|
+
type: "text",
|
|
81
|
+
inputmode: "numeric",
|
|
82
|
+
autocomplete: "off",
|
|
83
|
+
spellcheck: "false",
|
|
84
|
+
"aria-controls": panelId
|
|
85
|
+
});
|
|
86
|
+
this.clearButton = el("button", {
|
|
87
|
+
type: "button",
|
|
88
|
+
class: "ndp-icon-button",
|
|
89
|
+
"data-action": "clear"
|
|
90
|
+
}, [icon("close")]);
|
|
91
|
+
this.switchButton = el("button", {
|
|
92
|
+
type: "button",
|
|
93
|
+
class: "ndp-input__switch",
|
|
94
|
+
"data-action": "switch"
|
|
95
|
+
});
|
|
96
|
+
this.toggleButton = el("button", {
|
|
97
|
+
type: "button",
|
|
98
|
+
class: "ndp-icon-button",
|
|
99
|
+
"data-action": "toggle"
|
|
100
|
+
}, [icon("calendar")]);
|
|
101
|
+
this.box = el("div", { class: "ndp-input" }, [this.input, el("span", { class: "ndp-input__actions" }, [
|
|
102
|
+
this.clearButton,
|
|
103
|
+
this.switchButton,
|
|
104
|
+
this.toggleButton
|
|
105
|
+
])]);
|
|
106
|
+
this.hint = el("p", {
|
|
107
|
+
class: "ndp-hint",
|
|
108
|
+
id: `${inputId}-hint`,
|
|
109
|
+
"aria-live": "polite",
|
|
110
|
+
hidden: true
|
|
111
|
+
});
|
|
112
|
+
this.hidden = el("input", { type: "hidden" });
|
|
113
|
+
this.segment = el("div", {
|
|
114
|
+
class: "ndp-segment",
|
|
115
|
+
role: "group"
|
|
116
|
+
}, [el("button", {
|
|
117
|
+
type: "button",
|
|
118
|
+
class: "ndp-segment__item",
|
|
119
|
+
"data-calendar": "BS"
|
|
120
|
+
}), el("button", {
|
|
121
|
+
type: "button",
|
|
122
|
+
class: "ndp-segment__item",
|
|
123
|
+
"data-calendar": "AD"
|
|
124
|
+
})]);
|
|
125
|
+
this.todayButton = el("button", {
|
|
126
|
+
type: "button",
|
|
127
|
+
class: "ndp-button",
|
|
128
|
+
"data-action": "today"
|
|
129
|
+
});
|
|
130
|
+
const calendarRoot = el("div", { class: "ndp-panel__calendar" });
|
|
131
|
+
this.presetList = new PresetList((id) => {
|
|
132
|
+
if (this.store.actions.applyPreset(id) && !this.store.getState().open) restoreFocus(this.input);
|
|
133
|
+
});
|
|
134
|
+
this.panel = el("div", {
|
|
135
|
+
class: "ndp-panel",
|
|
136
|
+
id: panelId,
|
|
137
|
+
hidden: true
|
|
138
|
+
}, [el("div", { class: "ndp-panel__body" }, [this.presetList.element, calendarRoot]), el("div", { class: "ndp-panel__footer" }, [this.segment, this.todayButton])]);
|
|
139
|
+
this.field = el("div", { class: "ndp-field" }, [
|
|
140
|
+
this.box,
|
|
141
|
+
this.hint,
|
|
142
|
+
this.panel,
|
|
143
|
+
this.hidden
|
|
144
|
+
]);
|
|
145
|
+
host.append(this.field);
|
|
146
|
+
this.calendarView = new CalendarView(calendarRoot, this.store.calendar, {
|
|
147
|
+
locale: () => this.options.locale,
|
|
148
|
+
onDayActivate: (date) => {
|
|
149
|
+
if (this.store.actions.select(date) && !this.store.getState().open) restoreFocus(this.input);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
this.input.addEventListener("input", this.onTextInput);
|
|
153
|
+
this.input.addEventListener("blur", () => {
|
|
154
|
+
this.store.actions.blur();
|
|
155
|
+
});
|
|
156
|
+
this.input.addEventListener("keydown", this.onInputKeyDown);
|
|
157
|
+
this.field.addEventListener("click", this.onClick);
|
|
158
|
+
this.unsubscribe = this.store.subscribe(() => {
|
|
159
|
+
this.render();
|
|
160
|
+
});
|
|
161
|
+
this.restoreCalendar();
|
|
162
|
+
this.render();
|
|
163
|
+
}
|
|
164
|
+
getState() {
|
|
165
|
+
return this.store.getState();
|
|
166
|
+
}
|
|
167
|
+
/** Change view or store options. Unknown keys are ignored. */
|
|
168
|
+
setOptions(changes) {
|
|
169
|
+
this.options = {
|
|
170
|
+
...this.options,
|
|
171
|
+
...changes
|
|
172
|
+
};
|
|
173
|
+
const forStore = storeOptions(changes);
|
|
174
|
+
if (Object.keys(forStore).length > 0) this.store.setOptions(forStore);
|
|
175
|
+
else this.render();
|
|
176
|
+
}
|
|
177
|
+
open() {
|
|
178
|
+
if (!this.options.disabled) this.store.actions.open();
|
|
179
|
+
}
|
|
180
|
+
close() {
|
|
181
|
+
this.store.actions.close();
|
|
182
|
+
}
|
|
183
|
+
destroy() {
|
|
184
|
+
this.closePanel?.();
|
|
185
|
+
this.unsubscribe();
|
|
186
|
+
this.calendarView.destroy();
|
|
187
|
+
this.field.remove();
|
|
188
|
+
}
|
|
189
|
+
render() {
|
|
190
|
+
const state = this.store.getState();
|
|
191
|
+
const locale = getLocale(this.options.locale);
|
|
192
|
+
const disabled = this.options.disabled ?? false;
|
|
193
|
+
const hintText = state.error?.message ?? (this.options.showEquivalent ?? true ? state.equivalentText : null);
|
|
194
|
+
if (this.input.value !== state.text) this.input.value = state.text;
|
|
195
|
+
this.input.setCustomValidity(state.error?.message ?? "");
|
|
196
|
+
setAttrs(this.input, {
|
|
197
|
+
placeholder: this.options.placeholder ?? state.placeholder,
|
|
198
|
+
disabled,
|
|
199
|
+
required: this.options.required ?? false,
|
|
200
|
+
"aria-label": this.options.ariaLabel ?? null,
|
|
201
|
+
"aria-invalid": state.error ? "true" : null,
|
|
202
|
+
"aria-describedby": hintText ? this.hint.id : null
|
|
203
|
+
});
|
|
204
|
+
setAttrs(this.box, {
|
|
205
|
+
"data-invalid": state.error !== null,
|
|
206
|
+
"data-disabled": disabled
|
|
207
|
+
});
|
|
208
|
+
setAttrs(this.field, { "data-ndp-theme": this.options.theme ?? null });
|
|
209
|
+
setAttrs(this.panel, {
|
|
210
|
+
"data-ndp-theme": this.options.theme ?? null,
|
|
211
|
+
"aria-label": this.options.ariaLabel ? `${this.options.ariaLabel}: ${locale.labels.calendar}` : locale.labels.chooseDate
|
|
212
|
+
});
|
|
213
|
+
this.clearButton.hidden = !(this.options.clearable ?? true) || state.text === "" || disabled;
|
|
214
|
+
setAttrs(this.clearButton, { "aria-label": locale.labels.clear });
|
|
215
|
+
this.switchButton.hidden = !state.canSwitchCalendar;
|
|
216
|
+
setText(this.switchButton, locale.calendarNames[state.calendar]);
|
|
217
|
+
const other = state.calendar === "BS" ? "AD" : "BS";
|
|
218
|
+
setAttrs(this.switchButton, {
|
|
219
|
+
disabled,
|
|
220
|
+
"aria-label": `${locale.labels.calendar}: ${locale.calendarNames[state.calendar]} → ${locale.calendarNames[other]}`
|
|
221
|
+
});
|
|
222
|
+
setAttrs(this.toggleButton, {
|
|
223
|
+
disabled,
|
|
224
|
+
"aria-label": locale.labels.openCalendar,
|
|
225
|
+
"aria-expanded": state.open ? "true" : "false"
|
|
226
|
+
});
|
|
227
|
+
this.hint.hidden = hintText === null;
|
|
228
|
+
setText(this.hint, hintText ?? "");
|
|
229
|
+
setAttrs(this.hint, { "data-error": state.error !== null });
|
|
230
|
+
this.segment.hidden = !state.canSwitchCalendar;
|
|
231
|
+
setAttrs(this.segment, { "aria-label": locale.labels.calendar });
|
|
232
|
+
for (const button of this.segment.querySelectorAll("button")) {
|
|
233
|
+
const calendar = button.dataset["calendar"];
|
|
234
|
+
setText(button, locale.calendarNames[calendar]);
|
|
235
|
+
setAttrs(button, { "aria-pressed": calendar === state.calendar ? "true" : "false" });
|
|
236
|
+
}
|
|
237
|
+
setText(this.todayButton, locale.labels.today);
|
|
238
|
+
this.presetList.render(state.presets, locale.labels.presets);
|
|
239
|
+
const name = this.options.hiddenInput === false ? void 0 : this.options.name;
|
|
240
|
+
setAttrs(this.hidden, {
|
|
241
|
+
name: name ?? null,
|
|
242
|
+
value: state.value
|
|
243
|
+
});
|
|
244
|
+
this.hidden.value = state.value;
|
|
245
|
+
this.hidden.disabled = name === void 0 || disabled;
|
|
246
|
+
setPopupMode(state, [this.input], this.toggleButton, this.panel);
|
|
247
|
+
this.syncPanel(state.open && !state.inline);
|
|
248
|
+
this.panel.hidden = !state.inline && !this.wasOpen;
|
|
249
|
+
this.panel.style.setProperty("--ndp-panel-width", state.inline ? `${String(this.panelWidth())}px` : null);
|
|
250
|
+
}
|
|
251
|
+
panelWidth() {
|
|
252
|
+
return this.store.getState().presets.length > 0 ? 492 : 320;
|
|
253
|
+
}
|
|
254
|
+
syncPanel(open) {
|
|
255
|
+
if (open === this.wasOpen) return;
|
|
256
|
+
this.wasOpen = open;
|
|
257
|
+
this.options.onOpenChange?.(open);
|
|
258
|
+
if (open) {
|
|
259
|
+
this.panel.hidden = false;
|
|
260
|
+
const stopTracking = trackPosition(this.box, this.panel, {
|
|
261
|
+
width: this.panelWidth(),
|
|
262
|
+
layout: this.options.panelLayout
|
|
263
|
+
});
|
|
264
|
+
const stopOutside = onOutsidePointer([this.field, this.panel], () => {
|
|
265
|
+
this.store.actions.close();
|
|
266
|
+
});
|
|
267
|
+
const stopBackdrop = onBackdropPointer(this.panel, () => {
|
|
268
|
+
this.store.actions.close();
|
|
269
|
+
});
|
|
270
|
+
const stopEscape = onEscape(() => {
|
|
271
|
+
this.store.actions.close();
|
|
272
|
+
restoreFocus(this.input);
|
|
273
|
+
});
|
|
274
|
+
this.closePanel = () => {
|
|
275
|
+
stopTracking();
|
|
276
|
+
stopOutside();
|
|
277
|
+
stopBackdrop();
|
|
278
|
+
stopEscape();
|
|
279
|
+
this.panel.hidden = true;
|
|
280
|
+
};
|
|
281
|
+
this.calendarView.focusGrid();
|
|
282
|
+
} else {
|
|
283
|
+
this.closePanel?.();
|
|
284
|
+
this.closePanel = null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
remember(calendar) {
|
|
288
|
+
const key = this.options.persistCalendar;
|
|
289
|
+
if (!key) return;
|
|
290
|
+
try {
|
|
291
|
+
window.localStorage.setItem(key, calendar);
|
|
292
|
+
} catch {}
|
|
293
|
+
}
|
|
294
|
+
restoreCalendar() {
|
|
295
|
+
const key = this.options.persistCalendar;
|
|
296
|
+
if (!key) return;
|
|
297
|
+
const stored = readStorage(key);
|
|
298
|
+
if (stored === "BS" || stored === "AD") this.store.actions.switchCalendar(stored);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
/** Only the keys the picker store understands, minus the view's own callbacks. */
|
|
302
|
+
function storeOptions(options) {
|
|
303
|
+
const out = {};
|
|
304
|
+
for (const [key, value] of Object.entries(options)) if (!VIEW_KEYS.has(key) && key !== "onChange" && key !== "onCalendarChange") out[key] = value;
|
|
305
|
+
return out;
|
|
306
|
+
}
|
|
307
|
+
function readStorage(key) {
|
|
308
|
+
try {
|
|
309
|
+
return window.localStorage.getItem(key);
|
|
310
|
+
} catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region src/date-picker-element.ts
|
|
316
|
+
/**
|
|
317
|
+
* <nep-date-picker name="dob" min="2020-01-01"></nep-date-picker>
|
|
318
|
+
*
|
|
319
|
+
* A form-associated BS/AD date field: the form receives the AD "YYYY-MM-DD"
|
|
320
|
+
* value under `name`. Fires `change` with { value, ad, bs }, plus `nep-open`,
|
|
321
|
+
* `nep-close` and `nep-calendar-change`.
|
|
322
|
+
*/
|
|
323
|
+
var NepDatePickerElement = class extends Base {
|
|
324
|
+
constructor() {
|
|
325
|
+
super();
|
|
326
|
+
this.view = null;
|
|
327
|
+
this.rich = {};
|
|
328
|
+
this.unsubscribe = null;
|
|
329
|
+
this.internals = typeof this.attachInternals === "function" ? this.attachInternals() : null;
|
|
330
|
+
swallowInnerChange(this);
|
|
331
|
+
}
|
|
332
|
+
get value() {
|
|
333
|
+
return this.view?.getState().value ?? isoOf(fromIsoDate(this.getAttribute("value")));
|
|
334
|
+
}
|
|
335
|
+
set value(next) {
|
|
336
|
+
this.view?.store.actions.setValue(next);
|
|
337
|
+
}
|
|
338
|
+
get holidays() {
|
|
339
|
+
return this.rich.holidays;
|
|
340
|
+
}
|
|
341
|
+
set holidays(next) {
|
|
342
|
+
this.setRich({ holidays: next });
|
|
343
|
+
}
|
|
344
|
+
get events() {
|
|
345
|
+
return this.rich.events;
|
|
346
|
+
}
|
|
347
|
+
set events(next) {
|
|
348
|
+
this.setRich({ events: next });
|
|
349
|
+
}
|
|
350
|
+
get isDateDisabled() {
|
|
351
|
+
return this.rich.isDateDisabled;
|
|
352
|
+
}
|
|
353
|
+
set isDateDisabled(next) {
|
|
354
|
+
this.setRich({ isDateDisabled: next });
|
|
355
|
+
}
|
|
356
|
+
/** Shortcuts, including custom { id, label, resolve } ones. Overrides the presets attribute. */
|
|
357
|
+
get presets() {
|
|
358
|
+
return this.customPresets ?? presetIds(this);
|
|
359
|
+
}
|
|
360
|
+
set presets(next) {
|
|
361
|
+
this.customPresets = next;
|
|
362
|
+
this.view?.setOptions({ presets: this.presets });
|
|
363
|
+
}
|
|
364
|
+
get form() {
|
|
365
|
+
return this.internals?.form ?? null;
|
|
366
|
+
}
|
|
367
|
+
get validity() {
|
|
368
|
+
return this.internals?.validity;
|
|
369
|
+
}
|
|
370
|
+
get validationMessage() {
|
|
371
|
+
return this.internals?.validationMessage ?? "";
|
|
372
|
+
}
|
|
373
|
+
checkValidity() {
|
|
374
|
+
return this.internals?.checkValidity() ?? true;
|
|
375
|
+
}
|
|
376
|
+
reportValidity() {
|
|
377
|
+
return this.internals?.reportValidity() ?? true;
|
|
378
|
+
}
|
|
379
|
+
connectedCallback() {
|
|
380
|
+
if (this.view) return;
|
|
381
|
+
const view = new DatePickerView(this, {
|
|
382
|
+
...this.readOptions(),
|
|
383
|
+
defaultValue: str(this, "value"),
|
|
384
|
+
onChange: (value, detail) => {
|
|
385
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
386
|
+
bubbles: true,
|
|
387
|
+
detail: {
|
|
388
|
+
value,
|
|
389
|
+
ad: detail?.ad ?? null,
|
|
390
|
+
bs: detail?.bs ?? null
|
|
391
|
+
}
|
|
392
|
+
}));
|
|
393
|
+
},
|
|
394
|
+
onCalendarChange: (calendar) => {
|
|
395
|
+
this.dispatchEvent(new CustomEvent("nep-calendar-change", {
|
|
396
|
+
bubbles: true,
|
|
397
|
+
detail: { calendar }
|
|
398
|
+
}));
|
|
399
|
+
},
|
|
400
|
+
onOpenChange: (open) => {
|
|
401
|
+
this.dispatchEvent(new CustomEvent(open ? "nep-open" : "nep-close", { bubbles: true }));
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
this.view = view;
|
|
405
|
+
this.unsubscribe = view.store.subscribe(() => {
|
|
406
|
+
this.syncForm();
|
|
407
|
+
});
|
|
408
|
+
this.syncForm();
|
|
409
|
+
}
|
|
410
|
+
disconnectedCallback() {
|
|
411
|
+
this.unsubscribe?.();
|
|
412
|
+
this.view?.destroy();
|
|
413
|
+
this.view = null;
|
|
414
|
+
}
|
|
415
|
+
attributeChangedCallback(name, previous, next) {
|
|
416
|
+
if (!this.view || previous === next) return;
|
|
417
|
+
if (name === "value") this.view.store.actions.setValue(next ?? "");
|
|
418
|
+
this.view.setOptions(this.readOptions());
|
|
419
|
+
this.syncForm();
|
|
420
|
+
}
|
|
421
|
+
formResetCallback() {
|
|
422
|
+
this.view?.store.actions.reset();
|
|
423
|
+
}
|
|
424
|
+
formDisabledCallback(disabled) {
|
|
425
|
+
this.view?.setOptions({ disabled: disabled || bool(this, "disabled") });
|
|
426
|
+
}
|
|
427
|
+
formStateRestoreCallback(state) {
|
|
428
|
+
if (typeof state === "string") this.view?.store.actions.setValue(state);
|
|
429
|
+
}
|
|
430
|
+
focus(options) {
|
|
431
|
+
this.view?.input.focus(options);
|
|
432
|
+
}
|
|
433
|
+
open() {
|
|
434
|
+
this.view?.open();
|
|
435
|
+
}
|
|
436
|
+
close() {
|
|
437
|
+
this.view?.close();
|
|
438
|
+
}
|
|
439
|
+
setRich(changes) {
|
|
440
|
+
this.rich = {
|
|
441
|
+
...this.rich,
|
|
442
|
+
...changes
|
|
443
|
+
};
|
|
444
|
+
this.view?.setOptions(changes);
|
|
445
|
+
}
|
|
446
|
+
readOptions() {
|
|
447
|
+
return {
|
|
448
|
+
...this.rich,
|
|
449
|
+
min: str(this, "min"),
|
|
450
|
+
max: str(this, "max"),
|
|
451
|
+
calendar: calendarAttr(this, "calendar"),
|
|
452
|
+
defaultCalendar: calendarAttr(this, "default-calendar"),
|
|
453
|
+
locale: str(this, "locale"),
|
|
454
|
+
name: str(this, "name"),
|
|
455
|
+
hiddenInput: this.internals === null,
|
|
456
|
+
placeholder: str(this, "placeholder"),
|
|
457
|
+
required: bool(this, "required"),
|
|
458
|
+
disabled: bool(this, "disabled"),
|
|
459
|
+
clearable: onUnlessFalse(this, "clearable"),
|
|
460
|
+
showEquivalent: onUnlessFalse(this, "show-equivalent"),
|
|
461
|
+
closeOnSelect: onUnlessFalse(this, "close-on-select"),
|
|
462
|
+
theme: theme(this),
|
|
463
|
+
panelLayout: panelLayout(this),
|
|
464
|
+
mask: onUnlessFalse(this, "mask"),
|
|
465
|
+
inline: this.hasAttribute("inline"),
|
|
466
|
+
persistCalendar: str(this, "persist-calendar"),
|
|
467
|
+
weekStartsOn: weekday(this, "week-starts-on"),
|
|
468
|
+
displayFormat: str(this, "display-format"),
|
|
469
|
+
ariaLabel: str(this, "label"),
|
|
470
|
+
id: str(this, "input-id"),
|
|
471
|
+
presets: this.presets
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
syncForm() {
|
|
475
|
+
const view = this.view;
|
|
476
|
+
if (!view || !this.internals) return;
|
|
477
|
+
const state = view.getState();
|
|
478
|
+
this.internals.setFormValue(state.value === "" ? null : state.value, state.value);
|
|
479
|
+
if (state.error) this.internals.setValidity({ customError: true }, state.error.message, view.input);
|
|
480
|
+
else if (bool(this, "required") && state.value === "") this.internals.setValidity({ valueMissing: true }, view.input.validationMessage || "Please choose a date.", view.input);
|
|
481
|
+
else this.internals.setValidity({});
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
NepDatePickerElement.formAssociated = true;
|
|
485
|
+
NepDatePickerElement.observedAttributes = [
|
|
486
|
+
"value",
|
|
487
|
+
"min",
|
|
488
|
+
"max",
|
|
489
|
+
"calendar",
|
|
490
|
+
"default-calendar",
|
|
491
|
+
"locale",
|
|
492
|
+
"name",
|
|
493
|
+
"placeholder",
|
|
494
|
+
"required",
|
|
495
|
+
"disabled",
|
|
496
|
+
"clearable",
|
|
497
|
+
"show-equivalent",
|
|
498
|
+
"theme",
|
|
499
|
+
"panel-layout",
|
|
500
|
+
"mask",
|
|
501
|
+
"inline",
|
|
502
|
+
"persist-calendar",
|
|
503
|
+
"week-starts-on",
|
|
504
|
+
"display-format",
|
|
505
|
+
"label",
|
|
506
|
+
"close-on-select",
|
|
507
|
+
"input-id",
|
|
508
|
+
"presets"
|
|
509
|
+
];
|
|
510
|
+
//#endregion
|
|
511
|
+
//#region src/date-picker.ts
|
|
512
|
+
/** Register <nep-date-picker> (skipped if already defined). */
|
|
513
|
+
function defineDatePicker(registry) {
|
|
514
|
+
defineElement(ELEMENT_NAMES.datePicker, NepDatePickerElement, registry);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Mount a date picker without custom elements.
|
|
518
|
+
*
|
|
519
|
+
* - Given a container, renders the field into it.
|
|
520
|
+
* - Given an <input>, hides it and keeps its value in step with the picker
|
|
521
|
+
* (AD "YYYY-MM-DD"), so existing forms and server code keep working.
|
|
522
|
+
*/
|
|
523
|
+
function createDatePicker$1(target, options = {}) {
|
|
524
|
+
const enhanced = target instanceof HTMLInputElement ? target : null;
|
|
525
|
+
let host = target;
|
|
526
|
+
if (enhanced) {
|
|
527
|
+
host = document.createElement("span");
|
|
528
|
+
enhanced.after(host);
|
|
529
|
+
enhanced.hidden = true;
|
|
530
|
+
}
|
|
531
|
+
const view = new DatePickerView(host, {
|
|
532
|
+
...enhanced ? {
|
|
533
|
+
defaultValue: enhanced.value,
|
|
534
|
+
name: void 0,
|
|
535
|
+
required: enhanced.required,
|
|
536
|
+
disabled: enhanced.disabled
|
|
537
|
+
} : {},
|
|
538
|
+
...options,
|
|
539
|
+
onChange: (value, detail) => {
|
|
540
|
+
if (enhanced) {
|
|
541
|
+
enhanced.value = value;
|
|
542
|
+
enhanced.dispatchEvent(new Event("input", { bubbles: true }));
|
|
543
|
+
enhanced.dispatchEvent(new Event("change", { bubbles: true }));
|
|
544
|
+
}
|
|
545
|
+
options.onChange?.(value, detail);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
return {
|
|
549
|
+
view,
|
|
550
|
+
getValue: () => view.getState().value,
|
|
551
|
+
getState: () => view.getState(),
|
|
552
|
+
setValue: (value) => {
|
|
553
|
+
view.store.actions.setValue(value);
|
|
554
|
+
if (enhanced) enhanced.value = view.getState().value;
|
|
555
|
+
},
|
|
556
|
+
setOptions: (changes) => {
|
|
557
|
+
view.setOptions(changes);
|
|
558
|
+
},
|
|
559
|
+
open: () => {
|
|
560
|
+
view.open();
|
|
561
|
+
},
|
|
562
|
+
close: () => {
|
|
563
|
+
view.close();
|
|
564
|
+
},
|
|
565
|
+
destroy: () => {
|
|
566
|
+
view.destroy();
|
|
567
|
+
if (enhanced) {
|
|
568
|
+
host.remove();
|
|
569
|
+
enhanced.hidden = false;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
//#endregion
|
|
575
|
+
export { DatePickerView as i, defineDatePicker as n, NepDatePickerElement as r, createDatePicker$1 as t };
|
|
576
|
+
|
|
577
|
+
//# sourceMappingURL=date-picker-ucoEFnMW.js.map
|