vueless 0.0.492 → 0.0.494
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/constants.js +1 -1
- package/index.ts +2 -1
- package/package.json +1 -1
- package/preset-tailwind.js +1 -1
- package/types.ts +37 -0
- package/ui.form-calendar/UCalendar.vue +20 -11
- package/ui.form-calendar/UCalendarDayView.vue +1 -1
- package/ui.form-calendar/UCalendarMonthView.vue +1 -1
- package/ui.form-calendar/UCalendarYearView.vue +1 -1
- package/ui.form-calendar/config.ts +1 -0
- package/ui.form-calendar/constants.ts +0 -6
- package/ui.form-calendar/storybook/stories.ts +5 -3
- package/ui.form-calendar/types.ts +7 -2
- package/ui.form-calendar/useAttrs.ts +1 -1
- package/ui.form-calendar/utilDate.ts +2 -2
- package/ui.form-date-picker/UDatePicker.vue +18 -16
- package/ui.form-date-picker/storybook/stories.ts +6 -4
- package/ui.form-date-picker/types.ts +2 -6
- package/ui.form-date-picker/useAttrs.ts +1 -1
- package/ui.form-date-picker-range/UDatePickerRange.vue +371 -433
- package/ui.form-date-picker-range/UDatePickerRangeInputs.vue +67 -76
- package/ui.form-date-picker-range/UDatePickerRangePeriodMenu.vue +158 -205
- package/ui.form-date-picker-range/{constants.js → constants.ts} +17 -18
- package/ui.form-date-picker-range/storybook/Docs.mdx +16 -0
- package/ui.form-date-picker-range/storybook/stories.ts +237 -0
- package/ui.form-date-picker-range/types.ts +193 -0
- package/ui.form-date-picker-range/{useAttrs.js → useAttrs.ts} +21 -5
- package/ui.form-date-picker-range/useLocale.ts +65 -0
- package/ui.form-date-picker-range/{useUserFormat.js → useUserFormat.ts} +22 -8
- package/ui.form-date-picker-range/{utilDateRange.js → utilDateRange.ts} +14 -8
- package/ui.form-date-picker-range/{utilValidation.js → utilValidation.ts} +4 -4
- package/utils/theme.ts +19 -5
- package/web-types.json +158 -52
- package/ui.form-date-picker-range/useLocale.js +0 -63
- /package/ui.form-date-picker-range/{config.js → config.ts} +0 -0
|
@@ -6,24 +6,23 @@ export const UDatePickerRange = "UDatePickerRange";
|
|
|
6
6
|
|
|
7
7
|
export const DATE_PICKER_BUTTON_TYPE = "button";
|
|
8
8
|
export const DATE_PICKER_INPUT_TYPE = "input";
|
|
9
|
+
export const INPUT_RANGE_FORMAT = "d.m.Y";
|
|
9
10
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const PERIOD = {
|
|
16
|
-
week: "week",
|
|
17
|
-
month: "month",
|
|
18
|
-
quarter: "quarter",
|
|
19
|
-
year: "year",
|
|
20
|
-
ownRange: "ownRange",
|
|
21
|
-
custom: "custom",
|
|
22
|
-
};
|
|
11
|
+
export enum InputRangeType {
|
|
12
|
+
Start = "start",
|
|
13
|
+
End = "end",
|
|
14
|
+
}
|
|
23
15
|
|
|
24
|
-
export
|
|
16
|
+
export enum Period {
|
|
17
|
+
Week = "week",
|
|
18
|
+
Month = "month",
|
|
19
|
+
Quarter = "quarter",
|
|
20
|
+
Year = "year",
|
|
21
|
+
OwnRange = "ownRange",
|
|
22
|
+
Custom = "custom",
|
|
23
|
+
}
|
|
25
24
|
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
25
|
+
export enum ShiftAction {
|
|
26
|
+
Prev = "prev",
|
|
27
|
+
Next = "next",
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
2
|
+
import { getSource } from "../../utils/storybook.ts";
|
|
3
|
+
|
|
4
|
+
import * as stories from "./stories.ts";
|
|
5
|
+
import defaultConfig from "../config.ts?raw"
|
|
6
|
+
|
|
7
|
+
<Meta of={stories} />
|
|
8
|
+
<Title of={stories} />
|
|
9
|
+
<Subtitle of={stories} />
|
|
10
|
+
<Description of={stories} />
|
|
11
|
+
<Primary of={stories} />
|
|
12
|
+
<Controls of={stories.Default} />
|
|
13
|
+
<Stories of={stories} />
|
|
14
|
+
|
|
15
|
+
## Default config
|
|
16
|
+
<Source code={getSource(defaultConfig)} language="jsx" dark />
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
2
|
+
import { getArgTypes, getSlotNames, getSlotsFragment } from "../../utils/storybook.ts";
|
|
3
|
+
|
|
4
|
+
import UDatePickerRange from "../UDatePickerRange.vue";
|
|
5
|
+
import URow from "../../ui.container-row/URow.vue";
|
|
6
|
+
import UIcon from "../../ui.image-icon/UIcon.vue";
|
|
7
|
+
import UButton from "../../ui.button/UButton.vue";
|
|
8
|
+
|
|
9
|
+
import { addDays } from "../../ui.form-calendar/utilDate.ts";
|
|
10
|
+
|
|
11
|
+
import { UDatePickerRange as UDatePickerRangeName } from "../constants.ts";
|
|
12
|
+
|
|
13
|
+
import type { UDatePickerRangeProps } from "../types.ts";
|
|
14
|
+
|
|
15
|
+
interface DefaultUDatePickerRangeArgs extends UDatePickerRangeProps<unknown> {
|
|
16
|
+
slotTemplate?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface EnumUDatePickerRangeArgs extends UDatePickerRangeProps<unknown> {
|
|
20
|
+
slotTemplate?: string;
|
|
21
|
+
enum: "size" | "variant";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The `UDatePickerRange` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/ui.form-date-picker-range)
|
|
26
|
+
*/
|
|
27
|
+
export default {
|
|
28
|
+
id: "3180",
|
|
29
|
+
title: "Form Inputs & Controls / Date Picker Range",
|
|
30
|
+
component: UDatePickerRange,
|
|
31
|
+
args: {
|
|
32
|
+
modelValue: {
|
|
33
|
+
from: new Date(2022, 1, 14),
|
|
34
|
+
to: new Date(2022, 2, 20),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
argTypes: {
|
|
38
|
+
...getArgTypes(UDatePickerRangeName),
|
|
39
|
+
},
|
|
40
|
+
parameters: {
|
|
41
|
+
docs: {
|
|
42
|
+
story: {
|
|
43
|
+
height: "620px",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
} as Meta;
|
|
48
|
+
|
|
49
|
+
const DefaultTemplate: StoryFn<DefaultUDatePickerRangeArgs> = (
|
|
50
|
+
args: DefaultUDatePickerRangeArgs,
|
|
51
|
+
) => ({
|
|
52
|
+
components: { UDatePickerRange, UIcon, UButton },
|
|
53
|
+
setup() {
|
|
54
|
+
const slots = getSlotNames(UDatePickerRangeName);
|
|
55
|
+
|
|
56
|
+
return { args, slots };
|
|
57
|
+
},
|
|
58
|
+
template: `
|
|
59
|
+
<UDatePickerRange open-direction-y="bottom" v-bind="args" v-model="args.modelValue">
|
|
60
|
+
${args.slotTemplate || getSlotsFragment("")}
|
|
61
|
+
</UDatePickerRange>
|
|
62
|
+
|
|
63
|
+
<div class="mt-4">
|
|
64
|
+
{{ args.modelValue }}
|
|
65
|
+
</div>
|
|
66
|
+
`,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const EnumVariantTemplate: StoryFn<EnumUDatePickerRangeArgs> = (
|
|
70
|
+
args: EnumUDatePickerRangeArgs,
|
|
71
|
+
{ argTypes },
|
|
72
|
+
) => ({
|
|
73
|
+
components: { UDatePickerRange, URow },
|
|
74
|
+
setup() {
|
|
75
|
+
return {
|
|
76
|
+
args,
|
|
77
|
+
options: argTypes[args.enum]?.options,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
template: `
|
|
81
|
+
<URow>
|
|
82
|
+
<UDatePickerRange
|
|
83
|
+
v-for="(option, index) in options"
|
|
84
|
+
:key="index"
|
|
85
|
+
open-direction-y="bottom"
|
|
86
|
+
v-bind="args"
|
|
87
|
+
v-model="args.modelValue"
|
|
88
|
+
:[args.enum]="option"
|
|
89
|
+
/>
|
|
90
|
+
</URow>
|
|
91
|
+
`,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const OpenDirectionTemplate: StoryFn<DefaultUDatePickerRangeArgs> = (
|
|
95
|
+
args: DefaultUDatePickerRangeArgs,
|
|
96
|
+
) => ({
|
|
97
|
+
components: { UDatePickerRange, URow },
|
|
98
|
+
setup() {
|
|
99
|
+
return { args };
|
|
100
|
+
},
|
|
101
|
+
template: `
|
|
102
|
+
<URow class="!flex-col">
|
|
103
|
+
<UDatePickerRange
|
|
104
|
+
class="w-full"
|
|
105
|
+
open-direction-y="top"
|
|
106
|
+
open-direction-x="left"
|
|
107
|
+
v-bind="args"
|
|
108
|
+
v-model="args.modelValue"
|
|
109
|
+
label="Top Left"
|
|
110
|
+
/>
|
|
111
|
+
<UDatePickerRange
|
|
112
|
+
class="w-full"
|
|
113
|
+
open-direction-y="top"
|
|
114
|
+
open-direction-x="right"
|
|
115
|
+
v-bind="args"
|
|
116
|
+
v-model="args.modelValue"
|
|
117
|
+
label="Top Right"
|
|
118
|
+
/>
|
|
119
|
+
<UDatePickerRange
|
|
120
|
+
class="w-full"
|
|
121
|
+
open-direction-y="bottom"
|
|
122
|
+
open-direction-x="left"
|
|
123
|
+
v-bind="args"
|
|
124
|
+
v-model="args.modelValue"
|
|
125
|
+
label="Bottom Left"
|
|
126
|
+
/>
|
|
127
|
+
<UDatePickerRange
|
|
128
|
+
class="w-full"
|
|
129
|
+
open-direction-y="bottom"
|
|
130
|
+
open-direction-x="right"
|
|
131
|
+
v-bind="args"
|
|
132
|
+
v-model="args.modelValue"
|
|
133
|
+
label="Bottom Right"
|
|
134
|
+
/>
|
|
135
|
+
</URow>
|
|
136
|
+
`,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
export const Default = DefaultTemplate.bind({});
|
|
140
|
+
Default.args = {};
|
|
141
|
+
|
|
142
|
+
export const Variants = EnumVariantTemplate.bind({});
|
|
143
|
+
Variants.args = { enum: "variant" };
|
|
144
|
+
|
|
145
|
+
export const OpenDirection = OpenDirectionTemplate.bind({});
|
|
146
|
+
OpenDirection.args = {};
|
|
147
|
+
|
|
148
|
+
export const Disabled = EnumVariantTemplate.bind({});
|
|
149
|
+
Disabled.args = { enum: "variant", disabled: true };
|
|
150
|
+
|
|
151
|
+
export const Label = DefaultTemplate.bind({});
|
|
152
|
+
Label.args = { variant: "input", label: "some label" };
|
|
153
|
+
|
|
154
|
+
export const Description = DefaultTemplate.bind({});
|
|
155
|
+
Description.args = { variant: "input", description: "some description" };
|
|
156
|
+
|
|
157
|
+
export const Error = DefaultTemplate.bind({});
|
|
158
|
+
Error.args = { variant: "input", error: "some error" };
|
|
159
|
+
|
|
160
|
+
export const MinMax = DefaultTemplate.bind({});
|
|
161
|
+
MinMax.args = {
|
|
162
|
+
minDate: new Date(2022, 2, 22),
|
|
163
|
+
maxDate: new Date(2022, 2, 26),
|
|
164
|
+
modelValue: { from: new Date(2022, 2, 24), to: new Date(2022, 2, 25) },
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const DateFormat = DefaultTemplate.bind({});
|
|
168
|
+
DateFormat.args = {
|
|
169
|
+
dateFormat: "d.m.Y",
|
|
170
|
+
userDateFormat: "d.m.Y",
|
|
171
|
+
modelValue: { from: "28.06.2024", to: "30.06.2024" },
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const CustomRangeButton = DefaultTemplate.bind({});
|
|
175
|
+
CustomRangeButton.args = {
|
|
176
|
+
customRangeButton: {
|
|
177
|
+
range: {
|
|
178
|
+
from: new Date(),
|
|
179
|
+
to: addDays(new Date(), 2),
|
|
180
|
+
},
|
|
181
|
+
label: "Next 2 days",
|
|
182
|
+
description: "Some description",
|
|
183
|
+
},
|
|
184
|
+
modelValue: { from: null, to: null },
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export const LeftIcon = DefaultTemplate.bind({});
|
|
188
|
+
LeftIcon.args = { leftIcon: "star", variant: "input" };
|
|
189
|
+
|
|
190
|
+
export const RightIcon = DefaultTemplate.bind({});
|
|
191
|
+
RightIcon.args = { rightIcon: "star", variant: "input" };
|
|
192
|
+
|
|
193
|
+
export const LeftIconSlot = DefaultTemplate.bind({});
|
|
194
|
+
LeftIconSlot.args = {
|
|
195
|
+
variant: "input",
|
|
196
|
+
slotTemplate: `
|
|
197
|
+
<template #left-icon>
|
|
198
|
+
<UIcon
|
|
199
|
+
name="archive"
|
|
200
|
+
color="red"
|
|
201
|
+
/>
|
|
202
|
+
</template>
|
|
203
|
+
`,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const RightIconSlot = DefaultTemplate.bind({});
|
|
207
|
+
RightIconSlot.args = {
|
|
208
|
+
variant: "input",
|
|
209
|
+
slotTemplate: `
|
|
210
|
+
<template #right-icon>
|
|
211
|
+
<UIcon
|
|
212
|
+
name="archive"
|
|
213
|
+
color="red"
|
|
214
|
+
/>
|
|
215
|
+
</template>
|
|
216
|
+
`,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export const LeftSlot = DefaultTemplate.bind({});
|
|
220
|
+
LeftSlot.args = {
|
|
221
|
+
variant: "input",
|
|
222
|
+
slotTemplate: `
|
|
223
|
+
<template #left>
|
|
224
|
+
<UButton variant="thirdary" filled square label="Filter" class="rounded-r-none h-full" />
|
|
225
|
+
</template>
|
|
226
|
+
`,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const RightSlot = DefaultTemplate.bind({});
|
|
230
|
+
RightSlot.args = {
|
|
231
|
+
variant: "input",
|
|
232
|
+
slotTemplate: `
|
|
233
|
+
<template #right>
|
|
234
|
+
<UButton variant="thirdary" filled square label="Filter" class="rounded-l-none" />
|
|
235
|
+
</template>
|
|
236
|
+
`,
|
|
237
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import defaultConfig from "./config.ts";
|
|
2
|
+
import { ShiftAction } from "./constants.ts";
|
|
3
|
+
|
|
4
|
+
import type { UnknownObject } from "../types.ts";
|
|
5
|
+
import type { DatePeriodRange } from "./utilDateRange.ts";
|
|
6
|
+
import type { Ref } from "vue";
|
|
7
|
+
|
|
8
|
+
export type Locale = typeof defaultConfig.i18n;
|
|
9
|
+
export type Config = Partial<typeof defaultConfig>;
|
|
10
|
+
export type IsDatePeriodOutOfRange = (datePeriod: DatePeriodRange) => boolean;
|
|
11
|
+
export type ShiftActions = `${ShiftAction}`;
|
|
12
|
+
|
|
13
|
+
export interface SortedLocale extends Omit<Locale, "weekdays" | "months"> {
|
|
14
|
+
months: {
|
|
15
|
+
shorthand: string[];
|
|
16
|
+
longhand: string[];
|
|
17
|
+
};
|
|
18
|
+
weekdays: {
|
|
19
|
+
shorthand: string[];
|
|
20
|
+
longhand: string[];
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IsPeriod {
|
|
25
|
+
week: boolean;
|
|
26
|
+
month: boolean;
|
|
27
|
+
quarter: boolean;
|
|
28
|
+
year: boolean;
|
|
29
|
+
ownRange: boolean;
|
|
30
|
+
custom: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface UDatePickerRangePeriodMenuAttrs {
|
|
34
|
+
periodRowAttrs: Ref<UnknownObject>;
|
|
35
|
+
periodButtonAttrs: Ref<UnknownObject>;
|
|
36
|
+
periodButtonActiveAttrs: Ref<UnknownObject>;
|
|
37
|
+
periodDateAttrs: Ref<UnknownObject>;
|
|
38
|
+
periodDateCurrentAttrs: Ref<UnknownObject>;
|
|
39
|
+
periodDateSelectedAttrs: Ref<UnknownObject>;
|
|
40
|
+
periodDateCurrentSelectedAttrs: Ref<UnknownObject>;
|
|
41
|
+
periodDateListAttrs: Ref<UnknownObject>;
|
|
42
|
+
rangeSwitchButtonAttrs: Ref<UnknownObject>;
|
|
43
|
+
rangeSwitchTitleAttrs: Ref<UnknownObject>;
|
|
44
|
+
rangeSwitchWrapperAttrs: Ref<UnknownObject>;
|
|
45
|
+
customRangeDescriptionAttrs: Ref<UnknownObject>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface UDatePickerRangePeriodMenuProps {
|
|
49
|
+
locale: SortedLocale;
|
|
50
|
+
dateFormat: string | undefined;
|
|
51
|
+
isPeriod: IsPeriod;
|
|
52
|
+
maxDate: string | Date | undefined;
|
|
53
|
+
minDate: string | Date | undefined;
|
|
54
|
+
customRangeButton: CustomRangeButton;
|
|
55
|
+
config: Config;
|
|
56
|
+
attrs: UDatePickerRangePeriodMenuAttrs;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface UDatePickerRangeInputsAttrs {
|
|
60
|
+
rangeInputFirstAttrs: Ref<UnknownObject>;
|
|
61
|
+
rangeInputLastAttrs: Ref<UnknownObject>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface UDatePickerRangeInputsProps {
|
|
65
|
+
locale: SortedLocale;
|
|
66
|
+
dateFormat: string | undefined;
|
|
67
|
+
rangeInputName: string;
|
|
68
|
+
maxDate: string | Date | undefined;
|
|
69
|
+
minDate: string | Date | undefined;
|
|
70
|
+
config: Config;
|
|
71
|
+
attrs: UDatePickerRangeInputsAttrs;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface CustomRangeButton {
|
|
75
|
+
range: {
|
|
76
|
+
from: Date | null;
|
|
77
|
+
to: Date | null;
|
|
78
|
+
};
|
|
79
|
+
label?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface UDatePickerRangeProps<TModelValue> {
|
|
84
|
+
/**
|
|
85
|
+
* Datepicker range value (JavaScript Date objects or strings formatted in given `dateFormat`).
|
|
86
|
+
*/
|
|
87
|
+
modelValue: TModelValue;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Custom range button.
|
|
91
|
+
*/
|
|
92
|
+
customRangeButton?: CustomRangeButton;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Datepicker open direction on x-axis.
|
|
96
|
+
*/
|
|
97
|
+
openDirectionX?: "auto" | "left" | "right";
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Datepicker open direction on y-axis.
|
|
101
|
+
*/
|
|
102
|
+
openDirectionY?: "auto" | "top" | "bottom";
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The variant of the date picker.
|
|
106
|
+
*/
|
|
107
|
+
variant?: "button" | "input";
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Min date (JavaScript Date object or string formatted in given `dateFormat`).
|
|
111
|
+
*/
|
|
112
|
+
minDate?: string | Date | undefined;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Max date (JavaScript Date object or string formatted in given `dateFormat`).
|
|
116
|
+
*/
|
|
117
|
+
maxDate?: string | Date | undefined;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Date string format.
|
|
121
|
+
*/
|
|
122
|
+
dateFormat?: string | undefined;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Same as date format, but used when timepicker is enabled.
|
|
126
|
+
*/
|
|
127
|
+
dateTimeFormat?: string;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* User-friendly date format (it will be shown in UI).
|
|
131
|
+
*/
|
|
132
|
+
userDateFormat?: string;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Datepicker size.
|
|
136
|
+
*/
|
|
137
|
+
size?: "sm" | "md" | "lg";
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Left icon name.
|
|
141
|
+
*/
|
|
142
|
+
leftIcon?: string;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Right icon name.
|
|
146
|
+
*/
|
|
147
|
+
rightIcon?: string;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Datepicker label.
|
|
151
|
+
*/
|
|
152
|
+
label?: string;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Datepicker label placement.
|
|
156
|
+
*/
|
|
157
|
+
labelAlign?: "top" | "topInside" | "topWithDesc" | "left" | "right";
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Datepicker placeholder.
|
|
161
|
+
*/
|
|
162
|
+
placeholder?: string;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Datepicker description.
|
|
166
|
+
*/
|
|
167
|
+
description?: string;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Datepicker error message.
|
|
171
|
+
*/
|
|
172
|
+
error?: string;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Make datepicker disabled.
|
|
176
|
+
*/
|
|
177
|
+
disabled?: boolean;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Unique element id.
|
|
181
|
+
*/
|
|
182
|
+
id?: string;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Component config object.
|
|
186
|
+
*/
|
|
187
|
+
config?: Config;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Data-test attribute for automated testing.
|
|
191
|
+
*/
|
|
192
|
+
dataTest?: string;
|
|
193
|
+
}
|
|
@@ -6,7 +6,22 @@ import useUI from "../composables/useUI.ts";
|
|
|
6
6
|
import defaultConfig from "./config.js";
|
|
7
7
|
import { POSITION } from "../composables/useAutoPosition.ts";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
import type { Ref } from "vue";
|
|
10
|
+
import type { UseAttrs } from "../types.ts";
|
|
11
|
+
import type { UDatePickerRangeProps, Config, IsPeriod } from "./types.ts";
|
|
12
|
+
import type { Config as UCalendarConfig } from "../ui.form-calendar/types.ts";
|
|
13
|
+
|
|
14
|
+
export interface DatePickerRangeState {
|
|
15
|
+
isShownMenu: Ref<boolean>;
|
|
16
|
+
isTop: Ref<boolean>;
|
|
17
|
+
isRight: Ref<boolean>;
|
|
18
|
+
isPeriod: Ref<IsPeriod>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function useAttrs(
|
|
22
|
+
props: UDatePickerRangeProps<unknown>,
|
|
23
|
+
{ isShownMenu, isTop, isRight, isPeriod }: DatePickerRangeState,
|
|
24
|
+
): UseAttrs<Config> {
|
|
10
25
|
const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI(
|
|
11
26
|
defaultConfig,
|
|
12
27
|
() => props.config,
|
|
@@ -35,6 +50,7 @@ export default function useAttrs(props, { isShownMenu, isTop, isRight, isPeriod
|
|
|
35
50
|
mutatedProps,
|
|
36
51
|
);
|
|
37
52
|
|
|
53
|
+
// TODO: Declare types for getKeysAttrs return value, this could be implemented using generic;
|
|
38
54
|
const keysAttrs = getKeysAttrs(mutatedProps, extendingKeys, {
|
|
39
55
|
buttonWrapper: {
|
|
40
56
|
extend: computed(() => [isShownMenu.value && extendingKeysClasses.buttonWrapperActive.value]),
|
|
@@ -82,16 +98,16 @@ export default function useAttrs(props, { isShownMenu, isTop, isRight, isPeriod
|
|
|
82
98
|
|
|
83
99
|
/* Merging DatePickerRange's i18n translations into Calendar's i18n translations. */
|
|
84
100
|
watchEffect(() => {
|
|
85
|
-
const
|
|
101
|
+
const calendarAttrs = keysAttrs.calendarAttrs as Ref<{ config: UCalendarConfig }>;
|
|
102
|
+
const calendarConfig = calendarAttrs.value.config || {};
|
|
86
103
|
|
|
87
|
-
if (!calendarConfig.i18n || props.config
|
|
88
|
-
|
|
104
|
+
if (!calendarConfig.i18n || props.config?.i18n) {
|
|
105
|
+
calendarAttrs.value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
|
|
89
106
|
}
|
|
90
107
|
});
|
|
91
108
|
|
|
92
109
|
return {
|
|
93
110
|
config,
|
|
94
|
-
keysAttrs,
|
|
95
111
|
...keysAttrs,
|
|
96
112
|
hasSlotContent,
|
|
97
113
|
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { merge } from "lodash-es";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { useLocale as useGlobalLocale } from "../composables/useLocale.ts";
|
|
4
|
+
|
|
5
|
+
import { getSortedLocale } from "../ui.form-calendar/utilDate.ts";
|
|
6
|
+
import { LocaleType } from "../ui.form-calendar/constants.ts";
|
|
7
|
+
import { UDatePickerRange } from "./constants.js";
|
|
8
|
+
|
|
9
|
+
import defaultConfig from "./config.ts";
|
|
10
|
+
|
|
11
|
+
import type { Locale, UDatePickerRangeProps } from "./types.ts";
|
|
12
|
+
|
|
13
|
+
export function useLocale(props: UDatePickerRangeProps<unknown>) {
|
|
14
|
+
const { tm } = useGlobalLocale();
|
|
15
|
+
|
|
16
|
+
const i18nGlobal = tm<Locale>(UDatePickerRange);
|
|
17
|
+
|
|
18
|
+
const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config?.i18n));
|
|
19
|
+
|
|
20
|
+
const locale = computed(() => {
|
|
21
|
+
const { months, weekdays } = currentLocale.value;
|
|
22
|
+
|
|
23
|
+
// formatted locale
|
|
24
|
+
return {
|
|
25
|
+
...currentLocale.value,
|
|
26
|
+
months: {
|
|
27
|
+
shorthand: getSortedLocale(months.shorthand, LocaleType.Month),
|
|
28
|
+
longhand: getSortedLocale(months.longhand, LocaleType.Month),
|
|
29
|
+
},
|
|
30
|
+
weekdays: {
|
|
31
|
+
shorthand: getSortedLocale(weekdays.shorthand, LocaleType.Day),
|
|
32
|
+
longhand: getSortedLocale(weekdays.longhand, LocaleType.Day),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const userFormatLocale = computed(() => {
|
|
38
|
+
const { months, weekdays } = currentLocale.value;
|
|
39
|
+
|
|
40
|
+
const monthsLonghand =
|
|
41
|
+
Boolean(props.config?.i18n?.months?.userFormat) || Boolean(i18nGlobal?.months?.userFormat)
|
|
42
|
+
? months.userFormat
|
|
43
|
+
: months.longhand;
|
|
44
|
+
|
|
45
|
+
const weekdaysLonghand =
|
|
46
|
+
Boolean(props.config?.i18n?.weekdays?.userFormat) || Boolean(i18nGlobal?.weekdays?.userFormat)
|
|
47
|
+
? weekdays.userFormat
|
|
48
|
+
: weekdays.longhand;
|
|
49
|
+
|
|
50
|
+
// formatted locale
|
|
51
|
+
return {
|
|
52
|
+
...currentLocale.value,
|
|
53
|
+
months: {
|
|
54
|
+
shorthand: getSortedLocale(months.shorthand, LocaleType.Month),
|
|
55
|
+
longhand: getSortedLocale(monthsLonghand, LocaleType.Month),
|
|
56
|
+
},
|
|
57
|
+
weekdays: {
|
|
58
|
+
shorthand: getSortedLocale(weekdays.shorthand, LocaleType.Day),
|
|
59
|
+
longhand: getSortedLocale(weekdaysLonghand, LocaleType.Day),
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return { userFormatLocale, locale };
|
|
65
|
+
}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
|
|
3
3
|
import { isSameMonth } from "../ui.form-calendar/utilDate.ts";
|
|
4
|
-
import { formatDate } from "../ui.form-calendar/utilCalendar.ts";
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { formatDate, parseDate } from "../ui.form-calendar/utilCalendar.ts";
|
|
5
|
+
|
|
6
|
+
import type { Ref } from "vue";
|
|
7
|
+
import type { IsPeriod, SortedLocale } from "./types.ts";
|
|
8
|
+
import type { RangeDate } from "../ui.form-calendar/types.ts";
|
|
9
|
+
|
|
10
|
+
export function useUserFormat(
|
|
11
|
+
localValue: Ref<RangeDate>,
|
|
12
|
+
userFormatLocale: Ref<SortedLocale>,
|
|
13
|
+
dateFormat: string,
|
|
14
|
+
isPeriod: Ref<IsPeriod>,
|
|
15
|
+
locale: Ref<SortedLocale | undefined>,
|
|
16
|
+
userDateFormat: string,
|
|
17
|
+
) {
|
|
7
18
|
const userFormatDate = computed(() => {
|
|
8
19
|
if ((!localValue.value.from && !localValue.value.to) || !localValue.value.from) return "";
|
|
9
20
|
|
|
@@ -11,13 +22,16 @@ export function useUserFormat(localValue, userFormatLocale, isPeriod, locale, us
|
|
|
11
22
|
|
|
12
23
|
const isDefaultTitle = isPeriod.value.week || isPeriod.value.custom || isPeriod.value.ownRange;
|
|
13
24
|
|
|
14
|
-
const from = localValue.value.from;
|
|
15
|
-
const to =
|
|
25
|
+
const from = parseDate(localValue.value.from, dateFormat, locale.value);
|
|
26
|
+
const to =
|
|
27
|
+
localValue.value.to !== null
|
|
28
|
+
? parseDate(localValue.value.to, dateFormat, locale.value)
|
|
29
|
+
: null;
|
|
16
30
|
|
|
17
|
-
if (isDefaultTitle) {
|
|
31
|
+
if (isDefaultTitle && from && to) {
|
|
18
32
|
let startMonthName = userFormatLocale.value.months.longhand[from.getMonth()];
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
const endMonthName = userFormatLocale.value.months.longhand[to.getMonth()];
|
|
34
|
+
const endYear = String(to.getFullYear());
|
|
21
35
|
|
|
22
36
|
if (startMonthName === endMonthName && endMonthName === endYear) {
|
|
23
37
|
startMonthName = "";
|