@tylertech/forge 3.9.2 → 3.10.1

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.
Files changed (31) hide show
  1. package/custom-elements.json +169 -11
  2. package/dist/lib.js +22 -22
  3. package/dist/lib.js.map +3 -3
  4. package/dist/vscode.html-custom-data.json +20 -0
  5. package/esm/app-bar/profile-button/app-bar-profile-button-adapter.js +1 -1
  6. package/esm/core/mask/date-input-mask.js +18 -1
  7. package/esm/core/utils/date-utils.d.ts +14 -5
  8. package/esm/core/utils/date-utils.js +228 -69
  9. package/esm/date-picker/base/base-date-picker-constants.d.ts +19 -4
  10. package/esm/date-picker/base/base-date-picker-constants.js +20 -1
  11. package/esm/date-picker/base/base-date-picker-core.d.ts +11 -3
  12. package/esm/date-picker/base/base-date-picker-core.js +68 -13
  13. package/esm/date-picker/base/base-date-picker.d.ts +10 -2
  14. package/esm/date-picker/base/base-date-picker.js +17 -1
  15. package/esm/date-picker/date-picker-core.js +1 -1
  16. package/esm/date-range-picker/date-range-picker-core.d.ts +1 -0
  17. package/esm/date-range-picker/date-range-picker-core.js +14 -4
  18. package/esm/floating-action-button/floating-action-button-adapter.d.ts +0 -4
  19. package/esm/floating-action-button/floating-action-button-adapter.js +3 -24
  20. package/esm/floating-action-button/floating-action-button-core.d.ts +0 -1
  21. package/esm/floating-action-button/floating-action-button-core.js +0 -3
  22. package/esm/floating-action-button/floating-action-button.d.ts +0 -1
  23. package/esm/floating-action-button/floating-action-button.js +0 -3
  24. package/esm/list/list/list.js +1 -1
  25. package/esm/list/list-item/list-item.js +1 -1
  26. package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
  27. package/esm/time-picker/time-picker-core.d.ts +1 -0
  28. package/esm/time-picker/time-picker-core.js +80 -16
  29. package/package.json +1 -1
  30. package/sass/list/list/list.scss +4 -2
  31. package/sass/list/list-item/list-item.scss +3 -1
@@ -672,6 +672,11 @@
672
672
  "description": "Whether the mask format is displayed in the input or not. Only applies if `masked` is `true`.",
673
673
  "values": []
674
674
  },
675
+ {
676
+ "name": "date-format",
677
+ "description": "The date format to use for the date picker.",
678
+ "values": [{ "name": "DatePickerDateFormat" }]
679
+ },
675
680
  {
676
681
  "name": "show-today",
677
682
  "description": "Whether the today button is visible in the popup.",
@@ -682,6 +687,11 @@
682
687
  "description": "The type for the `value` property and `forge-date-picker-change` event.",
683
688
  "values": [{ "name": "DatePickerValueMode" }]
684
689
  },
690
+ {
691
+ "name": "shortcuts",
692
+ "description": "When specifies as an attribute you can only use the `off` value to disable shortcuts. Otherwise, you can use the `shortcuts` property to set your own shortcuts.",
693
+ "values": [{ "name": "DatePickerShortcuts" }]
694
+ },
685
695
  { "name": "year-range", "description": "The year range.", "values": [] }
686
696
  ],
687
697
  "references": []
@@ -751,6 +761,11 @@
751
761
  "description": "Whether the mask format is displayed in the input or not. Only applies if `masked` is `true`.",
752
762
  "values": []
753
763
  },
764
+ {
765
+ "name": "date-format",
766
+ "description": "The date format to use for the date picker.",
767
+ "values": [{ "name": "DatePickerDateFormat" }]
768
+ },
754
769
  {
755
770
  "name": "show-today",
756
771
  "description": "Whether the today button is visible in the popup.",
@@ -761,6 +776,11 @@
761
776
  "description": "The type for the `value` property and `forge-date-picker-change` event.",
762
777
  "values": [{ "name": "DatePickerValueMode" }]
763
778
  },
