@weni/unnnic-system 3.12.7-alpha-teleports.0 → 3.12.8-alpha-teleports.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{es-95214495.mjs → es-2f6793d2.mjs} +1 -1
- package/dist/{index-edacc4d7.mjs → index-799af668.mjs} +3278 -3258
- package/dist/index.d.ts +27 -18
- package/dist/{pt-br-fb80e803.mjs → pt-br-f5121b47.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +1 -1
- package/dist/unnnic.umd.js +30 -30
- package/package.json +1 -1
- package/src/components/DatePicker/DatePicker.vue +11 -1
- package/src/components/InputDatePicker/InputDatePicker.vue +68 -73
- package/src/components/InputDatePicker/__test__/InputDatePicker.spec.js +31 -24
- package/src/components/ModalDialog/ModalDialog.vue +3 -3
- package/src/components/ModalDialog/__tests__/ModalDialog.spec.js +31 -1
- package/src/components/ui/popover/PopoverContent.vue +27 -9
- package/src/components/ui/popover/PopoverOption.vue +1 -1
- package/src/stories/ModalDialog.stories.js +95 -0
- package/src/stories/Popover.stories.js +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="unnnic-date-picker"
|
|
3
|
+
:class="['unnnic-date-picker', `unnnic-date-picker--${props.variant}`]"
|
|
4
4
|
data-testid="date-picker-root"
|
|
5
5
|
>
|
|
6
6
|
<template v-if="type === 'day'">
|
|
@@ -296,6 +296,8 @@ export interface DatePickerProps {
|
|
|
296
296
|
|
|
297
297
|
locale?: string;
|
|
298
298
|
translations?: Record<string, unknown>;
|
|
299
|
+
|
|
300
|
+
variant?: 'card' | 'popover';
|
|
299
301
|
}
|
|
300
302
|
|
|
301
303
|
const props = withDefaults(defineProps<DatePickerProps>(), {
|
|
@@ -315,6 +317,7 @@ const props = withDefaults(defineProps<DatePickerProps>(), {
|
|
|
315
317
|
disableClear: false,
|
|
316
318
|
locale: undefined,
|
|
317
319
|
translations: undefined,
|
|
320
|
+
variant: 'card',
|
|
318
321
|
});
|
|
319
322
|
|
|
320
323
|
const emit = defineEmits<{
|
|
@@ -963,6 +966,13 @@ onMounted(() => {
|
|
|
963
966
|
box-shadow: $unnnic-shadow-level-separated;
|
|
964
967
|
overflow: hidden;
|
|
965
968
|
|
|
969
|
+
&--popover {
|
|
970
|
+
background-color: transparent;
|
|
971
|
+
border-radius: 0;
|
|
972
|
+
box-shadow: none;
|
|
973
|
+
overflow: visible;
|
|
974
|
+
}
|
|
975
|
+
|
|
966
976
|
.month-container {
|
|
967
977
|
display: flex;
|
|
968
978
|
flex-direction: column;
|
|
@@ -1,51 +1,61 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
2
|
+
<div :class="['dropdown', { 'fill-w': fillW }]">
|
|
3
|
+
<UnnnicPopover v-model:open="isPopoverOpen">
|
|
4
|
+
<UnnnicPopoverTrigger :asChild="true">
|
|
5
|
+
<UnnnicInput
|
|
6
|
+
data-testid="input"
|
|
7
|
+
:class="['input', { 'date-picker-input-next': next }]"
|
|
8
|
+
:size="size"
|
|
9
|
+
:iconLeft="iconPosition === 'left' ? 'calendar_month' : undefined"
|
|
10
|
+
:iconRight="iconPosition === 'right' ? 'calendar_month' : undefined"
|
|
11
|
+
readonly
|
|
12
|
+
:modelValue="overwrittenValue || filterText || ''"
|
|
13
|
+
@click="openPopover"
|
|
14
|
+
@focus="openPopover"
|
|
15
|
+
/>
|
|
16
|
+
</UnnnicPopoverTrigger>
|
|
17
|
+
|
|
18
|
+
<UnnnicPopoverContent
|
|
19
|
+
width="auto"
|
|
20
|
+
side="bottom"
|
|
21
|
+
:align="popoverAlign"
|
|
22
|
+
class="date-picker-popover-content"
|
|
23
|
+
>
|
|
24
|
+
<UnnnicDatePicker
|
|
25
|
+
v-model:equivalentOption="overwrittenValue"
|
|
26
|
+
data-testid="date-picker"
|
|
27
|
+
variant="popover"
|
|
28
|
+
:type="type"
|
|
29
|
+
:clearLabel="clearText"
|
|
30
|
+
:actionLabel="actionText"
|
|
31
|
+
:months="months"
|
|
32
|
+
:days="days"
|
|
33
|
+
:options="options"
|
|
34
|
+
:periodBaseDate="periodBaseDate"
|
|
35
|
+
:initialStartDate="initialStartDate"
|
|
36
|
+
:initialEndDate="initialEndDate"
|
|
37
|
+
:minDate="minDate"
|
|
38
|
+
:maxDate="maxDate"
|
|
39
|
+
:disableClear="disableClear"
|
|
40
|
+
@change="emitSelectDate"
|
|
41
|
+
@submit="changeDate"
|
|
42
|
+
/>
|
|
43
|
+
</UnnnicPopoverContent>
|
|
44
|
+
</UnnnicPopover>
|
|
40
45
|
</div>
|
|
41
46
|
</template>
|
|
42
47
|
|
|
43
48
|
<script setup lang="ts">
|
|
44
|
-
import { computed,
|
|
49
|
+
import { computed, ref } from 'vue';
|
|
45
50
|
import moment from 'moment';
|
|
46
51
|
|
|
47
52
|
import UnnnicInput from '../Input/Input.vue';
|
|
48
53
|
import UnnnicDatePicker from '../DatePicker/DatePicker.vue';
|
|
54
|
+
import {
|
|
55
|
+
Popover as UnnnicPopover,
|
|
56
|
+
PopoverContent as UnnnicPopoverContent,
|
|
57
|
+
PopoverTrigger as UnnnicPopoverTrigger,
|
|
58
|
+
} from '../ui/popover';
|
|
49
59
|
|
|
50
60
|
defineOptions({
|
|
51
61
|
name: 'UnnnicInputDatePicker',
|
|
@@ -112,9 +122,11 @@ const emit = defineEmits<{
|
|
|
112
122
|
(e: 'selectDate', value: DateRangeValue): void;
|
|
113
123
|
}>();
|
|
114
124
|
|
|
115
|
-
const
|
|
116
|
-
const showCalendarFilter = ref(false);
|
|
125
|
+
const isPopoverOpen = ref(false);
|
|
117
126
|
const overwrittenValue = ref('');
|
|
127
|
+
const popoverAlign = computed<'start' | 'end'>(() =>
|
|
128
|
+
props.position === 'right' ? 'end' : 'start',
|
|
129
|
+
);
|
|
118
130
|
|
|
119
131
|
const filterText = computed(() => {
|
|
120
132
|
const dates: string[] = [];
|
|
@@ -160,20 +172,12 @@ function emitSelectDate(date: { startDate: string; endDate: string }) {
|
|
|
160
172
|
emit('selectDate', formattedDates);
|
|
161
173
|
}
|
|
162
174
|
|
|
163
|
-
function mouseout(event: MouseEvent | { target: EventTarget | null }) {
|
|
164
|
-
if (dropdown.value?.contains(event.target as Node)) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
showCalendarFilter.value = false;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
175
|
function changeDate(value: { startDate: string; endDate: string }) {
|
|
172
176
|
const startDate = value.startDate.replace(/(\d+)-(\d+)-(\d+)/, '$3-$1-$2');
|
|
173
177
|
|
|
174
178
|
const endDate = value.endDate.replace(/(\d+)-(\d+)-(\d+)/, '$3-$1-$2');
|
|
175
179
|
|
|
176
|
-
|
|
180
|
+
isPopoverOpen.value = false;
|
|
177
181
|
|
|
178
182
|
emit('update:model-value', {
|
|
179
183
|
start: startDate
|
|
@@ -183,39 +187,30 @@ function changeDate(value: { startDate: string; endDate: string }) {
|
|
|
183
187
|
});
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
onBeforeUnmount(() => {
|
|
191
|
-
window.document.body.removeEventListener('click', mouseout as any);
|
|
192
|
-
});
|
|
190
|
+
function openPopover() {
|
|
191
|
+
isPopoverOpen.value = true;
|
|
192
|
+
}
|
|
193
193
|
</script>
|
|
194
194
|
|
|
195
|
+
<style lang="scss">
|
|
196
|
+
@use '@/assets/scss/unnnic' as *;
|
|
197
|
+
|
|
198
|
+
.date-picker-popover-content {
|
|
199
|
+
overflow: hidden;
|
|
200
|
+
border-radius: $unnnic-radius-2;
|
|
201
|
+
padding: 0;
|
|
202
|
+
}
|
|
203
|
+
</style>
|
|
204
|
+
|
|
195
205
|
<style lang="scss" scoped>
|
|
196
206
|
@use '@/assets/scss/unnnic' as *;
|
|
197
207
|
.fill-w {
|
|
198
208
|
width: 100%;
|
|
199
209
|
}
|
|
210
|
+
|
|
200
211
|
.dropdown {
|
|
201
|
-
position: relative;
|
|
202
212
|
display: inline-block;
|
|
203
213
|
|
|
204
|
-
.dropdown-data {
|
|
205
|
-
position: absolute;
|
|
206
|
-
pointer-events: none;
|
|
207
|
-
display: none;
|
|
208
|
-
top: 100%;
|
|
209
|
-
z-index: 2;
|
|
210
|
-
margin-top: $unnnic-spacing-stack-nano;
|
|
211
|
-
width: max-content;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
&.active .dropdown-data {
|
|
215
|
-
pointer-events: auto;
|
|
216
|
-
display: block;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
214
|
.input {
|
|
220
215
|
display: inline-block;
|
|
221
216
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
|
-
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
3
4
|
import InputDatePicker from '../InputDatePicker.vue';
|
|
4
5
|
|
|
5
6
|
const factory = (props = {}) =>
|
|
@@ -11,20 +12,7 @@ const factory = (props = {}) =>
|
|
|
11
12
|
},
|
|
12
13
|
...props,
|
|
13
14
|
},
|
|
14
|
-
|
|
15
|
-
stubs: {
|
|
16
|
-
UnnnicInput: {
|
|
17
|
-
name: 'UnnnicInput',
|
|
18
|
-
template:
|
|
19
|
-
'<input data-testid="input" v-bind="$attrs" @focus="$emit(\'focus\', $event)" />',
|
|
20
|
-
},
|
|
21
|
-
UnnnicDatePicker: {
|
|
22
|
-
name: 'UnnnicDatePicker',
|
|
23
|
-
props: ['minDate', 'maxDate', 'periodBaseDate', 'options'],
|
|
24
|
-
template: '<div data-testid="datepicker"></div>',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
15
|
+
attachTo: document.body,
|
|
28
16
|
});
|
|
29
17
|
|
|
30
18
|
describe('InputDatePicker.vue', () => {
|
|
@@ -34,6 +22,12 @@ describe('InputDatePicker.vue', () => {
|
|
|
34
22
|
wrapper = factory();
|
|
35
23
|
});
|
|
36
24
|
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
if (wrapper) {
|
|
27
|
+
wrapper.unmount();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
37
31
|
it('renders input and does not show datepicker by default', () => {
|
|
38
32
|
expect(wrapper.find('[data-testid="input"]').exists()).toBe(true);
|
|
39
33
|
expect(wrapper.find('[data-testid="datepicker"]').exists()).toBe(false);
|
|
@@ -42,13 +36,23 @@ describe('InputDatePicker.vue', () => {
|
|
|
42
36
|
it('opens datepicker when input receives focus', async () => {
|
|
43
37
|
const input = wrapper.find('[data-testid="input"]');
|
|
44
38
|
await input.trigger('focus');
|
|
39
|
+
await wrapper.vm.$nextTick();
|
|
45
40
|
|
|
46
|
-
wrapper.
|
|
41
|
+
expect(wrapper.findComponent({ name: 'UnnnicDatePicker' }).exists()).toBe(
|
|
42
|
+
true,
|
|
43
|
+
);
|
|
44
|
+
expect(wrapper.vm.isPopoverOpen).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('opens datepicker when input receives click', async () => {
|
|
48
|
+
const input = wrapper.find('[data-testid="input"]');
|
|
49
|
+
await input.trigger('click');
|
|
47
50
|
await wrapper.vm.$nextTick();
|
|
48
51
|
|
|
49
52
|
expect(wrapper.findComponent({ name: 'UnnnicDatePicker' }).exists()).toBe(
|
|
50
53
|
true,
|
|
51
54
|
);
|
|
55
|
+
expect(wrapper.vm.isPopoverOpen).toBe(true);
|
|
52
56
|
});
|
|
53
57
|
|
|
54
58
|
it('computes filterText placeholder when there is no date selected', () => {
|
|
@@ -66,6 +70,7 @@ describe('InputDatePicker.vue', () => {
|
|
|
66
70
|
});
|
|
67
71
|
|
|
68
72
|
expect(withDates.vm.filterText).toBe('01-10-2025 ~ 01-20-2025');
|
|
73
|
+
withDates.unmount();
|
|
69
74
|
});
|
|
70
75
|
|
|
71
76
|
it('computes initialStartDate and initialEndDate for DatePicker', () => {
|
|
@@ -78,10 +83,11 @@ describe('InputDatePicker.vue', () => {
|
|
|
78
83
|
|
|
79
84
|
expect(withDates.vm.initialStartDate).toBe('01 10 2025');
|
|
80
85
|
expect(withDates.vm.initialEndDate).toBe('01 20 2025');
|
|
86
|
+
withDates.unmount();
|
|
81
87
|
});
|
|
82
88
|
|
|
83
89
|
it('emits selectDate with formatted dates when DatePicker emits change', async () => {
|
|
84
|
-
wrapper.vm.
|
|
90
|
+
wrapper.vm.isPopoverOpen = true;
|
|
85
91
|
await wrapper.vm.$nextTick();
|
|
86
92
|
|
|
87
93
|
const datePicker = wrapper.findComponent({ name: 'UnnnicDatePicker' });
|
|
@@ -104,7 +110,7 @@ describe('InputDatePicker.vue', () => {
|
|
|
104
110
|
});
|
|
105
111
|
|
|
106
112
|
it('emits update:model-value and closes dropdown when DatePicker emits submit', async () => {
|
|
107
|
-
wrapper.vm.
|
|
113
|
+
wrapper.vm.isPopoverOpen = true;
|
|
108
114
|
await wrapper.vm.$nextTick();
|
|
109
115
|
|
|
110
116
|
const datePicker = wrapper.findComponent({ name: 'UnnnicDatePicker' });
|
|
@@ -125,7 +131,7 @@ describe('InputDatePicker.vue', () => {
|
|
|
125
131
|
end: '2025-01-20',
|
|
126
132
|
});
|
|
127
133
|
|
|
128
|
-
expect(wrapper.vm.
|
|
134
|
+
expect(wrapper.vm.isPopoverOpen).toBe(false);
|
|
129
135
|
});
|
|
130
136
|
|
|
131
137
|
it('passes minDate, maxDate, options and periodBaseDate down to DatePicker', async () => {
|
|
@@ -137,7 +143,7 @@ describe('InputDatePicker.vue', () => {
|
|
|
137
143
|
};
|
|
138
144
|
|
|
139
145
|
wrapper = factory(props);
|
|
140
|
-
wrapper.vm.
|
|
146
|
+
wrapper.vm.isPopoverOpen = true;
|
|
141
147
|
await wrapper.vm.$nextTick();
|
|
142
148
|
|
|
143
149
|
const datePicker = wrapper.findComponent({ name: 'UnnnicDatePicker' });
|
|
@@ -147,13 +153,14 @@ describe('InputDatePicker.vue', () => {
|
|
|
147
153
|
expect(dpProps.maxDate).toBe(props.maxDate);
|
|
148
154
|
expect(dpProps.periodBaseDate).toBe(props.periodBaseDate);
|
|
149
155
|
expect(dpProps.options).toEqual(props.options);
|
|
156
|
+
expect(dpProps.variant).toBe('popover');
|
|
150
157
|
});
|
|
151
158
|
|
|
152
|
-
it('
|
|
153
|
-
|
|
159
|
+
it('aligns the popover to the end when position is right', () => {
|
|
160
|
+
const rightWrapper = factory({ position: 'right' });
|
|
154
161
|
|
|
155
|
-
|
|
162
|
+
expect(rightWrapper.vm.popoverAlign).toBe('end');
|
|
156
163
|
|
|
157
|
-
|
|
164
|
+
rightWrapper.unmount();
|
|
158
165
|
});
|
|
159
166
|
});
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
class="unnnic-modal-dialog__container__actions__primary-button"
|
|
78
78
|
@click.stop="$emit('primaryButtonClick')"
|
|
79
79
|
/>
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
</UnnnicDialogFooter>
|
|
81
|
+
</section>
|
|
82
82
|
</UnnnicDialogContent>
|
|
83
83
|
</UnnnicDialog>
|
|
84
84
|
</template>
|
|
@@ -102,8 +102,8 @@ export default {
|
|
|
102
102
|
UnnnicDialogTitle,
|
|
103
103
|
UnnnicDialogFooter,
|
|
104
104
|
},
|
|
105
|
-
inheritAttrs: false,
|
|
106
105
|
mixins: [UnnnicI18n],
|
|
106
|
+
inheritAttrs: false,
|
|
107
107
|
props: {
|
|
108
108
|
modelValue: {
|
|
109
109
|
type: Boolean,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
|
-
import { describe, it } from 'vitest';
|
|
2
|
+
import { beforeEach, describe, it, expect, vi } from 'vitest';
|
|
3
3
|
import ModalDialog from '../ModalDialog.vue';
|
|
4
4
|
|
|
5
5
|
describe('ModalDialog.vue', () => {
|
|
@@ -43,4 +43,34 @@ describe('ModalDialog.vue', () => {
|
|
|
43
43
|
expect(modalContainer.attributes('size')).toContain('small');
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
|
+
|
|
47
|
+
describe('persistentHandler', () => {
|
|
48
|
+
it('prevents default when persistent is true', () => {
|
|
49
|
+
wrapper = mount(ModalDialog, {
|
|
50
|
+
props: {
|
|
51
|
+
title: 'Test Title',
|
|
52
|
+
modelValue: true,
|
|
53
|
+
persistent: true,
|
|
54
|
+
primaryButtonProps: { text: 'Confirm' },
|
|
55
|
+
},
|
|
56
|
+
global: {
|
|
57
|
+
stubs: [
|
|
58
|
+
'teleport',
|
|
59
|
+
'UnnnicIcon',
|
|
60
|
+
'UnnnicButton',
|
|
61
|
+
'UnnnicDialogContent',
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const mockEvent = {
|
|
67
|
+
preventDefault: vi.fn(),
|
|
68
|
+
target: document.createElement('div'),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
wrapper.vm.persistentHandler(mockEvent);
|
|
72
|
+
|
|
73
|
+
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
46
76
|
});
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
<PopoverPortal :to="portalTarget">
|
|
3
3
|
<PopoverContent
|
|
4
4
|
v-bind="{ ...forwarded, ...$attrs }"
|
|
5
|
+
:style="{ width: contentWidth, zIndex: popoverZIndex }"
|
|
5
6
|
:class="
|
|
6
7
|
cn(
|
|
7
8
|
'unnnic-popover',
|
|
8
|
-
`unnnic-popover--size-${props.size}`,
|
|
9
9
|
'bg-popover text-popover-foreground outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
10
10
|
)
|
|
11
11
|
"
|
|
12
|
-
:style="{ zIndex: popoverZIndex }"
|
|
13
12
|
>
|
|
14
13
|
<section :class="`unnnic-popover__content ${props.class || ''}`">
|
|
15
14
|
<component
|
|
@@ -46,7 +45,8 @@ const props = withDefaults(
|
|
|
46
45
|
defineProps<
|
|
47
46
|
PopoverContentProps & {
|
|
48
47
|
class?: HTMLAttributes['class'];
|
|
49
|
-
size?:
|
|
48
|
+
size?: string;
|
|
49
|
+
width?: string;
|
|
50
50
|
}
|
|
51
51
|
>(),
|
|
52
52
|
{
|
|
@@ -54,6 +54,7 @@ const props = withDefaults(
|
|
|
54
54
|
sideOffset: 4,
|
|
55
55
|
size: 'medium',
|
|
56
56
|
class: '',
|
|
57
|
+
width: '',
|
|
57
58
|
},
|
|
58
59
|
);
|
|
59
60
|
const emits = defineEmits<PopoverContentEmits>();
|
|
@@ -85,6 +86,18 @@ const footerChildren = computed(() => {
|
|
|
85
86
|
(vnode: VNode) => getComponentName(vnode) === 'UnnnicPopoverFooter',
|
|
86
87
|
);
|
|
87
88
|
});
|
|
89
|
+
|
|
90
|
+
const contentWidth = computed(() => {
|
|
91
|
+
if (props.width) return props.width;
|
|
92
|
+
|
|
93
|
+
const sizes = {
|
|
94
|
+
small: '240px',
|
|
95
|
+
medium: '320px',
|
|
96
|
+
large: '400px',
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return sizes[props.size as keyof typeof sizes];
|
|
100
|
+
});
|
|
88
101
|
</script>
|
|
89
102
|
|
|
90
103
|
<style lang="scss">
|
|
@@ -95,15 +108,20 @@ $popover-space: $unnnic-space-4;
|
|
|
95
108
|
.unnnic-popover {
|
|
96
109
|
border-radius: $unnnic-radius-2;
|
|
97
110
|
box-shadow: $unnnic-shadow-1;
|
|
111
|
+
border: 1px solid $unnnic-color-border-soft;
|
|
98
112
|
|
|
99
|
-
|
|
100
|
-
width:
|
|
113
|
+
&::-webkit-scrollbar {
|
|
114
|
+
width: $unnnic-space-1;
|
|
101
115
|
}
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
|
|
117
|
+
&::-webkit-scrollbar-thumb {
|
|
118
|
+
background: $unnnic-color-neutral-cleanest;
|
|
119
|
+
border-radius: $unnnic-border-radius-pill;
|
|
104
120
|
}
|
|
105
|
-
|
|
106
|
-
|
|
121
|
+
|
|
122
|
+
&::-webkit-scrollbar-track {
|
|
123
|
+
background: $unnnic-color-neutral-soft;
|
|
124
|
+
border-radius: $unnnic-border-radius-pill;
|
|
107
125
|
}
|
|
108
126
|
|
|
109
127
|
&__content {
|
|
@@ -76,7 +76,7 @@ const schemeColor = computed(() => {
|
|
|
76
76
|
.unnnic-popover-option {
|
|
77
77
|
cursor: pointer;
|
|
78
78
|
border-radius: $unnnic-radius-2;
|
|
79
|
-
padding: $unnnic-space-2;
|
|
79
|
+
padding: $unnnic-space-2 $unnnic-space-4;
|
|
80
80
|
font: $unnnic-font-emphasis;
|
|
81
81
|
display: flex;
|
|
82
82
|
gap: $unnnic-space-2;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import UnnnicModalDialog from '../components/ModalDialog/ModalDialog.vue';
|
|
2
2
|
import UnnnicInput from '../components/Input/Input.vue';
|
|
3
3
|
import UnnnicLabel from '../components/Label/Label.vue';
|
|
4
|
+
import UnnnicInputDatePicker from '../components/InputDatePicker/InputDatePicker.vue';
|
|
5
|
+
import UnnnicSwitch from '../components/Switch/Switch.vue';
|
|
6
|
+
import UnnnicButton from '../components/Button/Button.vue';
|
|
4
7
|
|
|
5
8
|
import { action } from '@storybook/addon-actions';
|
|
6
9
|
import iconsList from '../utils/iconList';
|
|
@@ -182,6 +185,85 @@ const TemplateLeftSidebar = (args) => ({
|
|
|
182
185
|
},
|
|
183
186
|
});
|
|
184
187
|
|
|
188
|
+
const TemplateWithDatePicker = (args) => ({
|
|
189
|
+
components: {
|
|
190
|
+
UnnnicModalDialog,
|
|
191
|
+
UnnnicInputDatePicker,
|
|
192
|
+
UnnnicSwitch,
|
|
193
|
+
UnnnicButton,
|
|
194
|
+
},
|
|
195
|
+
setup() {
|
|
196
|
+
const updateModelValue = (value) => {
|
|
197
|
+
action('update:modelValue')(value);
|
|
198
|
+
args.modelValue = value;
|
|
199
|
+
};
|
|
200
|
+
return { args, updateModelValue };
|
|
201
|
+
},
|
|
202
|
+
data() {
|
|
203
|
+
return {
|
|
204
|
+
forms: [{ date: { start: null, end: null }, repeat: false }],
|
|
205
|
+
isLoading: false,
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
template: `
|
|
209
|
+
<div>
|
|
210
|
+
<button @click="updateModelValue(true)">Open Modal with DatePicker</button>
|
|
211
|
+
<unnnic-modal-dialog
|
|
212
|
+
v-bind="args"
|
|
213
|
+
@primaryButtonClick="handleSave"
|
|
214
|
+
@secondaryButtonClick="secondaryButtonClick"
|
|
215
|
+
@update:modelValue="updateModelValue"
|
|
216
|
+
>
|
|
217
|
+
<section style="display: flex; flex-direction: column; gap: 16px;">
|
|
218
|
+
<section
|
|
219
|
+
v-for="(form, index) in forms"
|
|
220
|
+
:key="index"
|
|
221
|
+
style="display: flex; flex-direction: column; gap: 12px; padding: 16px; border: 1px solid #E2E6ED; border-radius: 8px;"
|
|
222
|
+
>
|
|
223
|
+
<section style="display: flex; flex-direction: column; gap: 8px;">
|
|
224
|
+
<p style="font-family: 'Lato'; font-size: 14px; font-weight: 600; margin: 0; color: #3B414D;">
|
|
225
|
+
Select date or period
|
|
226
|
+
</p>
|
|
227
|
+
<UnnnicInputDatePicker
|
|
228
|
+
v-model="form.date"
|
|
229
|
+
:options="[{ id: 'custom', name: 'Custom' }]"
|
|
230
|
+
next
|
|
231
|
+
fillW
|
|
232
|
+
actionText="Confirm"
|
|
233
|
+
disableClear
|
|
234
|
+
/>
|
|
235
|
+
</section>
|
|
236
|
+
<UnnnicSwitch
|
|
237
|
+
v-model="form.repeat"
|
|
238
|
+
textRight="Repeat annually"
|
|
239
|
+
size="small"
|
|
240
|
+
/>
|
|
241
|
+
</section>
|
|
242
|
+
<UnnnicButton
|
|
243
|
+
iconCenter="add-1"
|
|
244
|
+
type="tertiary"
|
|
245
|
+
text="Add"
|
|
246
|
+
@click="addForm"
|
|
247
|
+
/>
|
|
248
|
+
</section>
|
|
249
|
+
</unnnic-modal-dialog>
|
|
250
|
+
</div>
|
|
251
|
+
`,
|
|
252
|
+
methods: {
|
|
253
|
+
primaryButtonClick: action('primaryButtonClick'),
|
|
254
|
+
secondaryButtonClick: action('secondaryButtonClick'),
|
|
255
|
+
handleSave() {
|
|
256
|
+
action('primaryButtonClick')();
|
|
257
|
+
action('save')(this.forms);
|
|
258
|
+
console.log('Forms data:', this.forms);
|
|
259
|
+
},
|
|
260
|
+
addForm() {
|
|
261
|
+
this.forms.push({ date: { start: null, end: null }, repeat: false });
|
|
262
|
+
action('addForm')();
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
|
|
185
267
|
export const Default = Template.bind({});
|
|
186
268
|
Default.args = {
|
|
187
269
|
title: 'Default Modal',
|
|
@@ -261,3 +343,16 @@ Image.args = {
|
|
|
261
343
|
},
|
|
262
344
|
showActionsDivider: true,
|
|
263
345
|
};
|
|
346
|
+
|
|
347
|
+
export const WithDatePicker = TemplateWithDatePicker.bind({});
|
|
348
|
+
WithDatePicker.args = {
|
|
349
|
+
title: 'Add Non-Working Dates',
|
|
350
|
+
type: '',
|
|
351
|
+
primaryButtonProps: {
|
|
352
|
+
text: 'Save',
|
|
353
|
+
loading: false,
|
|
354
|
+
},
|
|
355
|
+
secondaryButtonProps: {
|
|
356
|
+
text: 'Cancel',
|
|
357
|
+
},
|
|
358
|
+
};
|
|
@@ -26,6 +26,11 @@ export default {
|
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
argTypes: {
|
|
29
|
+
width: {
|
|
30
|
+
control: { type: 'text' },
|
|
31
|
+
description:
|
|
32
|
+
'The width of the popover. This overrides the size prop. If not provided, the size prop will be used.',
|
|
33
|
+
},
|
|
29
34
|
size: {
|
|
30
35
|
control: { type: 'select' },
|
|
31
36
|
options: ['small', 'medium', 'large'],
|