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.
- package/dist/datePicker/components/ActionRow.vue.d.ts +1051 -0
- package/dist/datePicker/components/Common/ArrowBtn.vue.d.ts +29 -0
- package/dist/datePicker/components/Common/InstanceWrap.vue.d.ts +29 -0
- package/dist/datePicker/components/Common/SelectionOverlay.vue.d.ts +55 -0
- package/dist/datePicker/components/DatePicker/DatePicker.vue.d.ts +1114 -0
- package/dist/datePicker/components/DatePicker/DpCalendar.vue.d.ts +1085 -0
- package/dist/datePicker/components/DatePicker/DpHeader.vue.d.ts +1103 -0
- package/dist/datePicker/components/DatePicker/date-picker.d.ts +35 -0
- package/dist/datePicker/components/DatepickerInput.vue.d.ts +1008 -0
- package/dist/datePicker/components/DatepickerMenu.vue.d.ts +1061 -0
- package/dist/datePicker/components/Icons/CalendarIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/CancelIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronDownIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronLeftIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronRightIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ChevronUpIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/ClockIcon.d.ts +9 -0
- package/dist/datePicker/components/Icons/index.d.ts +7 -0
- package/dist/datePicker/components/MonthPicker/MonthPicker.vue.d.ts +1071 -0
- package/dist/datePicker/components/MonthPicker/month-picker.d.ts +34 -0
- package/dist/datePicker/components/QuarterPicker/QuarterPicker.vue.d.ts +1043 -0
- package/dist/datePicker/components/QuarterPicker/quarter-picker.d.ts +25 -0
- package/dist/datePicker/components/TimePicker/TimeInput.vue.d.ts +1116 -0
- package/dist/datePicker/components/TimePicker/TimePicker.vue.d.ts +1087 -0
- package/dist/datePicker/components/TimePicker/TimePickerSolo.vue.d.ts +1036 -0
- package/dist/datePicker/components/TimePicker/time-picker-utils.d.ts +15 -0
- package/dist/datePicker/components/TimePicker/time-picker.d.ts +13 -0
- package/dist/datePicker/components/YearPicker/YearPicker.vue.d.ts +1040 -0
- package/dist/datePicker/components/YearPicker/year-picker.d.ts +9 -0
- package/dist/datePicker/components/shared/YearModePicker.vue.d.ts +1075 -0
- package/dist/datePicker/components/shared/month-quarter-picker.d.ts +29 -0
- package/dist/datePicker/composables/arrow-navigate.d.ts +26 -0
- package/dist/datePicker/composables/calendar-class.d.ts +8 -0
- package/dist/datePicker/composables/common.d.ts +6 -0
- package/dist/datePicker/composables/defaults.d.ts +37 -0
- package/dist/datePicker/composables/external-internal-mapper.d.ts +14 -0
- package/dist/datePicker/composables/flow.d.ts +10 -0
- package/dist/datePicker/composables/index.d.ts +14 -0
- package/dist/datePicker/composables/model.d.ts +17 -0
- package/dist/datePicker/composables/month-year.d.ts +10 -0
- package/dist/datePicker/composables/position.d.ts +25 -0
- package/dist/datePicker/composables/shared.d.ts +12 -0
- package/dist/datePicker/composables/slots.d.ts +10 -0
- package/dist/datePicker/composables/state.d.ts +8 -0
- package/dist/datePicker/composables/transition.d.ts +7 -0
- package/dist/datePicker/composables/validation.d.ts +12 -0
- package/dist/datePicker/constants/index.d.ts +43 -0
- package/dist/datePicker/datePicker.vue.d.ts +1006 -0
- package/dist/datePicker/directives/clickOutside.d.ts +2 -0
- package/dist/datePicker/index.vue.d.ts +1012 -0
- package/dist/datePicker/interfaces.d.ts +323 -0
- package/dist/datePicker/props.d.ts +865 -0
- package/dist/datePicker/utils/date-utils.d.ts +45 -0
- package/dist/datePicker/utils/defaults.d.ts +42 -0
- package/dist/datePicker/utils/timezone.d.ts +8 -0
- package/dist/datePicker/utils/type-guard.d.ts +1 -0
- package/dist/datePicker/utils/util.d.ts +57 -0
- package/dist/dialog/index.vue.d.ts +6 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13008 -1250
- package/dist/style.css +1188 -1
- package/dist/tooltip/index.vue.d.ts +2 -2
- package/dist/tooltip/usePopper.d.ts +5 -5
- package/package.json +3 -2
- package/src/datePicker/components/ActionRow.vue +216 -0
- package/src/datePicker/components/Common/ArrowBtn.vue +42 -0
- package/src/datePicker/components/Common/InstanceWrap.vue +28 -0
- package/src/datePicker/components/Common/SelectionOverlay.vue +320 -0
- package/src/datePicker/components/DatePicker/DatePicker.vue +302 -0
- package/src/datePicker/components/DatePicker/DpCalendar.vue +405 -0
- package/src/datePicker/components/DatePicker/DpHeader.vue +332 -0
- package/src/datePicker/components/DatePicker/date-picker.ts +674 -0
- package/src/datePicker/components/DatepickerInput.vue +334 -0
- package/src/datePicker/components/DatepickerMenu.vue +424 -0
- package/src/datePicker/components/Icons/CalendarIcon.ts +40 -0
- package/src/datePicker/components/Icons/CancelIcon.ts +32 -0
- package/src/datePicker/components/Icons/ChevronDownIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronLeftIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronRightIcon.ts +29 -0
- package/src/datePicker/components/Icons/ChevronUpIcon.ts +29 -0
- package/src/datePicker/components/Icons/ClockIcon.ts +32 -0
- package/src/datePicker/components/Icons/index.ts +8 -0
- package/src/datePicker/components/MonthPicker/MonthPicker.vue +130 -0
- package/src/datePicker/components/MonthPicker/month-picker.ts +232 -0
- package/src/datePicker/components/QuarterPicker/QuarterPicker.vue +111 -0
- package/src/datePicker/components/QuarterPicker/quarter-picker.ts +153 -0
- package/src/datePicker/components/TimePicker/TimeInput.vue +477 -0
- package/src/datePicker/components/TimePicker/TimePicker.vue +265 -0
- package/src/datePicker/components/TimePicker/TimePickerSolo.vue +79 -0
- package/src/datePicker/components/TimePicker/time-picker-utils.ts +179 -0
- package/src/datePicker/components/TimePicker/time-picker.ts +112 -0
- package/src/datePicker/components/YearPicker/YearPicker.vue +70 -0
- package/src/datePicker/components/YearPicker/year-picker.ts +109 -0
- package/src/datePicker/components/shared/YearModePicker.vue +105 -0
- package/src/datePicker/components/shared/month-quarter-picker.ts +199 -0
- package/src/datePicker/composables/arrow-navigate.ts +191 -0
- package/src/datePicker/composables/calendar-class.ts +383 -0
- package/src/datePicker/composables/common.ts +25 -0
- package/src/datePicker/composables/defaults.ts +123 -0
- package/src/datePicker/composables/external-internal-mapper.ts +442 -0
- package/src/datePicker/composables/flow.ts +70 -0
- package/src/datePicker/composables/index.ts +14 -0
- package/src/datePicker/composables/model.ts +89 -0
- package/src/datePicker/composables/month-year.ts +72 -0
- package/src/datePicker/composables/position.ts +297 -0
- package/src/datePicker/composables/shared.ts +98 -0
- package/src/datePicker/composables/slots.ts +84 -0
- package/src/datePicker/composables/state.ts +25 -0
- package/src/datePicker/composables/transition.ts +18 -0
- package/src/datePicker/composables/validation.ts +312 -0
- package/src/datePicker/constants/index.ts +49 -0
- package/src/datePicker/datePicker.vue +554 -0
- package/src/datePicker/directives/clickOutside.ts +79 -0
- package/src/datePicker/index.vue +158 -0
- package/src/datePicker/interfaces.ts +404 -0
- package/src/datePicker/props.ts +173 -0
- package/src/datePicker/style/components/_ActionRow.scss +73 -0
- package/src/datePicker/style/components/_Calendar.scss +284 -0
- package/src/datePicker/style/components/_DatepickerInput.scss +109 -0
- package/src/datePicker/style/components/_DatepickerMenu.scss +213 -0
- package/src/datePicker/style/components/_MonthYearInput.scss +97 -0
- package/src/datePicker/style/components/_QuarterPicker.scss +53 -0
- package/src/datePicker/style/components/_SelectionOverlay.scss +142 -0
- package/src/datePicker/style/components/_TimeInput.scss +181 -0
- package/src/datePicker/style/components/_shared.scss +15 -0
- package/src/datePicker/style/main.scss +259 -0
- package/src/datePicker/utils/date-utils.ts +440 -0
- package/src/datePicker/utils/defaults.ts +327 -0
- package/src/datePicker/utils/timezone.ts +38 -0
- package/src/datePicker/utils/type-guard.ts +3 -0
- package/src/datePicker/utils/util.ts +322 -0
- package/src/dialog/index.vue +9 -0
- package/src/form/index.vue +2 -1
- package/src/index.ts +6 -2
- package/src/slider/index.vue +1 -1
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { h, ref, render, toRef, watch } from 'vue';
|
|
2
|
+
import {
|
|
3
|
+
type DatepickerInputRef,
|
|
4
|
+
type DatepickerMenuRef,
|
|
5
|
+
type InlineOptions,
|
|
6
|
+
type VueEmit,
|
|
7
|
+
OpenPosition,
|
|
8
|
+
type MaybeElementRef,
|
|
9
|
+
} from '../interfaces';
|
|
10
|
+
|
|
11
|
+
import { unrefElement } from '../utils/util';
|
|
12
|
+
import { MenuPlacement } from '../constants';
|
|
13
|
+
|
|
14
|
+
import type { Component, ComputedRef, Ref, Slots } from 'vue';
|
|
15
|
+
import type { AllPropsType } from '../props';
|
|
16
|
+
import { useDefaults } from '../composables/defaults';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extracted code from the main component, used for calculating the position of the menu
|
|
20
|
+
*/
|
|
21
|
+
interface Params {
|
|
22
|
+
menuRef: Ref<HTMLElement | null>;
|
|
23
|
+
menuRefInner: Ref<DatepickerMenuRef | null>;
|
|
24
|
+
inputRef: Ref<DatepickerInputRef | null>;
|
|
25
|
+
pickerWrapperRef: Ref<HTMLElement | null>;
|
|
26
|
+
inline: ComputedRef<InlineOptions>;
|
|
27
|
+
emit: VueEmit;
|
|
28
|
+
props: AllPropsType;
|
|
29
|
+
slots: Slots;
|
|
30
|
+
}
|
|
31
|
+
export const usePosition = ({
|
|
32
|
+
menuRef,
|
|
33
|
+
menuRefInner,
|
|
34
|
+
inputRef,
|
|
35
|
+
pickerWrapperRef,
|
|
36
|
+
inline,
|
|
37
|
+
emit,
|
|
38
|
+
props,
|
|
39
|
+
slots,
|
|
40
|
+
}: Params) => {
|
|
41
|
+
const { defaultedConfig } = useDefaults(props);
|
|
42
|
+
const menuRect = ref<DOMRect>({} as DOMRect);
|
|
43
|
+
const xCorrect = ref(false);
|
|
44
|
+
|
|
45
|
+
const menuStyle = ref<Record<string, string>>({
|
|
46
|
+
top: '0',
|
|
47
|
+
left: '0',
|
|
48
|
+
});
|
|
49
|
+
const openOnTop = ref(false);
|
|
50
|
+
const centered = toRef(props, 'teleportCenter');
|
|
51
|
+
|
|
52
|
+
watch(centered, () => {
|
|
53
|
+
menuStyle.value = JSON.parse(JSON.stringify({}));
|
|
54
|
+
setMenuPosition();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Get correct offset of an element
|
|
58
|
+
const getOffset = (el: HTMLElement): { top: number; left: number } => {
|
|
59
|
+
if (props.teleport) {
|
|
60
|
+
const rect = el.getBoundingClientRect();
|
|
61
|
+
return {
|
|
62
|
+
left: rect.left + window.scrollX,
|
|
63
|
+
top: rect.top + window.scrollY,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return { top: 0, left: 0 };
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const setPositionRight = (left: number, width: number): void => {
|
|
70
|
+
menuStyle.value.left = `${left + width - menuRect.value.width}px`;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const setPositionLeft = (left: number): void => {
|
|
74
|
+
menuStyle.value.left = `${left}px`;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const setHorizontalPositioning = (left: number, width: number): void => {
|
|
78
|
+
if (props.position === OpenPosition.left) {
|
|
79
|
+
setPositionLeft(left);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (props.position === OpenPosition.right) {
|
|
83
|
+
setPositionRight(left, width);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (props.position === OpenPosition.center) {
|
|
87
|
+
menuStyle.value.left = `${left + width / 2 - menuRect.value.width / 2}px`;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const getInputPositions = (inputEl: HTMLElement) => {
|
|
92
|
+
const { width, height } = inputEl.getBoundingClientRect();
|
|
93
|
+
const { top, left } = props.altPosition ? props.altPosition(inputEl) : getOffset(inputEl);
|
|
94
|
+
return { top: +top, left: +left, width, height };
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const teleportCenter = () => {
|
|
98
|
+
menuStyle.value.left = `50%`;
|
|
99
|
+
menuStyle.value.top = `50%`;
|
|
100
|
+
menuStyle.value.transform = `translate(-50%, -50%)`;
|
|
101
|
+
menuStyle.value.position = `fixed`;
|
|
102
|
+
delete menuStyle.value.opacity;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const customAltPosition = () => {
|
|
106
|
+
const el = unrefElement(inputRef as MaybeElementRef);
|
|
107
|
+
const { top, left, transform } = props.altPosition(el);
|
|
108
|
+
menuStyle.value = { top: `${top}px`, left: `${left}px`, transform: transform ?? '' };
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Main call, when input is clicked, opens the menu on the first entry
|
|
113
|
+
* Recalculate param is added when the position is recalculated on scroll or resize
|
|
114
|
+
*/
|
|
115
|
+
const setMenuPosition = (recalculate = true): void => {
|
|
116
|
+
if (!inline.value.enabled) {
|
|
117
|
+
if (centered.value) return teleportCenter();
|
|
118
|
+
|
|
119
|
+
if (props.altPosition !== null) return customAltPosition();
|
|
120
|
+
|
|
121
|
+
if (recalculate) {
|
|
122
|
+
const el = props.teleport ? menuRefInner.value?.$el : menuRef.value;
|
|
123
|
+
|
|
124
|
+
if (el) {
|
|
125
|
+
menuRect.value = el.getBoundingClientRect();
|
|
126
|
+
}
|
|
127
|
+
emit('recalculate-position');
|
|
128
|
+
}
|
|
129
|
+
return calculateMenuPosition();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const setLeftRightPosition = ({ inputEl, left, width }: { inputEl: HTMLElement; left: number; width: number }) => {
|
|
134
|
+
if (window.screen.width > 768 && !xCorrect.value) {
|
|
135
|
+
setHorizontalPositioning(left, width);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
autoLeftRight(inputEl);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Set menu position bellow input
|
|
142
|
+
const setBottomPosition = (inputEl: HTMLElement) => {
|
|
143
|
+
const { top: offset, left, height, width } = getInputPositions(inputEl);
|
|
144
|
+
menuStyle.value.top = `${height + offset + +props.offset}px`;
|
|
145
|
+
openOnTop.value = false;
|
|
146
|
+
if (!xCorrect.value) {
|
|
147
|
+
menuStyle.value.left = `${left + width / 2 - menuRect.value.width / 2}px`;
|
|
148
|
+
}
|
|
149
|
+
setLeftRightPosition({ inputEl, left, width });
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Set menu position above the input
|
|
153
|
+
const setTopPosition = (inputEl: HTMLElement) => {
|
|
154
|
+
const { top: offset, left, width } = getInputPositions(inputEl);
|
|
155
|
+
|
|
156
|
+
menuStyle.value.top = `${offset - +props.offset - menuRect.value.height}px`;
|
|
157
|
+
openOnTop.value = true;
|
|
158
|
+
setLeftRightPosition({ inputEl, left, width });
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Set auto left-right if the menu is out of the screen
|
|
162
|
+
const autoLeftRight = (inputEl: HTMLElement) => {
|
|
163
|
+
if (props.autoPosition) {
|
|
164
|
+
const { left, width } = getInputPositions(inputEl);
|
|
165
|
+
const { left: menuLeft, right: menuRight } = menuRect.value;
|
|
166
|
+
if (!xCorrect.value) {
|
|
167
|
+
if (Math.abs(menuLeft) !== Math.abs(menuRight)) {
|
|
168
|
+
if (menuLeft <= 0) {
|
|
169
|
+
xCorrect.value = true;
|
|
170
|
+
return setPositionLeft(left);
|
|
171
|
+
}
|
|
172
|
+
if (menuRight >= document.documentElement.clientWidth) {
|
|
173
|
+
xCorrect.value = true;
|
|
174
|
+
return setPositionRight(left, width);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return setHorizontalPositioning(left, width);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const getMenuPlacement = (): MenuPlacement => {
|
|
183
|
+
const inputEl = unrefElement(inputRef as MaybeElementRef);
|
|
184
|
+
if (inputEl) {
|
|
185
|
+
const { height: menuHeight } = menuRect.value;
|
|
186
|
+
const { top: inputTop, height: inputHeight } = inputEl.getBoundingClientRect();
|
|
187
|
+
|
|
188
|
+
const fullHeight = window.innerHeight;
|
|
189
|
+
const spaceBottom = fullHeight - inputTop - inputHeight;
|
|
190
|
+
const spaceTop = inputTop;
|
|
191
|
+
|
|
192
|
+
if (menuHeight <= spaceBottom) return MenuPlacement.bottom;
|
|
193
|
+
// If there is not enough space at the bottom but there is on top, set position on top
|
|
194
|
+
if (menuHeight > spaceBottom && menuHeight <= spaceTop) return MenuPlacement.top;
|
|
195
|
+
// If we pass both check, it means there is not enough space above and bellow the input
|
|
196
|
+
// Position where there is more space available
|
|
197
|
+
if (spaceBottom >= spaceTop) return MenuPlacement.bottom;
|
|
198
|
+
return MenuPlacement.top;
|
|
199
|
+
}
|
|
200
|
+
return MenuPlacement.bottom;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// If auto-position is enabled, perform calculation to fit menu on the screen
|
|
204
|
+
const setAutoPosition = (inputEl: HTMLElement) => {
|
|
205
|
+
const placement = getMenuPlacement();
|
|
206
|
+
if (placement === MenuPlacement.bottom) return setBottomPosition(inputEl);
|
|
207
|
+
return setTopPosition(inputEl);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// Parent function that will perform check on which calculation function to invoke
|
|
211
|
+
const calculateMenuPosition = () => {
|
|
212
|
+
const inputEl = unrefElement(inputRef as MaybeElementRef);
|
|
213
|
+
if (inputEl) {
|
|
214
|
+
if (props.autoPosition) {
|
|
215
|
+
return setAutoPosition(inputEl);
|
|
216
|
+
}
|
|
217
|
+
return setBottomPosition(inputEl);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const isScrollable = function (el: HTMLElement | null) {
|
|
222
|
+
if (el) {
|
|
223
|
+
const hasScrollableContent = el.scrollHeight > el.clientHeight;
|
|
224
|
+
|
|
225
|
+
const overflowYStyle = window.getComputedStyle(el).overflowY;
|
|
226
|
+
const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1;
|
|
227
|
+
|
|
228
|
+
return hasScrollableContent && !isOverflowHidden;
|
|
229
|
+
}
|
|
230
|
+
return true;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const getScrollableParent = function (el: HTMLElement | null): Window | HTMLElement {
|
|
234
|
+
if (!el || el === document.body || el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) return window;
|
|
235
|
+
if (isScrollable(el)) return el;
|
|
236
|
+
return getScrollableParent(
|
|
237
|
+
(el.assignedSlot && defaultedConfig.value.shadowDom
|
|
238
|
+
? el.assignedSlot.parentNode
|
|
239
|
+
: el.parentNode) as HTMLElement,
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const getShadowPos = (rect?: DOMRect) => {
|
|
244
|
+
if (rect) {
|
|
245
|
+
switch (props.position) {
|
|
246
|
+
case OpenPosition.left:
|
|
247
|
+
return { left: 0, transform: 'translateX(0)' };
|
|
248
|
+
case OpenPosition.right:
|
|
249
|
+
return { left: `${rect.width}px`, transform: 'translateX(-100%)' };
|
|
250
|
+
default:
|
|
251
|
+
return { left: `${rect.width / 2}px`, transform: 'translateX(-50%)' };
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return {};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// Renders invisible menu on open to determine the menu dimensions
|
|
258
|
+
const shadowRender = (DPMenu: Component, props: AllPropsType) => {
|
|
259
|
+
const container = document.createElement('div');
|
|
260
|
+
const input = unrefElement(inputRef as MaybeElementRef)?.getBoundingClientRect();
|
|
261
|
+
container.setAttribute('id', 'dp--temp-container');
|
|
262
|
+
const wrap = pickerWrapperRef.value?.clientWidth ? pickerWrapperRef.value : document.body;
|
|
263
|
+
wrap.append(container);
|
|
264
|
+
|
|
265
|
+
const pos = getShadowPos(input);
|
|
266
|
+
const mappedSlots = defaultedConfig.value.shadowDom
|
|
267
|
+
? Object.keys(slots).filter((slot) =>
|
|
268
|
+
['right-sidebar', 'left-sidebar', 'top-extra', 'action-extra'].includes(slot),
|
|
269
|
+
)
|
|
270
|
+
: Object.keys(slots);
|
|
271
|
+
|
|
272
|
+
const el = h(
|
|
273
|
+
DPMenu,
|
|
274
|
+
{
|
|
275
|
+
...props,
|
|
276
|
+
shadow: true,
|
|
277
|
+
style: { opacity: 0, position: 'absolute', ...pos },
|
|
278
|
+
},
|
|
279
|
+
Object.fromEntries(mappedSlots.map((slot) => [slot, slots[slot]])),
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
render(el, container);
|
|
283
|
+
menuRect.value = el.el?.getBoundingClientRect();
|
|
284
|
+
|
|
285
|
+
render(null, container);
|
|
286
|
+
wrap.removeChild(container);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
openOnTop,
|
|
291
|
+
menuStyle,
|
|
292
|
+
xCorrect,
|
|
293
|
+
setMenuPosition,
|
|
294
|
+
getScrollableParent,
|
|
295
|
+
shadowRender,
|
|
296
|
+
};
|
|
297
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { getDate, isDateAfter, isDateBefore, isDateEqual } from '../utils/date-utils';
|
|
2
|
+
|
|
3
|
+
import { localToTz } from '../utils/timezone';
|
|
4
|
+
import type { ComputedRef, WritableComputedRef } from 'vue';
|
|
5
|
+
import type { InternalModuleValue, RangeConfig, VueEmit } from '../interfaces';
|
|
6
|
+
|
|
7
|
+
export const handleMultiDatesSelect = (
|
|
8
|
+
date: Date,
|
|
9
|
+
modelValue: WritableComputedRef<InternalModuleValue>,
|
|
10
|
+
multiDatesLimit?: number | string | null,
|
|
11
|
+
): void => {
|
|
12
|
+
if (modelValue.value && Array.isArray(modelValue.value)) {
|
|
13
|
+
if (modelValue.value.some((dateVal) => isDateEqual(date, dateVal))) {
|
|
14
|
+
const value = modelValue.value.filter((dateVal) => !isDateEqual(dateVal, date));
|
|
15
|
+
modelValue.value = !value.length ? null : value;
|
|
16
|
+
} else if ((multiDatesLimit && +multiDatesLimit > modelValue.value.length) || !multiDatesLimit) {
|
|
17
|
+
modelValue.value.push(date);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
modelValue.value = [date];
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const setMonthOrYearRange = (
|
|
25
|
+
modelValue: WritableComputedRef<InternalModuleValue>,
|
|
26
|
+
date: Date,
|
|
27
|
+
emit: VueEmit,
|
|
28
|
+
) => {
|
|
29
|
+
let rangeDate = modelValue.value ? (modelValue.value as Date[]).slice() : [];
|
|
30
|
+
if (rangeDate.length === 2 && rangeDate[1] !== null) {
|
|
31
|
+
rangeDate = [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!rangeDate.length) {
|
|
35
|
+
rangeDate = [date];
|
|
36
|
+
emit('range-start', date);
|
|
37
|
+
} else if (isDateBefore(date, rangeDate[0])) {
|
|
38
|
+
rangeDate.unshift(date);
|
|
39
|
+
emit('range-start', rangeDate[0]);
|
|
40
|
+
emit('range-start', rangeDate[1]);
|
|
41
|
+
} else {
|
|
42
|
+
rangeDate[1] = date;
|
|
43
|
+
emit('range-end', date);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return rangeDate;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const checkRangeAutoApply = (range: Date[], emit: VueEmit, autoApply: boolean, modelAuto: boolean) => {
|
|
50
|
+
if (!range) return;
|
|
51
|
+
if (range[0] && range[1] && autoApply) {
|
|
52
|
+
emit('auto-apply');
|
|
53
|
+
}
|
|
54
|
+
if (range[0] && !range[1] && modelAuto && autoApply) {
|
|
55
|
+
emit('auto-apply');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const setPresetDate = (opts: {
|
|
60
|
+
value: Date[] | string[] | Date | string;
|
|
61
|
+
range: boolean;
|
|
62
|
+
timezone?: string;
|
|
63
|
+
modelValue: WritableComputedRef<InternalModuleValue>;
|
|
64
|
+
}) => {
|
|
65
|
+
if (Array.isArray(opts.value) && opts.value.length <= 2 && opts.range) {
|
|
66
|
+
opts.modelValue.value = opts.value.map((date) => localToTz(getDate(date), opts.timezone));
|
|
67
|
+
} else if (!Array.isArray(opts.value)) {
|
|
68
|
+
opts.modelValue.value = localToTz(getDate(opts.value), opts.timezone);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const getRangeWithFixedDate = (
|
|
73
|
+
date: Date,
|
|
74
|
+
modelValue: WritableComputedRef<InternalModuleValue>,
|
|
75
|
+
emit: VueEmit,
|
|
76
|
+
defaultedRange: ComputedRef<RangeConfig>,
|
|
77
|
+
): Date[] => {
|
|
78
|
+
if (
|
|
79
|
+
Array.isArray(modelValue.value) &&
|
|
80
|
+
(modelValue.value.length === 2 || (modelValue.value.length === 1 && defaultedRange.value.partialRange))
|
|
81
|
+
) {
|
|
82
|
+
if (
|
|
83
|
+
defaultedRange.value.fixedStart &&
|
|
84
|
+
(isDateAfter(date, modelValue.value[0]) || isDateEqual(date, modelValue.value[0]))
|
|
85
|
+
) {
|
|
86
|
+
return [modelValue.value[0], date];
|
|
87
|
+
}
|
|
88
|
+
if (
|
|
89
|
+
defaultedRange.value.fixedEnd &&
|
|
90
|
+
(isDateBefore(date, modelValue.value[1]) || isDateEqual(date, modelValue.value[1]))
|
|
91
|
+
) {
|
|
92
|
+
return [date, modelValue.value[1]];
|
|
93
|
+
}
|
|
94
|
+
emit('invalid-fixed-range', date);
|
|
95
|
+
return modelValue.value;
|
|
96
|
+
}
|
|
97
|
+
return [];
|
|
98
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Slots } from 'vue';
|
|
2
|
+
import type { PresetDate } from '../interfaces';
|
|
3
|
+
|
|
4
|
+
export const slots = [
|
|
5
|
+
{ name: 'clock-icon', use: ['time', 'calendar', 'shared'] },
|
|
6
|
+
{ name: 'arrow-left', use: ['month-year', 'calendar', 'shared', 'year-mode'] },
|
|
7
|
+
{ name: 'arrow-right', use: ['month-year', 'calendar', 'shared', 'year-mode'] },
|
|
8
|
+
{ name: 'arrow-up', use: ['time', 'calendar', 'month-year', 'shared'] },
|
|
9
|
+
{ name: 'arrow-down', use: ['time', 'calendar', 'month-year', 'shared'] },
|
|
10
|
+
{ name: 'calendar-icon', use: ['month-year', 'time', 'calendar', 'shared', 'year-mode'] },
|
|
11
|
+
{ name: 'day', use: ['calendar', 'shared'] },
|
|
12
|
+
{ name: 'month-overlay-value', use: ['calendar', 'month-year', 'shared'] },
|
|
13
|
+
{ name: 'year-overlay-value', use: ['calendar', 'month-year', 'shared', 'year-mode'] },
|
|
14
|
+
{ name: 'year-overlay', use: ['month-year', 'shared'] },
|
|
15
|
+
{ name: 'month-overlay', use: ['month-year', 'shared'] },
|
|
16
|
+
{ name: 'month-overlay-header', use: ['month-year', 'shared'] },
|
|
17
|
+
{ name: 'year-overlay-header', use: ['month-year', 'shared'] },
|
|
18
|
+
{ name: 'hours-overlay-value', use: ['calendar', 'time', 'shared'] },
|
|
19
|
+
{ name: 'hours-overlay-header', use: ['calendar', 'time', 'shared'] },
|
|
20
|
+
{ name: 'minutes-overlay-value', use: ['calendar', 'time', 'shared'] },
|
|
21
|
+
{ name: 'minutes-overlay-header', use: ['calendar', 'time', 'shared'] },
|
|
22
|
+
{ name: 'seconds-overlay-value', use: ['calendar', 'time', 'shared'] },
|
|
23
|
+
{ name: 'seconds-overlay-header', use: ['calendar', 'time', 'shared'] },
|
|
24
|
+
{ name: 'hours', use: ['calendar', 'time', 'shared'] },
|
|
25
|
+
{ name: 'minutes', use: ['calendar', 'time', 'shared'] },
|
|
26
|
+
{ name: 'month', use: ['calendar', 'month-year', 'shared'] },
|
|
27
|
+
{ name: 'year', use: ['calendar', 'month-year', 'shared', 'year-mode'] },
|
|
28
|
+
{ name: 'action-buttons', use: ['action'] },
|
|
29
|
+
{ name: 'action-preview', use: ['action'] },
|
|
30
|
+
{ name: 'calendar-header', use: ['calendar', 'shared'] },
|
|
31
|
+
{ name: 'marker-tooltip', use: ['calendar', 'shared'] },
|
|
32
|
+
{ name: 'action-extra', use: ['menu'] },
|
|
33
|
+
{ name: 'time-picker-overlay', use: ['calendar', 'time', 'shared'] },
|
|
34
|
+
{ name: 'am-pm-button', use: ['calendar', 'time', 'shared'] },
|
|
35
|
+
{ name: 'left-sidebar', use: ['menu'] },
|
|
36
|
+
{ name: 'right-sidebar', use: ['menu'] },
|
|
37
|
+
{ name: 'month-year', use: ['month-year', 'shared'] },
|
|
38
|
+
{ name: 'time-picker', use: ['menu', 'shared'] },
|
|
39
|
+
{ name: 'action-row', use: ['action'] },
|
|
40
|
+
{ name: 'marker', use: ['calendar', 'shared'] },
|
|
41
|
+
{ name: 'quarter', use: ['shared'] },
|
|
42
|
+
{ name: 'top-extra', use: ['shared', 'month-year'] },
|
|
43
|
+
{ name: 'tp-inline-arrow-up', use: ['shared', 'time'] },
|
|
44
|
+
{ name: 'tp-inline-arrow-down', use: ['shared', 'time'] },
|
|
45
|
+
{ name: 'menu-header', use: ['menu'] },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
export const inputSlots = [{ name: 'trigger' }, { name: 'input-icon' }, { name: 'clear-icon' }, { name: 'dp-input' }];
|
|
49
|
+
|
|
50
|
+
const slotNames = {
|
|
51
|
+
all: () => slots,
|
|
52
|
+
monthYear: () => slots.filter((slot) => slot.use.includes('month-year')),
|
|
53
|
+
input: () => inputSlots,
|
|
54
|
+
timePicker: () => slots.filter((slot) => slot.use.includes('time')),
|
|
55
|
+
action: () => slots.filter((slot) => slot.use.includes('action')),
|
|
56
|
+
calendar: () => slots.filter((slot) => slot.use.includes('calendar')),
|
|
57
|
+
menu: () => slots.filter((slot) => slot.use.includes('menu')),
|
|
58
|
+
shared: () => slots.filter((slot) => slot.use.includes('shared')),
|
|
59
|
+
yearMode: () => slots.filter((slot) => slot.use.includes('year-mode')),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const mapSlots = (
|
|
63
|
+
slots: Slots,
|
|
64
|
+
usage: 'all' | 'monthYear' | 'timePicker' | 'input' | 'action' | 'calendar' | 'menu' | 'shared' | 'yearMode',
|
|
65
|
+
presetDates?: PresetDate[],
|
|
66
|
+
): string[] => {
|
|
67
|
+
const toReturn: string[] = [];
|
|
68
|
+
|
|
69
|
+
slotNames[usage]().forEach((slot) => {
|
|
70
|
+
if (slots[slot.name]) {
|
|
71
|
+
toReturn.push(slot.name);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (presetDates?.length) {
|
|
76
|
+
presetDates.forEach((preset) => {
|
|
77
|
+
if (preset.slot) {
|
|
78
|
+
toReturn.push(preset.slot);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return toReturn;
|
|
84
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { computed, reactive } from 'vue';
|
|
2
|
+
|
|
3
|
+
const state = reactive({
|
|
4
|
+
menuFocused: false,
|
|
5
|
+
shiftKeyInMenu: false,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const useState = () => {
|
|
9
|
+
const setMenuFocused = (value: boolean): void => {
|
|
10
|
+
state.menuFocused = value;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const setShiftKey = (value: boolean): void => {
|
|
14
|
+
if (state.shiftKeyInMenu === value) return;
|
|
15
|
+
state.shiftKeyInMenu = value;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const control = computed(() => ({ shiftKeyInMenu: state.shiftKeyInMenu, menuFocused: state.menuFocused }));
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
control,
|
|
22
|
+
setMenuFocused,
|
|
23
|
+
setShiftKey,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
|
|
3
|
+
import type { Transition } from '../interfaces';
|
|
4
|
+
import type { ComputedRef } from 'vue';
|
|
5
|
+
|
|
6
|
+
export const useTransitions = (transitions: ComputedRef<Transition>) => {
|
|
7
|
+
const transitionName = computed(() => (isOpen: boolean): string => {
|
|
8
|
+
if (!transitions.value) return '';
|
|
9
|
+
return isOpen ? transitions.value.open : transitions.value.close;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const menuTransition = computed(() => (openOnTop: boolean) => {
|
|
13
|
+
if (!transitions.value) return '';
|
|
14
|
+
return openOnTop ? transitions.value.menuAppearTop : transitions.value.menuAppearBottom;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return { transitionName, showTransition: !!transitions.value, menuTransition };
|
|
18
|
+
};
|