bge-ui 1.3.4 → 1.3.6

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 (135) 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 +13008 -1250
  61. package/dist/style.css +1188 -1
  62. package/dist/tooltip/index.vue.d.ts +2 -2
  63. package/dist/tooltip/usePopper.d.ts +5 -5
  64. package/package.json +3 -2
  65. package/src/datePicker/components/ActionRow.vue +216 -0
  66. package/src/datePicker/components/Common/ArrowBtn.vue +42 -0
  67. package/src/datePicker/components/Common/InstanceWrap.vue +28 -0
  68. package/src/datePicker/components/Common/SelectionOverlay.vue +320 -0
  69. package/src/datePicker/components/DatePicker/DatePicker.vue +302 -0
  70. package/src/datePicker/components/DatePicker/DpCalendar.vue +405 -0
  71. package/src/datePicker/components/DatePicker/DpHeader.vue +332 -0
  72. package/src/datePicker/components/DatePicker/date-picker.ts +674 -0
  73. package/src/datePicker/components/DatepickerInput.vue +334 -0
  74. package/src/datePicker/components/DatepickerMenu.vue +424 -0
  75. package/src/datePicker/components/Icons/CalendarIcon.ts +40 -0
  76. package/src/datePicker/components/Icons/CancelIcon.ts +32 -0
  77. package/src/datePicker/components/Icons/ChevronDownIcon.ts +29 -0
  78. package/src/datePicker/components/Icons/ChevronLeftIcon.ts +29 -0
  79. package/src/datePicker/components/Icons/ChevronRightIcon.ts +29 -0
  80. package/src/datePicker/components/Icons/ChevronUpIcon.ts +29 -0
  81. package/src/datePicker/components/Icons/ClockIcon.ts +32 -0
  82. package/src/datePicker/components/Icons/index.ts +8 -0
  83. package/src/datePicker/components/MonthPicker/MonthPicker.vue +130 -0
  84. package/src/datePicker/components/MonthPicker/month-picker.ts +232 -0
  85. package/src/datePicker/components/QuarterPicker/QuarterPicker.vue +111 -0
  86. package/src/datePicker/components/QuarterPicker/quarter-picker.ts +153 -0
  87. package/src/datePicker/components/TimePicker/TimeInput.vue +477 -0
  88. package/src/datePicker/components/TimePicker/TimePicker.vue +265 -0
  89. package/src/datePicker/components/TimePicker/TimePickerSolo.vue +79 -0
  90. package/src/datePicker/components/TimePicker/time-picker-utils.ts +179 -0
  91. package/src/datePicker/components/TimePicker/time-picker.ts +112 -0
  92. package/src/datePicker/components/YearPicker/YearPicker.vue +70 -0
  93. package/src/datePicker/components/YearPicker/year-picker.ts +109 -0
  94. package/src/datePicker/components/shared/YearModePicker.vue +105 -0
  95. package/src/datePicker/components/shared/month-quarter-picker.ts +199 -0
  96. package/src/datePicker/composables/arrow-navigate.ts +191 -0
  97. package/src/datePicker/composables/calendar-class.ts +383 -0
  98. package/src/datePicker/composables/common.ts +25 -0
  99. package/src/datePicker/composables/defaults.ts +123 -0
  100. package/src/datePicker/composables/external-internal-mapper.ts +442 -0
  101. package/src/datePicker/composables/flow.ts +70 -0
  102. package/src/datePicker/composables/index.ts +14 -0
  103. package/src/datePicker/composables/model.ts +89 -0
  104. package/src/datePicker/composables/month-year.ts +72 -0
  105. package/src/datePicker/composables/position.ts +297 -0
  106. package/src/datePicker/composables/shared.ts +98 -0
  107. package/src/datePicker/composables/slots.ts +84 -0
  108. package/src/datePicker/composables/state.ts +25 -0
  109. package/src/datePicker/composables/transition.ts +18 -0
  110. package/src/datePicker/composables/validation.ts +312 -0
  111. package/src/datePicker/constants/index.ts +49 -0
  112. package/src/datePicker/datePicker.vue +554 -0
  113. package/src/datePicker/directives/clickOutside.ts +79 -0
  114. package/src/datePicker/index.vue +158 -0
  115. package/src/datePicker/interfaces.ts +404 -0
  116. package/src/datePicker/props.ts +173 -0
  117. package/src/datePicker/style/components/_ActionRow.scss +73 -0
  118. package/src/datePicker/style/components/_Calendar.scss +284 -0
  119. package/src/datePicker/style/components/_DatepickerInput.scss +109 -0
  120. package/src/datePicker/style/components/_DatepickerMenu.scss +213 -0
  121. package/src/datePicker/style/components/_MonthYearInput.scss +97 -0
  122. package/src/datePicker/style/components/_QuarterPicker.scss +53 -0
  123. package/src/datePicker/style/components/_SelectionOverlay.scss +142 -0
  124. package/src/datePicker/style/components/_TimeInput.scss +181 -0
  125. package/src/datePicker/style/components/_shared.scss +15 -0
  126. package/src/datePicker/style/main.scss +259 -0
  127. package/src/datePicker/utils/date-utils.ts +440 -0
  128. package/src/datePicker/utils/defaults.ts +327 -0
  129. package/src/datePicker/utils/timezone.ts +38 -0
  130. package/src/datePicker/utils/type-guard.ts +3 -0
  131. package/src/datePicker/utils/util.ts +322 -0
  132. package/src/dialog/index.vue +9 -0
  133. package/src/form/index.vue +2 -1
  134. package/src/index.ts +6 -2
  135. package/src/slider/index.vue +1 -1
