vueless 0.0.152 → 0.0.154
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/composable.adjustElementPosition/index.js +98 -0
- package/package.json +1 -1
- package/ui.form-date-picker/composables/attrs.composable.js +25 -3
- package/ui.form-date-picker/configs/default.config.js +16 -1
- package/ui.form-date-picker/index.stories.js +43 -0
- package/ui.form-date-picker/index.vue +47 -3
- package/ui.form-date-picker-range/composables/attrs.composable.js +18 -3
- package/ui.form-date-picker-range/configs/default.config.js +14 -1
- package/ui.form-date-picker-range/constants/index.js +1 -1
- package/ui.form-date-picker-range/index.stories.js +43 -0
- package/ui.form-date-picker-range/index.vue +56 -13
- package/ui.form-date-picker-range/services/dateRange.service.js +2 -4
- package/web-types.json +37 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ref, computed, toValue } from "vue";
|
|
2
|
+
|
|
3
|
+
export const POSITION = {
|
|
4
|
+
left: "left",
|
|
5
|
+
right: "right",
|
|
6
|
+
top: "top",
|
|
7
|
+
bottom: "bottom",
|
|
8
|
+
auto: "auto",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function useAdjustElementPosition(
|
|
12
|
+
anchorElement,
|
|
13
|
+
targetElement,
|
|
14
|
+
position,
|
|
15
|
+
preferredPosition,
|
|
16
|
+
) {
|
|
17
|
+
const preferredOpenDirectionY = ref(preferredPosition?.y || POSITION.bottom);
|
|
18
|
+
const preferredOpenDirectionX = ref(preferredPosition?.x || POSITION.left);
|
|
19
|
+
|
|
20
|
+
const localAnchorElement = computed(() => toValue(anchorElement));
|
|
21
|
+
const localTargetElement = computed(() => toValue(targetElement));
|
|
22
|
+
const localPosition = computed(() => toValue(position));
|
|
23
|
+
const localPreferredPosition = computed(() => toValue(preferredPosition));
|
|
24
|
+
|
|
25
|
+
const isTop = computed(() => {
|
|
26
|
+
if (localPosition.value.y !== POSITION.auto) {
|
|
27
|
+
return localPosition.value.y === POSITION.top;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return preferredOpenDirectionY.value === POSITION.top;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const isLeft = computed(() => {
|
|
34
|
+
if (localPosition.value.x !== POSITION.auto) {
|
|
35
|
+
return localPosition.value.x === POSITION.left;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return preferredOpenDirectionX.value === POSITION.right;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const isBottom = computed(() => {
|
|
42
|
+
if (localPosition.value.y !== POSITION.auto) {
|
|
43
|
+
return localPosition.value.y === POSITION.bottom;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return preferredOpenDirectionY.value === POSITION.bottom;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const isRight = computed(() => {
|
|
50
|
+
if (localPosition.value.x !== POSITION.auto) {
|
|
51
|
+
return localPosition.value.y === POSITION.right;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return preferredOpenDirectionX.value === POSITION.right;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function adjustPositionY() {
|
|
58
|
+
if (typeof window === "undefined") return;
|
|
59
|
+
|
|
60
|
+
const spaceAbove = localAnchorElement.value.getBoundingClientRect().top;
|
|
61
|
+
const spaceBelow = window.innerHeight - localAnchorElement.value.getBoundingClientRect().bottom;
|
|
62
|
+
const hasEnoughSpaceBelow =
|
|
63
|
+
spaceBelow > localTargetElement.value.getBoundingClientRect().height;
|
|
64
|
+
const hasEnoughSpaceAbove =
|
|
65
|
+
spaceAbove > localTargetElement.value.getBoundingClientRect().height;
|
|
66
|
+
|
|
67
|
+
if (localPreferredPosition.value.y === POSITION.top) {
|
|
68
|
+
preferredOpenDirectionY.value =
|
|
69
|
+
hasEnoughSpaceBelow || spaceBelow > spaceAbove ? POSITION.bottom : POSITION.top;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (localPreferredPosition.value.y === POSITION.bottom) {
|
|
73
|
+
preferredOpenDirectionY.value =
|
|
74
|
+
hasEnoughSpaceAbove || spaceAbove > spaceBelow ? POSITION.top : POSITION.bottom;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function adjustPositionX() {
|
|
79
|
+
if (typeof window === "undefined") return;
|
|
80
|
+
|
|
81
|
+
const spaceRight = localAnchorElement.value.getBoundingClientRect().right;
|
|
82
|
+
const spaceLeft = window.innerWidth - localAnchorElement.value.getBoundingClientRect().left;
|
|
83
|
+
const hasEnoughSpaceLeft = spaceLeft > localTargetElement.value.getBoundingClientRect().width;
|
|
84
|
+
const hasEnoughSpaceRight = spaceRight > localTargetElement.value.getBoundingClientRect().width;
|
|
85
|
+
|
|
86
|
+
if (localPreferredPosition.value.x === POSITION.left) {
|
|
87
|
+
preferredOpenDirectionX.value =
|
|
88
|
+
hasEnoughSpaceRight || spaceRight > spaceLeft ? POSITION.right : POSITION.left;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (localPreferredPosition.value.x === POSITION.right) {
|
|
92
|
+
preferredOpenDirectionX.value =
|
|
93
|
+
hasEnoughSpaceLeft || spaceLeft > spaceRight ? POSITION.left : POSITION.right;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { isTop, isRight, isBottom, isLeft, adjustPositionY, adjustPositionX };
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import useUI from "../../composable.ui";
|
|
2
|
+
import { cva } from "../../service.ui";
|
|
3
|
+
import { computed, watchEffect } from "vue";
|
|
2
4
|
|
|
3
5
|
import defaultConfig from "../configs/default.config";
|
|
4
|
-
import {
|
|
6
|
+
import { POSITION } from "../../composable.adjustElementPosition";
|
|
5
7
|
|
|
6
|
-
export default function useAttrs(props, { isShownCalendar }) {
|
|
8
|
+
export default function useAttrs(props, { isShownCalendar, isTop, isRight }) {
|
|
7
9
|
const { config, getAttrs } = useUI(defaultConfig, () => props.config);
|
|
10
|
+
const { calendar } = config.value;
|
|
8
11
|
|
|
9
|
-
const
|
|
12
|
+
const openDirectionY = computed(() => (isTop.value ? POSITION.top : POSITION.bottom));
|
|
13
|
+
const openDirectionX = computed(() => (isRight.value ? POSITION.right : POSITION.left));
|
|
14
|
+
|
|
15
|
+
const cvaCalendarWrapper = cva({
|
|
16
|
+
base: calendar.wrapper.base,
|
|
17
|
+
variants: calendar.wrapper.variants,
|
|
18
|
+
compoundVariants: calendar.wrapper.compoundVariants,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const calendarWrapperClasses = computed(() =>
|
|
22
|
+
cvaCalendarWrapper({
|
|
23
|
+
openDirectionY: openDirectionY.value,
|
|
24
|
+
openDirectionX: openDirectionX.value,
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const calendarAttrs = getAttrs("calendar", {
|
|
29
|
+
isComponent: true,
|
|
30
|
+
classes: calendarWrapperClasses,
|
|
31
|
+
});
|
|
10
32
|
const inputBlurAttrs = getAttrs("input");
|
|
11
33
|
const inputActiveAttrs = getAttrs("inputActive");
|
|
12
34
|
const wrapperAttrs = getAttrs("wrapper");
|
|
@@ -6,7 +6,20 @@ export default /*tw*/ {
|
|
|
6
6
|
base: "ring-4 ring-brand-600/[.15] border-brand-500 hover:border-brand-500",
|
|
7
7
|
},
|
|
8
8
|
},
|
|
9
|
-
calendar:
|
|
9
|
+
calendar: {
|
|
10
|
+
wrapper: {
|
|
11
|
+
base: "absolute z-40 my-2",
|
|
12
|
+
variants: {
|
|
13
|
+
openDirectionX: {
|
|
14
|
+
left: "left-0",
|
|
15
|
+
right: "right-0",
|
|
16
|
+
},
|
|
17
|
+
openDirectionY: {
|
|
18
|
+
top: "bottom-full mt-0",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
10
23
|
calendarTransition: {
|
|
11
24
|
enterFromClass: "opacity-0 scale-95",
|
|
12
25
|
enterActiveClass: "transition transform ease-out duration-100",
|
|
@@ -99,6 +112,8 @@ export default /*tw*/ {
|
|
|
99
112
|
dateFormat: "Y-m-d",
|
|
100
113
|
userFormat: "F j, Y",
|
|
101
114
|
size: "md",
|
|
115
|
+
openDirectionX: "auto",
|
|
116
|
+
openDirectionY: "auto",
|
|
102
117
|
timepicker: false,
|
|
103
118
|
disabled: false,
|
|
104
119
|
maxDate: undefined,
|
|
@@ -64,6 +64,46 @@ const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
|
64
64
|
`,
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
const OpenDirectionTemplate = (args, { argTypes } = {}) => ({
|
|
68
|
+
components: { UDatePicker, URow },
|
|
69
|
+
setup() {
|
|
70
|
+
return {
|
|
71
|
+
args,
|
|
72
|
+
directions: argTypes.openDirection.options,
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
template: `
|
|
76
|
+
<URow class="!flex-col">
|
|
77
|
+
<UDatePicker
|
|
78
|
+
class="w-full"
|
|
79
|
+
open-direction-y="top"
|
|
80
|
+
v-bind="args"
|
|
81
|
+
v-model="args.value"
|
|
82
|
+
/>
|
|
83
|
+
<UDatePicker
|
|
84
|
+
class="w-full"
|
|
85
|
+
open-direction-y="bottom"
|
|
86
|
+
open-direction-x="right"
|
|
87
|
+
v-bind="args"
|
|
88
|
+
v-model="args.value"
|
|
89
|
+
/>
|
|
90
|
+
<UDatePicker
|
|
91
|
+
class="w-full"
|
|
92
|
+
open-direction-y="bottom"
|
|
93
|
+
v-bind="args"
|
|
94
|
+
v-model="args.value"
|
|
95
|
+
/>
|
|
96
|
+
<UDatePicker
|
|
97
|
+
class="w-full"
|
|
98
|
+
open-direction-y="bottom"
|
|
99
|
+
open-direction-x="left"
|
|
100
|
+
v-bind="args"
|
|
101
|
+
v-model="args.value"
|
|
102
|
+
/>
|
|
103
|
+
</URow>
|
|
104
|
+
`,
|
|
105
|
+
});
|
|
106
|
+
|
|
67
107
|
const SlotTemplate = (args) => ({
|
|
68
108
|
components: { UDatePicker, UIcon },
|
|
69
109
|
setup() {
|
|
@@ -82,6 +122,9 @@ Default.args = { date: 1645653600 };
|
|
|
82
122
|
export const sizes = SizesTemplate.bind({});
|
|
83
123
|
sizes.args = { label: "" };
|
|
84
124
|
|
|
125
|
+
export const openDirection = OpenDirectionTemplate.bind({});
|
|
126
|
+
openDirection.args = {};
|
|
127
|
+
|
|
85
128
|
export const description = DefaultTemplate.bind({});
|
|
86
129
|
description.args = { description: "some description" };
|
|
87
130
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-bind="wrapperAttrs">
|
|
2
|
+
<div v-bind="wrapperAttrs" ref="wrapperRef">
|
|
3
3
|
<UInput
|
|
4
4
|
:id="id"
|
|
5
5
|
:key="isShownCalendar"
|
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
|
|
70
70
|
import useAttrs from "./composables/attrs.composable";
|
|
71
71
|
import { useLocale } from "../composable.locale";
|
|
72
|
+
import { useAdjustElementPosition } from "../composable.adjustElementPosition";
|
|
72
73
|
|
|
73
74
|
import defaultConfig from "./configs/default.config";
|
|
74
75
|
import { UDatePicker } from "./constants";
|
|
@@ -101,6 +102,24 @@ const props = defineProps({
|
|
|
101
102
|
default: null,
|
|
102
103
|
},
|
|
103
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Datepicker open direction on x-axis.
|
|
107
|
+
* @values auto, left, right
|
|
108
|
+
*/
|
|
109
|
+
openDirectionX: {
|
|
110
|
+
type: String,
|
|
111
|
+
default: UIService.get(defaultConfig, UDatePicker).default.openDirectionX,
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Datepicker open direction on y-axis.
|
|
116
|
+
* @values auto, top, bottom
|
|
117
|
+
*/
|
|
118
|
+
openDirectionY: {
|
|
119
|
+
type: String,
|
|
120
|
+
default: UIService.get(defaultConfig, UDatePicker).default.openDirectionY,
|
|
121
|
+
},
|
|
122
|
+
|
|
104
123
|
/**
|
|
105
124
|
* Min date in format date string or Date.
|
|
106
125
|
*/
|
|
@@ -211,8 +230,24 @@ const userFormatDate = ref("");
|
|
|
211
230
|
const formattedDate = ref("");
|
|
212
231
|
const customView = ref(VIEW.day);
|
|
213
232
|
|
|
233
|
+
const wrapperRef = ref(null);
|
|
214
234
|
const calendarRef = ref(null);
|
|
215
235
|
|
|
236
|
+
const calendarWrapperRef = computed(() => calendarRef?.value?.wrapperRef);
|
|
237
|
+
|
|
238
|
+
const { isTop, isRight, adjustPositionY, adjustPositionX } = useAdjustElementPosition(
|
|
239
|
+
wrapperRef,
|
|
240
|
+
calendarWrapperRef,
|
|
241
|
+
{
|
|
242
|
+
x: props.openDirectionX,
|
|
243
|
+
y: props.openDirectionY,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
x: "left",
|
|
247
|
+
y: "bottom",
|
|
248
|
+
},
|
|
249
|
+
);
|
|
250
|
+
|
|
216
251
|
defineExpose({
|
|
217
252
|
calendarRef,
|
|
218
253
|
userFormatDate,
|
|
@@ -224,12 +259,21 @@ const localValue = computed({
|
|
|
224
259
|
set: (value) => emit("update:modelValue", value),
|
|
225
260
|
});
|
|
226
261
|
|
|
227
|
-
const { config, inputAttrs, calendarAttrs, wrapperAttrs } = useAttrs(props, {
|
|
262
|
+
const { config, inputAttrs, calendarAttrs, wrapperAttrs } = useAttrs(props, {
|
|
263
|
+
isShownCalendar,
|
|
264
|
+
isTop,
|
|
265
|
+
isRight,
|
|
266
|
+
});
|
|
228
267
|
|
|
229
268
|
function activate() {
|
|
230
269
|
isShownCalendar.value = true;
|
|
231
270
|
|
|
232
|
-
nextTick(() =>
|
|
271
|
+
nextTick(() => {
|
|
272
|
+
adjustPositionY();
|
|
273
|
+
adjustPositionX();
|
|
274
|
+
|
|
275
|
+
calendarRef.value.wrapperRef.focus();
|
|
276
|
+
});
|
|
233
277
|
}
|
|
234
278
|
|
|
235
279
|
function deactivate() {
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import useUI from "../../composable.ui";
|
|
2
|
-
import { cx } from "../../service.ui";
|
|
2
|
+
import { cx, cva } from "../../service.ui";
|
|
3
3
|
|
|
4
4
|
import { computed, watchEffect } from "vue";
|
|
5
5
|
|
|
6
6
|
import defaultConfig from "../configs/default.config";
|
|
7
|
+
import { POSITION } from "../../composable.adjustElementPosition";
|
|
7
8
|
|
|
8
|
-
export default function useAttrs(props, { isShownMenu }) {
|
|
9
|
+
export default function useAttrs(props, { isShownMenu, isTop, isRight }) {
|
|
9
10
|
const { config, getAttrs } = useUI(defaultConfig, () => props.config);
|
|
11
|
+
const { menu } = config.value;
|
|
12
|
+
|
|
13
|
+
const openDirectionY = computed(() => (isTop.value ? POSITION.top : POSITION.bottom));
|
|
14
|
+
const openDirectionX = computed(() => (isRight.value ? POSITION.right : POSITION.left));
|
|
15
|
+
|
|
16
|
+
const cvaMenu = cva({
|
|
17
|
+
base: menu.base,
|
|
18
|
+
variants: menu.variants,
|
|
19
|
+
compoundVariants: menu.compoundVariants,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const menuClasses = computed(() =>
|
|
23
|
+
cvaMenu({ openDirectionY: openDirectionY.value, openDirectionX: openDirectionX.value }),
|
|
24
|
+
);
|
|
10
25
|
|
|
11
26
|
const wrapperAttrs = getAttrs("wrapper");
|
|
12
27
|
const buttonWrapperAttrsRaw = getAttrs("buttonWrapper");
|
|
@@ -57,7 +72,7 @@ export default function useAttrs(props, { isShownMenu }) {
|
|
|
57
72
|
return isShownMenu.value ? inputActiveAttrs.value : inputBlurAttrs.value;
|
|
58
73
|
});
|
|
59
74
|
|
|
60
|
-
const menuAttrs = getAttrs("menu");
|
|
75
|
+
const menuAttrs = getAttrs("menu", { classes: menuClasses });
|
|
61
76
|
const periodsRowAttrs = getAttrs("periodsRow");
|
|
62
77
|
const rangeSwitchWrapperAttrs = getAttrs("rangeSwitchWrapper");
|
|
63
78
|
const nextIconAttrs = getAttrs("nextIcon");
|
|
@@ -19,7 +19,18 @@ export default /*tw*/ {
|
|
|
19
19
|
hover:bg-zinc-200 hover:ring-brand-600/[.15] focus:border-0 focus:ring-0 focus:ring-brand-600/[.15] active:bg-zinc-200
|
|
20
20
|
disabled:cursor-not-allowed last:rounded-l-none last:rounded-r-lg first:rounded-l-lg first:rounded-r-none
|
|
21
21
|
`,
|
|
22
|
-
menu:
|
|
22
|
+
menu: {
|
|
23
|
+
base: "absolute z-40 my-2 w-80 overflow-hidden rounded-lg border border-brand-300 bg-white p-2 shadow focus:outline-none",
|
|
24
|
+
variants: {
|
|
25
|
+
openDirectionX: {
|
|
26
|
+
left: "left-0",
|
|
27
|
+
right: "right-0",
|
|
28
|
+
},
|
|
29
|
+
openDirectionY: {
|
|
30
|
+
top: "bottom-full mt-0",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
23
34
|
menuTransition: {
|
|
24
35
|
enterFromClass: "opacity-0 scale-95",
|
|
25
36
|
enterActiveClass: "transition transform ease-out duration-100",
|
|
@@ -185,6 +196,8 @@ export default /*tw*/ {
|
|
|
185
196
|
defaultVariants: {
|
|
186
197
|
size: "md",
|
|
187
198
|
variant: "button",
|
|
199
|
+
openDirectionX: "auto",
|
|
200
|
+
openDirectionY: "auto",
|
|
188
201
|
timepicker: false,
|
|
189
202
|
disabled: false,
|
|
190
203
|
dateFormat: "d.m.Y",
|
|
@@ -79,12 +79,55 @@ const VariantsTemplate = (args, { argTypes } = {}) => ({
|
|
|
79
79
|
`,
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
+
const OpenDirectionTemplate = (args, { argTypes } = {}) => ({
|
|
83
|
+
components: { UDatePickerRange, URow },
|
|
84
|
+
setup() {
|
|
85
|
+
return {
|
|
86
|
+
args,
|
|
87
|
+
directions: argTypes.openDirection.options,
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
template: `
|
|
91
|
+
<URow class="!flex-col">
|
|
92
|
+
<UDatePickerRange
|
|
93
|
+
class="w-full"
|
|
94
|
+
open-direction-y="top"
|
|
95
|
+
v-bind="args"
|
|
96
|
+
v-model="args.value"
|
|
97
|
+
/>
|
|
98
|
+
<UDatePickerRange
|
|
99
|
+
class="w-full"
|
|
100
|
+
open-direction-y="bottom"
|
|
101
|
+
open-direction-x="right"
|
|
102
|
+
v-bind="args"
|
|
103
|
+
v-model="args.value"
|
|
104
|
+
/>
|
|
105
|
+
<UDatePickerRange
|
|
106
|
+
class="w-full"
|
|
107
|
+
open-direction-y="bottom"
|
|
108
|
+
v-bind="args"
|
|
109
|
+
v-model="args.value"
|
|
110
|
+
/>
|
|
111
|
+
<UDatePickerRange
|
|
112
|
+
class="w-full"
|
|
113
|
+
open-direction-y="bottom"
|
|
114
|
+
open-direction-x="left"
|
|
115
|
+
v-bind="args"
|
|
116
|
+
v-model="args.value"
|
|
117
|
+
/>
|
|
118
|
+
</URow>
|
|
119
|
+
`,
|
|
120
|
+
});
|
|
121
|
+
|
|
82
122
|
export const Default = DefaultTemplate.bind({});
|
|
83
123
|
Default.args = {};
|
|
84
124
|
|
|
85
125
|
export const variants = VariantsTemplate.bind({});
|
|
86
126
|
variants.args = {};
|
|
87
127
|
|
|
128
|
+
export const openDirection = OpenDirectionTemplate.bind({});
|
|
129
|
+
openDirection.args = {};
|
|
130
|
+
|
|
88
131
|
export const disabled = VariantsTemplate.bind({});
|
|
89
132
|
disabled.args = { disabled: true };
|
|
90
133
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-bind="wrapperAttrs">
|
|
2
|
+
<div v-bind="wrapperAttrs" ref="wrapperRef">
|
|
3
3
|
<UInput
|
|
4
4
|
v-if="isVariant.input"
|
|
5
5
|
:id="id"
|
|
@@ -235,6 +235,7 @@ import { wrongDateFormat, wrongMonthNumber, wrongDayNumber } from "./services/va
|
|
|
235
235
|
import useAttrs from "./composables/attrs.composable";
|
|
236
236
|
import { useLocale } from "../composable.locale";
|
|
237
237
|
import useBreakpoint from "../composable.breakpoint";
|
|
238
|
+
import { useAdjustElementPosition } from "../composable.adjustElementPosition";
|
|
238
239
|
|
|
239
240
|
import defaultConfig from "./configs/default.config";
|
|
240
241
|
import {
|
|
@@ -272,6 +273,24 @@ const props = defineProps({
|
|
|
272
273
|
}),
|
|
273
274
|
},
|
|
274
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Datepicker open direction on x-axis.
|
|
278
|
+
* @values auto, left, right
|
|
279
|
+
*/
|
|
280
|
+
openDirectionX: {
|
|
281
|
+
type: String,
|
|
282
|
+
default: UIService.get(defaultConfig, UDatePickerRange).default.openDirectionX,
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Datepicker open direction on y-axis.
|
|
287
|
+
* @values auto, top, bottom
|
|
288
|
+
*/
|
|
289
|
+
openDirectionY: {
|
|
290
|
+
type: String,
|
|
291
|
+
default: UIService.get(defaultConfig, UDatePickerRange).default.openDirectionY,
|
|
292
|
+
},
|
|
293
|
+
|
|
275
294
|
/**
|
|
276
295
|
* The variant of the date picker.
|
|
277
296
|
* @values button, input
|
|
@@ -383,6 +402,23 @@ const props = defineProps({
|
|
|
383
402
|
const emit = defineEmits(["update:modelValue"]);
|
|
384
403
|
|
|
385
404
|
const isShownMenu = ref(false);
|
|
405
|
+
const wrapperRef = ref(null);
|
|
406
|
+
const menuRef = ref(null);
|
|
407
|
+
const rangeInputStartRef = ref(null);
|
|
408
|
+
const rangeInputEndRef = ref(null);
|
|
409
|
+
|
|
410
|
+
const { isTop, isRight, adjustPositionY, adjustPositionX } = useAdjustElementPosition(
|
|
411
|
+
wrapperRef,
|
|
412
|
+
menuRef,
|
|
413
|
+
{
|
|
414
|
+
x: props.openDirectionX,
|
|
415
|
+
y: props.openDirectionY,
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
x: "left",
|
|
419
|
+
y: "bottom",
|
|
420
|
+
},
|
|
421
|
+
);
|
|
386
422
|
|
|
387
423
|
const {
|
|
388
424
|
config,
|
|
@@ -405,7 +441,7 @@ const {
|
|
|
405
441
|
rangeInputAttrs,
|
|
406
442
|
rangeInputWrapperAttrs,
|
|
407
443
|
inputRangeErrorAttrs,
|
|
408
|
-
} = useAttrs(props, { isShownMenu });
|
|
444
|
+
} = useAttrs(props, { isShownMenu, isTop, isRight });
|
|
409
445
|
const { tm } = useLocale();
|
|
410
446
|
|
|
411
447
|
const calendarValue = ref(props.modelValue);
|
|
@@ -413,16 +449,15 @@ const activeDate = ref(
|
|
|
413
449
|
props.modelValue.from !== null ? getDateFromUnixTimestamp(props.modelValue.from) : new Date(),
|
|
414
450
|
);
|
|
415
451
|
const period = ref(PERIOD.ownRange);
|
|
416
|
-
const periodDateList = ref(null);
|
|
417
452
|
const rangeStart = ref("");
|
|
418
453
|
const rangeEnd = ref("");
|
|
419
454
|
const inputRangeStartError = ref("");
|
|
420
455
|
const inputRangeEndError = ref("");
|
|
421
456
|
const isHoverEvent = ref(false);
|
|
457
|
+
const periodDateList = ref(null);
|
|
422
458
|
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
const rangeInputEndRef = ref(null);
|
|
459
|
+
const { isMobileBreakpoint } = useBreakpoint();
|
|
460
|
+
const i18nGlobal = tm(UDatePickerRange);
|
|
426
461
|
|
|
427
462
|
const localValue = computed({
|
|
428
463
|
get: () => props.modelValue,
|
|
@@ -435,9 +470,6 @@ const localValue = computed({
|
|
|
435
470
|
},
|
|
436
471
|
});
|
|
437
472
|
|
|
438
|
-
const { isMobileBreakpoint } = useBreakpoint();
|
|
439
|
-
const i18nGlobal = tm(UDatePickerRange);
|
|
440
|
-
|
|
441
473
|
const rangeInputName = computed(() => `rangeInput-${props.id}`);
|
|
442
474
|
const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
|
|
443
475
|
|
|
@@ -593,7 +625,7 @@ const userFormatDate = computed(() => {
|
|
|
593
625
|
const endMonth = String(to?.getMonth())?.padStart(2, "0");
|
|
594
626
|
|
|
595
627
|
const fromTitle = `${startDay}.${startMonth}`;
|
|
596
|
-
const toTitle = to ? `${endDay}.${endMonth} / ${to.getFullYear}` : "";
|
|
628
|
+
const toTitle = to ? `${endDay}.${endMonth} / ${to.getFullYear()}` : "";
|
|
597
629
|
|
|
598
630
|
title = `${fromTitle} – ${toTitle}`;
|
|
599
631
|
}
|
|
@@ -782,7 +814,12 @@ function getPeriodDateListClasses() {
|
|
|
782
814
|
function activate() {
|
|
783
815
|
isShownMenu.value = true;
|
|
784
816
|
|
|
785
|
-
nextTick(() =>
|
|
817
|
+
nextTick(() => {
|
|
818
|
+
adjustPositionY();
|
|
819
|
+
adjustPositionX();
|
|
820
|
+
|
|
821
|
+
menuRef.value.focus();
|
|
822
|
+
});
|
|
786
823
|
}
|
|
787
824
|
|
|
788
825
|
function deactivate() {
|
|
@@ -860,8 +897,11 @@ function onInputRangeInput(value, type) {
|
|
|
860
897
|
setDefaultPeriodForButton();
|
|
861
898
|
|
|
862
899
|
function setDefaultPeriodForButton() {
|
|
863
|
-
const from = utcToGMT(getDateFromUnixTimestamp(props.modelValue.
|
|
864
|
-
const to = utcToGMT(getDateFromUnixTimestamp(props.modelValue.
|
|
900
|
+
const from = utcToGMT(getDateFromUnixTimestamp(props.modelValue.from || new Date()));
|
|
901
|
+
const to = utcToGMT(getDateFromUnixTimestamp(props.modelValue.to || new Date()));
|
|
902
|
+
|
|
903
|
+
const customFrom = utcToGMT(getDateFromUnixTimestamp(props.customRangeButton.range.from));
|
|
904
|
+
const customTo = utcToGMT(getDateFromUnixTimestamp(props.customRangeButton.range.to));
|
|
865
905
|
|
|
866
906
|
const isWeekPeriod =
|
|
867
907
|
String(from) === String(getStartOfWeek(from, { weekStartsOn: 1 })) &&
|
|
@@ -874,6 +914,7 @@ function setDefaultPeriodForButton() {
|
|
|
874
914
|
String(from) === String(getStartOfQuarter(from)) && String(to) === String(getEndOfQuarter(to));
|
|
875
915
|
const isYearPeriod =
|
|
876
916
|
String(from) === String(getStartOfYear(from)) && String(to) === String(getEndOfYear(to));
|
|
917
|
+
const isCustomPeriod = String(from) === String(customFrom) && String(to) === String(customTo);
|
|
877
918
|
|
|
878
919
|
if (!props.modelValue.from && !props.modelValue.to) {
|
|
879
920
|
period.value = PERIOD.ownRange;
|
|
@@ -885,6 +926,8 @@ function setDefaultPeriodForButton() {
|
|
|
885
926
|
period.value = PERIOD.quarter;
|
|
886
927
|
} else if (isWeekPeriod) {
|
|
887
928
|
period.value = PERIOD.week;
|
|
929
|
+
} else if (isCustomPeriod) {
|
|
930
|
+
period.value = PERIOD.custom;
|
|
888
931
|
} else {
|
|
889
932
|
period.value = PERIOD.ownRange;
|
|
890
933
|
}
|
|
@@ -93,12 +93,10 @@ export function getWeekDateList(date, monthShortLocales = {}) {
|
|
|
93
93
|
const isLastWeek = week + day === weeksInMonth;
|
|
94
94
|
|
|
95
95
|
let monthFirstDayOfWeek = "";
|
|
96
|
-
let monthLastDayOfWeek = endOfWeekDate.
|
|
96
|
+
let monthLastDayOfWeek = endOfWeekDate.getMonth();
|
|
97
97
|
|
|
98
98
|
if (isDayInPreviousMonth || isLastWeek) {
|
|
99
|
-
monthFirstDayOfWeek = startOfWeekDate
|
|
100
|
-
.toLocaleString("en-us", { month: "long" })
|
|
101
|
-
.toLowerCase();
|
|
99
|
+
monthFirstDayOfWeek = startOfWeekDate.getMonth();
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
const title = `${firstDayOfWeek} ${
|
package/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"framework": "vue",
|
|
3
3
|
"name": "vueless",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.154",
|
|
5
5
|
"contributions": {
|
|
6
6
|
"html": {
|
|
7
7
|
"description-markup": "markdown",
|
|
@@ -1530,6 +1530,24 @@
|
|
|
1530
1530
|
},
|
|
1531
1531
|
"default": "null"
|
|
1532
1532
|
},
|
|
1533
|
+
{
|
|
1534
|
+
"name": "openDirectionX",
|
|
1535
|
+
"description": "Datepicker open direction on x-axis.",
|
|
1536
|
+
"value": {
|
|
1537
|
+
"kind": "expression",
|
|
1538
|
+
"type": "'auto' | 'left' | 'right'"
|
|
1539
|
+
},
|
|
1540
|
+
"default": "auto"
|
|
1541
|
+
},
|
|
1542
|
+
{
|
|
1543
|
+
"name": "openDirectionY",
|
|
1544
|
+
"description": "Datepicker open direction on y-axis.",
|
|
1545
|
+
"value": {
|
|
1546
|
+
"kind": "expression",
|
|
1547
|
+
"type": "'auto' | 'top' | 'bottom'"
|
|
1548
|
+
},
|
|
1549
|
+
"default": "auto"
|
|
1550
|
+
},
|
|
1533
1551
|
{
|
|
1534
1552
|
"name": "minDate",
|
|
1535
1553
|
"description": "Min date in format date string or Date.",
|
|
@@ -1683,6 +1701,24 @@
|
|
|
1683
1701
|
},
|
|
1684
1702
|
"default": "{\n range: { from: 0, to: 0 },\n label: \"\",\n description: \"\"\n}"
|
|
1685
1703
|
},
|
|
1704
|
+
{
|
|
1705
|
+
"name": "openDirectionX",
|
|
1706
|
+
"description": "Datepicker open direction on x-axis.",
|
|
1707
|
+
"value": {
|
|
1708
|
+
"kind": "expression",
|
|
1709
|
+
"type": "'auto' | 'left' | 'right'"
|
|
1710
|
+
},
|
|
1711
|
+
"default": "auto"
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
"name": "openDirectionY",
|
|
1715
|
+
"description": "Datepicker open direction on y-axis.",
|
|
1716
|
+
"value": {
|
|
1717
|
+
"kind": "expression",
|
|
1718
|
+
"type": "'auto' | 'top' | 'bottom'"
|
|
1719
|
+
},
|
|
1720
|
+
"default": "auto"
|
|
1721
|
+
},
|
|
1686
1722
|
{
|
|
1687
1723
|
"name": "variant",
|
|
1688
1724
|
"description": "The variant of the date picker.",
|