vueless 1.4.7-beta.1 → 1.4.7-beta.3
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/icons/internal/apps.svg +1 -1
- package/icons/internal/calendar_month-fill.svg +1 -1
- package/icons/internal/error.svg +1 -1
- package/icons/internal/info.svg +1 -1
- package/icons/internal/progress_activity.svg +1 -1
- package/icons/internal/search.svg +1 -1
- package/icons/internal/visibility-fill.svg +1 -1
- package/icons/internal/warning.svg +1 -1
- package/icons/storybook/account_circle.svg +1 -1
- package/icons/storybook/cloud_sync.svg +1 -0
- package/icons/storybook/contact_mail.svg +1 -1
- package/icons/storybook/date_range.svg +1 -0
- package/icons/storybook/delivery_truck_speed.svg +1 -1
- package/icons/storybook/directions_bike.svg +1 -1
- package/icons/storybook/error.svg +1 -1
- package/icons/storybook/event.svg +1 -0
- package/icons/storybook/folder.svg +1 -0
- package/icons/storybook/format_quote.svg +1 -0
- package/icons/storybook/handyman.svg +1 -1
- package/icons/storybook/help.svg +1 -1
- package/icons/storybook/inbox.svg +1 -1
- package/icons/storybook/inbox_customize.svg +1 -1
- package/icons/storybook/info.svg +1 -1
- package/icons/storybook/key.svg +1 -1
- package/icons/storybook/local_shipping.svg +1 -0
- package/icons/storybook/location_city.svg +1 -0
- package/icons/storybook/lock.svg +1 -1
- package/icons/storybook/lock_open.svg +1 -1
- package/icons/storybook/mark_email_unread.svg +1 -0
- package/icons/storybook/notifications.svg +1 -0
- package/icons/storybook/palette.svg +1 -1
- package/icons/storybook/person.svg +1 -1
- package/icons/storybook/person_search.svg +1 -1
- package/icons/storybook/progress_activity.svg +1 -1
- package/icons/storybook/rocket_launch.svg +1 -1
- package/icons/storybook/sentiment_satisfied.svg +1 -1
- package/icons/storybook/shield.svg +1 -0
- package/icons/storybook/timer.svg +1 -1
- package/icons/storybook/travel_explore.svg +1 -1
- package/icons/storybook/workspace_premium.svg +1 -0
- package/package.json +32 -31
- package/plugin-vite.js +18 -7
- package/ui.container-accordion-item/tests/UAccordionItem.test.ts +4 -2
- package/ui.container-drawer/tests/UDrawer.test.ts +11 -29
- package/ui.container-modal/tests/UModal.test.ts +10 -22
- package/ui.data-table/UTableRow.vue +2 -2
- package/ui.form-calendar/tests/UCalendar.test.ts +14 -13
- package/ui.form-calendar/tests/UCalendarDayView.test.ts +15 -16
- package/ui.form-checkbox/UCheckbox.vue +0 -5
- package/ui.form-checkbox/storybook/stories.ts +56 -18
- package/ui.form-checkbox/tests/UCheckbox.test.ts +0 -17
- package/ui.form-checkbox-group/storybook/stories.ts +61 -0
- package/ui.form-date-picker/storybook/stories.ts +85 -37
- package/ui.form-date-picker-range/storybook/stories.ts +97 -38
- package/ui.form-input/storybook/stories.ts +75 -37
- package/ui.form-input-file/storybook/stories.ts +44 -5
- package/ui.form-input-number/storybook/stories.ts +66 -28
- package/ui.form-input-password/storybook/stories.ts +94 -50
- package/ui.form-input-search/storybook/stories.ts +40 -4
- package/ui.form-label/ULabel.vue +0 -6
- package/ui.form-label/storybook/stories.ts +46 -24
- package/ui.form-label/tests/ULabel.test.ts +0 -12
- package/ui.form-listbox/UListbox.vue +71 -72
- package/ui.form-listbox/tests/UListbox.test.ts +3 -1
- package/ui.form-radio/URadio.vue +0 -5
- package/ui.form-radio/storybook/stories.ts +65 -25
- package/ui.form-radio/tests/URadio.test.ts +0 -17
- package/ui.form-radio-group/storybook/stories.ts +67 -0
- package/ui.form-select/storybook/stories.ts +99 -44
- package/ui.form-switch/storybook/stories.ts +35 -11
- package/ui.form-textarea/storybook/stories.ts +61 -20
- package/ui.loader/tests/ULoader.test.ts +3 -3
- package/ui.navigation-progress/tests/UProgress.test.ts +2 -3
- package/ui.text-block/tests/UText.test.ts +3 -3
- package/ui.text-files/storybook/stories.ts +30 -13
- package/ui.text-header/tests/UHeader.test.ts +3 -3
- package/ui.text-notify/tests/UNotify.test.ts +14 -18
- package/utils/node/helper.js +8 -9
|
@@ -578,10 +578,10 @@ describe("UModal", () => {
|
|
|
578
578
|
});
|
|
579
579
|
|
|
580
580
|
// CloseOnOverlay events
|
|
581
|
-
it("emits events when overlay is clicked based on closeOnOverlay prop", () => {
|
|
581
|
+
it("emits events when overlay is clicked based on closeOnOverlay prop", async () => {
|
|
582
582
|
const closeOnOverlay = [true, false];
|
|
583
583
|
|
|
584
|
-
|
|
584
|
+
for (const value of closeOnOverlay) {
|
|
585
585
|
const component = mount(UModal, {
|
|
586
586
|
props: {
|
|
587
587
|
modelValue,
|
|
@@ -594,15 +594,9 @@ describe("UModal", () => {
|
|
|
594
594
|
await innerWrapper.trigger("mousedown");
|
|
595
595
|
await innerWrapper.trigger("click");
|
|
596
596
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
expect(component.emitted("close")).toBeTruthy();
|
|
601
|
-
} else {
|
|
602
|
-
expect(component.emitted("update:modelValue")).toBeFalsy();
|
|
603
|
-
expect(component.emitted("close")).toBeFalsy();
|
|
604
|
-
}
|
|
605
|
-
});
|
|
597
|
+
expect(component.emitted("update:modelValue")).toEqual(value ? [[false]] : undefined);
|
|
598
|
+
expect(Boolean(component.emitted("close")?.length)).toBe(value);
|
|
599
|
+
}
|
|
606
600
|
});
|
|
607
601
|
|
|
608
602
|
it("does not close when mousedown on modal and mouseup on overlay", async () => {
|
|
@@ -627,10 +621,10 @@ describe("UModal", () => {
|
|
|
627
621
|
});
|
|
628
622
|
|
|
629
623
|
// CloseOnEsc events
|
|
630
|
-
it("emits events when escape key is pressed based on closeOnEsc prop", () => {
|
|
624
|
+
it("emits events when escape key is pressed based on closeOnEsc prop", async () => {
|
|
631
625
|
const closeOnEsc = [true, false];
|
|
632
626
|
|
|
633
|
-
|
|
627
|
+
for (const value of closeOnEsc) {
|
|
634
628
|
const component = mount(UModal, {
|
|
635
629
|
props: {
|
|
636
630
|
modelValue,
|
|
@@ -642,15 +636,9 @@ describe("UModal", () => {
|
|
|
642
636
|
|
|
643
637
|
await wrapper.trigger("keydown", { key: "Escape" });
|
|
644
638
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
expect(component.emitted("close")).toBeTruthy();
|
|
649
|
-
} else {
|
|
650
|
-
expect(component.emitted("update:modelValue")).toBeFalsy();
|
|
651
|
-
expect(component.emitted("close")).toBeFalsy();
|
|
652
|
-
}
|
|
653
|
-
});
|
|
639
|
+
expect(component.emitted("update:modelValue")).toEqual(value ? [[false]] : undefined);
|
|
640
|
+
expect(Boolean(component.emitted("close")?.length)).toBe(value);
|
|
641
|
+
}
|
|
654
642
|
});
|
|
655
643
|
});
|
|
656
644
|
|
|
@@ -284,8 +284,8 @@ function resolveSlotContent(slot: Slot | undefined, slotParams: Record<string, u
|
|
|
284
284
|
function shouldRenderCellWrapper(row: Row, key: string): boolean {
|
|
285
285
|
return Boolean(
|
|
286
286
|
props.textEllipsis ||
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
(props.search && isCellSearchMatch(key)) ||
|
|
288
|
+
getCellContentClass(row, String(key)),
|
|
289
289
|
);
|
|
290
290
|
}
|
|
291
291
|
|
|
@@ -62,6 +62,15 @@ describe("UCalendar.vue", () => {
|
|
|
62
62
|
it("View – sets the correct view variant", () => {
|
|
63
63
|
const viewCases = [View.Day, View.Month, View.Year];
|
|
64
64
|
|
|
65
|
+
const viewExpectations: Record<
|
|
66
|
+
(typeof viewCases)[number],
|
|
67
|
+
{ day: boolean; month: boolean; year: boolean }
|
|
68
|
+
> = {
|
|
69
|
+
[View.Day]: { day: true, month: false, year: false },
|
|
70
|
+
[View.Month]: { day: false, month: true, year: false },
|
|
71
|
+
[View.Year]: { day: false, month: false, year: true },
|
|
72
|
+
};
|
|
73
|
+
|
|
65
74
|
viewCases.forEach((view) => {
|
|
66
75
|
const component = mount(UCalendar, {
|
|
67
76
|
props: {
|
|
@@ -70,19 +79,11 @@ describe("UCalendar.vue", () => {
|
|
|
70
79
|
},
|
|
71
80
|
});
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
expect(component.findComponent(DayView).exists()).toBe(false);
|
|
79
|
-
expect(component.findComponent(MonthView).exists()).toBe(true);
|
|
80
|
-
expect(component.findComponent(YearView).exists()).toBe(false);
|
|
81
|
-
} else if (view === View.Year) {
|
|
82
|
-
expect(component.findComponent(DayView).exists()).toBe(false);
|
|
83
|
-
expect(component.findComponent(MonthView).exists()).toBe(false);
|
|
84
|
-
expect(component.findComponent(YearView).exists()).toBe(true);
|
|
85
|
-
}
|
|
82
|
+
const expected = viewExpectations[view];
|
|
83
|
+
|
|
84
|
+
expect(component.findComponent(DayView).exists()).toBe(expected.day);
|
|
85
|
+
expect(component.findComponent(MonthView).exists()).toBe(expected.month);
|
|
86
|
+
expect(component.findComponent(YearView).exists()).toBe(expected.year);
|
|
86
87
|
});
|
|
87
88
|
});
|
|
88
89
|
|
|
@@ -332,13 +332,12 @@ describe("UCalendarDayView.vue", () => {
|
|
|
332
332
|
const dayButtons = component.findAll("button");
|
|
333
333
|
const targetDay = dayButtons.find((button) => button.text() === "15");
|
|
334
334
|
|
|
335
|
-
|
|
336
|
-
|
|
335
|
+
expect(targetDay, "day 15 should exist in the grid").toBeTruthy();
|
|
336
|
+
await targetDay!.trigger("mouseover");
|
|
337
337
|
|
|
338
|
-
|
|
338
|
+
const lastRangePreview = component.find('[vl-key="lastDayInRange"]');
|
|
339
339
|
|
|
340
|
-
|
|
341
|
-
}
|
|
340
|
+
expect(lastRangePreview.exists()).toBe(true);
|
|
342
341
|
});
|
|
343
342
|
|
|
344
343
|
it("applies another month range preview classes when hovering over another month day", async () => {
|
|
@@ -354,13 +353,14 @@ describe("UCalendarDayView.vue", () => {
|
|
|
354
353
|
|
|
355
354
|
const anotherMonthDays = component.findAll('[vl-key="anotherMonthDay"]');
|
|
356
355
|
|
|
357
|
-
|
|
358
|
-
|
|
356
|
+
expect(anotherMonthDays.length, "need another-month cells for hover preview").toBeGreaterThan(
|
|
357
|
+
0,
|
|
358
|
+
);
|
|
359
|
+
await anotherMonthDays[0].trigger("mouseover");
|
|
359
360
|
|
|
360
|
-
|
|
361
|
+
const anotherMonthPreview = component.findAll('[vl-key="anotherMonthDayInRange"]');
|
|
361
362
|
|
|
362
|
-
|
|
363
|
-
}
|
|
363
|
+
expect(anotherMonthPreview.length).toBeGreaterThanOrEqual(0);
|
|
364
364
|
});
|
|
365
365
|
|
|
366
366
|
it("clears range preview when mouse leaves day view", async () => {
|
|
@@ -376,14 +376,13 @@ describe("UCalendarDayView.vue", () => {
|
|
|
376
376
|
const dayButtons = component.findAll("button");
|
|
377
377
|
const targetDay = dayButtons.find((button) => button.text() === "15");
|
|
378
378
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
379
|
+
expect(targetDay, "day 15 should exist in the grid").toBeTruthy();
|
|
380
|
+
await targetDay!.trigger("mouseover");
|
|
381
|
+
await component.trigger("mouseleave");
|
|
382
382
|
|
|
383
|
-
|
|
383
|
+
const lastRangePreview = component.find('[vl-key="lastDayInRange"]');
|
|
384
384
|
|
|
385
|
-
|
|
386
|
-
}
|
|
385
|
+
expect(lastRangePreview.exists()).toBe(false);
|
|
387
386
|
});
|
|
388
387
|
});
|
|
389
388
|
|
|
@@ -211,10 +211,5 @@ const {
|
|
|
211
211
|
|
|
212
212
|
<UIcon v-else :name="config.defaults.checkedIcon" color="inherit" v-bind="checkedIconAttrs" />
|
|
213
213
|
</label>
|
|
214
|
-
|
|
215
|
-
<template #bottom>
|
|
216
|
-
<!-- @slot Use it to add something below the checkbox. -->
|
|
217
|
-
<slot name="bottom" />
|
|
218
|
-
</template>
|
|
219
214
|
</ULabel>
|
|
220
215
|
</template>
|
|
@@ -17,6 +17,7 @@ import UChip from "../../ui.other-chip/UChip.vue";
|
|
|
17
17
|
|
|
18
18
|
import type { Meta, StoryFn } from "@storybook/vue3-vite";
|
|
19
19
|
import type { Props } from "../types";
|
|
20
|
+
import { ref } from "vue";
|
|
20
21
|
|
|
21
22
|
interface UCheckboxArgs extends Props {
|
|
22
23
|
slotTemplate?: string;
|
|
@@ -142,23 +143,60 @@ Partial.parameters = {
|
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
export const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
146
|
+
export const Slots: StoryFn<UCheckboxArgs> = (args) => ({
|
|
147
|
+
components: { UCheckbox, UCol, UText, URow, ULink, UIcon },
|
|
148
|
+
setup: () => ({
|
|
149
|
+
args,
|
|
150
|
+
labelSlotValue: ref(false),
|
|
151
|
+
descriptionSlotValue: ref(false),
|
|
152
|
+
errorSlotValue: ref(false),
|
|
153
|
+
}),
|
|
154
|
+
template: `
|
|
155
|
+
<UCol gap="3xl">
|
|
156
|
+
<UCheckbox v-bind="args" v-model="labelSlotValue">
|
|
157
|
+
<template #label>
|
|
158
|
+
<URow gap="2xs" align="center">
|
|
159
|
+
<UText>I agree to the Privacy Policy</UText>
|
|
160
|
+
<UIcon name="contract" size="xs" />
|
|
161
|
+
</URow>
|
|
162
|
+
</template>
|
|
163
|
+
</UCheckbox>
|
|
164
|
+
|
|
165
|
+
<UCheckbox
|
|
166
|
+
v-bind="args"
|
|
167
|
+
v-model="descriptionSlotValue"
|
|
168
|
+
label="Email me product updates"
|
|
169
|
+
>
|
|
170
|
+
<template #description>
|
|
171
|
+
<URow align="center" gap="2xs" class="text-neutral">
|
|
172
|
+
<UIcon name="mail" size="xs" class="mt-0.5" color="primary" />
|
|
173
|
+
<UText size="sm">
|
|
174
|
+
Unsubscribe anytime.
|
|
175
|
+
<ULink label="Privacy policy" underlined size="sm" />.
|
|
176
|
+
</UText>
|
|
177
|
+
</URow>
|
|
178
|
+
</template>
|
|
179
|
+
</UCheckbox>
|
|
156
180
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
181
|
+
<UCheckbox
|
|
182
|
+
v-bind="args"
|
|
183
|
+
v-model="errorSlotValue"
|
|
184
|
+
label="Accept terms"
|
|
185
|
+
:error="true"
|
|
186
|
+
>
|
|
187
|
+
<template #error>
|
|
188
|
+
<URow align="center" gap="2xs">
|
|
189
|
+
<UIcon name="error" size="xs" color="error" />
|
|
190
|
+
<UText size="sm" color="error">
|
|
191
|
+
<ul>
|
|
192
|
+
<li>You must accept the terms to continue</li>
|
|
193
|
+
<li>This checkbox is required for registration</li>
|
|
194
|
+
<li>Clear the error by checking the box above</li>
|
|
195
|
+
</ul>
|
|
196
|
+
</UText>
|
|
197
|
+
</URow>
|
|
198
|
+
</template>
|
|
199
|
+
</UCheckbox>
|
|
200
|
+
</UCol>
|
|
163
201
|
`,
|
|
164
|
-
};
|
|
202
|
+
});
|
|
@@ -319,23 +319,6 @@ describe("UCheckbox.vue", () => {
|
|
|
319
319
|
|
|
320
320
|
expect(errorElement.text()).toBe(customError);
|
|
321
321
|
});
|
|
322
|
-
|
|
323
|
-
it("Bottom – renders custom content from bottom slot", () => {
|
|
324
|
-
const customBottomContent = "Custom Bottom Content";
|
|
325
|
-
|
|
326
|
-
const component = mount(UCheckbox, {
|
|
327
|
-
props: {
|
|
328
|
-
label: "Test Label",
|
|
329
|
-
},
|
|
330
|
-
slots: {
|
|
331
|
-
bottom: customBottomContent,
|
|
332
|
-
},
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
const labelComponent = component.getComponent(ULabel);
|
|
336
|
-
|
|
337
|
-
expect(labelComponent.text()).toContain(customBottomContent);
|
|
338
|
-
});
|
|
339
322
|
});
|
|
340
323
|
|
|
341
324
|
describe("Events", () => {
|
|
@@ -189,3 +189,64 @@ CustomKeys.parameters = {
|
|
|
189
189
|
},
|
|
190
190
|
},
|
|
191
191
|
};
|
|
192
|
+
|
|
193
|
+
export const Slots: StoryFn<UCheckboxGroupArgs> = (args) => ({
|
|
194
|
+
components: { UCheckboxGroup, UCol, UText, URow, ULink, UIcon },
|
|
195
|
+
setup: () => ({
|
|
196
|
+
args,
|
|
197
|
+
modelValueLabel: ref(""),
|
|
198
|
+
modelValueDescription: ref(""),
|
|
199
|
+
modelValueError: ref(""),
|
|
200
|
+
}),
|
|
201
|
+
template: `
|
|
202
|
+
<UCol gap="3xl">
|
|
203
|
+
<UCheckboxGroup
|
|
204
|
+
v-bind="args"
|
|
205
|
+
v-model="modelValueLabel"
|
|
206
|
+
name="LabelSlot"
|
|
207
|
+
>
|
|
208
|
+
<template #label>
|
|
209
|
+
<URow align="center" gap="2xs">
|
|
210
|
+
<UText>Choose how we notify you</UText>
|
|
211
|
+
<UIcon name="notifications" size="xs" color="neutral" />
|
|
212
|
+
</URow>
|
|
213
|
+
</template>
|
|
214
|
+
</UCheckboxGroup>
|
|
215
|
+
|
|
216
|
+
<UCheckboxGroup
|
|
217
|
+
v-bind="args"
|
|
218
|
+
v-model="modelValueDescription"
|
|
219
|
+
name="SlotsDescription"
|
|
220
|
+
label="Notification channels"
|
|
221
|
+
>
|
|
222
|
+
<template #description>
|
|
223
|
+
<URow align="center" gap="2xs" class="text-neutral">
|
|
224
|
+
<UIcon name="notifications" size="xs" color="primary" />
|
|
225
|
+
<UText size="sm">
|
|
226
|
+
You can change this later.
|
|
227
|
+
<ULink label="Notification settings" underlined size="sm" />.
|
|
228
|
+
</UText>
|
|
229
|
+
</URow>
|
|
230
|
+
</template>
|
|
231
|
+
</UCheckboxGroup>
|
|
232
|
+
|
|
233
|
+
<UCheckboxGroup
|
|
234
|
+
v-bind="args"
|
|
235
|
+
v-model="modelValueError"
|
|
236
|
+
name="SlotsError"
|
|
237
|
+
label="Select options"
|
|
238
|
+
:error="true"
|
|
239
|
+
>
|
|
240
|
+
<template #error>
|
|
241
|
+
<UText size="sm" color="error">
|
|
242
|
+
<ul>
|
|
243
|
+
<li>Invalid selection</li>
|
|
244
|
+
<li>At least one channel is required</li>
|
|
245
|
+
<li>Choose at least one option before submitting</li>
|
|
246
|
+
</ul>
|
|
247
|
+
</UText>
|
|
248
|
+
</template>
|
|
249
|
+
</UCheckboxGroup>
|
|
250
|
+
</UCol>
|
|
251
|
+
`,
|
|
252
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryFn } from "@storybook/vue3-vite";
|
|
2
|
+
import { ref } from "vue";
|
|
2
3
|
import {
|
|
3
4
|
getArgs,
|
|
4
5
|
getArgTypes,
|
|
@@ -13,6 +14,7 @@ import URow from "../../ui.container-row/URow.vue";
|
|
|
13
14
|
import UCol from "../../ui.container-col/UCol.vue";
|
|
14
15
|
import UButton from "../../ui.button/UButton.vue";
|
|
15
16
|
import UText from "../../ui.text-block/UText.vue";
|
|
17
|
+
import ULink from "../../ui.button-link/ULink.vue";
|
|
16
18
|
|
|
17
19
|
import { COMPONENT_NAME } from "../constants";
|
|
18
20
|
|
|
@@ -364,43 +366,89 @@ export const IconProps: StoryFn<DefaultUDatePickerArgs> = (args) => ({
|
|
|
364
366
|
});
|
|
365
367
|
|
|
366
368
|
export const Slots: StoryFn<DefaultUDatePickerArgs> = (args) => ({
|
|
367
|
-
components: { UDatePicker, URow, UButton },
|
|
368
|
-
setup: () => ({
|
|
369
|
+
components: { UDatePicker, URow, UCol, UButton, UText, ULink, UIcon },
|
|
370
|
+
setup: () => ({
|
|
371
|
+
args,
|
|
372
|
+
descriptionSlotValue: ref(dateValue),
|
|
373
|
+
errorSlotValue: ref<Date | null>(null),
|
|
374
|
+
}),
|
|
369
375
|
template: `
|
|
370
|
-
<
|
|
371
|
-
<
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
<
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
<
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
376
|
+
<UCol gap="3xl">
|
|
377
|
+
<URow block>
|
|
378
|
+
<UDatePicker
|
|
379
|
+
v-bind="args"
|
|
380
|
+
v-model="args.leftModel"
|
|
381
|
+
class="w-full"
|
|
382
|
+
:config="{ datepickerInput: { wrapper: 'pl-0' } }"
|
|
383
|
+
>
|
|
384
|
+
<template #left>
|
|
385
|
+
<UButton
|
|
386
|
+
label="Today"
|
|
387
|
+
size="sm"
|
|
388
|
+
variant="soft"
|
|
389
|
+
class="h-full rounded-r-none"
|
|
390
|
+
@click="args.leftModel = new Date()"
|
|
391
|
+
/>
|
|
392
|
+
</template>
|
|
393
|
+
</UDatePicker>
|
|
394
|
+
|
|
395
|
+
<UDatePicker
|
|
396
|
+
v-bind="args"
|
|
397
|
+
v-model="args.modelValue"
|
|
398
|
+
class="w-full"
|
|
399
|
+
:config="{ datepickerInput: { wrapper: 'pr-0' } }"
|
|
400
|
+
>
|
|
401
|
+
<template #right>
|
|
402
|
+
<UButton
|
|
403
|
+
label="Clear"
|
|
404
|
+
size="sm"
|
|
405
|
+
variant="ghost"
|
|
406
|
+
class="h-full rounded-l-none"
|
|
407
|
+
@click="args.modelValue = null"
|
|
408
|
+
/>
|
|
409
|
+
</template>
|
|
410
|
+
</UDatePicker>
|
|
411
|
+
</URow>
|
|
412
|
+
|
|
413
|
+
<URow block>
|
|
414
|
+
<UDatePicker
|
|
415
|
+
v-bind="args"
|
|
416
|
+
v-model="descriptionSlotValue"
|
|
417
|
+
label="Event date"
|
|
418
|
+
class="w-full"
|
|
419
|
+
>
|
|
420
|
+
<template #description>
|
|
421
|
+
<URow align="center" gap="2xs" class="text-neutral">
|
|
422
|
+
<UIcon name="event" size="xs" color="primary" />
|
|
423
|
+
<UText size="sm">
|
|
424
|
+
Uses your local timezone.
|
|
425
|
+
<ULink label="Date policy" underlined size="sm" />.
|
|
426
|
+
</UText>
|
|
427
|
+
</URow>
|
|
428
|
+
</template>
|
|
429
|
+
</UDatePicker>
|
|
430
|
+
|
|
431
|
+
<UDatePicker
|
|
432
|
+
v-bind="args"
|
|
433
|
+
v-model="errorSlotValue"
|
|
434
|
+
label="Due date"
|
|
435
|
+
:error="true"
|
|
436
|
+
class="w-full"
|
|
437
|
+
>
|
|
438
|
+
<template #error>
|
|
439
|
+
<URow align="center" gap="2xs">
|
|
440
|
+
<UIcon name="error" size="xs" color="error" />
|
|
441
|
+
<UText size="sm" color="error">
|
|
442
|
+
<ul>
|
|
443
|
+
<li>The selected date is not available</li>
|
|
444
|
+
<li>Pick a day within the allowed range</li>
|
|
445
|
+
<li>Weekends and holidays are excluded</li>
|
|
446
|
+
</ul>
|
|
447
|
+
</UText>
|
|
448
|
+
</URow>
|
|
449
|
+
</template>
|
|
450
|
+
</UDatePicker>
|
|
451
|
+
</URow>
|
|
452
|
+
</UCol>
|
|
405
453
|
`,
|
|
406
454
|
});
|
|
@@ -15,6 +15,7 @@ import UCol from "../../ui.container-col/UCol.vue";
|
|
|
15
15
|
import UIcon from "../../ui.image-icon/UIcon.vue";
|
|
16
16
|
import UButton from "../../ui.button/UButton.vue";
|
|
17
17
|
import UText from "../../ui.text-block/UText.vue";
|
|
18
|
+
import ULink from "../../ui.button-link/ULink.vue";
|
|
18
19
|
|
|
19
20
|
import { addDays } from "../../ui.form-calendar/utilDate";
|
|
20
21
|
|
|
@@ -296,44 +297,102 @@ export const IconProps: StoryFn<DefaultUDatePickerRangeArgs> = (args) => ({
|
|
|
296
297
|
});
|
|
297
298
|
|
|
298
299
|
export const Slots: StoryFn<DefaultUDatePickerRangeArgs> = (args) => ({
|
|
299
|
-
components: { UDatePickerRange, URow, UButton },
|
|
300
|
-
setup: () => ({
|
|
300
|
+
components: { UDatePickerRange, URow, UCol, UButton, UText, ULink, UIcon },
|
|
301
|
+
setup: () => ({
|
|
302
|
+
args,
|
|
303
|
+
fromDate,
|
|
304
|
+
toDate,
|
|
305
|
+
leftModel: ref({ from: null, to: null }),
|
|
306
|
+
descriptionSlotValue: ref({ from: fromDate, to: toDate }),
|
|
307
|
+
errorSlotValue: ref({ from: null, to: null }),
|
|
308
|
+
}),
|
|
301
309
|
template: `
|
|
302
|
-
<
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
<
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
310
|
+
<UCol gap="3xl">
|
|
311
|
+
<URow block>
|
|
312
|
+
<UDatePickerRange
|
|
313
|
+
label="Select date range"
|
|
314
|
+
v-model="leftModel"
|
|
315
|
+
variant="input"
|
|
316
|
+
class="w-full"
|
|
317
|
+
:config="{ datepickerInput: { wrapper: 'pl-0' } }"
|
|
318
|
+
>
|
|
319
|
+
<template #left>
|
|
320
|
+
<UButton
|
|
321
|
+
label="2 weeks"
|
|
322
|
+
size="sm"
|
|
323
|
+
variant="soft"
|
|
324
|
+
class="h-full rounded-r-none"
|
|
325
|
+
@click="leftModel = { from: fromDate, to: toDate }"
|
|
326
|
+
/>
|
|
327
|
+
</template>
|
|
328
|
+
</UDatePickerRange>
|
|
329
|
+
<UDatePickerRange
|
|
330
|
+
label="Select date range"
|
|
331
|
+
v-model="args.modelValue"
|
|
332
|
+
variant="input"
|
|
333
|
+
class="w-full"
|
|
334
|
+
:config="{ datepickerInput: { wrapper: 'pr-0' } }"
|
|
335
|
+
>
|
|
336
|
+
<template #right>
|
|
337
|
+
<UButton
|
|
338
|
+
label="Clear"
|
|
339
|
+
size="sm"
|
|
340
|
+
variant="ghost"
|
|
341
|
+
class="h-full rounded-l-none"
|
|
342
|
+
@click="args.modelValue = { from: null, to: null }"
|
|
343
|
+
/>
|
|
344
|
+
</template>
|
|
345
|
+
</UDatePickerRange>
|
|
346
|
+
</URow>
|
|
347
|
+
|
|
348
|
+
<URow block>
|
|
349
|
+
<UDatePickerRange
|
|
350
|
+
v-bind="args"
|
|
351
|
+
v-model="descriptionSlotValue"
|
|
352
|
+
variant="input"
|
|
353
|
+
label="Report period"
|
|
354
|
+
class="w-full"
|
|
355
|
+
>
|
|
356
|
+
<template #description>
|
|
357
|
+
<URow align="center" gap="2xs" class="text-neutral">
|
|
358
|
+
<UIcon name="date_range" size="xs" color="primary" />
|
|
359
|
+
<UText size="sm">
|
|
360
|
+
Inclusive of start and end.
|
|
361
|
+
<ULink label="Fiscal calendar" underlined size="sm" />.
|
|
362
|
+
</UText>
|
|
363
|
+
</URow>
|
|
364
|
+
</template>
|
|
365
|
+
</UDatePickerRange>
|
|
366
|
+
|
|
367
|
+
<UDatePickerRange
|
|
368
|
+
v-bind="args"
|
|
369
|
+
v-model="errorSlotValue"
|
|
370
|
+
variant="input"
|
|
371
|
+
label="Stay dates"
|
|
372
|
+
:error="true"
|
|
373
|
+
class="w-full"
|
|
374
|
+
>
|
|
375
|
+
<template #error>
|
|
376
|
+
<URow align="center" gap="2xs">
|
|
377
|
+
<UIcon name="error" size="xs" color="error" />
|
|
378
|
+
<UText size="sm" color="error">
|
|
379
|
+
<ul>
|
|
380
|
+
<li>End date must be after the start date</li>
|
|
381
|
+
<li>Range cannot span more than 30 days</li>
|
|
382
|
+
<li>Select both dates from the calendar</li>
|
|
383
|
+
</ul>
|
|
384
|
+
</UText>
|
|
385
|
+
</URow>
|
|
386
|
+
</template>
|
|
387
|
+
</UDatePickerRange>
|
|
388
|
+
</URow>
|
|
389
|
+
</UCol>
|
|
338
390
|
`,
|
|
339
391
|
});
|
|
392
|
+
Slots.parameters = {
|
|
393
|
+
docs: {
|
|
394
|
+
story: {
|
|
395
|
+
height: "700px",
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
};
|