@@ -0,0 +1,265 @@
1
+ <template>
2
+ <div class="dp--tp-wrap">
3
+ <button
4
+ v-if="!timePicker && !timePickerInline"
5
+ v-show="!hideNavigationButtons(hideNavigation, 'time')"
6
+ ref="openTimePickerBtn"
7
+ type="button"
8
+ :class="{ ...toggleButtonClass, 'dp--hidden-el': showTimePicker }"
9
+ :aria-label="defaultedAriaLabels?.openTimePicker"
10
+ :tabindex="noOverlayFocus ? undefined : 0"
11
+ data-test="open-time-picker-btn"
12
+ @keydown="checkKeyDown($event, () => toggleTimePicker(true))"
13
+ @click="toggleTimePicker(true)"
14
+ >
15
+ <slot v-if="$slots['clock-icon']" name="clock-icon" />
16
+ <ClockIcon v-if="!$slots['clock-icon']" />
17
+ </button>
18
+ <transition :name="transitionName(showTimePicker)" :css="showTransition && !timePickerInline">
19
+ <div
20
+ v-if="showTimePicker || timePicker || timePickerInline"
21
+ ref="overlayRef"
22
+ :role="timePickerInline ? undefined : 'dialog'"
23
+ :class="{
24
+ dp__overlay: !timePickerInline,
25
+ 'dp--overlay-absolute': !props.timePicker && !timePickerInline,
26
+ 'dp--overlay-relative': props.timePicker,
27
+ }"
28
+ :style="timePicker ? { height: `${defaultedConfig.modeHeight}px` } : undefined"
29
+ :aria-label="defaultedAriaLabels?.timePicker"
30
+ :tabindex="timePickerInline ? undefined : 0"
31
+ >
32
+ <div
33
+ :class="
34
+ !timePickerInline
35
+ ? 'dp__overlay_container dp__container_flex dp__time_picker_overlay_container'
36
+ : 'dp__time_picker_inline_container'
37
+ "
38
+ style="display: flex"
39
+ >
40
+ <slot
41
+ v-if="$slots['time-picker-overlay']"
42
+ name="time-picker-overlay"
43
+ :hours="hours"
44
+ :minutes="minutes"
45
+ :seconds="seconds"
46
+ :set-hours="updateHours"
47
+ :set-minutes="updateMinutes"
48
+ :set-seconds="updateSeconds"
49
+ ></slot>
50
+ <template v-if="!$slots['time-picker-overlay']">
51
+ <div :class="timePickerInline ? 'dp__flex' : 'dp__overlay_row dp__flex_row'">
52
+ <TimeInput
53
+ v-for="(tInput, index) in timeInputs"
54
+ v-show="index === 0 ? true : shouldShowRangedInput"
55
+ :key="index"
56
+ v-bind="{
57
+ ...$props,
58
+ order: index,
59
+ hours: tInput.hours,
60
+ minutes: tInput.minutes,
61
+ seconds: tInput.seconds,
62
+ closeTimePickerBtn,
63
+ disabledTimesConfig,
64
+ disabled: index === 0 ? defaultedRange.fixedStart : defaultedRange.fixedEnd,
65
+ }"
66
+ ref="timeInputRefs"
67
+ :validate-time="
68
+ (type: TimeType, value: number) => validateTime(type, getEvent(value, index, type))
69
+ "
70
+ @update:hours="updateHours(getEvent($event, index, 'hours'))"
71
+ @update:minutes="updateMinutes(getEvent($event, index, 'minutes'))"
72
+ @update:seconds="updateSeconds(getEvent($event, index, 'seconds'))"
73
+ @mounted="focusOverlay"
74
+ @overlay-closed="timeInputOverlayClose"
75
+ @overlay-opened="timeInputOverlayOpen"
76
+ @am-pm-change="$emit('am-pm-change', $event)"
77
+ >
78
+ <template v-for="(slot, i) in timeInputSlots" #[slot]="args" :key="i">
79
+ <slot :name="slot" v-bind="args" />
80
+ </template>
81
+ </TimeInput>
82
+ </div>
83
+ </template>
84
+ <button
85
+ v-if="!timePicker && !timePickerInline"
86
+ v-show="!hideNavigationButtons(hideNavigation, 'time')"
87
+ ref="closeTimePickerBtn"
88
+ type="button"
89
+ :class="{ ...toggleButtonClass, 'dp--hidden-el': timePickerOverlayOpen }"
90
+ :aria-label="defaultedAriaLabels?.closeTimePicker"
91
+ tabindex="0"
92
+ @keydown="checkKeyDown($event, () => toggleTimePicker(false))"
93
+ @click="toggleTimePicker(false)"
94
+ >
95
+ <slot v-if="$slots['calendar-icon']" name="calendar-icon" />
96
+ <CalendarIcon v-if="!$slots['calendar-icon']" />
97
+ </button>
98
+ </div>
99
+ </div>
100
+ </transition>
101
+ </div>
102
+ </template>
103
+
104
+ <script lang="ts" setup>
105
+ import { computed, nextTick, onMounted, ref, useSlots } from 'vue';
106
+
107
+ import { ClockIcon, CalendarIcon } from '../../components/Icons';
108
+ import TimeInput from '../../components/TimePicker/TimeInput.vue';
109
+
110
+ import { checkKeyDown, findFocusableEl, isModelAuto, unrefElement } from '../../utils/util';
111
+ import { mapSlots, useTransitions, useArrowNavigation, useDefaults, useCommon } from '../../composables';
112
+ import { PickerBaseProps } from '../../props';
113
+
114
+ import type { PropType } from 'vue';
115
+ import type { DisabledTimesArrProp, TimeInputRef, TimeType } from '../../interfaces';
116
+ import { FlowStep } from '../../constants';
117
+
118
+ defineOptions({
119
+ compatConfig: {
120
+ MODE: 3,
121
+ },
122
+ });
123
+
124
+ const emit = defineEmits([
125
+ 'update:hours',
126
+ 'update:minutes',
127
+ 'update:seconds',
128
+ 'mount',
129
+ 'reset-flow',
130
+ 'overlay-opened',
131
+ 'overlay-closed',
132
+ 'am-pm-change',
133
+ ]);
134
+
135
+ const props = defineProps({
136
+ hours: { type: [Number, Array] as PropType<number | number[]>, default: 0 },
137
+ minutes: { type: [Number, Array] as PropType<number | number[]>, default: 0 },
138
+ seconds: { type: [Number, Array] as PropType<number | number[]>, default: 0 },
139
+ disabledTimesConfig: { type: Function as PropType<DisabledTimesArrProp>, default: null },
140
+ validateTime: {
141
+ type: Function as PropType<(type: TimeType, value: number | number[]) => boolean>,
142
+ default: () => false,
143
+ },
144
+ ...PickerBaseProps,
145
+ });
146
+
147
+ const { buildMatrix, setTimePicker } = useArrowNavigation();
148
+ const slots = useSlots();
149
+
150
+ const { defaultedTransitions, defaultedAriaLabels, defaultedTextInput, defaultedConfig, defaultedRange } =
151
+ useDefaults(props);
152
+ const { transitionName, showTransition } = useTransitions(defaultedTransitions);
153
+ const { hideNavigationButtons } = useCommon();
154
+
155
+ const openTimePickerBtn = ref(null);
156
+ const closeTimePickerBtn = ref(null);
157
+ const timeInputRefs = ref<TimeInputRef[]>([]);
158
+ const overlayRef = ref<HTMLElement | null>(null);
159
+ const timePickerOverlayOpen = ref(false);
160
+
161
+ onMounted(() => {
162
+ emit('mount');
163
+ if (!props.timePicker && props.arrowNavigation) {
164
+ buildMatrix([unrefElement(openTimePickerBtn.value) as HTMLElement], 'time');
165
+ } else {
166
+ setTimePicker(true, props.timePicker);
167
+ }
168
+ });
169
+
170
+ const shouldShowRangedInput = computed(() => {
171
+ if (defaultedRange.value.enabled && props.modelAuto) return isModelAuto(props.internalModelValue);
172
+ return true;
173
+ });
174
+
175
+ const showTimePicker = ref(false);
176
+
177
+ const getTimeInput = (i: number) => {
178
+ return {
179
+ hours: Array.isArray(props.hours) ? props.hours[i] : props.hours,
180
+ minutes: Array.isArray(props.minutes) ? props.minutes[i] : props.minutes,
181
+ seconds: Array.isArray(props.seconds) ? props.seconds[i] : props.seconds,
182
+ };
183
+ };
184
+
185
+ const timeInputs = computed((): { hours: number; minutes: number; seconds: number }[] => {
186
+ const arr = [];
187
+ if (defaultedRange.value.enabled) {
188
+ for (let i = 0; i < 2; i++) {
189
+ arr.push(getTimeInput(i));
190
+ }
191
+ } else {
192
+ arr.push(getTimeInput(0));
193
+ }
194
+ return arr as { hours: number; minutes: number; seconds: number }[];
195
+ });
196
+
197
+ const toggleTimePicker = (show: boolean, flow = false, childOpen = ''): void => {
198
+ if (!flow) {
199
+ emit('reset-flow');
200
+ }
201
+ showTimePicker.value = show;
202
+
203
+ emit(show ? 'overlay-opened' : 'overlay-closed', FlowStep.time);
204
+
205
+ if (props.arrowNavigation) {
206
+ setTimePicker(show);
207
+ }
208
+
209
+ nextTick(() => {
210
+ if (childOpen !== '' && timeInputRefs.value[0]) {
211
+ timeInputRefs.value[0].openChildCmp(childOpen);
212
+ }
213
+ });
214
+ };
215
+
216
+ const toggleButtonClass = computed(() => ({
217
+ dp__btn: true,
218
+ dp__button: true,
219
+ dp__button_bottom: props.autoApply && !defaultedConfig.value.keepActionRow,
220
+ }));
221
+
222
+ const timeInputSlots = mapSlots(slots, 'timePicker');
223
+
224
+ const getEvent = (event: number, index: number, property: 'hours' | 'minutes' | 'seconds') => {
225
+ if (!defaultedRange.value.enabled) {
226
+ return event;
227
+ }
228
+ if (index === 0) {
229
+ return [event, timeInputs.value[1][property]];
230
+ }
231
+ return [timeInputs.value[0][property], event];
232
+ };
233
+
234
+ const updateHours = (hours: number | number[]): void => {
235
+ emit('update:hours', hours);
236
+ };
237
+
238
+ const updateMinutes = (minutes: number | number[]): void => {
239
+ emit('update:minutes', minutes);
240
+ };
241
+
242
+ const updateSeconds = (seconds: number | number[]): void => {
243
+ emit('update:seconds', seconds);
244
+ };
245
+
246
+ const focusOverlay = () => {
247
+ if (overlayRef.value && !defaultedTextInput.value.enabled && !props.noOverlayFocus) {
248
+ const el = findFocusableEl(overlayRef.value);
249
+ if (el) {
250
+ el.focus({ preventScroll: true });
251
+ }
252
+ }
253
+ };
254
+
255
+ const timeInputOverlayClose = (mode: TimeType) => {
256
+ timePickerOverlayOpen.value = false;
257
+ emit('overlay-closed', mode);
258
+ };
259
+ const timeInputOverlayOpen = (mode: TimeType) => {
260
+ timePickerOverlayOpen.value = true;
261
+ emit('overlay-opened', mode);
262
+ };
263
+
264
+ defineExpose({ toggleTimePicker });
265
+ </script>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <InstanceWrap :multi-calendars="0" stretch>
3
+ <TimePicker
4
+ ref="tpRef"
5
+ v-bind="$props"
6
+ :hours="time.hours"
7
+ :minutes="time.minutes"
8
+ :seconds="time.seconds"
9
+ :internal-model-value="internalModelValue"
10
+ :disabled-times-config="disabledTimesConfig"
11
+ :validate-time="validateTime"
12
+ @update:hours="updateTime($event)"
13
+ @update:minutes="updateTime($event, false)"
14
+ @update:seconds="updateTime($event, false, true)"
15
+ @am-pm-change="$emit('am-pm-change', $event)"
16
+ @reset-flow="$emit('reset-flow')"
17
+ @overlay-closed="$emit('overlay-toggle', { open: false, overlay: $event })"
18
+ @overlay-opened="$emit('overlay-toggle', { open: true, overlay: $event })"
19
+ >
20
+ <template v-for="(slot, i) in timePickerSlots" #[slot]="args" :key="i">
21
+ <slot :name="slot" v-bind="args" />
22
+ </template>
23
+ </TimePicker>
24
+ </InstanceWrap>
25
+ </template>
26
+
27
+ <script lang="ts" setup>
28
+ import { onMounted, ref, useSlots } from 'vue';
29
+
30
+ import TimePicker from '../../components/TimePicker/TimePicker.vue';
31
+
32
+ import { PickerBaseProps } from '../../props';
33
+ import { mapSlots } from '../../composables';
34
+ import { useTimePicker } from '../../components/TimePicker/time-picker';
35
+ import InstanceWrap from '../../components/Common/InstanceWrap.vue';
36
+
37
+ const emit = defineEmits([
38
+ 'update:internal-model-value',
39
+ 'time-update',
40
+ 'am-pm-change',
41
+ 'mount',
42
+ 'reset-flow',
43
+ 'update-flow-step',
44
+ 'overlay-toggle',
45
+ ]);
46
+ const props = defineProps({
47
+ ...PickerBaseProps,
48
+ });
49
+ defineOptions({
50
+ compatConfig: {
51
+ MODE: 3,
52
+ },
53
+ });
54
+ const slots = useSlots();
55
+ const timePickerSlots = mapSlots(slots, 'timePicker');
56
+ const tpRef = ref<InstanceType<typeof TimePicker> | null>(null);
57
+
58
+ const { time, modelValue, disabledTimesConfig, updateTime, validateTime } = useTimePicker(props, emit);
59
+
60
+ onMounted(() => {
61
+ if (!props.shadow) {
62
+ emit('mount', null);
63
+ }
64
+ });
65
+
66
+ const getSidebarProps = () => {
67
+ return {
68
+ modelValue,
69
+ time,
70
+ updateTime,
71
+ };
72
+ };
73
+
74
+ const toggleTimePicker = (show: boolean, flow = false, childOpen = '') => {
75
+ tpRef.value?.toggleTimePicker(show, flow, childOpen);
76
+ };
77
+
78
+ defineExpose({ getSidebarProps, toggleTimePicker });
79
+ </script>
@@ -0,0 +1,179 @@
1
+ import { computed } from 'vue';
2
+
3
+ import { isAfter, isBefore, setMilliseconds, setSeconds } from 'date-fns';
4
+
5
+ import { getDate, isDateEqual, setDateTime } from '../../utils/date-utils';
6
+ import { useDefaults } from '../../composables';
7
+
8
+ import type { InternalModuleValue, Time, TimeType, TimeModel, TimeValuesInv, DisabledTime } from '../../interfaces';
9
+ import type { UnwrapNestedRefs, WritableComputedRef } from 'vue';
10
+ import type { PickerBasePropsType } from '../../props';
11
+
12
+ export const useTimePickerUtils = (
13
+ props: PickerBasePropsType,
14
+ time: UnwrapNestedRefs<Time>,
15
+ modelValue: WritableComputedRef<InternalModuleValue>,
16
+ updateFlow?: () => void,
17
+ ) => {
18
+ const { defaultedRange } = useDefaults(props);
19
+ const getTimeValue = (type: TimeType, i?: number): number => {
20
+ if (Array.isArray(time[type])) return (time[type] as number[])[i as number];
21
+ return time[type] as number;
22
+ };
23
+ // Check if seconds are enabled, and return proper value
24
+ const getSecondsValue = (i?: number): number => {
25
+ if (props.enableSeconds) {
26
+ if (Array.isArray(time.seconds)) {
27
+ return time.seconds[i as number];
28
+ }
29
+ return time.seconds;
30
+ }
31
+ return 0;
32
+ };
33
+ const getSetDateTime = (dateValue: Date | null, i?: number): Date => {
34
+ if (!dateValue) return setSeconds(getDate(), getSecondsValue(i));
35
+ if (i !== undefined) {
36
+ return setDateTime(dateValue, getTimeValue('hours', i), getTimeValue('minutes', i), getSecondsValue(i));
37
+ }
38
+ return setDateTime(dateValue, time.hours as number, time.minutes as number, getSecondsValue());
39
+ };
40
+ // Any time modification will go through this function
41
+ const setTime = (property: TimeType, value: number | number[]): void => {
42
+ time[property] = value;
43
+ };
44
+
45
+ const isRangeCheck = computed(() => {
46
+ if (props.modelAuto && defaultedRange.value.enabled) {
47
+ return Array.isArray(modelValue.value) ? modelValue.value.length > 1 : false;
48
+ }
49
+ return defaultedRange.value.enabled;
50
+ });
51
+
52
+ const validateTime = (type: TimeType, value: number | number[]) => {
53
+ const copies = Object.fromEntries(
54
+ Object.keys(time).map((key) => {
55
+ if (key === type) return [key, value];
56
+ return [key, time[key as TimeType]].slice();
57
+ }),
58
+ );
59
+
60
+ if (isRangeCheck.value && !defaultedRange.value.disableTimeRangeValidation) {
61
+ const setTime = (index: number) =>
62
+ !modelValue.value
63
+ ? (null as unknown as Date)
64
+ : setDateTime(
65
+ (modelValue.value as Date[])[index],
66
+ (copies.hours as number[])[index],
67
+ (copies.minutes as number[])[index],
68
+ (copies.seconds as number[])[index],
69
+ );
70
+
71
+ const resetMilliseconds = (index: number) => setMilliseconds((modelValue.value as Date[])[index], 0);
72
+ return !(
73
+ isDateEqual(setTime(0), setTime(1)) &&
74
+ (isAfter(setTime(0), resetMilliseconds(1)) || isBefore(setTime(1), resetMilliseconds(0)))
75
+ );
76
+ }
77
+ return true;
78
+ };
79
+
80
+ const updateTime = (type: TimeType, value: number | number[]) => {
81
+ const valid = validateTime(type, value);
82
+ if (valid) {
83
+ setTime(type, value);
84
+ if (updateFlow) updateFlow();
85
+ }
86
+ };
87
+
88
+ const updateHours = (value: number | number[]) => {
89
+ updateTime('hours', value);
90
+ };
91
+
92
+ const updateMinutes = (value: number | number[]) => {
93
+ updateTime('minutes', value);
94
+ };
95
+
96
+ const updateSeconds = (value: number | number[]) => {
97
+ updateTime('seconds', value);
98
+ };
99
+
100
+ const updateTimeValues = (
101
+ value: number | number[],
102
+ isHours: boolean,
103
+ isSeconds: boolean,
104
+ handleTimeUpdate: (date: Date | Date[]) => void,
105
+ ) => {
106
+ if (isHours) updateHours(value);
107
+ if (!isHours && !isSeconds) updateMinutes(value);
108
+ if (isSeconds) updateSeconds(value);
109
+
110
+ if (modelValue.value) {
111
+ handleTimeUpdate(modelValue.value);
112
+ }
113
+ };
114
+
115
+ /**
116
+ * If start time is provided, assign data.
117
+ * Note: data is sanitized parameters since prop value can be provided partially
118
+ */
119
+ const assignStartTime = (startTime: TimeModel | TimeModel[] | null): void => {
120
+ if (startTime) {
121
+ const isMulti = Array.isArray(startTime);
122
+ const hours = isMulti ? [+startTime[0].hours, +startTime[1].hours] : +startTime.hours;
123
+ const minutes = isMulti ? [+startTime[0].minutes, +startTime[1].minutes] : +startTime.minutes;
124
+ const seconds = isMulti ? [+startTime[0].seconds, +startTime[1].seconds] : +startTime.seconds;
125
+
126
+ setTime('hours', hours);
127
+ setTime('minutes', minutes);
128
+ if (props.enableSeconds) {
129
+ setTime('seconds', seconds);
130
+ }
131
+ }
132
+ };
133
+
134
+ const getDisabledTimesData = (ind: number, hours?: number) => {
135
+ const data: { hours: number; disabledArr: DisabledTime[] } = {
136
+ hours: Array.isArray(time.hours) ? time.hours[ind] : time.hours,
137
+ disabledArr: [],
138
+ };
139
+
140
+ if (hours || hours === 0) data.hours = hours;
141
+
142
+ if (Array.isArray(props.disabledTimes)) {
143
+ data.disabledArr = (
144
+ defaultedRange.value.enabled && Array.isArray(props.disabledTimes[ind])
145
+ ? props.disabledTimes[ind]
146
+ : props.disabledTimes
147
+ ) as DisabledTime[];
148
+ }
149
+ return data;
150
+ };
151
+
152
+ const disabledTimesConfig = computed(() => (ind: number, hoursVal?: number): TimeValuesInv => {
153
+ if (Array.isArray(props.disabledTimes)) {
154
+ const { disabledArr, hours } = getDisabledTimesData(ind, hoursVal);
155
+
156
+ const timeFound = disabledArr.filter((time) => +time.hours === hours);
157
+ if (timeFound[0]?.minutes === '*') return { hours: [hours], minutes: undefined, seconds: undefined };
158
+ return {
159
+ hours: [],
160
+ minutes: timeFound?.map((t) => +t.minutes) ?? [],
161
+ seconds: timeFound?.map((t) => (t.seconds ? +t.seconds : undefined)) ?? [],
162
+ };
163
+ }
164
+ return { hours: [], minutes: [], seconds: [] };
165
+ });
166
+
167
+ return {
168
+ setTime,
169
+ updateHours,
170
+ updateMinutes,
171
+ updateSeconds,
172
+ getSetDateTime,
173
+ updateTimeValues,
174
+ getSecondsValue,
175
+ assignStartTime,
176
+ validateTime,
177
+ disabledTimesConfig,
178
+ };
179
+ };
@@ -0,0 +1,112 @@
1
+ import { onMounted } from 'vue';
2
+ import { set } from 'date-fns';
3
+
4
+ import { useDefaults, useModel } from '../../composables';
5
+ import { useTimePickerUtils } from '../../components/TimePicker/time-picker-utils';
6
+ import { getDate, getTimeObj } from '../../utils/date-utils';
7
+
8
+ import type { PickerBasePropsType } from '../../props';
9
+ import type { TimeModel, VueEmit } from '../../interfaces';
10
+ import { localToTz } from '../../utils/timezone';
11
+
12
+ export const useTimePicker = (props: PickerBasePropsType, emit: VueEmit) => {
13
+ const reMap = () => {
14
+ if (props.isTextInputDate) setTimeFromModel();
15
+ };
16
+ const { modelValue, time } = useModel(props, emit, reMap);
17
+ const { defaultedStartTime, defaultedRange, defaultedTz } = useDefaults(props);
18
+ const { updateTimeValues, getSetDateTime, setTime, assignStartTime, disabledTimesConfig, validateTime } =
19
+ useTimePickerUtils(props, time, modelValue, updateFlowStep);
20
+
21
+ function updateFlowStep() {
22
+ emit('update-flow-step');
23
+ }
24
+
25
+ const parseStartTime = (startTime: TimeModel) => {
26
+ const { hours, minutes, seconds } = startTime;
27
+ return { hours: +hours, minutes: +minutes, seconds: seconds ? +seconds : 0 };
28
+ };
29
+
30
+ const getDateFromStartTime = () => {
31
+ if (props.startTime) {
32
+ if (Array.isArray(props.startTime)) {
33
+ const parsedFirst = parseStartTime(props.startTime[0]);
34
+ const parsedSecond = parseStartTime(props.startTime[1]);
35
+ return [set(getDate(), parsedFirst), set(getDate(), parsedSecond)];
36
+ }
37
+ const parsed = parseStartTime(props.startTime);
38
+ return set(getDate(), parsed);
39
+ }
40
+ return defaultedRange.value.enabled ? [null, null] : null;
41
+ };
42
+
43
+ const assignEmptyModel = () => {
44
+ if (defaultedRange.value.enabled) {
45
+ const [firstStartTime, secondStartTime] = getDateFromStartTime() as Date[];
46
+ modelValue.value = [
47
+ localToTz(getSetDateTime(firstStartTime, 0), defaultedTz.value.timezone),
48
+ localToTz(getSetDateTime(secondStartTime, 1), defaultedTz.value.timezone),
49
+ ];
50
+ } else {
51
+ modelValue.value = localToTz(getSetDateTime(getDateFromStartTime() as Date), defaultedTz.value.timezone);
52
+ }
53
+ };
54
+
55
+ const getTimeValue = (dates: Date | Date[] | null) => {
56
+ if (Array.isArray(dates)) {
57
+ return [getTimeObj(getDate(dates[0])), getTimeObj(getDate(dates[1]))];
58
+ }
59
+ return [getTimeObj(dates ?? getDate())];
60
+ };
61
+
62
+ const assignTime = (hours: number | number[], minutes: number | number[], seconds: number | number[]) => {
63
+ setTime('hours', hours);
64
+ setTime('minutes', minutes);
65
+ setTime('seconds', props.enableSeconds ? seconds : 0);
66
+ };
67
+
68
+ const setTimeFromModel = () => {
69
+ const [first, second] = getTimeValue(modelValue.value);
70
+
71
+ if (defaultedRange.value.enabled) {
72
+ return assignTime(
73
+ [first.hours, second.hours],
74
+ [first.minutes, second.minutes],
75
+ [first.seconds, second.seconds],
76
+ );
77
+ }
78
+ return assignTime(first.hours, first.minutes, first.seconds);
79
+ };
80
+
81
+ onMounted(() => {
82
+ if (!props.shadow) {
83
+ assignStartTime(defaultedStartTime.value);
84
+ if (!modelValue.value) return assignEmptyModel();
85
+ return setTimeFromModel();
86
+ }
87
+ });
88
+
89
+ const handleTimeUpdate = () => {
90
+ if (Array.isArray(modelValue.value)) {
91
+ modelValue.value = modelValue.value.map((date, i) => {
92
+ if (date) return getSetDateTime(date, i);
93
+ return date;
94
+ });
95
+ } else {
96
+ modelValue.value = getSetDateTime(modelValue.value);
97
+ }
98
+ emit('time-update');
99
+ };
100
+
101
+ const updateTime = (value: number | number[], isHours = true, isSeconds = false) => {
102
+ updateTimeValues(value, isHours, isSeconds, handleTimeUpdate);
103
+ };
104
+
105
+ return {
106
+ modelValue,
107
+ time,
108
+ disabledTimesConfig,
109
+ updateTime,
110
+ validateTime,
111
+ };
112
+ };