vueless 1.0.2-beta.47 → 1.0.2-beta.49
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/package.json +1 -1
- package/ui.container-modal/UModal.vue +30 -32
- package/ui.form-calendar/UCalendar.vue +33 -3
- package/ui.form-calendar/UCalendarMonthView.vue +6 -1
- package/ui.form-calendar/UCalendarYearView.vue +6 -1
- package/ui.form-calendar/storybook/stories.ts +39 -47
- package/ui.form-date-picker/storybook/stories.ts +145 -45
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, useSlots, watch, useId, useTemplateRef } from "vue";
|
|
2
|
+
import { computed, useSlots, watch, useId, useTemplateRef, nextTick } from "vue";
|
|
3
3
|
|
|
4
4
|
import useUI from "../composables/useUI.ts";
|
|
5
5
|
import { getDefaults } from "../utils/ui.ts";
|
|
@@ -71,42 +71,40 @@ const isExistFooter = computed(() => {
|
|
|
71
71
|
return hasSlotContent(slots["footer-left"]) || hasSlotContent(slots["footer-right"]);
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
function getFocusableElements() {
|
|
75
|
+
if (!wrapperRef.value) return [];
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// ),
|
|
83
|
-
// );
|
|
84
|
-
// }
|
|
77
|
+
return Array.from(
|
|
78
|
+
wrapperRef.value.querySelectorAll(
|
|
79
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
function trapFocus(e: KeyboardEvent) {
|
|
85
|
+
if (e.key !== "Tab") return;
|
|
88
86
|
|
|
89
|
-
|
|
87
|
+
const focusableElements = getFocusableElements();
|
|
90
88
|
|
|
91
|
-
|
|
89
|
+
if (!focusableElements.length) return;
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
const firstElement = focusableElements.at(0) as HTMLElement;
|
|
92
|
+
const lastElement = focusableElements.at(-1) as HTMLElement;
|
|
95
93
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
// Shift+Tab - if focused on first element, move to last
|
|
95
|
+
if (e.shiftKey && document.activeElement === firstElement) {
|
|
96
|
+
e.preventDefault();
|
|
97
|
+
lastElement.focus();
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
103
101
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
// Tab - if focused on last element, move to first
|
|
103
|
+
if (!e.shiftKey && document.activeElement === lastElement) {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
firstElement.focus();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
110
108
|
|
|
111
109
|
watch(isShownModal, onChangeShownModal);
|
|
112
110
|
|
|
@@ -115,7 +113,7 @@ function onChangeShownModal(newValue: boolean) {
|
|
|
115
113
|
toggleOverflow();
|
|
116
114
|
|
|
117
115
|
if (newValue) {
|
|
118
|
-
|
|
116
|
+
nextTick(() => wrapperRef.value?.focus());
|
|
119
117
|
}
|
|
120
118
|
}
|
|
121
119
|
|
|
@@ -135,10 +133,10 @@ function toggleOverflow() {
|
|
|
135
133
|
|
|
136
134
|
function toggleEventListeners() {
|
|
137
135
|
if (isShownModal.value) {
|
|
138
|
-
|
|
136
|
+
document.addEventListener("keydown", trapFocus);
|
|
139
137
|
document.addEventListener("keydown", onKeydownEsc);
|
|
140
138
|
} else {
|
|
141
|
-
|
|
139
|
+
document.removeEventListener("keydown", trapFocus);
|
|
142
140
|
document.removeEventListener("keydown", onKeydownEsc);
|
|
143
141
|
}
|
|
144
142
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts" generic="TModelValue extends DateValue">
|
|
2
|
-
import { computed, ref, watch, useTemplateRef, nextTick } from "vue";
|
|
2
|
+
import { computed, ref, watch, useTemplateRef, nextTick, onMounted } from "vue";
|
|
3
3
|
|
|
4
4
|
import useUI from "../composables/useUI.ts";
|
|
5
5
|
import { getDefaults } from "../utils/ui.ts";
|
|
@@ -63,24 +63,29 @@ const emit = defineEmits([
|
|
|
63
63
|
* @property {object} modelValue
|
|
64
64
|
*/
|
|
65
65
|
"update:modelValue",
|
|
66
|
+
|
|
66
67
|
/**
|
|
67
68
|
* Triggers when calendar view changes.
|
|
68
69
|
* @property {string} view
|
|
69
70
|
*/
|
|
70
71
|
"update:view",
|
|
72
|
+
|
|
71
73
|
/**
|
|
72
74
|
* Triggers when date value changes.
|
|
73
75
|
* @property {object} value
|
|
74
76
|
*/
|
|
75
77
|
"input",
|
|
78
|
+
|
|
76
79
|
/**
|
|
77
80
|
* Triggers when calendar date is selected by clicking "Enter".
|
|
78
81
|
*/
|
|
79
82
|
"submit",
|
|
83
|
+
|
|
80
84
|
/**
|
|
81
85
|
* Triggers when arrow keys are used to change calendar date.
|
|
82
86
|
*/
|
|
83
87
|
"keydown",
|
|
88
|
+
|
|
84
89
|
/**
|
|
85
90
|
* Triggers when the user changes the date input value.
|
|
86
91
|
* @property {string} value
|
|
@@ -315,6 +320,32 @@ const currentViewLabel = computed(() => {
|
|
|
315
320
|
return label;
|
|
316
321
|
});
|
|
317
322
|
|
|
323
|
+
onMounted(() => {
|
|
324
|
+
if (props.modelValue && (props.dateFormat || props.dateTimeFormat)) {
|
|
325
|
+
const formatted = isRangeDate(props.modelValue)
|
|
326
|
+
? {
|
|
327
|
+
from: formatDate(
|
|
328
|
+
parseDate(props.modelValue.from, actualDateFormat.value, locale.value),
|
|
329
|
+
actualDateFormat.value,
|
|
330
|
+
locale.value,
|
|
331
|
+
),
|
|
332
|
+
to: formatDate(
|
|
333
|
+
parseDate(props.modelValue.to, actualDateFormat.value, locale.value),
|
|
334
|
+
actualDateFormat.value,
|
|
335
|
+
locale.value,
|
|
336
|
+
),
|
|
337
|
+
}
|
|
338
|
+
: formatDate(
|
|
339
|
+
parseDate(props.modelValue, actualDateFormat.value, locale.value),
|
|
340
|
+
actualDateFormat.value,
|
|
341
|
+
locale.value,
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
emit("update:modelValue", formatted);
|
|
345
|
+
emit("userDateChange", userFormattedDate.value);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
318
349
|
watch(userFormattedDate, () => {
|
|
319
350
|
emit("userDateChange", userFormattedDate.value);
|
|
320
351
|
});
|
|
@@ -792,7 +823,6 @@ const {
|
|
|
792
823
|
>
|
|
793
824
|
<div v-bind="navigationAttrs" :data-test="getDataTest('navigation')">
|
|
794
825
|
<UButton
|
|
795
|
-
v-if="range"
|
|
796
826
|
square
|
|
797
827
|
size="sm"
|
|
798
828
|
color="grayscale"
|
|
@@ -818,6 +848,7 @@ const {
|
|
|
818
848
|
|
|
819
849
|
<UButton
|
|
820
850
|
block
|
|
851
|
+
square
|
|
821
852
|
size="sm"
|
|
822
853
|
color="grayscale"
|
|
823
854
|
variant="ghost"
|
|
@@ -841,7 +872,6 @@ const {
|
|
|
841
872
|
/>
|
|
842
873
|
|
|
843
874
|
<UButton
|
|
844
|
-
v-if="range"
|
|
845
875
|
square
|
|
846
876
|
size="sm"
|
|
847
877
|
color="grayscale"
|
|
@@ -55,7 +55,12 @@ function getMonthState(month: Date) {
|
|
|
55
55
|
props.selectedDateTo &&
|
|
56
56
|
props.selectedDate &&
|
|
57
57
|
isMoreThanOneMonthDiff(props.selectedDate, props.selectedDateTo);
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
const isActiveMonth =
|
|
60
|
+
props.activeMonth &&
|
|
61
|
+
isSameMonth(props.activeMonth, month) &&
|
|
62
|
+
!props.range &&
|
|
63
|
+
!dateIsOutOfRange(month, props.minDate, props.maxDate, props.locale, props.dateFormat);
|
|
59
64
|
|
|
60
65
|
return {
|
|
61
66
|
isSelectedMonth,
|
|
@@ -127,7 +127,12 @@ function getYearState(year: Date) {
|
|
|
127
127
|
props.selectedDateTo &&
|
|
128
128
|
props.selectedDate &&
|
|
129
129
|
props.selectedDateTo.getFullYear() - props.selectedDate.getFullYear() >= 1;
|
|
130
|
-
|
|
130
|
+
|
|
131
|
+
const isActiveYear =
|
|
132
|
+
props.activeMonth &&
|
|
133
|
+
isSameMonth(props.activeMonth, year) &&
|
|
134
|
+
!props.range &&
|
|
135
|
+
!dateIsOutOfRange(year, props.minDate, props.maxDate, props.locale, props.dateFormat);
|
|
131
136
|
|
|
132
137
|
return {
|
|
133
138
|
isSelectedYear,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
import UCalendar from "../../ui.form-calendar/UCalendar.vue";
|
|
11
11
|
import URow from "../../ui.container-row/URow.vue";
|
|
12
|
-
import
|
|
12
|
+
import UText from "../../ui.text-block/UText.vue";
|
|
13
13
|
|
|
14
14
|
import { COMPONENT_NAME } from "../constants.ts";
|
|
15
15
|
|
|
@@ -25,7 +25,7 @@ export default {
|
|
|
25
25
|
title: "Form Inputs & Controls / Calendar",
|
|
26
26
|
component: UCalendar,
|
|
27
27
|
args: {
|
|
28
|
-
modelValue:
|
|
28
|
+
modelValue: new Date(new Date().getFullYear(), new Date().getMonth(), 10, 12, 35, 50),
|
|
29
29
|
},
|
|
30
30
|
argTypes: {
|
|
31
31
|
...getArgTypes(COMPONENT_NAME),
|
|
@@ -41,21 +41,19 @@ export default {
|
|
|
41
41
|
} as Meta;
|
|
42
42
|
|
|
43
43
|
const DefaultTemplate: StoryFn<UCalendarArgs> = (args: UCalendarArgs) => ({
|
|
44
|
-
components: { UCalendar },
|
|
44
|
+
components: { UCalendar, UText },
|
|
45
45
|
setup: () => ({ args, slots: getSlotNames(COMPONENT_NAME) }),
|
|
46
46
|
template: `
|
|
47
47
|
<UCalendar v-bind="args" v-model="args.modelValue">
|
|
48
48
|
${args.slotTemplate || getSlotsFragment("")}
|
|
49
49
|
</UCalendar>
|
|
50
50
|
|
|
51
|
-
<
|
|
52
|
-
{{ args.modelValue }}
|
|
53
|
-
</div>
|
|
51
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
54
52
|
`,
|
|
55
53
|
});
|
|
56
54
|
|
|
57
55
|
const EnumTemplate: StoryFn<UCalendarArgs> = (args: UCalendarArgs, { argTypes }) => ({
|
|
58
|
-
components: { UCalendar, URow },
|
|
56
|
+
components: { UCalendar, URow, UText },
|
|
59
57
|
setup: () => ({ args, argTypes, getArgs }),
|
|
60
58
|
template: `
|
|
61
59
|
<URow>
|
|
@@ -66,19 +64,13 @@ const EnumTemplate: StoryFn<UCalendarArgs> = (args: UCalendarArgs, { argTypes })
|
|
|
66
64
|
v-model="args.modelValue"
|
|
67
65
|
/>
|
|
68
66
|
</URow>
|
|
69
|
-
`,
|
|
70
|
-
});
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
setup: () => ({ args, slots: getSlotNames(COMPONENT_NAME) }),
|
|
75
|
-
template: `
|
|
76
|
-
<UDatePicker v-bind="args" v-model="args.modelValue" />
|
|
77
|
-
`,
|
|
68
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
69
|
+
`,
|
|
78
70
|
});
|
|
79
71
|
|
|
80
72
|
export const Default = DefaultTemplate.bind({});
|
|
81
|
-
Default.args = {
|
|
73
|
+
Default.args = {};
|
|
82
74
|
|
|
83
75
|
export const View = EnumTemplate.bind({});
|
|
84
76
|
View.args = { enum: "view" };
|
|
@@ -102,42 +94,42 @@ Range.args = {
|
|
|
102
94
|
export const Timepicker = DefaultTemplate.bind({});
|
|
103
95
|
Timepicker.args = { modelValue: new Date(2024, 2, 14, 12, 24, 14), timepicker: true };
|
|
104
96
|
|
|
105
|
-
export const DateFormat =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
};
|
|
97
|
+
export const DateFormat: StoryFn<UCalendarArgs> = (args: UCalendarArgs) => ({
|
|
98
|
+
components: { UCalendar, UText, URow },
|
|
99
|
+
setup: () => ({ args }),
|
|
100
|
+
template: `
|
|
101
|
+
<URow block gap="2xl">
|
|
102
|
+
<UCalendar v-model="args.modelValue" date-format="Y-m-d" />
|
|
114
103
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
};
|
|
104
|
+
<UCalendar
|
|
105
|
+
v-model="args.modelValue"
|
|
106
|
+
date-time-format="Y-m-d H:i:S"
|
|
107
|
+
timepicker
|
|
108
|
+
/>
|
|
109
|
+
</URow>
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
111
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
112
|
+
`,
|
|
113
|
+
});
|
|
114
|
+
DateFormat.parameters = {
|
|
128
115
|
docs: {
|
|
129
116
|
description: {
|
|
130
|
-
story: "
|
|
117
|
+
story: "Date string format.",
|
|
131
118
|
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
119
|
+
source: {
|
|
120
|
+
code: `
|
|
121
|
+
<URow block gap="2xl">
|
|
122
|
+
<UCalendar v-model="args.modelValue" date-format="Y-m-d" />
|
|
123
|
+
|
|
124
|
+
<UCalendar
|
|
125
|
+
v-model="args.modelValue"
|
|
126
|
+
date-time-format="Y-m-d H:i:S"
|
|
127
|
+
timepicker
|
|
128
|
+
/>
|
|
129
|
+
</URow>
|
|
130
|
+
|
|
131
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
132
|
+
`,
|
|
141
133
|
},
|
|
142
134
|
},
|
|
143
135
|
};
|
|
@@ -12,6 +12,7 @@ import UIcon from "../../ui.image-icon/UIcon.vue";
|
|
|
12
12
|
import URow from "../../ui.container-row/URow.vue";
|
|
13
13
|
import UCol from "../../ui.container-col/UCol.vue";
|
|
14
14
|
import UButton from "../../ui.button/UButton.vue";
|
|
15
|
+
import UText from "../../ui.text-block/UText.vue";
|
|
15
16
|
|
|
16
17
|
import { COMPONENT_NAME } from "../constants.ts";
|
|
17
18
|
|
|
@@ -38,8 +39,7 @@ export default {
|
|
|
38
39
|
component: UDatePicker,
|
|
39
40
|
args: {
|
|
40
41
|
label: "Select a date",
|
|
41
|
-
modelValue:
|
|
42
|
-
openDirectionY: "bottom",
|
|
42
|
+
modelValue: new Date(),
|
|
43
43
|
},
|
|
44
44
|
argTypes: {
|
|
45
45
|
...getArgTypes(COMPONENT_NAME),
|
|
@@ -48,28 +48,26 @@ export default {
|
|
|
48
48
|
docs: {
|
|
49
49
|
...getDocsDescription(COMPONENT_NAME),
|
|
50
50
|
story: {
|
|
51
|
-
height: "
|
|
51
|
+
height: "450px",
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
} as Meta;
|
|
56
56
|
|
|
57
57
|
const DefaultTemplate: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
|
|
58
|
-
components: { UDatePicker, UIcon },
|
|
58
|
+
components: { UDatePicker, UIcon, UText },
|
|
59
59
|
setup: () => ({ args, slots: getSlotNames(COMPONENT_NAME) }),
|
|
60
60
|
template: `
|
|
61
|
-
<UDatePicker
|
|
61
|
+
<UDatePicker v-bind="args" v-model="args.modelValue" class="max-w-96">
|
|
62
62
|
${args.slotTemplate || getSlotsFragment("")}
|
|
63
63
|
</UDatePicker>
|
|
64
64
|
|
|
65
|
-
<
|
|
66
|
-
{{ args.modelValue }}
|
|
67
|
-
</div>
|
|
65
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
68
66
|
`,
|
|
69
67
|
});
|
|
70
68
|
|
|
71
69
|
const EnumTemplate: StoryFn<EnumUDatePickerArgs> = (args: EnumUDatePickerArgs, { argTypes }) => ({
|
|
72
|
-
components: { UDatePicker, UCol },
|
|
70
|
+
components: { UDatePicker, UCol, UText },
|
|
73
71
|
setup: () => ({ args, argTypes, getArgs }),
|
|
74
72
|
template: `
|
|
75
73
|
<UCol :class="args.wrapperClass">
|
|
@@ -77,54 +75,54 @@ const EnumTemplate: StoryFn<EnumUDatePickerArgs> = (args: EnumUDatePickerArgs, {
|
|
|
77
75
|
v-for="option in argTypes?.[args.enum]?.options"
|
|
78
76
|
v-bind="getArgs(args, option)"
|
|
79
77
|
:key="option"
|
|
80
|
-
class="w-full"
|
|
78
|
+
class="w-full max-w-96"
|
|
81
79
|
/>
|
|
82
80
|
</UCol>
|
|
81
|
+
|
|
82
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
83
83
|
`,
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
const OpenDirectionTemplate: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
|
|
87
|
-
components: { UDatePicker, UCol },
|
|
88
|
-
setup() {
|
|
89
|
-
return {
|
|
90
|
-
args,
|
|
91
|
-
};
|
|
92
|
-
},
|
|
87
|
+
components: { UDatePicker, UCol, UText },
|
|
88
|
+
setup: () => ({ args }),
|
|
93
89
|
template: `
|
|
94
90
|
<UCol>
|
|
95
91
|
<UDatePicker
|
|
96
|
-
class="w-full"
|
|
97
92
|
open-direction-y="top"
|
|
98
93
|
open-direction-x="left"
|
|
99
94
|
v-bind="args"
|
|
100
95
|
v-model="args.modelValue"
|
|
101
96
|
label="Top Left"
|
|
97
|
+
class="w-full max-w-96"
|
|
102
98
|
/>
|
|
103
99
|
<UDatePicker
|
|
104
|
-
class="w-full"
|
|
105
100
|
open-direction-y="top"
|
|
106
101
|
open-direction-x="right"
|
|
107
102
|
v-bind="args"
|
|
108
103
|
v-model="args.modelValue"
|
|
109
104
|
label="Top Right"
|
|
105
|
+
class="w-full max-w-96"
|
|
110
106
|
/>
|
|
111
107
|
<UDatePicker
|
|
112
|
-
class="w-full"
|
|
113
108
|
open-direction-y="bottom"
|
|
114
109
|
open-direction-x="left"
|
|
115
110
|
v-bind="args"
|
|
116
111
|
v-model="args.modelValue"
|
|
117
112
|
label="Bottom Left"
|
|
113
|
+
class="w-full max-w-96"
|
|
118
114
|
/>
|
|
119
115
|
<UDatePicker
|
|
120
|
-
class="w-full"
|
|
121
116
|
open-direction-y="bottom"
|
|
122
117
|
open-direction-x="right"
|
|
123
118
|
v-bind="args"
|
|
124
119
|
v-model="args.modelValue"
|
|
125
120
|
label="Bottom Right"
|
|
121
|
+
class="w-full max-w-96"
|
|
126
122
|
/>
|
|
127
123
|
</UCol>
|
|
124
|
+
|
|
125
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
128
126
|
`,
|
|
129
127
|
});
|
|
130
128
|
|
|
@@ -132,23 +130,27 @@ export const Default = DefaultTemplate.bind({});
|
|
|
132
130
|
Default.args = { modelValue: dateValue };
|
|
133
131
|
|
|
134
132
|
export const Placeholder = DefaultTemplate.bind({});
|
|
135
|
-
Placeholder.args = { placeholder: "MM/DD/YYYY" };
|
|
133
|
+
Placeholder.args = { placeholder: "MM/DD/YYYY", modelValue: null };
|
|
136
134
|
|
|
137
135
|
export const Description = DefaultTemplate.bind({});
|
|
138
136
|
Description.args = { description: "Please choose a date from the calendar." };
|
|
139
137
|
|
|
140
138
|
export const Error: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
|
|
141
|
-
components: { UDatePicker, UIcon },
|
|
139
|
+
components: { UDatePicker, UIcon, UText },
|
|
142
140
|
setup: () => ({ args, slots: getSlotNames(COMPONENT_NAME) }),
|
|
143
141
|
template: `
|
|
144
142
|
<UDatePicker
|
|
145
143
|
open-direction-y="bottom"
|
|
146
144
|
v-bind="args"
|
|
147
145
|
v-model="args.modelValue"
|
|
146
|
+
class="max-w-96"
|
|
148
147
|
:error="args.modelValue ? '' : 'Please select a valid date.'"
|
|
149
148
|
/>
|
|
149
|
+
|
|
150
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
150
151
|
`,
|
|
151
152
|
});
|
|
153
|
+
Error.args = { modelValue: null };
|
|
152
154
|
|
|
153
155
|
export const Disabled = DefaultTemplate.bind({});
|
|
154
156
|
Disabled.args = { disabled: true };
|
|
@@ -156,8 +158,24 @@ Disabled.args = { disabled: true };
|
|
|
156
158
|
export const LabelAlign = EnumTemplate.bind({});
|
|
157
159
|
LabelAlign.args = { enum: "labelAlign", description: "{enumValue}", wrapperClass: "gap-16" };
|
|
158
160
|
|
|
159
|
-
export const Sizes =
|
|
160
|
-
|
|
161
|
+
export const Sizes: StoryFn<EnumUDatePickerArgs> = (args: EnumUDatePickerArgs, { argTypes }) => ({
|
|
162
|
+
components: { UDatePicker, URow, UText },
|
|
163
|
+
setup: () => ({ args, argTypes, getArgs }),
|
|
164
|
+
template: `
|
|
165
|
+
<URow block>
|
|
166
|
+
<UDatePicker
|
|
167
|
+
v-for="option in argTypes?.[args.enum]?.options"
|
|
168
|
+
v-bind="getArgs(args, option)"
|
|
169
|
+
:key="option"
|
|
170
|
+
v-model="args.modelValue"
|
|
171
|
+
class="w-full max-w-96"
|
|
172
|
+
/>
|
|
173
|
+
</URow>
|
|
174
|
+
|
|
175
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
176
|
+
`,
|
|
177
|
+
});
|
|
178
|
+
Sizes.args = { enum: "size" };
|
|
161
179
|
|
|
162
180
|
export const OpenDirection = OpenDirectionTemplate.bind({});
|
|
163
181
|
OpenDirection.args = {};
|
|
@@ -183,43 +201,125 @@ Timepicker.args = {
|
|
|
183
201
|
14,
|
|
184
202
|
),
|
|
185
203
|
};
|
|
186
|
-
|
|
187
|
-
export const DateFormat = DefaultTemplate.bind({});
|
|
188
|
-
DateFormat.args = { dateFormat: "Y-m-d" };
|
|
189
|
-
DateFormat.parameters = {
|
|
204
|
+
Timepicker.parameters = {
|
|
190
205
|
docs: {
|
|
191
|
-
|
|
192
|
-
|
|
206
|
+
story: {
|
|
207
|
+
height: "500px",
|
|
193
208
|
},
|
|
194
209
|
},
|
|
195
210
|
};
|
|
196
211
|
|
|
197
|
-
export const
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
export const DateFormat: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
|
|
213
|
+
components: { UDatePicker, UText, URow },
|
|
214
|
+
setup: () => ({ args }),
|
|
215
|
+
template: `
|
|
216
|
+
<URow block>
|
|
217
|
+
<UDatePicker
|
|
218
|
+
v-model="args.modelValue"
|
|
219
|
+
label="Select a date"
|
|
220
|
+
date-format="Y-m-d"
|
|
221
|
+
class="w-full"
|
|
222
|
+
/>
|
|
223
|
+
|
|
224
|
+
<UDatePicker
|
|
225
|
+
v-model="args.modelValue"
|
|
226
|
+
label="Select a date"
|
|
227
|
+
date-time-format="Y-m-d H:i:S"
|
|
228
|
+
timepicker
|
|
229
|
+
class="w-full"
|
|
230
|
+
/>
|
|
231
|
+
</URow>
|
|
232
|
+
|
|
233
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
234
|
+
`,
|
|
235
|
+
});
|
|
236
|
+
DateFormat.parameters = {
|
|
200
237
|
docs: {
|
|
201
238
|
description: {
|
|
202
|
-
story: "
|
|
239
|
+
story: "Date string format.",
|
|
240
|
+
},
|
|
241
|
+
source: {
|
|
242
|
+
code: `
|
|
243
|
+
<URow block>
|
|
244
|
+
<UDatePicker
|
|
245
|
+
v-model="args.modelValue"
|
|
246
|
+
label="Select a date"
|
|
247
|
+
date-format="Y-m-d"
|
|
248
|
+
class="w-full"
|
|
249
|
+
/>
|
|
250
|
+
|
|
251
|
+
<UDatePicker
|
|
252
|
+
v-model="args.modelValue"
|
|
253
|
+
label="Select a date"
|
|
254
|
+
date-time-format="Y-m-d H:i:S"
|
|
255
|
+
timepicker
|
|
256
|
+
class="w-full"
|
|
257
|
+
/>
|
|
258
|
+
</URow>
|
|
259
|
+
|
|
260
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
261
|
+
`,
|
|
203
262
|
},
|
|
204
263
|
},
|
|
205
264
|
};
|
|
206
265
|
|
|
207
|
-
export const UserDateFormat =
|
|
208
|
-
|
|
266
|
+
export const UserDateFormat: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
|
|
267
|
+
components: { UDatePicker, UText, URow },
|
|
268
|
+
setup: () => ({ args }),
|
|
269
|
+
template: `
|
|
270
|
+
<URow block>
|
|
271
|
+
<UDatePicker
|
|
272
|
+
v-model="args.modelValue"
|
|
273
|
+
label="Select a date"
|
|
274
|
+
user-date-format="d/m/Y"
|
|
275
|
+
class="w-full"
|
|
276
|
+
/>
|
|
277
|
+
|
|
278
|
+
<UDatePicker
|
|
279
|
+
v-model="args.modelValue"
|
|
280
|
+
label="Select a date"
|
|
281
|
+
user-date-time-format="d/m/Y H:i:S"
|
|
282
|
+
timepicker
|
|
283
|
+
class="w-full"
|
|
284
|
+
/>
|
|
285
|
+
</URow>
|
|
286
|
+
|
|
287
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
288
|
+
`,
|
|
289
|
+
});
|
|
209
290
|
UserDateFormat.parameters = {
|
|
210
291
|
docs: {
|
|
211
292
|
description: {
|
|
212
|
-
story: "
|
|
293
|
+
story: "Date string format.",
|
|
294
|
+
},
|
|
295
|
+
source: {
|
|
296
|
+
code: `
|
|
297
|
+
<URow block>
|
|
298
|
+
<UDatePicker
|
|
299
|
+
v-model="args.modelValue"
|
|
300
|
+
label="Select a date"
|
|
301
|
+
user-date-format="d/m/Y"
|
|
302
|
+
class="w-full"
|
|
303
|
+
/>
|
|
304
|
+
|
|
305
|
+
<UDatePicker
|
|
306
|
+
v-model="args.modelValue"
|
|
307
|
+
label="Select a date"
|
|
308
|
+
user-date-time-format="d/m/Y H:i:S"
|
|
309
|
+
timepicker
|
|
310
|
+
class="w-full"
|
|
311
|
+
/>
|
|
312
|
+
</URow>
|
|
313
|
+
|
|
314
|
+
<UText color="neutral" class="mt-4">{{ args.modelValue }}</UText>
|
|
315
|
+
`,
|
|
213
316
|
},
|
|
214
317
|
},
|
|
215
318
|
};
|
|
216
|
-
|
|
217
|
-
export const UserDateTimeFormat = DefaultTemplate.bind({});
|
|
218
|
-
UserDateTimeFormat.args = { timepicker: true, userDateTimeFormat: "d/m/Y H:i:S" };
|
|
219
|
-
UserDateTimeFormat.parameters = {
|
|
319
|
+
UserDateFormat.parameters = {
|
|
220
320
|
docs: {
|
|
221
321
|
description: {
|
|
222
|
-
story: "
|
|
322
|
+
story: "User-friendly date format (it will be shown in UI).",
|
|
223
323
|
},
|
|
224
324
|
},
|
|
225
325
|
};
|
|
@@ -268,7 +368,7 @@ export const Slots: StoryFn<DefaultUDatePickerArgs> = (args) => ({
|
|
|
268
368
|
<URow align="stretch">
|
|
269
369
|
<UDatePicker
|
|
270
370
|
v-bind="args"
|
|
271
|
-
v-model="args.
|
|
371
|
+
v-model="args.leftModel"
|
|
272
372
|
class="w-full"
|
|
273
373
|
:config="{ datepickerInput: { wrapper: 'pl-0' } }"
|
|
274
374
|
>
|
|
@@ -276,9 +376,9 @@ export const Slots: StoryFn<DefaultUDatePickerArgs> = (args) => ({
|
|
|
276
376
|
<UButton
|
|
277
377
|
label="Today"
|
|
278
378
|
size="sm"
|
|
279
|
-
variant="
|
|
379
|
+
variant="soft"
|
|
280
380
|
class="h-full rounded-r-none"
|
|
281
|
-
@click="args.
|
|
381
|
+
@click="args.leftModel = new Date()"
|
|
282
382
|
/>
|
|
283
383
|
</template>
|
|
284
384
|
</UDatePicker>
|