bge-ui 1.3.3 → 1.3.5

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 (137) hide show
  1. package/dist/datePicker/components/ActionRow.vue.d.ts +1051 -0
  2. package/dist/datePicker/components/Common/ArrowBtn.vue.d.ts +29 -0
  3. package/dist/datePicker/components/Common/InstanceWrap.vue.d.ts +29 -0
  4. package/dist/datePicker/components/Common/SelectionOverlay.vue.d.ts +55 -0
  5. package/dist/datePicker/components/DatePicker/DatePicker.vue.d.ts +1114 -0
  6. package/dist/datePicker/components/DatePicker/DpCalendar.vue.d.ts +1085 -0
  7. package/dist/datePicker/components/DatePicker/DpHeader.vue.d.ts +1103 -0
  8. package/dist/datePicker/components/DatePicker/date-picker.d.ts +35 -0
  9. package/dist/datePicker/components/DatepickerInput.vue.d.ts +1008 -0
  10. package/dist/datePicker/components/DatepickerMenu.vue.d.ts +1061 -0
  11. package/dist/datePicker/components/Icons/CalendarIcon.d.ts +9 -0
  12. package/dist/datePicker/components/Icons/CancelIcon.d.ts +9 -0
  13. package/dist/datePicker/components/Icons/ChevronDownIcon.d.ts +9 -0
  14. package/dist/datePicker/components/Icons/ChevronLeftIcon.d.ts +9 -0
  15. package/dist/datePicker/components/Icons/ChevronRightIcon.d.ts +9 -0
  16. package/dist/datePicker/components/Icons/ChevronUpIcon.d.ts +9 -0
  17. package/dist/datePicker/components/Icons/ClockIcon.d.ts +9 -0
  18. package/dist/datePicker/components/Icons/index.d.ts +7 -0
  19. package/dist/datePicker/components/MonthPicker/MonthPicker.vue.d.ts +1071 -0
  20. package/dist/datePicker/components/MonthPicker/month-picker.d.ts +34 -0
  21. package/dist/datePicker/components/QuarterPicker/QuarterPicker.vue.d.ts +1043 -0
  22. package/dist/datePicker/components/QuarterPicker/quarter-picker.d.ts +25 -0
  23. package/dist/datePicker/components/TimePicker/TimeInput.vue.d.ts +1116 -0
  24. package/dist/datePicker/components/TimePicker/TimePicker.vue.d.ts +1087 -0
  25. package/dist/datePicker/components/TimePicker/TimePickerSolo.vue.d.ts +1036 -0
  26. package/dist/datePicker/components/TimePicker/time-picker-utils.d.ts +15 -0
  27. package/dist/datePicker/components/TimePicker/time-picker.d.ts +13 -0
  28. package/dist/datePicker/components/YearPicker/YearPicker.vue.d.ts +1040 -0
  29. package/dist/datePicker/components/YearPicker/year-picker.d.ts +9 -0
  30. package/dist/datePicker/components/shared/YearModePicker.vue.d.ts +1075 -0
  31. package/dist/datePicker/components/shared/month-quarter-picker.d.ts +29 -0
  32. package/dist/datePicker/composables/arrow-navigate.d.ts +26 -0
  33. package/dist/datePicker/composables/calendar-class.d.ts +8 -0
  34. package/dist/datePicker/composables/common.d.ts +6 -0
  35. package/dist/datePicker/composables/defaults.d.ts +37 -0
  36. package/dist/datePicker/composables/external-internal-mapper.d.ts +14 -0
  37. package/dist/datePicker/composables/flow.d.ts +10 -0
  38. package/dist/datePicker/composables/index.d.ts +14 -0
  39. package/dist/datePicker/composables/model.d.ts +17 -0
  40. package/dist/datePicker/composables/month-year.d.ts +10 -0
  41. package/dist/datePicker/composables/position.d.ts +25 -0
  42. package/dist/datePicker/composables/shared.d.ts +12 -0
  43. package/dist/datePicker/composables/slots.d.ts +10 -0
  44. package/dist/datePicker/composables/state.d.ts +8 -0
  45. package/dist/datePicker/composables/transition.d.ts +7 -0
  46. package/dist/datePicker/composables/validation.d.ts +12 -0
  47. package/dist/datePicker/constants/index.d.ts +43 -0
  48. package/dist/datePicker/datePicker.vue.d.ts +1006 -0
  49. package/dist/datePicker/directives/clickOutside.d.ts +2 -0
  50. package/dist/datePicker/index.vue.d.ts +1012 -0
  51. package/dist/datePicker/interfaces.d.ts +323 -0
  52. package/dist/datePicker/props.d.ts +865 -0
  53. package/dist/datePicker/utils/date-utils.d.ts +45 -0
  54. package/dist/datePicker/utils/defaults.d.ts +42 -0
  55. package/dist/datePicker/utils/timezone.d.ts +8 -0
  56. package/dist/datePicker/utils/type-guard.d.ts +1 -0
  57. package/dist/datePicker/utils/util.d.ts +57 -0
  58. package/dist/dialog/index.vue.d.ts +6 -3
  59. package/dist/index.d.ts +2 -1
  60. package/dist/index.js +13014 -1253
  61. package/dist/slider/index.vue.d.ts +9 -0
  62. package/dist/style.css +1188 -1
  63. package/dist/tooltip/index.vue.d.ts +2 -2
  64. package/dist/tooltip/usePopper.d.ts +5 -5
  65. package/package.json +3 -2
  66. package/src/datePicker/components/ActionRow.vue +217 -0
  67. package/src/datePicker/components/Common/ArrowBtn.vue +42 -0
  68. package/src/datePicker/components/Common/InstanceWrap.vue +28 -0
  69. package/src/datePicker/components/Common/SelectionOverlay.vue +320 -0
  70. package/src/datePicker/components/DatePicker/DatePicker.vue +302 -0
  71. package/src/datePicker/components/DatePicker/DpCalendar.vue +405 -0
  72. package/src/datePicker/components/DatePicker/DpHeader.vue +332 -0
  73. package/src/datePicker/components/DatePicker/date-picker.ts +674 -0
  74. package/src/datePicker/components/DatepickerInput.vue +334 -0
  75. package/src/datePicker/components/DatepickerMenu.vue +424 -0
  76. package/src/datePicker/components/Icons/CalendarIcon.ts +40 -0
  77. package/src/datePicker/components/Icons/CancelIcon.ts +32 -0
  78. package/src/datePicker/components/Icons/ChevronDownIcon.ts +29 -0
  79. package/src/datePicker/components/Icons/ChevronLeftIcon.ts +29 -0
  80. package/src/datePicker/components/Icons/ChevronRightIcon.ts +29 -0
  81. package/src/datePicker/components/Icons/ChevronUpIcon.ts +29 -0
  82. package/src/datePicker/components/Icons/ClockIcon.ts +32 -0
  83. package/src/datePicker/components/Icons/index.ts +8 -0
  84. package/src/datePicker/components/MonthPicker/MonthPicker.vue +130 -0
  85. package/src/datePicker/components/MonthPicker/month-picker.ts +232 -0
  86. package/src/datePicker/components/QuarterPicker/QuarterPicker.vue +111 -0
  87. package/src/datePicker/components/QuarterPicker/quarter-picker.ts +153 -0
  88. package/src/datePicker/components/TimePicker/TimeInput.vue +477 -0
  89. package/src/datePicker/components/TimePicker/TimePicker.vue +265 -0
  90. package/src/datePicker/components/TimePicker/TimePickerSolo.vue +79 -0
  91. package/src/datePicker/components/TimePicker/time-picker-utils.ts +179 -0
  92. package/src/datePicker/components/TimePicker/time-picker.ts +112 -0
  93. package/src/datePicker/components/YearPicker/YearPicker.vue +70 -0
  94. package/src/datePicker/components/YearPicker/year-picker.ts +109 -0
  95. package/src/datePicker/components/shared/YearModePicker.vue +105 -0
  96. package/src/datePicker/components/shared/month-quarter-picker.ts +199 -0
  97. package/src/datePicker/composables/arrow-navigate.ts +191 -0
  98. package/src/datePicker/composables/calendar-class.ts +384 -0
  99. package/src/datePicker/composables/common.ts +25 -0
  100. package/src/datePicker/composables/defaults.ts +123 -0
  101. package/src/datePicker/composables/external-internal-mapper.ts +443 -0
  102. package/src/datePicker/composables/flow.ts +70 -0
  103. package/src/datePicker/composables/index.ts +14 -0
  104. package/src/datePicker/composables/model.ts +89 -0
  105. package/src/datePicker/composables/month-year.ts +72 -0
  106. package/src/datePicker/composables/position.ts +297 -0
  107. package/src/datePicker/composables/shared.ts +98 -0
  108. package/src/datePicker/composables/slots.ts +84 -0
  109. package/src/datePicker/composables/state.ts +25 -0
  110. package/src/datePicker/composables/transition.ts +18 -0
  111. package/src/datePicker/composables/validation.ts +312 -0
  112. package/src/datePicker/constants/index.ts +49 -0
  113. package/src/datePicker/datePicker.vue +554 -0
  114. package/src/datePicker/directives/clickOutside.ts +79 -0
  115. package/src/datePicker/index.vue +157 -0
  116. package/src/datePicker/interfaces.ts +404 -0
  117. package/src/datePicker/props.ts +173 -0
  118. package/src/datePicker/style/components/_ActionRow.scss +73 -0
  119. package/src/datePicker/style/components/_Calendar.scss +284 -0
  120. package/src/datePicker/style/components/_DatepickerInput.scss +109 -0
  121. package/src/datePicker/style/components/_DatepickerMenu.scss +213 -0
  122. package/src/datePicker/style/components/_MonthYearInput.scss +97 -0
  123. package/src/datePicker/style/components/_QuarterPicker.scss +53 -0
  124. package/src/datePicker/style/components/_SelectionOverlay.scss +142 -0
  125. package/src/datePicker/style/components/_TimeInput.scss +181 -0
  126. package/src/datePicker/style/components/_shared.scss +15 -0
  127. package/src/datePicker/style/main.scss +259 -0
  128. package/src/datePicker/utils/date-utils.ts +432 -0
  129. package/src/datePicker/utils/defaults.ts +327 -0
  130. package/src/datePicker/utils/timezone.ts +38 -0
  131. package/src/datePicker/utils/type-guard.ts +3 -0
  132. package/src/datePicker/utils/util.ts +322 -0
  133. package/src/dialog/index.vue +9 -0
  134. package/src/form/index.vue +2 -1
  135. package/src/index.ts +6 -2
  136. package/src/slider/index.vue +6 -2
  137. package/src/tooltip/usePopper.ts +1 -1
