@genesislcap/foundation-ui 14.448.0 → 14.449.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/custom-elements.json +992 -456
- package/dist/dts/date-picker/date-picker.d.ts +63 -0
- package/dist/dts/date-picker/date-picker.d.ts.map +1 -1
- package/dist/dts/date-picker/date-picker.template.d.ts.map +1 -1
- package/dist/dts/date-picker/date-picker.util.d.ts +37 -0
- package/dist/dts/date-picker/date-picker.util.d.ts.map +1 -0
- package/dist/dts/date-picker/index.d.ts +1 -0
- package/dist/dts/date-picker/index.d.ts.map +1 -1
- package/dist/dts/react.d.ts +9 -9
- package/dist/esm/date-picker/date-picker.js +264 -17
- package/dist/esm/date-picker/date-picker.template.js +9 -1
- package/dist/esm/date-picker/date-picker.util.js +92 -0
- package/dist/esm/date-picker/index.js +1 -0
- package/dist/react.cjs +6 -6
- package/dist/react.mjs +5 -5
- package/package.json +19 -19
|
@@ -22,6 +22,14 @@ export declare class DatePicker extends FoundationElement {
|
|
|
22
22
|
format: string;
|
|
23
23
|
formatChanged(oldValue: string, newValue: string): void;
|
|
24
24
|
lang: string;
|
|
25
|
+
langChanged(): void;
|
|
26
|
+
/**
|
|
27
|
+
* @attr use-locale-format - when true, `format` is set from dayjs locale `L`.
|
|
28
|
+
* Uses the browser locale (`navigator.language`) unless `lang` is set on the element.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
useLocaleFormat: boolean;
|
|
32
|
+
useLocaleFormatChanged(oldValue: boolean, newValue: boolean): void;
|
|
25
33
|
visible: boolean;
|
|
26
34
|
/**
|
|
27
35
|
* @attr inline-calendar - display the calendar beneath the value display.
|
|
@@ -68,6 +76,19 @@ export declare class DatePicker extends FoundationElement {
|
|
|
68
76
|
* ```
|
|
69
77
|
*/
|
|
70
78
|
label: string;
|
|
79
|
+
/**
|
|
80
|
+
* @attr allow-empty - when true, no initial date is selected; the input shows a placeholder until the user picks a date.
|
|
81
|
+
* @default false
|
|
82
|
+
* @example
|
|
83
|
+
* ```html
|
|
84
|
+
* <rapid-date-picker allow-empty format="DD/MM/YYYY"></rapid-date-picker>
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
allowEmpty: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* @attr placeholder - hint shown when allow-empty is set and no date is selected. Defaults from `format` (e.g. DD/MM/YYYY → dd/mm/yyyy).
|
|
90
|
+
*/
|
|
91
|
+
placeholder: string;
|
|
71
92
|
/**
|
|
72
93
|
* @attr value - sets the value of the date picker
|
|
73
94
|
* @example
|
|
@@ -116,8 +137,50 @@ export declare class DatePicker extends FoundationElement {
|
|
|
116
137
|
disabledDaysOfWeek: number[];
|
|
117
138
|
calendar: Calendar;
|
|
118
139
|
substringNumber: number;
|
|
140
|
+
private suppressValueChanged;
|
|
141
|
+
private cachedFormat;
|
|
142
|
+
disconnectedCallback(): void;
|
|
119
143
|
connectedCallback(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Clears the selected date (only when `allow-empty` is enabled).
|
|
146
|
+
* @public
|
|
147
|
+
*/
|
|
148
|
+
clear(): void;
|
|
149
|
+
/**
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
get inputValue(): string;
|
|
153
|
+
/**
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
get inputPlaceholder(): string;
|
|
157
|
+
/**
|
|
158
|
+
* Locale for display format and calendar labels: explicit `lang`, or browser when using locale format.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
private get effectiveLang();
|
|
162
|
+
private applyLocaleFormat;
|
|
163
|
+
private cacheUserFormat;
|
|
164
|
+
private restoreUserFormat;
|
|
165
|
+
private applyEffectiveLangChange;
|
|
166
|
+
private syncValueAttribute;
|
|
167
|
+
private initializeEmpty;
|
|
168
|
+
private initializeWithDefaultDate;
|
|
169
|
+
private resetToDefaultDate;
|
|
170
|
+
private applyValue;
|
|
171
|
+
/**
|
|
172
|
+
* Resets to the empty/cleared view.
|
|
173
|
+
* @param emitEvent - emit `value-changed` for user-driven clears (public `clear()`); skip for
|
|
174
|
+
* host-driven attribute writes since the host is the source of the change.
|
|
175
|
+
*/
|
|
176
|
+
private clearToEmpty;
|
|
120
177
|
updateHeaderText(): void;
|
|
178
|
+
protected visibleChanged(_prev: boolean, next: boolean): void;
|
|
179
|
+
private clickOutside;
|
|
180
|
+
private keydownOutside;
|
|
181
|
+
private handleKeydownOutside;
|
|
182
|
+
private handleClickOutside;
|
|
183
|
+
private closeCalendar;
|
|
121
184
|
toggleCalendar(): void;
|
|
122
185
|
toggleVisibility(): void;
|
|
123
186
|
isSelectedDate(date: any): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/date-picker/date-picker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/date-picker/date-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.template.d.ts","sourceRoot":"","sources":["../../../src/date-picker/date-picker.template.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,
|
|
1
|
+
{"version":3,"file":"date-picker.template.d.ts","sourceRoot":"","sources":["../../../src/date-picker/date-picker.template.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,oEA0EnD,CAAC;AAEF,eAAO,MAAM,4BAA4B,iEAExC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import 'dayjs/locale/en-gb';
|
|
3
|
+
/**
|
|
4
|
+
* Maps BCP-47 tags to dayjs locale ids (lowercase, e.g. `fr-FR` → `fr-fr`).
|
|
5
|
+
* English variants map to dayjs bundles: `en-US` → `en`, `en-GB` → `en-gb`.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveDayjsLocale(lang: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Browser BCP-47 locale (e.g. `en-GB`), or `en` when unavailable (SSR/tests).
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export declare function getBrowserLocale(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Display format from dayjs locale `L` (e.g. en / en-US → MM/DD/YYYY, en-gb → DD/MM/YYYY).
|
|
16
|
+
* Falls back to `en` when the locale is not loaded in dayjs (import the matching `dayjs/locale/*` bundle).
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export declare function getDisplayFormatForLang(lang?: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Maps a dayjs-style display format to a lowercase placeholder hint (e.g. DD/MM/YYYY → dd/mm/yyyy).
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatToPlaceholder(format: string): string;
|
|
25
|
+
export declare function hasDateValue(value: string | null | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Internal wire format for the date picker's `value` attribute.
|
|
28
|
+
* Display formatting is independent (see `format` / `getDisplayFormatForLang`).
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export declare const DATE_PICKER_VALUE_FORMAT = "MM-DD-YYYY";
|
|
32
|
+
/**
|
|
33
|
+
* Strictly parses a date picker value (`displayFormat` or internal `DATE_PICKER_VALUE_FORMAT`). Returns null when invalid.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseDatePickerValue(dateString: string, displayFormat: string): dayjs.Dayjs | null;
|
|
37
|
+
//# sourceMappingURL=date-picker.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-picker.util.d.ts","sourceRoot":"","sources":["../../../src/date-picker/date-picker.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,oBAAoB,CAAC;AAM5B;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,MAAa,GAAG,MAAM,CAUnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAWpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/date-picker/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/date-picker/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
|
package/dist/dts/react.d.ts
CHANGED
|
@@ -137,6 +137,15 @@ export declare const ActionsMenu: React.ForwardRefExoticComponent<
|
|
|
137
137
|
>;
|
|
138
138
|
export type ActionsMenuRef = ActionsMenuWC;
|
|
139
139
|
|
|
140
|
+
export declare const AiIndicator: React.ForwardRefExoticComponent<
|
|
141
|
+
React.PropsWithChildren<
|
|
142
|
+
Omit<PublicOf<AiIndicatorWC>, 'children' | 'style'> &
|
|
143
|
+
HTMLWCProps & {
|
|
144
|
+
}
|
|
145
|
+
> & React.RefAttributes<AiIndicatorWC>
|
|
146
|
+
>;
|
|
147
|
+
export type AiIndicatorRef = AiIndicatorWC;
|
|
148
|
+
|
|
140
149
|
export declare const AiCriteriaSearch: React.ForwardRefExoticComponent<
|
|
141
150
|
React.PropsWithChildren<
|
|
142
151
|
Omit<PublicOf<AiCriteriaSearchWC>, 'children' | 'style'> &
|
|
@@ -148,15 +157,6 @@ export declare const AiCriteriaSearch: React.ForwardRefExoticComponent<
|
|
|
148
157
|
>;
|
|
149
158
|
export type AiCriteriaSearchRef = AiCriteriaSearchWC;
|
|
150
159
|
|
|
151
|
-
export declare const AiIndicator: React.ForwardRefExoticComponent<
|
|
152
|
-
React.PropsWithChildren<
|
|
153
|
-
Omit<PublicOf<AiIndicatorWC>, 'children' | 'style'> &
|
|
154
|
-
HTMLWCProps & {
|
|
155
|
-
}
|
|
156
|
-
> & React.RefAttributes<AiIndicatorWC>
|
|
157
|
-
>;
|
|
158
|
-
export type AiIndicatorRef = AiIndicatorWC;
|
|
159
|
-
|
|
160
160
|
export declare const Accordion: React.ForwardRefExoticComponent<
|
|
161
161
|
React.PropsWithChildren<
|
|
162
162
|
Omit<PublicOf<AccordionWC>, 'children' | 'style'> &
|
|
@@ -6,9 +6,11 @@ import dayjs from 'dayjs';
|
|
|
6
6
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
7
7
|
import localeData from 'dayjs/plugin/localeData';
|
|
8
8
|
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
|
|
9
|
+
import { wasClickOutsideElement } from '../utils';
|
|
9
10
|
import Calendar from './calendar';
|
|
10
11
|
import { foundationDatePickerStyles as styles } from './date-picker.styles';
|
|
11
12
|
import { foundationDatePickerTemplate as template } from './date-picker.template';
|
|
13
|
+
import { DATE_PICKER_VALUE_FORMAT, formatToPlaceholder, getBrowserLocale, getDisplayFormatForLang, hasDateValue, parseDatePickerValue, } from './date-picker.util';
|
|
12
14
|
import Day from './day';
|
|
13
15
|
import { getNextEnabledDay } from './day.util';
|
|
14
16
|
export const foundationDatePickerShadowOptions = undefined;
|
|
@@ -31,7 +33,7 @@ export class DatePicker extends FoundationElement {
|
|
|
31
33
|
* </rapid-date-picker>
|
|
32
34
|
* ```
|
|
33
35
|
*/
|
|
34
|
-
this.format =
|
|
36
|
+
this.format = DATE_PICKER_VALUE_FORMAT;
|
|
35
37
|
this.lang = 'en-US';
|
|
36
38
|
this.visible = false;
|
|
37
39
|
/**
|
|
@@ -56,53 +58,284 @@ export class DatePicker extends FoundationElement {
|
|
|
56
58
|
* ```
|
|
57
59
|
*/
|
|
58
60
|
this.disabledDaysOfWeek = [];
|
|
61
|
+
this.suppressValueChanged = false;
|
|
62
|
+
this.cachedFormat = DATE_PICKER_VALUE_FORMAT;
|
|
63
|
+
this.clickOutside = (e) => this.handleClickOutside(e);
|
|
64
|
+
this.keydownOutside = (e) => this.handleKeydownOutside(e);
|
|
59
65
|
}
|
|
60
66
|
formatChanged(oldValue, newValue) {
|
|
61
|
-
if (
|
|
67
|
+
if (!this.useLocaleFormat && newValue) {
|
|
68
|
+
this.cacheUserFormat(newValue);
|
|
69
|
+
}
|
|
70
|
+
if (newValue && this.calendar && hasDateValue(this.value)) {
|
|
62
71
|
this.formatDate = dayjs(this.currentDate.Date).format(newValue);
|
|
63
72
|
}
|
|
64
73
|
}
|
|
74
|
+
langChanged() {
|
|
75
|
+
this.applyEffectiveLangChange();
|
|
76
|
+
}
|
|
77
|
+
useLocaleFormatChanged(oldValue, newValue) {
|
|
78
|
+
// Pre-mount: format/useLocaleFormat may be set in any order; let connectedCallback do the
|
|
79
|
+
// initial cache so we don't snapshot the default format before the `format` attribute is parsed.
|
|
80
|
+
if (!this.calendar) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (newValue && !oldValue) {
|
|
84
|
+
this.cacheUserFormat(this.format);
|
|
85
|
+
}
|
|
86
|
+
else if (!newValue && oldValue) {
|
|
87
|
+
this.restoreUserFormat();
|
|
88
|
+
}
|
|
89
|
+
this.applyEffectiveLangChange();
|
|
90
|
+
}
|
|
65
91
|
inlineCalendarChanged() {
|
|
92
|
+
if (this.inlineCalendar) {
|
|
93
|
+
document.removeEventListener('mousedown', this.clickOutside);
|
|
94
|
+
document.removeEventListener('keydown', this.keydownOutside);
|
|
95
|
+
}
|
|
96
|
+
else if (this.visible) {
|
|
97
|
+
document.addEventListener('mousedown', this.clickOutside);
|
|
98
|
+
document.addEventListener('keydown', this.keydownOutside);
|
|
99
|
+
}
|
|
66
100
|
this.toggleVisibility();
|
|
67
101
|
}
|
|
68
102
|
hideWeekendsCalendarChanged() {
|
|
69
103
|
this.toggleVisibility();
|
|
70
104
|
}
|
|
71
105
|
valueChanged(oldValue, newValue) {
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
106
|
+
if (this.suppressValueChanged) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!this.calendar) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!hasDateValue(newValue)) {
|
|
113
|
+
if (this.allowEmpty) {
|
|
114
|
+
this.clearToEmpty(false);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.resetToDefaultDate();
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
79
120
|
}
|
|
121
|
+
this.applyValue(newValue);
|
|
122
|
+
}
|
|
123
|
+
disconnectedCallback() {
|
|
124
|
+
document.removeEventListener('mousedown', this.clickOutside);
|
|
125
|
+
document.removeEventListener('keydown', this.keydownOutside);
|
|
126
|
+
super.disconnectedCallback();
|
|
80
127
|
}
|
|
81
128
|
connectedCallback() {
|
|
82
|
-
var _a;
|
|
83
129
|
super.connectedCallback();
|
|
84
130
|
dayjs.extend(customParseFormat);
|
|
85
131
|
dayjs.extend(LocalizedFormat);
|
|
86
132
|
dayjs.extend(localeData);
|
|
87
133
|
this.substringNumber = 3;
|
|
134
|
+
if (this.useLocaleFormat) {
|
|
135
|
+
this.cacheUserFormat(this.format);
|
|
136
|
+
this.applyLocaleFormat();
|
|
137
|
+
}
|
|
88
138
|
const dateString = this.value;
|
|
89
|
-
|
|
90
|
-
|
|
139
|
+
if (this.allowEmpty && !hasDateValue(dateString)) {
|
|
140
|
+
this.initializeEmpty();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (hasDateValue(dateString)) {
|
|
144
|
+
this.applyValue(dateString);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
this.initializeWithDefaultDate();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Clears the selected date (only when `allow-empty` is enabled).
|
|
151
|
+
* @public
|
|
152
|
+
*/
|
|
153
|
+
clear() {
|
|
154
|
+
if (!this.allowEmpty) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.clearToEmpty(true);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
get inputValue() {
|
|
163
|
+
return hasDateValue(this.value) ? this.formatDate : '';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
get inputPlaceholder() {
|
|
169
|
+
var _a;
|
|
170
|
+
if (!this.allowEmpty || hasDateValue(this.value)) {
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
return ((_a = this.placeholder) === null || _a === void 0 ? void 0 : _a.trim()) || formatToPlaceholder(this.format);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Locale for display format and calendar labels: explicit `lang`, or browser when using locale format.
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
get effectiveLang() {
|
|
180
|
+
if (this.useLocaleFormat && !this.hasAttribute('lang')) {
|
|
181
|
+
return getBrowserLocale();
|
|
182
|
+
}
|
|
183
|
+
return this.lang;
|
|
184
|
+
}
|
|
185
|
+
applyLocaleFormat() {
|
|
186
|
+
this.format = getDisplayFormatForLang(this.effectiveLang);
|
|
187
|
+
}
|
|
188
|
+
cacheUserFormat(format) {
|
|
189
|
+
const trimmed = format === null || format === void 0 ? void 0 : format.trim();
|
|
190
|
+
if (trimmed) {
|
|
191
|
+
this.cachedFormat = trimmed;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
restoreUserFormat() {
|
|
195
|
+
this.format = this.cachedFormat;
|
|
196
|
+
}
|
|
197
|
+
applyEffectiveLangChange() {
|
|
198
|
+
var _a, _b;
|
|
199
|
+
if (!this.calendar) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (this.useLocaleFormat) {
|
|
203
|
+
this.applyLocaleFormat();
|
|
204
|
+
}
|
|
205
|
+
const viewYear = this.calendar.year;
|
|
206
|
+
const viewMonth = this.calendar.month.number;
|
|
207
|
+
const selectedDate = (_b = (_a = this.currentDate) === null || _a === void 0 ? void 0 : _a.Date) !== null && _b !== void 0 ? _b : dayjs().toDate();
|
|
208
|
+
this.currentDate = new Day(selectedDate, this.effectiveLang);
|
|
209
|
+
this.calendar = new Calendar(viewYear, viewMonth, this.effectiveLang);
|
|
210
|
+
if (hasDateValue(this.value)) {
|
|
211
|
+
this.formatDate = dayjs(this.currentDate.Date).format(this.format);
|
|
212
|
+
}
|
|
213
|
+
this.updateHeaderText();
|
|
214
|
+
this.monthList = this.getMonthDaysGrid();
|
|
215
|
+
}
|
|
216
|
+
syncValueAttribute(value) {
|
|
217
|
+
this.suppressValueChanged = true;
|
|
218
|
+
this.value = value;
|
|
219
|
+
this.suppressValueChanged = false;
|
|
220
|
+
}
|
|
221
|
+
initializeEmpty() {
|
|
222
|
+
const viewDate = dayjs();
|
|
223
|
+
this.currentDate = new Day(viewDate.toDate(), this.effectiveLang);
|
|
224
|
+
this.calendar = new Calendar(this.currentDate.year, this.currentDate.monthNumber, this.effectiveLang);
|
|
225
|
+
this.formatDate = '';
|
|
226
|
+
this.syncValueAttribute('');
|
|
227
|
+
this.currentMonth = this.calendar.month.name;
|
|
228
|
+
this.currentYear = this.calendar.year;
|
|
229
|
+
this.monthList = this.getMonthDaysGrid();
|
|
230
|
+
}
|
|
231
|
+
initializeWithDefaultDate() {
|
|
232
|
+
this.resetToDefaultDate(true);
|
|
233
|
+
}
|
|
234
|
+
resetToDefaultDate(createCalendar = false) {
|
|
235
|
+
var _a;
|
|
236
|
+
let currentDate = new Day(dayjs().toDate(), this.effectiveLang);
|
|
91
237
|
if ((_a = this.disabledDaysOfWeek) === null || _a === void 0 ? void 0 : _a.length) {
|
|
92
|
-
currentDate = getNextEnabledDay(this.disabledDaysOfWeek, currentDate, this.
|
|
238
|
+
currentDate = getNextEnabledDay(this.disabledDaysOfWeek, currentDate, this.effectiveLang);
|
|
93
239
|
}
|
|
94
240
|
this.currentDate = currentDate;
|
|
95
|
-
|
|
96
|
-
|
|
241
|
+
if (createCalendar || !this.calendar) {
|
|
242
|
+
this.calendar = new Calendar(this.currentDate.year, this.currentDate.monthNumber, this.effectiveLang);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
this.calendar.goToDate(this.currentDate.monthNumber, this.currentDate.year);
|
|
246
|
+
}
|
|
247
|
+
this.formatDate = dayjs(this.currentDate.Date).format(this.format);
|
|
248
|
+
this.syncValueAttribute(dayjs(this.currentDate.Date).format(DATE_PICKER_VALUE_FORMAT));
|
|
97
249
|
this.currentMonth = this.calendar.month.name;
|
|
98
250
|
this.currentYear = this.calendar.year;
|
|
251
|
+
this.monthList = this.getMonthDaysGrid();
|
|
252
|
+
}
|
|
253
|
+
applyValue(dateString) {
|
|
254
|
+
const parsed = parseDatePickerValue(dateString, this.format);
|
|
255
|
+
if (!parsed) {
|
|
256
|
+
if (this.allowEmpty) {
|
|
257
|
+
this.clearToEmpty(false);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
this.resetToDefaultDate();
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
// Honor the host's value verbatim. Disabled-day roll-forward only applies to the
|
|
265
|
+
// default "today" fallback (see `resetToDefaultDate`); programmatic writes should not
|
|
266
|
+
// be silently shifted, and user clicks on disabled day cells are blocked in the template.
|
|
267
|
+
this.currentDate = new Day(parsed.toDate(), this.effectiveLang);
|
|
268
|
+
if (!this.calendar) {
|
|
269
|
+
this.calendar = new Calendar(this.currentDate.year, this.currentDate.monthNumber, this.effectiveLang);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.calendar.goToDate(this.currentDate.monthNumber, this.currentDate.year);
|
|
273
|
+
}
|
|
99
274
|
this.formatDate = dayjs(this.currentDate.Date).format(this.format);
|
|
275
|
+
this.syncValueAttribute(dayjs(this.currentDate.Date).format(DATE_PICKER_VALUE_FORMAT));
|
|
276
|
+
this.updateHeaderText();
|
|
100
277
|
this.monthList = this.getMonthDaysGrid();
|
|
101
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Resets to the empty/cleared view.
|
|
281
|
+
* @param emitEvent - emit `value-changed` for user-driven clears (public `clear()`); skip for
|
|
282
|
+
* host-driven attribute writes since the host is the source of the change.
|
|
283
|
+
*/
|
|
284
|
+
clearToEmpty(emitEvent) {
|
|
285
|
+
const viewDate = dayjs();
|
|
286
|
+
this.currentDate = new Day(viewDate.toDate(), this.effectiveLang);
|
|
287
|
+
if (this.calendar) {
|
|
288
|
+
this.calendar.goToDate(this.currentDate.monthNumber, this.currentDate.year);
|
|
289
|
+
this.updateHeaderText();
|
|
290
|
+
this.monthList = this.getMonthDaysGrid();
|
|
291
|
+
}
|
|
292
|
+
this.formatDate = '';
|
|
293
|
+
this.syncValueAttribute('');
|
|
294
|
+
if (emitEvent) {
|
|
295
|
+
this.$emit('value-changed', undefined);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
102
298
|
updateHeaderText() {
|
|
103
299
|
this.currentMonth = this.calendar.month.name;
|
|
104
300
|
this.currentYear = this.calendar.year;
|
|
105
301
|
}
|
|
302
|
+
visibleChanged(_prev, next) {
|
|
303
|
+
if (this.inlineCalendar) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (next) {
|
|
307
|
+
document.addEventListener('mousedown', this.clickOutside);
|
|
308
|
+
document.addEventListener('keydown', this.keydownOutside);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
document.removeEventListener('mousedown', this.clickOutside);
|
|
312
|
+
document.removeEventListener('keydown', this.keydownOutside);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
handleKeydownOutside(event) {
|
|
316
|
+
if (this.inlineCalendar || !this.visible) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (event.key === 'Escape') {
|
|
320
|
+
event.preventDefault();
|
|
321
|
+
this.closeCalendar();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
handleClickOutside(event) {
|
|
325
|
+
if (this.inlineCalendar || !this.visible) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (wasClickOutsideElement(event, this)) {
|
|
329
|
+
this.closeCalendar();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
closeCalendar() {
|
|
333
|
+
if (!this.visible) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
this.visible = false;
|
|
337
|
+
this.toggleVisibility();
|
|
338
|
+
}
|
|
106
339
|
toggleCalendar() {
|
|
107
340
|
this.visible = !this.visible;
|
|
108
341
|
this.toggleVisibility();
|
|
@@ -115,6 +348,9 @@ export class DatePicker extends FoundationElement {
|
|
|
115
348
|
this.calendarDropdownClasses = classNames(['visible', this.visible], this.position, ['inline', this.inlineCalendar], ['hide-weekends', this.hideWeekends]);
|
|
116
349
|
}
|
|
117
350
|
isSelectedDate(date) {
|
|
351
|
+
if (this.allowEmpty && !hasDateValue(this.value)) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
118
354
|
return dayjs(date.Date).isSame(this.currentDate.Date, 'day');
|
|
119
355
|
}
|
|
120
356
|
isCurrentCalendarMonth() {
|
|
@@ -135,14 +371,16 @@ export class DatePicker extends FoundationElement {
|
|
|
135
371
|
this.monthList = this.getMonthDaysGrid();
|
|
136
372
|
}
|
|
137
373
|
selectDay(day) {
|
|
138
|
-
|
|
374
|
+
const sameDayAsCurrent = dayjs(day.Date).isSame(this.currentDate.Date, 'day');
|
|
375
|
+
if (sameDayAsCurrent && hasDateValue(this.value)) {
|
|
139
376
|
return;
|
|
377
|
+
}
|
|
140
378
|
this.currentDate = day;
|
|
141
379
|
if (day.monthNumber !== this.calendar.month.number) {
|
|
142
380
|
this.prevMonth();
|
|
143
381
|
}
|
|
144
382
|
this.formatDate = dayjs(this.currentDate.Date).format(this.format);
|
|
145
|
-
this.
|
|
383
|
+
this.syncValueAttribute(dayjs(day.Date).format(DATE_PICKER_VALUE_FORMAT));
|
|
146
384
|
this.$emit('value-changed', this.value);
|
|
147
385
|
this.toggleCalendar();
|
|
148
386
|
}
|
|
@@ -168,6 +406,9 @@ __decorate([
|
|
|
168
406
|
__decorate([
|
|
169
407
|
attr
|
|
170
408
|
], DatePicker.prototype, "lang", void 0);
|
|
409
|
+
__decorate([
|
|
410
|
+
attr({ attribute: 'use-locale-format', mode: 'boolean' })
|
|
411
|
+
], DatePicker.prototype, "useLocaleFormat", void 0);
|
|
171
412
|
__decorate([
|
|
172
413
|
attr
|
|
173
414
|
], DatePicker.prototype, "visible", void 0);
|
|
@@ -183,6 +424,12 @@ __decorate([
|
|
|
183
424
|
__decorate([
|
|
184
425
|
attr
|
|
185
426
|
], DatePicker.prototype, "label", void 0);
|
|
427
|
+
__decorate([
|
|
428
|
+
attr({ attribute: 'allow-empty', mode: 'boolean' })
|
|
429
|
+
], DatePicker.prototype, "allowEmpty", void 0);
|
|
430
|
+
__decorate([
|
|
431
|
+
attr
|
|
432
|
+
], DatePicker.prototype, "placeholder", void 0);
|
|
186
433
|
__decorate([
|
|
187
434
|
attr
|
|
188
435
|
], DatePicker.prototype, "value", void 0);
|
|
@@ -5,7 +5,15 @@ const SUNDAY_INDEX = 1;
|
|
|
5
5
|
const SATURDAY_INDEX = 7;
|
|
6
6
|
const WEEKEND_DAY_INDICES = [SUNDAY_INDEX, SATURDAY_INDEX];
|
|
7
7
|
export const getPrefixedDatePicker = (prefix) => html `
|
|
8
|
-
<${prefix}-text-field
|
|
8
|
+
<${prefix}-text-field
|
|
9
|
+
data-test-id="date-picker"
|
|
10
|
+
readonly
|
|
11
|
+
:value="${(x) => x.inputValue}"
|
|
12
|
+
placeholder="${(x) => x.inputPlaceholder}"
|
|
13
|
+
part="date-toggle"
|
|
14
|
+
class="date-toggle"
|
|
15
|
+
@click="${(x) => x.toggleCalendar()}"
|
|
16
|
+
>
|
|
9
17
|
${(x) => x.label}
|
|
10
18
|
<div class="input-icon-container" part="input-icon-container" slot="end"><${prefix}-icon variant="regular" name="calendar-alt" size="sm"></${prefix}-icon></div>
|
|
11
19
|
</${prefix}-text-field>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
3
|
+
import localeData from 'dayjs/plugin/localeData';
|
|
4
|
+
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
|
|
5
|
+
import 'dayjs/locale/en-gb';
|
|
6
|
+
dayjs.extend(customParseFormat);
|
|
7
|
+
dayjs.extend(localeData);
|
|
8
|
+
dayjs.extend(LocalizedFormat);
|
|
9
|
+
/**
|
|
10
|
+
* Maps BCP-47 tags to dayjs locale ids (lowercase, e.g. `fr-FR` → `fr-fr`).
|
|
11
|
+
* English variants map to dayjs bundles: `en-US` → `en`, `en-GB` → `en-gb`.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export function resolveDayjsLocale(lang) {
|
|
15
|
+
const normalized = ((lang === null || lang === void 0 ? void 0 : lang.trim()) || 'en').toLowerCase().replace(/_/g, '-');
|
|
16
|
+
if (normalized === 'en-us' || normalized === 'en') {
|
|
17
|
+
return 'en';
|
|
18
|
+
}
|
|
19
|
+
if (normalized === 'en-gb') {
|
|
20
|
+
return 'en-gb';
|
|
21
|
+
}
|
|
22
|
+
return normalized;
|
|
23
|
+
}
|
|
24
|
+
function dayjsLocaleWasApplied(requested, applied) {
|
|
25
|
+
if (requested === applied) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const language = requested.split('-')[0];
|
|
29
|
+
return applied === language;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Browser BCP-47 locale (e.g. `en-GB`), or `en` when unavailable (SSR/tests).
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export function getBrowserLocale() {
|
|
36
|
+
if (typeof navigator !== 'undefined' && navigator.language) {
|
|
37
|
+
return navigator.language;
|
|
38
|
+
}
|
|
39
|
+
return 'en';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Display format from dayjs locale `L` (e.g. en / en-US → MM/DD/YYYY, en-gb → DD/MM/YYYY).
|
|
43
|
+
* Falls back to `en` when the locale is not loaded in dayjs (import the matching `dayjs/locale/*` bundle).
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export function getDisplayFormatForLang(lang = 'en') {
|
|
47
|
+
const locale = resolveDayjsLocale(lang);
|
|
48
|
+
const instance = dayjs().locale(locale);
|
|
49
|
+
const appliedLocale = instance.locale();
|
|
50
|
+
if (!dayjsLocaleWasApplied(locale, appliedLocale)) {
|
|
51
|
+
return dayjs().locale('en').localeData().longDateFormat('L') || 'MM/DD/YYYY';
|
|
52
|
+
}
|
|
53
|
+
return instance.localeData().longDateFormat('L') || 'MM/DD/YYYY';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Maps a dayjs-style display format to a lowercase placeholder hint (e.g. DD/MM/YYYY → dd/mm/yyyy).
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export function formatToPlaceholder(format) {
|
|
60
|
+
return format
|
|
61
|
+
.replace(/YYYY/g, 'yyyy')
|
|
62
|
+
.replace(/YY(?!Y)/g, 'yy')
|
|
63
|
+
.replace(/DD/g, 'dd')
|
|
64
|
+
.replace(/D(?!D)/g, 'd')
|
|
65
|
+
.replace(/MM/g, 'mm')
|
|
66
|
+
.replace(/M(?!M)/g, 'm');
|
|
67
|
+
}
|
|
68
|
+
export function hasDateValue(value) {
|
|
69
|
+
return value !== null && value !== undefined && String(value).trim() !== '';
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Internal wire format for the date picker's `value` attribute.
|
|
73
|
+
* Display formatting is independent (see `format` / `getDisplayFormatForLang`).
|
|
74
|
+
* @public
|
|
75
|
+
*/
|
|
76
|
+
export const DATE_PICKER_VALUE_FORMAT = 'MM-DD-YYYY';
|
|
77
|
+
/**
|
|
78
|
+
* Strictly parses a date picker value (`displayFormat` or internal `DATE_PICKER_VALUE_FORMAT`). Returns null when invalid.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export function parseDatePickerValue(dateString, displayFormat) {
|
|
82
|
+
const trimmed = String(dateString).trim();
|
|
83
|
+
const display = dayjs(trimmed, displayFormat, true);
|
|
84
|
+
if (display.isValid()) {
|
|
85
|
+
return display;
|
|
86
|
+
}
|
|
87
|
+
const internal = dayjs(trimmed, DATE_PICKER_VALUE_FORMAT, true);
|
|
88
|
+
if (internal.isValid()) {
|
|
89
|
+
return internal;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|