779
+ {
780
+ "name": "shortcuts",
781
+ "description": "When specifies as an attribute you can only use the `off` value to disable shortcuts. Otherwise, you can use the `shortcuts` property to set your own shortcuts.",
782
+ "values": [{ "name": "DatePickerShortcuts" }]
783
+ },
764
784
  { "name": "year-range", "description": "The year range.", "values": [] }
765
785
  ],
766
786
  "references": []
@@ -87,7 +87,7 @@ export class AppBarProfileButtonAdapter extends BaseAdapter {
87
87
  async closePopup() {
88
88
  if (this._popupElement) {
89
89
  await this._popupElement.hideAsync();
90
- this._popupElement.remove();
90
+ this._popupElement?.remove();
91
91
  this._popupElement = undefined;
92
92
  this._profileCardElement = undefined;
93
93
  }
@@ -4,7 +4,7 @@
4
4
  * License: Apache-2.0
5
5
  */
6
6
  import { isNumeric } from '@tylertech/forge-core';
7
- import { InputMask, MaskedRange, createMask } from 'imask';
7
+ import { InputMask, MaskedEnum, MaskedRange, createMask } from 'imask';
8
8
  export const DEFAULT_DATE_MASK = '0`0{/}`0`0{/}`0`0`0`0';
9
9
  export class DateInputMask {
10
10
  constructor(_element, _options = {}) {
@@ -49,6 +49,16 @@ export class DateInputMask {
49
49
  to: 12,
50
50
  maxLength: 2
51
51
  },
52
+ Mmm: {
53
+ mask: MaskedEnum,
54
+ enum: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
55
+ matchValue: (enumStr, inputStr, matchFrom) => MaskedEnum.DEFAULTS.matchValue(enumStr.toLowerCase(), inputStr.toLowerCase(), matchFrom)
56
+ },
57
+ MMM: {
58
+ mask: MaskedEnum,
59
+ enum: ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
60
+ matchValue: (enumStr, inputStr, matchFrom) => MaskedEnum.DEFAULTS.matchValue(enumStr.toLowerCase(), inputStr.toLowerCase(), matchFrom)
61
+ },
52
62
  DD: {
53
63
  mask: MaskedRange,
54
64
  autofix: true,
@@ -62,6 +72,13 @@ export class DateInputMask {
62
72
  from: 0,
63
73
  to: 9999,
64
74
  maxLength: 4
75
+ },
76
+ YY: {
77
+ mask: MaskedRange,
78
+ autofix: true,
79
+ from: 0,
80
+ to: 99,
81
+ maxLength: 2
65
82
  }
66
83
  }
67
84
  };
@@ -3,18 +3,27 @@
3
3
  * Copyright Tyler Technologies, Inc.
4
4
  * License: Apache-2.0
5
5
  */
6
+ export type SupportedDateFormats = 'MM/DD/YYYY' | 'MM/DD/YY' | 'DD/MMM/YYYY' | 'MM-DD-YYYY' | 'MM-DD-YY' | 'DD-MMM-YYYY' | 'YYYY-MM-DD' | 'YYYY-MMM-DD' | 'DD.MM.YYYY' | 'DD.MM.YY';
6
7
  export declare const ISO_8601_REGEX: RegExp;
7
8
  export declare const ISO_TIMEZONE_REGEX: RegExp;
8
9
  /**
9
10
  * Parses a date string value to a `Date` object in local time.
10
- * @param str The date string value.
11
+ * Supports multiple formats as defined in SupportedDateFormats.
12
+ *
13
+ * @param value The date string value to parse
14
+ * @param format Optional format hint for better parsing accuracy
15
+ * @returns Parsed Date object or null if parsing fails
11
16
  */
12
- export declare function parseDateString(value: string): Date | null;
17
+ export declare function parseDateString(value: string, format?: SupportedDateFormats): Date | null;
13
18
  /**
14
- * Formats a `Date` to a specified format.
15
- * @param str The date string value.
19
+ * Formats a Date object to a specified string format.
20
+ *
21
+ * @param date The Date object to format
22
+ * @param format The desired output format (defaults to 'MM/DD/YYYY')
23
+ * @returns Formatted date string
24
+ * @throws Error if date is invalid or format is unsupported
16
25
  */
17
- export declare function formatDate(date: Date): string;
26
+ export declare function formatDate(date: Date, format?: SupportedDateFormats): string;
18
27
  /**
19
28
  * Determines if two date objects are equal.
20
29
  *
@@ -7,89 +7,248 @@ import { isValidDate } from '@tylertech/forge-core';
7
7
  export const ISO_8601_REGEX = /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
8
8
  export const ISO_TIMEZONE_REGEX = /a-z/i;
9
9
  const FUTURE_YEAR_COERCION = 10; // The number of years in the future to coerce two-digit years into current century
10
- /**
11
- * Parses a date string value to a `Date` object in local time.
12
- * @param str The date string value.
13
- */
14
- export function parseDateString(value) {
15
- value = value.replace(/_|\s/g, ''); // Remove potential extraneous characters
16
- // We first check if this is a valid date in ISO 8601 format and return it if so
17
- if (ISO_8601_REGEX.test(value)) {
18
- const iso8601Date = new Date(value);
19
- // This is an ISO string, but does it have a timezone? If not, we add current timezone offset
20
- if (!ISO_TIMEZONE_REGEX.test(value)) {
21
- iso8601Date.setMinutes(iso8601Date.getMinutes() + iso8601Date.getTimezoneOffset());
22
- }
23
- if (isValidDate(iso8601Date)) {
24
- return iso8601Date;
25
- }
10
+ const MONTH_ABBREVIATIONS = {
11
+ JAN: 1,
12
+ FEB: 2,
13
+ MAR: 3,
14
+ APR: 4,
15
+ MAY: 5,
16
+ JUN: 6,
17
+ JUL: 7,
18
+ AUG: 8,
19
+ SEP: 9,
20
+ OCT: 10,
21
+ NOV: 11,
22
+ DEC: 12
23
+ };
24
+ const MONTH_NAMES = {
25
+ 1: 'JAN',
26
+ 2: 'FEB',
27
+ 3: 'MAR',
28
+ 4: 'APR',
29
+ 5: 'MAY',
30
+ 6: 'JUN',
31
+ 7: 'JUL',
32
+ 8: 'AUG',
33
+ 9: 'SEP',
34
+ 10: 'OCT',
35
+ 11: 'NOV',
36
+ 12: 'DEC'
37
+ };
38
+ const DATE_PATTERNS = [
39
+ // YYYY-MM-DD (ISO-like numeric)
40
+ {
41
+ regex: /^(\d{4})-(\d{1,2})-(\d{1,2})$/,
42
+ parser: ([year, month, day]) => parseNumericDate(year, month, day, 'YMD')
43
+ },
44
+ // YYYY-MMM-DD
45
+ {
46
+ regex: /^(\d{4})-([A-Za-z]{3})-(\d{1,2})$/,
47
+ parser: ([year, monthAbbr, day]) => parseWithMonthAbbr(year, monthAbbr, day, 'YMD')
48
+ },
49
+ // MM/DD/YYYY or MM/DD/YY
50
+ {
51
+ regex: /^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/,
52
+ parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
53
+ },
54
+ // MM-DD-YYYY or MM-DD-YY
55
+ {
56
+ regex: /^(\d{1,2})-(\d{1,2})-(\d{2,4})$/,
57
+ parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
58
+ },
59
+ // DD/MMM/YYYY
60
+ {
61
+ regex: /^(\d{1,2})\/([A-Za-z]{3})\/(\d{2,4})$/,
62
+ parser: ([day, monthAbbr, year]) => parseWithMonthAbbr(day, monthAbbr, year, 'DMY')
63
+ },
64
+ // DD-MMM-YYYY
65
+ {
66
+ regex: /^(\d{1,2})-([A-Za-z]{3})-(\d{2,4})$/,
67
+ parser: ([day, monthAbbr, year]) => parseWithMonthAbbr(day, monthAbbr, year, 'DMY')
68
+ },
69
+ // Numeric without separators (MMDDYYYY or MMDDYY)
70
+ {
71
+ regex: /^(\d{2})(\d{2})(\d{2,4})$/,
72
+ parser: ([month, day, year]) => parseNumericDate(month, day, year, 'MDY')
73
+ },
74
+ // DD.MM.YYYY or DD.MM.YY
75
+ {
76
+ regex: /^(\d{1,2})\.(\d{1,2})\.(\d{2,4})$/,
77
+ parser: ([day, month, year]) => parseNumericDate(day, month, year, 'DMY')
26
78
  }
27
- let values = [];
28
- // We accept dates with a "/" or "-" separator and in the format of MM/DD/YYYY
29
- if (value.indexOf('/') !== -1) {
30
- values = value.split('/');
79
+ ];
80
+ const FORMAT_CONFIGS = {
81
+ 'MM/DD/YYYY': {
82
+ pattern: 'MM/DD/YYYY',
83
+ formatter: date => `${pad(date.getMonth() + 1)}/${pad(date.getDate())}/${date.getFullYear()}`
84
+ },
85
+ 'MM/DD/YY': {
86
+ pattern: 'MM/DD/YY',
87
+ formatter: date => `${pad(date.getMonth() + 1)}/${pad(date.getDate())}/${String(date.getFullYear()).slice(-2)}`
88
+ },
89
+ 'DD/MMM/YYYY': {
90
+ pattern: 'DD/MMM/YYYY',
91
+ formatter: date => `${pad(date.getDate())}/${MONTH_NAMES[(date.getMonth() + 1)]}/${date.getFullYear()}`
92
+ },
93
+ 'MM-DD-YYYY': {
94
+ pattern: 'MM-DD-YYYY',
95
+ formatter: date => `${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${date.getFullYear()}`
96
+ },
97
+ 'MM-DD-YY': {
98
+ pattern: 'MM-DD-YY',
99
+ formatter: date => `${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${String(date.getFullYear()).slice(-2)}`
100
+ },
101
+ 'DD-MMM-YYYY': {
102
+ pattern: 'DD-MMM-YYYY',
103
+ formatter: date => `${pad(date.getDate())}-${MONTH_NAMES[(date.getMonth() + 1)]}-${date.getFullYear()}`
104
+ },
105
+ 'YYYY-MM-DD': {
106
+ pattern: 'YYYY-MM-DD',
107
+ formatter: date => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
108
+ },
109
+ 'YYYY-MMM-DD': {
110
+ pattern: 'YYYY-MMM-DD',
111
+ formatter: date => `${date.getFullYear()}-${MONTH_NAMES[(date.getMonth() + 1)]}-${pad(date.getDate())}`
112
+ },
113
+ 'DD.MM.YYYY': {
114
+ pattern: 'DD.MM.YYYY',
115
+ formatter: date => `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${date.getFullYear()}`
116
+ },
117
+ 'DD.MM.YY': {
118
+ pattern: 'DD.MM.YY',
119
+ formatter: date => `${pad(date.getDate())}.${pad(date.getMonth() + 1)}.${String(date.getFullYear()).slice(-2)}`
31
120
  }
32
- else if (value.indexOf('-') !== -1) {
33
- values = value.split('-');
121
+ };
122
+ function pad(num) {
123
+ return String(num).padStart(2, '0');
124
+ }
125
+ function normalizeYear(year) {
126
+ if (year.length === 3) {
127
+ year = year.padStart(4, '0');
34
128
  }
35
- else if ((value.length === 6 || value.length === 8) && !isNaN(+value)) {
36
- values = [value.substring(0, 2), value.substring(2, 4), value.substring(4)];
129
+ if (year.length === 2) {
130
+ const currentYear = new Date().getFullYear();
131
+ const minYear = currentYear - (100 - FUTURE_YEAR_COERCION);
132
+ const maxYear = currentYear + FUTURE_YEAR_COERCION;
133
+ const minCentury = String(minYear).slice(0, 2);
134
+ const maxCentury = String(maxYear).slice(0, 2);
135
+ const maxYearLastTwo = +String(maxYear).slice(2);
136
+ return +year <= maxYearLastTwo ? +`${maxCentury}${year}` : +`${minCentury}${year}`;
37
137
  }
38
- const hasMonthDayYear = values.length === 3;
39
- let [month, day, year] = values;
40
- // Ensure are month and year values are coerced from 0 to 1 in case of incomplete entry
41
- if (month === '0') {
42
- month = '1';
138
+ return +year;
139
+ }
140
+ function validateAndClampDate(month, day, year) {
141
+ const clampedMonth = Math.min(Math.max(month, 1), 12);
142
+ const maxDaysInMonth = new Date(year, clampedMonth, 0).getDate();
143
+ const clampedDay = Math.min(Math.max(day, 1), maxDaysInMonth);
144
+ return { month: clampedMonth, day: clampedDay, year };
145
+ }
146
+ function parseMonthAbbreviation(abbr) {
147
+ const upperAbbr = abbr.toUpperCase();
148
+ return MONTH_ABBREVIATIONS[upperAbbr] || null;
149
+ }
150
+ function parseNumericDate(part1, part2, part3, order) {
151
+ let monthStr;
152
+ let dayStr;
153
+ let yearStr;
154
+ if (order === 'MDY') {
155
+ [monthStr, dayStr, yearStr] = [part1, part2, part3];
43
156
  }
44
- if (day === '0') {
45
- day = '1';
157
+ else if (order === 'YMD') {
158
+ [yearStr, monthStr, dayStr] = [part1, part2, part3];
46
159
  }
47
- // Trap for the case where only 3 digit years are entered
48
- if (typeof year === 'string' && year.length === 3) {
49
- year = year.padStart(4, '0');
160
+ else {
161
+ // DMY
162
+ [dayStr, monthStr, yearStr] = [part1, part2, part3];
50
163
  }
51
- if (hasMonthDayYear) {
52
- const isValidMonthLength = month.length === 1 || month.length === 2;
53
- const isValidDayLength = day.length === 1 || day.length === 2;
54
- const isValidYearLength = year.length === 2 || year.length === 4;
55
- if (!isValidMonthLength || !isValidDayLength || !isValidYearLength) {
56
- return null;
57
- }
164
+ // Handle edge cases for incomplete input
165
+ if (monthStr === '0') {
166
+ monthStr = '1';
167
+ }
168
+ if (dayStr === '0') {
169
+ dayStr = '1';
170
+ }
171
+ const year = normalizeYear(yearStr);
172
+ const month = +monthStr;
173
+ const day = +dayStr;
174
+ const { month: validMonth, day: validDay, year: validYear } = validateAndClampDate(month, day, year);
175
+ const date = new Date(validYear, validMonth - 1, validDay, 0, 0, 0, 0);
176
+ return isValidDate(date) ? date : null;
177
+ }
178
+ function parseWithMonthAbbr(part1, monthAbbr, part3, order) {
179
+ const monthNum = parseMonthAbbreviation(monthAbbr);
180
+ if (!monthNum) {
181
+ return null;
182
+ }
183
+ let dayStr;
184
+ let yearStr;
185
+ if (order === 'DMY') {
186
+ [dayStr, yearStr] = [part1, part3];
58
187
  }
59
188
  else {
189
+ [yearStr, dayStr] = [part1, part3];
190
+ }
191
+ const year = normalizeYear(yearStr);
192
+ const day = +dayStr;
193
+ const { day: validDay, year: validYear } = validateAndClampDate(monthNum, day, year);
194
+ const date = new Date(validYear, monthNum - 1, validDay, 0, 0, 0, 0);
195
+ return isValidDate(date) ? date : null;
196
+ }
197
+ function parseISO8601(value) {
198
+ if (!ISO_8601_REGEX.test(value)) {
60
199
  return null;
61
200
  }
62
- // Check if we need to coerce two-digit years to the four-digit equivalent
63
- if (year.length === 2) {
64
- const minYear = new Date().getFullYear() - (100 - FUTURE_YEAR_COERCION);
65
- const maxYear = new Date().getFullYear() + FUTURE_YEAR_COERCION;
66
- const minYearCentury = String(minYear).slice(0, 2);
67
- const maxYearCentury = String(maxYear).slice(0, 2);
68
- const normalizedMaxYear = +String(maxYear).slice(2);
69
- year = +year <= normalizedMaxYear ? `${maxYearCentury}${year}` : `${minYearCentury}${year}`;
70
- }
71
- let numMonth = +month;
72
- let numDay = +day;
73
- const numYear = +year;
74
- if (numMonth > 12) {
75
- numMonth = 12;
76
- }
77
- const maxDaysInMonth = new Date(numYear, numMonth, 0).getDate();
78
- if (numDay > maxDaysInMonth) {
79
- numDay = maxDaysInMonth;
80
- }
81
- const parsedDate = new Date(numYear, numMonth - 1, numDay, 0, 0, 0, 0);
82
- return isValidDate(parsedDate) ? parsedDate : null;
201
+ const date = new Date(value);
202
+ // Handle timezone offset for ISO strings without explicit timezone
203
+ if (!ISO_TIMEZONE_REGEX.test(value)) {
204
+ date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
205
+ }
206
+ return isValidDate(date) ? date : null;
83
207
  }
84
208
  /**
85
- * Formats a `Date` to a specified format.
86
- * @param str The date string value.
209
+ * Parses a date string value to a `Date` object in local time.
210
+ * Supports multiple formats as defined in SupportedDateFormats.
211
+ *
212
+ * @param value The date string value to parse
213
+ * @param format Optional format hint for better parsing accuracy
214
+ * @returns Parsed Date object or null if parsing fails
87
215
  */
88
- export function formatDate(date) {
89
- const month = String(date.getMonth() + 1).padStart(2, '0');
90
- const day = String(date.getDate()).padStart(2, '0');
91
- const year = String(date.getFullYear()).padStart(4, '0');
92
- return [month, day, year].join('/');
216
+ export function parseDateString(value, format) {
217
+ const cleanValue = value.replace(/[_\s]/g, '');
218
+ // Try ISO 8601 first
219
+ const isoDate = parseISO8601(cleanValue);
220
+ if (isoDate) {
221
+ return isoDate;
222
+ }
223
+ // Try each pattern until one matches
224
+ for (const pattern of DATE_PATTERNS) {
225
+ const match = cleanValue.match(pattern.regex);
226
+ if (match) {
227
+ const result = pattern.parser(match.slice(1));
228
+ if (result) {
229
+ return result;
230
+ }
231
+ }
232
+ }
233
+ return null;
234
+ }
235
+ /**
236
+ * Formats a Date object to a specified string format.
237
+ *
238
+ * @param date The Date object to format
239
+ * @param format The desired output format (defaults to 'MM/DD/YYYY')
240
+ * @returns Formatted date string
241
+ * @throws Error if date is invalid or format is unsupported
242
+ */
243
+ export function formatDate(date, format = 'MM/DD/YYYY') {
244
+ if (!isValidDate(date)) {
245
+ throw new Error('Invalid date provided');
246
+ }
247
+ const config = FORMAT_CONFIGS[format];
248
+ if (!config) {
249
+ throw new Error(`Unsupported format: ${format}`);
250
+ }
251
+ return config.formatter(date);
93
252
  }
94
253
  /**
95
254
  * Determines if two date objects are equal.
@@ -5,10 +5,19 @@
5
5
  */
6
6
  import { Masked, InputMask, type AppendFlags, type FactoryArg } from 'imask';
7
7
  import { DayOfWeek, ICalendarDateSelectEventData } from '../../calendar';
8
- export declare type DatePickerParseCallback = (value: string) => Date | null;
9
- export declare type DatePickerFormatCallback = (value: Date | null) => string;
10
- export declare type DatePickerPrepareMaskCallback = (value: string, masked: Masked<string>, flags: AppendFlags, maskInstance: InputMask<FactoryArg>) => string;
11
- export declare type DatePickerValueMode = 'object' | 'string' | 'iso-string';
8
+ import { type IDatePickerComponent } from '../date-picker';
9
+ import { SupportedDateFormats } from '../../core/utils/date-utils';
10
+ export type DatePickerParseCallback = (value: string) => Date | null;
11
+ export type DatePickerFormatCallback = (value: Date | null) => string | null;
12
+ export type DatePickerPrepareMaskCallback = (value: string, masked: Masked<string>, flags: AppendFlags, maskInstance: InputMask<FactoryArg>) => string;
13
+ export type DatePickerValueMode = 'object' | 'string' | 'iso-string';
14
+ export type DatePickerShortcuts = IDatePickerShortcuts | 'off' | undefined;
15
+ export type DatePickerDateFormat = SupportedDateFormats;
16
+ export interface IDatePickerShortcuts {
17
+ [key: string]: (context: {
18
+ instance: IDatePickerComponent;
19
+ }) => Date | null | undefined | void;
20
+ }
12
21
  export interface IDatePickerCalendarDropdownConfig<T> {
13
22
  value?: T | null;
14
23
  min?: Date | null;
@@ -45,7 +54,9 @@ export declare const BASE_DATE_PICKER_CONSTANTS: {
45
54
  MASKED: string;
46
55
  MASK_FORMAT: string;
47
56
  SHOW_MASK_FORMAT: string;
57
+ DATE_FORMAT: string;
48
58
  VALUE_MODE: string;
59
+ SHORTCUTS: string;
49
60
  ALLOW_INVALID_DATE: string;
50
61
  SHOW_TODAY: string;
51
62
  SHOW_CLEAR: string;
@@ -61,4 +72,8 @@ export declare const BASE_DATE_PICKER_CONSTANTS: {
61
72
  INPUT: string;
62
73
  TOGGLE: string;
63
74
  };
75
+ defaults: {
76
+ DATE_FORMAT: DatePickerDateFormat;
77
+ };
78
+ supportedDateFormats: SupportedDateFormats[];
64
79
  };
@@ -12,7 +12,9 @@ const observedAttributes = {
12
12
  MASKED: 'masked',
13
13
  MASK_FORMAT: 'mask-format',
14
14
  SHOW_MASK_FORMAT: 'show-mask-format',
15
+ DATE_FORMAT: 'date-format',
15
16
  VALUE_MODE: 'value-mode',
17
+ SHORTCUTS: 'shortcuts',
16
18
  ALLOW_INVALID_DATE: 'allow-invalid-date',
17
19
  SHOW_TODAY: 'show-today',
18
20
  SHOW_CLEAR: 'show-clear',
@@ -28,8 +30,25 @@ const selectors = {
28
30
  INPUT: 'input',
29
31
  TOGGLE: '[forge-date-picker-toggle],[data-forge-date-picker-toggle]'
30
32
  };
33
+ const defaults = {
34
+ DATE_FORMAT: 'MM/DD/YYYY'
35
+ };
36
+ const supportedDateFormats = [
37
+ 'MM/DD/YYYY',
38
+ 'MM/DD/YY',
39
+ 'DD/MMM/YYYY',
40
+ 'MM-DD-YYYY',
41
+ 'MM-DD-YY',
42
+ 'DD-MMM-YYYY',
43
+ 'YYYY-MM-DD',
44
+ 'YYYY-MMM-DD',
45
+ 'DD.MM.YYYY',
46
+ 'DD.MM.YY'
47
+ ];
31
48
  export const BASE_DATE_PICKER_CONSTANTS = {
32
49
  observedAttributes,
33
50
  attributes,
34
- selectors
51
+ selectors,
52
+ defaults,
53
+ supportedDateFormats
35
54
  };
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { CalendarMode, DayOfWeek, ICalendarDateSelectEventData } from '../../calendar/calendar-constants';
7
7
  import { IBaseDatePickerAdapter } from './base-date-picker-adapter';
8
- import { DatePickerFormatCallback, DatePickerParseCallback, DatePickerPrepareMaskCallback, DatePickerValueMode, IDatePickerCalendarDropdownText } from './base-date-picker-constants';
8
+ import { DatePickerFormatCallback, DatePickerParseCallback, DatePickerPrepareMaskCallback, IDatePickerShortcuts, DatePickerValueMode, IDatePickerCalendarDropdownText, DatePickerShortcuts, DatePickerDateFormat } from './base-date-picker-constants';
9
9
  export interface IBaseDatePickerCore<TValue> {
10
10
  value: TValue | null | undefined;
11
11
  min: Date | string | null | undefined;
@@ -20,6 +20,7 @@ export interface IBaseDatePickerCore<TValue> {
20
20
  masked: boolean;
21
21
  maskFormat: string;
22
22
  showMaskFormat: boolean;
23
+ dateFormat: DatePickerDateFormat;
23
24
  valueMode: DatePickerValueMode;
24
25
  notifyInputValueChanges: boolean;
25
26
  allowInvalidDate: boolean;
@@ -45,7 +46,9 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
45
46
  protected _masked: boolean;
46
47
  protected _maskFormat: string;
47
48
  protected _showMaskFormat: boolean;
49
+ protected _dateFormat: DatePickerDateFormat;
48
50
  protected _valueMode: DatePickerValueMode;
51
+ protected _shortcuts: IDatePickerShortcuts | undefined;
49
52
  protected _notifyInputValueChanges: boolean;
50
53
  protected _allowInvalidDate: boolean;
51
54
  protected _showToday: boolean;
@@ -95,6 +98,7 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
95
98
  protected _onInputBlur(evt: FocusEvent): void;
96
99
  protected _openCalendar(emitOpenEvent?: boolean): void;
97
100
  protected _closeCalendar(emitCloseEvent?: boolean): void;
101
+ private _getDefaultShortcuts;
98
102
  protected _onInputKeydown(evt: KeyboardEvent): void;
99
103
  protected _getSanitizedDateString(value: string): string;
100
104
  private _onToggleMousedown;
@@ -102,19 +106,21 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
102
106
  private _onMonthChanged;
103
107
  private _onActiveDescendantChanged;
104
108
  protected _formatInputValue(): void;
105
- protected _formatDate(date: Date | null | undefined): string;
109
+ protected _formatDate(date: Date | null | undefined): string | null;
106
110
  protected _parseDateString(value: string): Date | null;
107
111
  protected _coerceDateValue(value?: Date | string | null): Date | null | undefined;
108
112
  protected _getTypedValue(value: Date | null | undefined): Date | string | null | undefined;
109
113
  protected _isDateValueAcceptable(value?: Date | null): boolean;
110
114
  protected _initializeMask(): void;
111
- private _applyMask;
115
+ protected _applyMask(): void;
112
116
  protected _applyMin(): void;
113
117
  protected _applyMax(): void;
114
118
  private _applyDisableDayCallback;
115
119
  private _applyDisabled;
116
120
  get valueMode(): DatePickerValueMode;
117
121
  set valueMode(value: DatePickerValueMode);
122
+ get shortcuts(): DatePickerShortcuts;
123
+ set shortcuts(value: DatePickerShortcuts);
118
124
  get min(): Date | string | null | undefined;
119
125
  set min(value: Date | string | null | undefined);
120
126
  get max(): Date | string | null | undefined;
@@ -133,6 +139,8 @@ export declare abstract class BaseDatePickerCore<TAdapter extends IBaseDatePicke
133
139
  set maskFormat(value: string);
134
140
  get showMaskFormat(): boolean;
135
141
  set showMaskFormat(value: boolean);
142
+ get dateFormat(): DatePickerDateFormat;
143
+ set dateFormat(value: DatePickerDateFormat);
136
144
  get notifyInputValueChanges(): boolean;
137
145
  set notifyInputValueChanges(value: boolean);
138
146
  get allowInvalidDate(): boolean;