@@ -0,0 +1,327 @@
1
+ import type {
2
+ AriaLabels,
3
+ IFormat,
4
+ Transition,
5
+ TextInputOptions,
6
+ DateFilter,
7
+ ActionRowData,
8
+ MultiCalendarsProp,
9
+ MultiCalendarsOptions,
10
+ OptionEnabled,
11
+ TextInputProp,
12
+ InlineProp,
13
+ InlineOptions,
14
+ Config,
15
+ HighlightProp,
16
+ Highlight,
17
+ HighlightFn,
18
+ WeekNumbersProp,
19
+ WeekNumbersOpts,
20
+ RangeProp,
21
+ RangeConfig,
22
+ TimeZoneProp,
23
+ TimeZoneConfig,
24
+ IMarker,
25
+ PropDates,
26
+ MultiDatesProp,
27
+ MultiDatesDefault,
28
+ MapPropDatesOpts,
29
+ UIOpts,
30
+ UIParsed,
31
+ } from '../interfaces';
32
+ import { getDate } from '../utils/date-utils';
33
+ import { dateToTimezoneSafe, sanitizeDateToLocal } from '../utils/timezone';
34
+ import { getMapKey, shouldMap } from '../utils/util';
35
+
36
+ export const mergeDefaultTransitions = (conf: Partial<Transition>): Transition => ({
37
+ menuAppearTop: 'dp-menu-appear-top',
38
+ menuAppearBottom: 'dp-menu-appear-bottom',
39
+ open: 'dp-slide-down',
40
+ close: 'dp-slide-up',
41
+ next: 'calendar-next',
42
+ previous: 'calendar-prev',
43
+ vNext: 'dp-slide-up',
44
+ vPrevious: 'dp-slide-down',
45
+ ...(conf ?? {}),
46
+ });
47
+
48
+ export const defaultAriaLabels = (labels: Partial<AriaLabels>): AriaLabels => {
49
+ return {
50
+ toggleOverlay: 'Toggle overlay',
51
+ menu: 'Datepicker menu',
52
+ input: 'Datepicker input',
53
+ openTimePicker: 'Open time picker',
54
+ closeTimePicker: 'Close time Picker',
55
+ incrementValue: (type: string) => `Increment ${type}`,
56
+ decrementValue: (type: string) => `Decrement ${type}`,
57
+ openTpOverlay: (type: string) => `Open ${type} overlay`,
58
+ amPmButton: 'Switch AM/PM mode',
59
+ openYearsOverlay: 'Open years overlay',
60
+ openMonthsOverlay: 'Open months overlay',
61
+ nextMonth: 'Next month',
62
+ prevMonth: 'Previous month',
63
+ nextYear: 'Next year',
64
+ prevYear: 'Previous year',
65
+ day: undefined,
66
+ weekDay: undefined,
67
+ clearInput: 'Clear value',
68
+ calendarIcon: 'Calendar icon',
69
+ timePicker: 'Time picker',
70
+ monthPicker: (overlay: boolean) => `Month picker${overlay ? ' overlay' : ''}`,
71
+ yearPicker: (overlay: boolean) => `Year picker${overlay ? ' overlay' : ''}`,
72
+ timeOverlay: (type: string) => `${type} overlay`,
73
+ ...(labels ?? {}),
74
+ };
75
+ };
76
+
77
+ const getMultiCalendarsCount = (option?: OptionEnabled) => {
78
+ if (!option) return 0;
79
+ if (typeof option === 'boolean') return option ? 2 : 0;
80
+ return +option >= 2 ? +option : 2;
81
+ };
82
+
83
+ export const defaultMultiCalendars = (multiCalendars?: MultiCalendarsProp): MultiCalendarsOptions => {
84
+ const isConfig = typeof multiCalendars === 'object' && multiCalendars;
85
+ const defaultOptions = {
86
+ static: true,
87
+ solo: false,
88
+ };
89
+ if (!multiCalendars) return { ...defaultOptions, count: getMultiCalendarsCount(false) };
90
+ const addOptions = isConfig ? multiCalendars : ({} as MultiCalendarsOptions);
91
+ const option = isConfig ? addOptions.count ?? true : multiCalendars;
92
+ const count = getMultiCalendarsCount(option);
93
+
94
+ return Object.assign(defaultOptions, addOptions, { count });
95
+ };
96
+
97
+ export const defaultPreviewFormat = (
98
+ previewFormat: IFormat,
99
+ format: IFormat,
100
+ defaultPattern: string | ((val: Date) => string),
101
+ ): IFormat => {
102
+ if (!previewFormat) {
103
+ return typeof defaultPattern === 'string' ? defaultPattern : format;
104
+ }
105
+ return previewFormat;
106
+ };
107
+
108
+ export const defaultTransitions = (transitions: boolean | Partial<Transition>): Transition => {
109
+ if (typeof transitions === 'boolean') {
110
+ return transitions ? mergeDefaultTransitions({}) : (false as unknown as Transition);
111
+ }
112
+ return mergeDefaultTransitions(transitions);
113
+ };
114
+
115
+ /**
116
+ * Default options to merge with user provided ones
117
+ */
118
+ export const getDefaultTextInputOptions = (textInput: TextInputProp): TextInputOptions & { enabled: boolean } => {
119
+ const defaultOptions = {
120
+ enterSubmit: true,
121
+ tabSubmit: true,
122
+ openMenu: 'open',
123
+ selectOnFocus: false,
124
+ rangeSeparator: ' - ',
125
+ };
126
+
127
+ if (typeof textInput === 'object') {
128
+ return { ...defaultOptions, ...(textInput ?? {}), enabled: true };
129
+ }
130
+ return { ...defaultOptions, enabled: textInput };
131
+ };
132
+
133
+ /**
134
+ * Default filters to merge with user provided values
135
+ */
136
+ export const getDefaultFilters = (filters: Partial<DateFilter>): DateFilter => ({
137
+ months: [],
138
+ years: [],
139
+ times: { hours: [], minutes: [], seconds: [] },
140
+ ...(filters ?? {}),
141
+ });
142
+
143
+ export const getDefaultActionRowData = (actionRow: Partial<ActionRowData>): ActionRowData => ({
144
+ showSelect: true,
145
+ showCancel: true,
146
+ showNow: false,
147
+ showPreview: true,
148
+ ...(actionRow ?? {}),
149
+ });
150
+
151
+ export const getDefaultInlineOptions = (inline: InlineProp): InlineOptions => {
152
+ const defaultOptions = { input: false };
153
+ if (typeof inline === 'object') {
154
+ return { ...defaultOptions, ...(inline ?? {}), enabled: true };
155
+ }
156
+ return {
157
+ enabled: inline,
158
+ ...defaultOptions,
159
+ };
160
+ };
161
+
162
+ export const getDefaultConfig = (config?: Partial<Config>): Config => {
163
+ const defaultConfig = {
164
+ allowStopPropagation: true,
165
+ closeOnScroll: false,
166
+ modeHeight: 255,
167
+ allowPreventDefault: false,
168
+ closeOnClearValue: true,
169
+ closeOnAutoApply: true,
170
+ noSwipe: false,
171
+ keepActionRow: false,
172
+ onClickOutside: undefined,
173
+ tabOutClosesMenu: true,
174
+ arrowLeft: undefined,
175
+ keepViewOnOffsetClick: false,
176
+ timeArrowHoldThreshold: 0,
177
+ shadowDom: false,
178
+ };
179
+ return { ...defaultConfig, ...(config ?? {}) };
180
+ };
181
+
182
+ export const getDefaultHighlight = (highlight: HighlightProp): Highlight | HighlightFn => {
183
+ const defaultOptions = {
184
+ dates: Array.isArray(highlight) ? highlight.map((date) => getDate(date)) : [],
185
+ years: [],
186
+ months: [],
187
+ quarters: [],
188
+ weeks: [],
189
+ weekdays: [],
190
+ options: { highlightDisabled: false },
191
+ };
192
+
193
+ if (typeof highlight === 'function') return highlight;
194
+ return { ...defaultOptions, ...(highlight ?? {}) };
195
+ };
196
+
197
+ export const getDefaultWeekNumbers = (weekNumbers: WeekNumbersProp): WeekNumbersOpts => {
198
+ if (typeof weekNumbers === 'object') {
199
+ return {
200
+ type: weekNumbers?.type ?? 'local',
201
+ hideOnOffsetDates: weekNumbers?.hideOnOffsetDates ?? false,
202
+ };
203
+ }
204
+ return {
205
+ type: weekNumbers,
206
+ hideOnOffsetDates: false,
207
+ };
208
+ };
209
+
210
+ export const getDefaultRangeOptions = (config: RangeProp): RangeConfig => {
211
+ const defaultOptions = {
212
+ noDisabledRange: false,
213
+ showLastInRange: true,
214
+ minMaxRawRange: false,
215
+ partialRange: true,
216
+ disableTimeRangeValidation: false,
217
+ maxRange: undefined,
218
+ minRange: undefined,
219
+ autoRange: undefined,
220
+ fixedStart: false,
221
+ fixedEnd: false,
222
+ };
223
+ if (typeof config === 'object') {
224
+ return { enabled: true, ...defaultOptions, ...config };
225
+ }
226
+ return {
227
+ enabled: config,
228
+ ...defaultOptions,
229
+ };
230
+ };
231
+
232
+ export const getDefaultTimeZone = (timeZone: TimeZoneProp) => {
233
+ if (!timeZone) return { timezone: undefined, exactMatch: false, emitTimezone: undefined };
234
+ if (typeof timeZone === 'string') {
235
+ return {
236
+ timezone: timeZone,
237
+ exactMatch: false,
238
+ dateInTz: undefined,
239
+ emitTimezone: undefined,
240
+ convertModel: true,
241
+ };
242
+ }
243
+ return {
244
+ timezone: timeZone.timezone,
245
+ exactMatch: timeZone.exactMatch ?? false,
246
+ dateInTz: timeZone.dateInTz ?? undefined,
247
+ emitTimezone: timeZone.emitTimezone ?? undefined,
248
+ convertModel: timeZone.convertModel ?? true,
249
+ };
250
+ };
251
+
252
+ const datesArrToMap = (
253
+ datesArr: (Date | string | number)[],
254
+ timezone: TimeZoneConfig | undefined,
255
+ reset?: boolean,
256
+ ): Map<string, Date | null> => {
257
+ return new Map(
258
+ datesArr.map((date) => {
259
+ const d = dateToTimezoneSafe(date, timezone, reset);
260
+ return [getMapKey(d), d];
261
+ }),
262
+ );
263
+ };
264
+
265
+ const mapMarkers = (markers: IMarker[], timezone: TimeZoneConfig | undefined) => {
266
+ if (markers.length) {
267
+ return new Map(
268
+ markers.map((marker) => {
269
+ const date = dateToTimezoneSafe(marker.date, timezone);
270
+ return [getMapKey(date), marker];
271
+ }),
272
+ );
273
+ }
274
+ return null;
275
+ };
276
+
277
+ /**
278
+ * Sync all props that rely on the date value to be in the same timezone
279
+ * All validation that is done from these props will now be in sync with provided timezone config
280
+ */
281
+ export const mapPropDates = (opts: MapPropDatesOpts): PropDates => {
282
+ return {
283
+ minDate: sanitizeDateToLocal(opts.minDate, opts.timezone, opts.isSpecific),
284
+ maxDate: sanitizeDateToLocal(opts.maxDate, opts.timezone, opts.isSpecific),
285
+ disabledDates: shouldMap(opts.disabledDates)
286
+ ? datesArrToMap(opts.disabledDates, opts.timezone, opts.isSpecific)
287
+ : opts.disabledDates,
288
+ allowedDates: shouldMap(opts.allowedDates)
289
+ ? datesArrToMap(opts.allowedDates, opts.timezone, opts.isSpecific)
290
+ : null,
291
+ highlight:
292
+ typeof opts.highlight === 'object' && shouldMap(opts.highlight?.dates)
293
+ ? datesArrToMap(opts.highlight.dates, opts.timezone)
294
+ : (opts.highlight as HighlightFn),
295
+ markers: mapMarkers(opts.markers, opts.timezone),
296
+ };
297
+ };
298
+
299
+ export const getDefaultMultiDates = (multiDates: MultiDatesProp): MultiDatesDefault => {
300
+ if (typeof multiDates === 'boolean') {
301
+ return { enabled: multiDates, dragSelect: true, limit: null };
302
+ }
303
+ return {
304
+ enabled: !!multiDates,
305
+ limit: multiDates.limit ? +multiDates.limit : null,
306
+ dragSelect: multiDates.dragSelect ?? true,
307
+ };
308
+ };
309
+
310
+ export const getDefaultUI = (ui: Partial<UIOpts>): UIParsed => {
311
+ const defaulted = {
312
+ ...Object.fromEntries(
313
+ Object.keys(ui).map((item) => {
314
+ const key = item as keyof UIOpts;
315
+ const value = ui[key];
316
+ const val = (
317
+ typeof ui[key] === 'string'
318
+ ? { [value as string]: true }
319
+ : Object.fromEntries((value as string[]).map((k) => [k, true]))
320
+ ) as Record<string, boolean>;
321
+ return [item, val];
322
+ }),
323
+ ),
324
+ };
325
+
326
+ return defaulted as UIParsed;
327
+ };
@@ -0,0 +1,38 @@
1
+ import { getDate, resetDateTime } from '../utils/date-utils';
2
+ import type { MaybeDate, TimeZoneConfig } from '../interfaces';
3
+
4
+ /**
5
+ * Converts date from the local timezone into the specific timezone
6
+ */
7
+ export const localToTz = (date: Date, timeZone?: string) => {
8
+ if (!timeZone) return new Date(date);
9
+ return new Date(date.toLocaleString('en-US', { timeZone }));
10
+ };
11
+
12
+ export const dateToTimezoneSafe = (date: Date | string | number, tz?: TimeZoneConfig, reset?: boolean) => {
13
+ const d = sanitizeDateToLocal(date, tz, reset);
14
+ if (!d) return getDate();
15
+ return d;
16
+ };
17
+
18
+ const getDateInTz = (date: Date | number | string, tz: TimeZoneConfig, reset?: boolean) => {
19
+ const newDate = tz.dateInTz ? localToTz(new Date(date), tz.dateInTz) : getDate(date);
20
+ return reset ? resetDateTime(newDate, true) : newDate;
21
+ };
22
+
23
+ // Converts specific date to a Date object based on a provided timezone
24
+ export const sanitizeDateToLocal = (date: MaybeDate, tz?: TimeZoneConfig, reset?: boolean) => {
25
+ if (!date) return null;
26
+ const newDate = reset ? resetDateTime(getDate(date), true) : getDate(date);
27
+ if (!tz) return newDate;
28
+ return tz.exactMatch ? getDateInTz(date, tz, reset) : localToTz(newDate, tz.timezone);
29
+ };
30
+
31
+ export const getTimezoneOffset = (timezone?: string) => {
32
+ if (!timezone) return 0;
33
+ const date = new Date();
34
+ const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
35
+ const specificDate = new Date(date.toLocaleString('en-US', { timeZone: timezone }));
36
+ const dstOffset = specificDate.getTimezoneOffset() / 60;
37
+ return (+utcDate - +specificDate) / (1000 * 60 * 60) - dstOffset;
38
+ };
@@ -0,0 +1,3 @@
1
+ export const isNumberArray = (value: number | number[]): value is number[] => {
2
+ return Array.isArray(value);
3
+ };
@@ -0,0 +1,322 @@
1
+ import { unref } from 'vue';
2
+ import { format } from 'date-fns';
3
+
4
+ import type {
5
+ Config,
6
+ DPElements,
7
+ IDefaultSelect,
8
+ IMarker,
9
+ MaybeElementRef,
10
+ ModelValue,
11
+ OverlayGridItem,
12
+ } from '../interfaces';
13
+ import { type Locale } from 'date-fns';
14
+ import type { ComponentPublicInstance } from 'vue';
15
+ import { getDate } from './date-utils';
16
+ import { localToTz } from './timezone';
17
+ import { EventKey } from '../constants';
18
+
19
+ export const getArrayInArray = <T>(list: T[], increment = 3): T[][] => {
20
+ const items = [];
21
+ for (let i = 0; i < list.length; i += increment) {
22
+ items.push([list[i], list[i + 1], list[i + 2]]);
23
+ }
24
+
25
+ return items;
26
+ };
27
+
28
+ function dayNameIntlMapper(locale: string) {
29
+ return (day: number) => {
30
+ const start = locale.startsWith('zh-') ? 1 : 0
31
+ return new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' })
32
+ .format(new Date(`2017-01-0${day}T00:00:00+00:00`))
33
+ .slice(start, 2);
34
+ };
35
+ }
36
+
37
+ function dayNameDateFnsMapper(formatLocale: Locale) {
38
+ return (day: number) => {
39
+ return format(localToTz(new Date(`2017-01-0${day}T00:00:00+00:00`), 'UTC'), 'EEEEEE', { locale: formatLocale });
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Generate week day names based on formatLocale or locale and in order specified in week start
45
+ */
46
+ export const getDayNames = (formatLocale: Locale | null, locale: string, weekStart: number): string[] => {
47
+ // Get list in order from sun ... sat
48
+ const daysArray = [1, 2, 3, 4, 5, 6, 7];
49
+ let days;
50
+
51
+ // Map day order numbers to names
52
+ if (formatLocale !== null) {
53
+ try {
54
+ days = daysArray.map(dayNameDateFnsMapper(formatLocale));
55
+ } catch (e) {
56
+ days = daysArray.map(dayNameIntlMapper(locale));
57
+ }
58
+ } else {
59
+ days = daysArray.map(dayNameIntlMapper(locale));
60
+ }
61
+
62
+ // Get days that are in order before specified week start
63
+ const beforeWeekStart = days.slice(0, weekStart);
64
+ // Get days that are in order after specified week start
65
+ const afterWeekStart = days.slice(weekStart + 1, days.length);
66
+
67
+ // return them in correct order
68
+ return [days[weekStart]].concat(...afterWeekStart).concat(...beforeWeekStart);
69
+ };
70
+
71
+ /**
72
+ * Generate array of years for selection display
73
+ */
74
+ export const getYears = (yearRange: number[] | string[], locale: string, reverse?: boolean): IDefaultSelect[] => {
75
+ const years: IDefaultSelect[] = [];
76
+ for (let year = +yearRange[0]; year <= +yearRange[1]; year++) {
77
+ years.push({ value: +year, text: formatNumber(year, locale) });
78
+ }
79
+ return reverse ? years.reverse() : years;
80
+ };
81
+
82
+ /**
83
+ * Generate month names based on formatLocale or locale for selection display
84
+ */
85
+ export const getMonths = (
86
+ formatLocale: Locale | null,
87
+ locale: string,
88
+ monthFormat: 'long' | 'short',
89
+ ): IDefaultSelect[] => {
90
+ const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((month) => {
91
+ const mm = month < 10 ? `0${month}` : month;
92
+ return new Date(`2017-${mm}-01T00:00:00+00:00`);
93
+ });
94
+
95
+ if (formatLocale !== null) {
96
+ try {
97
+ const monthDateFnsFormat = monthFormat === 'long' ? 'LLLL' : 'LLL';
98
+ return months.map((date, i) => {
99
+ const month = format(localToTz(date, 'UTC'), monthDateFnsFormat, { locale: formatLocale });
100
+ return {
101
+ text: month.charAt(0).toUpperCase() + month.substring(1),
102
+ value: i,
103
+ };
104
+ });
105
+ } catch (e) {
106
+ // Do nothing. Go ahead to execute fallback
107
+ }
108
+ }
109
+
110
+ const formatter = new Intl.DateTimeFormat(locale, { month: monthFormat, timeZone: 'UTC' });
111
+ return months.map((date, i) => {
112
+ const month = formatter.format(date);
113
+ return {
114
+ text: month.charAt(0).toUpperCase() + month.substring(1),
115
+ value: i,
116
+ };
117
+ });
118
+ };
119
+
120
+ /**
121
+ * Since internally watched values are in 24h mode, this will get am-pm value from set hour
122
+ */
123
+ export const hoursToAmPmHours = (index: number): number => {
124
+ const hoursValues = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
125
+
126
+ return hoursValues[index];
127
+ };
128
+
129
+ export const unrefElement = (elRef: MaybeElementRef): HTMLElement | null => {
130
+ const plain = unref(elRef);
131
+ if (!(plain as ComponentPublicInstance)?.$el) return plain as HTMLElement | null;
132
+ return (plain as ComponentPublicInstance)?.$el;
133
+ };
134
+
135
+ export const getDefaultMarker = (marker: IMarker): IMarker => ({ type: 'dot', ...(marker ?? {}) });
136
+
137
+ export const isModelAuto = (modelValue: ModelValue): boolean => {
138
+ if (Array.isArray(modelValue)) {
139
+ return !!modelValue[0] && !!modelValue[1];
140
+ }
141
+ return false;
142
+ };
143
+
144
+ export const errors = {
145
+ prop: (name: string): string => `"${name}" prop must be enabled!`,
146
+ dateArr: (name: string) => `You need to use array as "model-value" binding in order to support "${name}"`,
147
+ };
148
+
149
+ export const convertType = <T>(val: any): T => {
150
+ return val as unknown as T;
151
+ };
152
+
153
+ export const getNumVal = (num?: string | number | null): number | null => {
154
+ if (num === 0) return num;
155
+ if (!num || isNaN(+num)) return null;
156
+ return +num;
157
+ };
158
+
159
+ export const isNumNullish = (num?: number | null): num is null => {
160
+ return num === null;
161
+ };
162
+
163
+ export const findFocusableEl = (container: HTMLElement | null): HTMLElement | undefined => {
164
+ if (container) {
165
+ const elementsList = container.querySelectorAll('input, button, select, textarea, a[href]');
166
+ const elArr = [...elementsList] as HTMLElement[];
167
+ return elArr[0];
168
+ }
169
+ return undefined;
170
+ };
171
+
172
+ /**
173
+ * Create array for the SelectionOverlay grouped by 3
174
+ */
175
+ export const getGroupedList = (items: IDefaultSelect[]): IDefaultSelect[][] => {
176
+ const list = [];
177
+ const setList = (listItems: IDefaultSelect[]) => {
178
+ return listItems.filter((item) => item);
179
+ };
180
+ for (let i = 0; i < items.length; i += 3) {
181
+ const listItems = [items[i], items[i + 1], items[i + 2]];
182
+ list.push(setList(listItems));
183
+ }
184
+ return list;
185
+ };
186
+
187
+ /**
188
+ * Check if number is between min and max values
189
+ */
190
+ export const checkMinMaxValue = (value: number | string, min?: number, max?: number): boolean => {
191
+ const hasMax = max !== undefined && max !== null;
192
+ const hasMin = min !== undefined && min !== null;
193
+
194
+ if (!hasMax && !hasMin) return false;
195
+
196
+ const maxVal = +(max as number);
197
+ const minVal = +(min as number);
198
+
199
+ if (hasMax && hasMin) {
200
+ return +value > maxVal || +value < minVal;
201
+ }
202
+ if (hasMax) {
203
+ return +value > maxVal;
204
+ }
205
+
206
+ if (hasMin) {
207
+ return +value < minVal;
208
+ }
209
+
210
+ return false;
211
+ };
212
+
213
+ /**
214
+ * Maps data for the SelectionOverlay
215
+ */
216
+ export const groupListAndMap = (
217
+ list: IDefaultSelect[],
218
+ cb: (item: IDefaultSelect) => { active: boolean; disabled: boolean; highlighted?: boolean; isBetween?: boolean },
219
+ ): OverlayGridItem[][] => {
220
+ return getGroupedList(list).map((items) => {
221
+ return items.map((item) => {
222
+ const { active, disabled, isBetween, highlighted } = cb(item);
223
+ return {
224
+ ...item,
225
+ active,
226
+ disabled: disabled,
227
+ className: {
228
+ dp__overlay_cell_active: active,
229
+ dp__overlay_cell: !active,
230
+ dp__overlay_cell_disabled: disabled,
231
+ dp__overlay_cell_pad: false,
232
+ dp__overlay_cell_active_disabled: disabled && active,
233
+ dp__cell_in_between: isBetween,
234
+ 'dp--highlighted': highlighted,
235
+ },
236
+ };
237
+ });
238
+ });
239
+ };
240
+
241
+ export const checkStopPropagation = (ev: Event | undefined, config: Config, immediate = false) => {
242
+ if (ev && config.allowStopPropagation) {
243
+ if (immediate) {
244
+ ev.stopImmediatePropagation();
245
+ }
246
+ ev.stopPropagation();
247
+ }
248
+ };
249
+
250
+ const getFocusableElementsSelector = () =>
251
+ [
252
+ 'a[href]',
253
+ 'area[href]',
254
+ "input:not([disabled]):not([type='hidden'])",
255
+ 'select:not([disabled])',
256
+ 'textarea:not([disabled])',
257
+ 'button:not([disabled])',
258
+ "[tabindex]:not([tabindex='-1'])",
259
+ '[data-datepicker-instance]',
260
+ ].join(', ');
261
+
262
+ export function findNextFocusableElement(startingElement: HTMLElement, reverse: boolean) {
263
+ let focusable = [...document.querySelectorAll(getFocusableElementsSelector())];
264
+
265
+ focusable = focusable.filter((elem) => {
266
+ return !startingElement.contains(elem) || elem.hasAttribute('data-datepicker-instance');
267
+ });
268
+
269
+ const currentIndex = focusable.indexOf(startingElement);
270
+
271
+ if (currentIndex >= 0 && (reverse ? currentIndex - 1 >= 0 : currentIndex + 1 <= focusable.length)) {
272
+ return focusable[currentIndex + (reverse ? -1 : 1)] as HTMLElement;
273
+ }
274
+ }
275
+
276
+ export const getElWithin = (wrapper: HTMLElement | null, attribute: DPElements): HTMLElement | undefined | null => {
277
+ return wrapper?.querySelector(`[data-dp-element="${attribute}"]`);
278
+ };
279
+
280
+ export const formatNumber = (num: number, locale: string): string => {
281
+ return new Intl.NumberFormat(locale, { useGrouping: false, style: 'decimal' }).format(num);
282
+ };
283
+
284
+ export const getMapKey = (date: Date | string | number) => {
285
+ return format(date, 'dd-MM-yyyy');
286
+ };
287
+
288
+ export const shouldMap = (arr: any): arr is Date[] | string[] | boolean => {
289
+ return Array.isArray(arr);
290
+ };
291
+
292
+ export const getMapDate = <T>(date: Date, map: Map<string, T>): T | undefined => {
293
+ return map.get(getMapKey(date));
294
+ };
295
+
296
+ export const matchDate = (date: Date, mapOrFn: Map<string, any> | ((date: Date) => boolean) | null) => {
297
+ if (!date) return true;
298
+ if (!mapOrFn) return false;
299
+ if (mapOrFn instanceof Map) {
300
+ return !!getMapDate(date, mapOrFn);
301
+ }
302
+ return mapOrFn(getDate(date));
303
+ };
304
+
305
+ export const checkKeyDown = (ev: KeyboardEvent, fn: () => any, prevent = false, cb?: (ev: KeyboardEvent) => void) => {
306
+ if (ev.key === EventKey.enter || ev.key === EventKey.space) {
307
+ if (prevent) {
308
+ ev.preventDefault();
309
+ }
310
+ return fn();
311
+ }
312
+ if (cb) return cb(ev);
313
+ };
314
+
315
+ export const isIOS = () => {
316
+ return (
317
+ ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].some((platform) =>
318
+ navigator.userAgent.includes(platform),
319
+ ) ||
320
+ (navigator.userAgent.includes('Mac') && 'ontouchend' in document)
321
+ );
322
+ };