@weni/unnnic-system 3.2.5-alpha.1 → 3.2.6
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/CHANGELOG.md +47 -0
- package/dist/components/Accordion/Accordion.vue.d.ts +1 -1
- package/dist/components/Alert/Alert.vue.d.ts +5 -5
- package/dist/components/Alert/Version1dot1.vue.d.ts +2 -2
- package/dist/components/AudioRecorder/AudioHandler.vue.d.ts +2 -2
- package/dist/components/AudioRecorder/AudioPlayer.vue.d.ts +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.vue.d.ts +5 -5
- package/dist/components/AvatarIcon/AvatarIcon.vue.d.ts +2 -2
- package/dist/components/Banner/Banner.vue.d.ts +1 -1
- package/dist/components/Banner/InfoBanner.vue.d.ts +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.vue.d.ts +1 -1
- package/dist/components/Button/Button.vue.d.ts +2 -2
- package/dist/components/Button/Button.vue.d.ts.map +1 -1
- package/dist/components/Button/ButtonIcon.vue.d.ts +1 -1
- package/dist/components/Button/types.d.ts +1 -1
- package/dist/components/Button/types.d.ts.map +1 -1
- package/dist/components/Card/AccountCard.vue.d.ts +3 -3
- package/dist/components/Card/BlankCard.vue.d.ts +1 -1
- package/dist/components/Card/Card.vue.d.ts +21 -21
- package/dist/components/Card/CardCompany.vue.d.ts +8 -8
- package/dist/components/Card/CardData.vue.d.ts +1 -1
- package/dist/components/Card/CardStatusesContainer.vue.d.ts +4 -4
- package/dist/components/Card/ContentCard.vue.d.ts +2 -2
- package/dist/components/Card/DashCard.vue.d.ts +4 -4
- package/dist/components/Card/DefaultCard.vue.d.ts +1 -1
- package/dist/components/Card/MarketplaceCard.vue.d.ts +2 -2
- package/dist/components/Card/SimpleCard.vue.d.ts +3 -3
- package/dist/components/Card/StatusCard.vue.d.ts +2 -2
- package/dist/components/Card/TitleCard.vue.d.ts +2 -2
- package/dist/components/CardImage/CardImage.vue.d.ts +16 -7
- package/dist/components/CardInformation/CardInformation.vue.d.ts +4 -4
- package/dist/components/CardProject/CardProject.vue.d.ts +11 -2
- package/dist/components/Carousel/Carousel.vue.d.ts +11 -11
- package/dist/components/Carousel/TagCarousel.vue.d.ts +9 -9
- package/dist/components/ChartBar/ChartBar.vue.d.ts +8 -8
- package/dist/components/ChartLine/ChartLine.vue.d.ts +1 -1
- package/dist/components/ChatText/ChatText.vue.d.ts +2 -2
- package/dist/components/ChatsContact/ChatsContact.vue.d.ts +15 -15
- package/dist/components/ChatsDashboardTagLive/ChatsDashboardTagLive.vue.d.ts +1 -1
- package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts +1 -1
- package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts.map +1 -1
- package/dist/components/ChatsMessage/ChatsMessage.vue.d.ts +5 -5
- package/dist/components/ChatsMessage/ChatsMessageStatusBackdrop.vue.d.ts +2 -2
- package/dist/components/ChatsNavbar/ChatsNavbar.vue.d.ts +1 -1
- package/dist/components/ChatsUserAvatar/ChatsUserAvatar.vue.d.ts +2 -2
- package/dist/components/Checkbox/Checkbox.vue.d.ts +3 -3
- package/dist/components/Chip/Chip.vue.d.ts +8 -0
- package/dist/components/Chip/Chip.vue.d.ts.map +1 -0
- package/dist/components/Chip/types.d.ts +9 -0
- package/dist/components/Chip/types.d.ts.map +1 -0
- package/dist/components/Comment/Comment.vue.d.ts +1 -1
- package/dist/components/DataArea/DataArea.vue.d.ts +2 -2
- package/dist/components/DataTable/index.vue.d.ts +1 -1
- package/dist/components/DataTable/index.vue.d.ts.map +1 -1
- package/dist/components/DateFilter/DateFilter.vue.d.ts +27 -182
- package/dist/components/DatePicker/DatePicker.vue.d.ts +8 -8
- package/dist/components/Disclaimer/types.d.ts +1 -1
- package/dist/components/Disclaimer/types.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.vue.d.ts +7 -7
- package/dist/components/DropArea/DropArea.vue.d.ts +0 -2
- package/dist/components/DropArea/DropArea.vue.d.ts.map +1 -1
- package/dist/components/Dropdown/Dropdown.vue.d.ts +9 -0
- package/dist/components/Dropdown/LanguageSelect.vue.d.ts +3 -3
- package/dist/components/Flag.vue.d.ts +2 -2
- package/dist/components/FormElement/FormElement.vue.d.ts +32 -38
- package/dist/components/FormElement/FormElement.vue.d.ts.map +1 -1
- package/dist/components/Icon/types.d.ts +2 -1
- package/dist/components/Icon/types.d.ts.map +1 -1
- package/dist/components/Icon.vue.d.ts +3 -2
- package/dist/components/Icon.vue.d.ts.map +1 -1
- package/dist/components/IconLoading/IconLoading.vue.d.ts +1 -1
- package/dist/components/ImportCard/ImportCard.vue.d.ts +7 -7
- package/dist/components/Input/BaseInput.vue.d.ts +1 -10
- package/dist/components/Input/BaseInput.vue.d.ts.map +1 -1
- package/dist/components/Input/Input.vue.d.ts +27 -182
- package/dist/components/Input/Input.vue.d.ts.map +1 -1
- package/dist/components/Input/TextInput.vue.d.ts +13 -31
- package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +37 -192
- package/dist/components/InputNext/InputNext.vue.d.ts +3 -3
- package/dist/components/Modal/Modal.vue.d.ts +2 -2
- package/dist/components/ModalDialog/ModalDialog.vue.d.ts +10 -10
- package/dist/components/ModalDialog/ModalDialog.vue.d.ts.map +1 -1
- package/dist/components/ModalNext/ModalNext.vue.d.ts +34 -189
- package/dist/components/ModalUpload/ModalUpload.vue.d.ts +14 -20
- package/dist/components/MoodRating/MoodRating.vue.d.ts +1 -1
- package/dist/components/MultiSelect/MultiSelect.vue.d.ts +7 -7
- package/dist/components/Pagination/Pagination.vue.d.ts +6 -6
- package/dist/components/ProgressBar/ProgressBar.vue.d.ts +1 -1
- package/dist/components/Radio/Radio.vue.d.ts +2 -2
- package/dist/components/SelectSmart/SelectSmart.vue.d.ts +28 -45
- package/dist/components/SelectSmart/SelectSmartMultipleHeader.vue.d.ts +8 -8
- package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts +4 -4
- package/dist/components/SelectTime/index.vue.d.ts +13 -31
- package/dist/components/Slider/Slider.vue.d.ts +2 -2
- package/dist/components/StarRating/StarRating.vue.d.ts +1 -1
- package/dist/components/Switch/Switch.vue.d.ts +2 -2
- package/dist/components/Tab/Tab.vue.d.ts +2 -2
- package/dist/components/TableNext/TableBodyCell.vue.d.ts +2 -2
- package/dist/components/TableNext/TablePagination.vue.d.ts +6 -6
- package/dist/components/TabsExpanded/TabsExpanded.vue.d.ts +1 -1
- package/dist/components/Tag/BrandTag.vue.d.ts +2 -2
- package/dist/components/Tag/DefaultTag.vue.d.ts +2 -2
- package/dist/components/Tag/IndicatorTag.vue.d.ts +2 -2
- package/dist/components/Tag/Tag.vue.d.ts +8 -8
- package/dist/components/TextArea/TextArea.vue.d.ts +32 -38
- package/dist/components/TextArea/TextArea.vue.d.ts.map +1 -1
- package/dist/components/ToolTip/ToolTip.vue.d.ts +1 -1
- package/dist/components/Tour/Tour.vue.d.ts +6 -6
- package/dist/components/Tour/TourPopover.vue.d.ts +6 -6
- package/dist/components/UploadArea/UploadArea.vue.d.ts +7 -13
- package/dist/components/index.d.ts +899 -2193
- package/dist/components/index.d.ts.map +1 -1
- package/dist/{es-dc7f4ae0.mjs → es-abc8e9a2.mjs} +1 -1
- package/dist/{index-93c6d4e1.mjs → index-22520f9b.mjs} +7776 -7910
- package/dist/{pt-br-6c72f1f4.mjs → pt-br-a1f8d5de.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +116 -118
- package/dist/unnnic.umd.js +41 -42
- package/package.json +2 -2
- package/src/assets/scss/scheme-colors.scss +132 -0
- package/src/assets/scss/unnnic.scss +2 -0
- package/src/components/Button/Button.vue +109 -58
- package/src/components/Button/types.ts +1 -0
- package/src/components/Card/Card.vue +12 -21
- package/src/components/Chip/Chip.vue +124 -0
- package/src/components/Chip/__tests__/Chip.spec.js +164 -0
- package/src/components/Chip/types.ts +8 -0
- package/src/components/Disclaimer/types.ts +1 -1
- package/src/components/DropArea/DropArea.vue +2 -26
- package/src/components/Dropdown/Dropdown.vue +6 -0
- package/src/components/Dropdown/__tests__/Dropdown.spec.js +57 -0
- package/src/components/FormElement/FormElement.vue +90 -50
- package/src/components/Icon/types.ts +4 -95
- package/src/components/Icon.vue +3 -98
- package/src/components/Input/BaseInput.vue +12 -10
- package/src/components/Input/Input.scss +20 -17
- package/src/components/Input/Input.vue +28 -86
- package/src/components/Input/TextInput.vue +35 -27
- package/src/components/Input/__test__/TextInput.spec.js +5 -5
- package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +3 -12
- package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +1 -1
- package/src/components/ModalDialog/ModalDialog.vue +29 -27
- package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -1
- package/src/components/SelectSmart/SelectSmart.vue +3 -1
- package/src/components/SelectSmart/__tests__/SelectSmart.spec.js +45 -0
- package/src/components/TableNext/__test__/__snapshots__/TableNext.spec.js.snap +2 -2
- package/src/components/TableNext/__test__/__snapshots__/TablePagination.spec.js.snap +2 -2
- package/src/components/TextArea/TextArea.vue +9 -14
- package/src/components/TextArea/__test__/__snapshots__/TextArea.spec.js.snap +2 -7
- package/src/components/index.ts +7 -12
- package/src/stories/Button.stories.js +10 -1
- package/src/stories/Chip.stories.js +173 -0
- package/src/stories/Input.stories.js +3 -17
- package/src/types/scheme-colors.d.ts +102 -0
- package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts +0 -9
- package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts.map +0 -1
- package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts +0 -15
- package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts.map +0 -1
- package/src/assets/img/previews/doc-preview.png +0 -0
- package/src/assets/img/previews/image-preview.png +0 -0
- package/src/assets/img/previews/video-preview.png +0 -0
- package/src/components/TemplatePreview/TemplatePreview.vue +0 -249
- package/src/components/TemplatePreview/TemplatePreviewModal.vue +0 -51
- package/src/components/TemplatePreview/types.d.ts +0 -16
- package/src/stories/TemplatePreview.stories.js +0 -94
- package/src/stories/TemplatePreviewModal.stories.js +0 -110
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { mount } from '@vue/test-utils';
|
|
3
|
+
|
|
4
|
+
import Chip from '../Chip.vue';
|
|
5
|
+
|
|
6
|
+
const createWrapper = (props) => {
|
|
7
|
+
return mount(Chip, {
|
|
8
|
+
props,
|
|
9
|
+
global: {
|
|
10
|
+
stubs: {
|
|
11
|
+
UnnnicIcon: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe('Chip', () => {
|
|
18
|
+
let wrapper;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
wrapper = createWrapper({ text: 'Test Chip', type: 'single' });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('Basic rendering', () => {
|
|
25
|
+
it('should render the chip with text', () => {
|
|
26
|
+
expect(wrapper.exists()).toBe(true);
|
|
27
|
+
expect(wrapper.text()).toContain('Test Chip');
|
|
28
|
+
expect(wrapper.classes()).toContain('chip');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should render with default unselected state', () => {
|
|
32
|
+
expect(wrapper.classes()).toContain('chip--border');
|
|
33
|
+
expect(wrapper.classes()).not.toContain('chip--is-selected');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('Selection state', () => {
|
|
38
|
+
it('should apply selected styling when isSelected is true', async () => {
|
|
39
|
+
await wrapper.setProps({ isSelected: true });
|
|
40
|
+
|
|
41
|
+
expect(wrapper.classes()).toContain('chip--is-selected');
|
|
42
|
+
expect(wrapper.classes()).not.toContain('chip--border');
|
|
43
|
+
|
|
44
|
+
const textElement = wrapper.find('.chip__text');
|
|
45
|
+
expect(textElement.classes()).toContain('chip__text--is-selected');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('Count functionality', () => {
|
|
50
|
+
it('should render count when provided', async () => {
|
|
51
|
+
await wrapper.setProps({ count: 5 });
|
|
52
|
+
|
|
53
|
+
const countElement = wrapper.find('.chip__count');
|
|
54
|
+
expect(countElement.exists()).toBe(true);
|
|
55
|
+
expect(countElement.text()).toBe('5');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should not render count when not provided or zero', async () => {
|
|
59
|
+
expect(wrapper.find('.chip__count').exists()).toBe(false);
|
|
60
|
+
|
|
61
|
+
await wrapper.setProps({ count: 0 });
|
|
62
|
+
expect(wrapper.find('.chip__count').exists()).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should apply selected styling to count when chip is selected', async () => {
|
|
66
|
+
await wrapper.setProps({ count: 3, isSelected: true });
|
|
67
|
+
|
|
68
|
+
const countElement = wrapper.find('.chip__count');
|
|
69
|
+
expect(countElement.classes()).toContain('chip__count--is-selected');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('Type functionality', () => {
|
|
74
|
+
it('should not render icon for single type', () => {
|
|
75
|
+
const icon = wrapper.findComponent({ name: 'UnnnicIcon' });
|
|
76
|
+
expect(icon.exists()).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should render correct icons for multiple type', async () => {
|
|
80
|
+
await wrapper.setProps({ type: 'multiple', isSelected: false });
|
|
81
|
+
|
|
82
|
+
let icon = wrapper.findComponent({ name: 'UnnnicIcon' });
|
|
83
|
+
expect(icon.exists()).toBe(true);
|
|
84
|
+
expect(icon.props('icon')).toBe('add');
|
|
85
|
+
expect(icon.props('scheme')).toBe('feedback-grey');
|
|
86
|
+
expect(icon.props('size')).toBe('sm');
|
|
87
|
+
|
|
88
|
+
await wrapper.setProps({ isSelected: true });
|
|
89
|
+
|
|
90
|
+
icon = wrapper.findComponent({ name: 'UnnnicIcon' });
|
|
91
|
+
expect(icon.props('icon')).toBe('close');
|
|
92
|
+
expect(icon.props('scheme')).toBe('teal-600');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('Combined functionality', () => {
|
|
97
|
+
it('should render all elements correctly when combined', async () => {
|
|
98
|
+
await wrapper.setProps({
|
|
99
|
+
text: 'Complete Chip',
|
|
100
|
+
count: 42,
|
|
101
|
+
type: 'multiple',
|
|
102
|
+
isSelected: true
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
expect(wrapper.text()).toContain('Complete Chip');
|
|
106
|
+
expect(wrapper.classes()).toContain('chip--is-selected');
|
|
107
|
+
|
|
108
|
+
const countElement = wrapper.find('.chip__count');
|
|
109
|
+
expect(countElement.exists()).toBe(true);
|
|
110
|
+
expect(countElement.text()).toBe('42');
|
|
111
|
+
expect(countElement.classes()).toContain('chip__count--is-selected');
|
|
112
|
+
|
|
113
|
+
const icon = wrapper.findComponent({ name: 'UnnnicIcon' });
|
|
114
|
+
expect(icon.exists()).toBe(true);
|
|
115
|
+
expect(icon.props('icon')).toBe('close');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('Click functionality', () => {
|
|
120
|
+
it('should emit click event when clicked', async () => {
|
|
121
|
+
await wrapper.setProps({ isClickable: true });
|
|
122
|
+
|
|
123
|
+
await wrapper.trigger('click');
|
|
124
|
+
|
|
125
|
+
expect(wrapper.emitted().click).toBeTruthy();
|
|
126
|
+
expect(wrapper.emitted().click).toHaveLength(1);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should apply clickable styling when isClickable is true', async () => {
|
|
130
|
+
await wrapper.setProps({ isClickable: true });
|
|
131
|
+
|
|
132
|
+
expect(wrapper.classes()).toContain('chip--is-clickable');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should not apply clickable styling when isClickable is false', () => {
|
|
136
|
+
expect(wrapper.classes()).not.toContain('chip--is-clickable');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should emit click event even when not marked as clickable', async () => {
|
|
140
|
+
await wrapper.trigger('click');
|
|
141
|
+
|
|
142
|
+
expect(wrapper.emitted().click).toBeTruthy();
|
|
143
|
+
expect(wrapper.emitted().click).toHaveLength(1);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('Edge cases', () => {
|
|
148
|
+
it('should handle negative count', async () => {
|
|
149
|
+
await wrapper.setProps({ count: -5 });
|
|
150
|
+
|
|
151
|
+
const countElement = wrapper.find('.chip__count');
|
|
152
|
+
expect(countElement.exists()).toBe(true);
|
|
153
|
+
expect(countElement.text()).toBe('-5');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should handle empty text', async () => {
|
|
157
|
+
await wrapper.setProps({ text: '' });
|
|
158
|
+
|
|
159
|
+
const textElement = wrapper.find('.chip__text');
|
|
160
|
+
expect(textElement.exists()).toBe(true);
|
|
161
|
+
expect(textElement.text()).toBe('');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
@dragleave.stop.prevent="dragleave"
|
|
12
12
|
@dragend.stop.prevent="dragend"
|
|
13
13
|
@drop.stop.prevent="drop"
|
|
14
|
-
@click="
|
|
14
|
+
@click="() => $refs.file.click()"
|
|
15
15
|
>
|
|
16
16
|
<UnnnicIcon
|
|
17
17
|
class="unnnic-upload-area__dropzone__icon"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
</template>
|
|
65
65
|
|
|
66
66
|
<script setup>
|
|
67
|
-
import { ref, computed, getCurrentInstance
|
|
67
|
+
import { ref, computed, getCurrentInstance } from 'vue';
|
|
68
68
|
import mime from 'mime';
|
|
69
69
|
|
|
70
70
|
import UnnnicIcon from '../Icon.vue';
|
|
@@ -73,7 +73,6 @@ const isDragging = ref(false);
|
|
|
73
73
|
const hasError = ref(false);
|
|
74
74
|
const dragEnterCounter = ref(0);
|
|
75
75
|
const file = ref();
|
|
76
|
-
const fileRef = useTemplateRef('file');
|
|
77
76
|
|
|
78
77
|
const props = defineProps({
|
|
79
78
|
acceptMultiple: {
|
|
@@ -112,11 +111,6 @@ const props = defineProps({
|
|
|
112
111
|
type: String,
|
|
113
112
|
default: '',
|
|
114
113
|
},
|
|
115
|
-
|
|
116
|
-
disabled: {
|
|
117
|
-
type: Boolean,
|
|
118
|
-
default: false,
|
|
119
|
-
}
|
|
120
114
|
});
|
|
121
115
|
|
|
122
116
|
const emit = defineEmits([
|
|
@@ -141,21 +135,15 @@ const formattedSupportedFormats = computed(() => {
|
|
|
141
135
|
});
|
|
142
136
|
|
|
143
137
|
function dragenter() {
|
|
144
|
-
if (props.disabled) return;
|
|
145
|
-
|
|
146
138
|
dragEnterCounter.value += 1;
|
|
147
139
|
isDragging.value = true;
|
|
148
140
|
}
|
|
149
141
|
|
|
150
142
|
function dragover() {
|
|
151
|
-
if (props.disabled) return;
|
|
152
|
-
|
|
153
143
|
isDragging.value = true;
|
|
154
144
|
}
|
|
155
145
|
|
|
156
146
|
function dragleave() {
|
|
157
|
-
if (props.disabled) return;
|
|
158
|
-
|
|
159
147
|
dragEnterCounter.value -= 1;
|
|
160
148
|
if (dragEnterCounter.value === 0) {
|
|
161
149
|
isDragging.value = false;
|
|
@@ -163,14 +151,10 @@ function dragleave() {
|
|
|
163
151
|
}
|
|
164
152
|
|
|
165
153
|
function dragend() {
|
|
166
|
-
if (props.disabled) return;
|
|
167
|
-
|
|
168
154
|
isDragging.value = false;
|
|
169
155
|
}
|
|
170
156
|
|
|
171
157
|
function drop(event) {
|
|
172
|
-
if (props.disabled) return;
|
|
173
|
-
|
|
174
158
|
isDragging.value = false;
|
|
175
159
|
|
|
176
160
|
const { files } = event.dataTransfer;
|
|
@@ -180,15 +164,7 @@ function drop(event) {
|
|
|
180
164
|
}
|
|
181
165
|
}
|
|
182
166
|
|
|
183
|
-
function handleDropzoneClick() {
|
|
184
|
-
if (props.disabled) return;
|
|
185
|
-
|
|
186
|
-
fileRef.value.click();
|
|
187
|
-
}
|
|
188
|
-
|
|
189
167
|
function handleFileChange(event) {
|
|
190
|
-
if (props.disabled) return;
|
|
191
|
-
|
|
192
168
|
const { files } = event.target;
|
|
193
169
|
|
|
194
170
|
if (validateFiles(files)) {
|
|
@@ -38,6 +38,10 @@ export default {
|
|
|
38
38
|
type: Boolean,
|
|
39
39
|
default: false,
|
|
40
40
|
},
|
|
41
|
+
forceOpen: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
default: false,
|
|
44
|
+
},
|
|
41
45
|
position: {
|
|
42
46
|
type: String,
|
|
43
47
|
default: 'bottom-left',
|
|
@@ -73,10 +77,12 @@ export default {
|
|
|
73
77
|
},
|
|
74
78
|
methods: {
|
|
75
79
|
onClickTrigger() {
|
|
80
|
+
if (this.forceOpen) return;
|
|
76
81
|
if (this.useOpenProp) this.$emit('update:open', !this.open);
|
|
77
82
|
else this.active = !this.active;
|
|
78
83
|
},
|
|
79
84
|
onClickOutside() {
|
|
85
|
+
if (this.forceOpen) return;
|
|
80
86
|
if (this.useOpenProp && this.open) {
|
|
81
87
|
this.$emit('update:open', false);
|
|
82
88
|
return;
|
|
@@ -95,4 +95,61 @@ describe('Dropdown.vue', () => {
|
|
|
95
95
|
expect(wrapper.vm.active).toBe(false);
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
|
+
|
|
99
|
+
describe('ForceOpen Functionality', () => {
|
|
100
|
+
it('should not toggle dropdown on trigger click when forceOpen is true', async () => {
|
|
101
|
+
await wrapper.setProps({ forceOpen: true, open: false });
|
|
102
|
+
const initialActiveState = wrapper.vm.active;
|
|
103
|
+
|
|
104
|
+
const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
|
|
105
|
+
await trigger.trigger('click');
|
|
106
|
+
|
|
107
|
+
expect(wrapper.vm.active).toBe(initialActiveState);
|
|
108
|
+
expect(wrapper.emitted('update:open')).toBeFalsy();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should not close dropdown on outside click when forceOpen is true', async () => {
|
|
112
|
+
await wrapper.setProps({ forceOpen: true, open: true });
|
|
113
|
+
expect(wrapper.vm.active).toBe(true);
|
|
114
|
+
|
|
115
|
+
await wrapper.vm.onClickOutside();
|
|
116
|
+
|
|
117
|
+
expect(wrapper.vm.active).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should not emit update:open when forceOpen is true and useOpenProp is true', async () => {
|
|
121
|
+
await wrapper.setProps({
|
|
122
|
+
forceOpen: true,
|
|
123
|
+
useOpenProp: true,
|
|
124
|
+
open: false
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
|
|
128
|
+
await trigger.trigger('click');
|
|
129
|
+
|
|
130
|
+
expect(wrapper.emitted('update:open')).toBeFalsy();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should not close dropdown via onClickOutside when forceOpen is true and useOpenProp is true', async () => {
|
|
134
|
+
await wrapper.setProps({
|
|
135
|
+
forceOpen: true,
|
|
136
|
+
useOpenProp: true,
|
|
137
|
+
open: true
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
await wrapper.vm.onClickOutside();
|
|
141
|
+
|
|
142
|
+
expect(wrapper.emitted('update:open')).toBeFalsy();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should allow normal behavior when forceOpen is false', async () => {
|
|
146
|
+
await wrapper.setProps({ forceOpen: false, open: false });
|
|
147
|
+
|
|
148
|
+
const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
|
|
149
|
+
await trigger.trigger('click');
|
|
150
|
+
|
|
151
|
+
expect(wrapper.vm.active).toBe(true);
|
|
152
|
+
expect(wrapper.emitted('update:open')).toBeTruthy();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
98
155
|
});
|
|
@@ -17,28 +17,51 @@
|
|
|
17
17
|
|
|
18
18
|
<slot></slot>
|
|
19
19
|
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
<p
|
|
21
|
+
v-if="shouldShowErrorSection"
|
|
22
|
+
class="unnnic-form-element__error"
|
|
23
|
+
>
|
|
24
|
+
<template v-if="error !== true">
|
|
25
|
+
<UnnnicIcon
|
|
26
|
+
size="sm"
|
|
27
|
+
icon="warning"
|
|
28
|
+
scheme="aux-red-500"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
{{ fullySanitize(error) }}
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<span
|
|
35
|
+
v-if="!!$slots.rightMessage"
|
|
36
|
+
class="unnnic-form-element__right-message"
|
|
37
|
+
>
|
|
38
|
+
<slot name="rightMessage"></slot>
|
|
39
|
+
</span>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<p
|
|
43
|
+
v-if="message || !!$slots.rightMessage"
|
|
44
|
+
class="unnnic-form-element__message"
|
|
45
|
+
>
|
|
46
|
+
{{ fullySanitize(message) }}
|
|
47
|
+
|
|
48
|
+
<span
|
|
49
|
+
v-if="!shouldShowErrorSection && !!$slots.rightMessage"
|
|
50
|
+
class="unnnic-form-element__right-message"
|
|
51
|
+
>
|
|
33
52
|
<slot name="rightMessage"></slot>
|
|
34
|
-
</
|
|
35
|
-
</
|
|
53
|
+
</span>
|
|
54
|
+
</p>
|
|
36
55
|
</section>
|
|
37
56
|
</template>
|
|
38
57
|
|
|
39
58
|
<script>
|
|
59
|
+
import UnnnicIcon from '../../components/Icon.vue';
|
|
40
60
|
import { fullySanitize } from '../../utils/sanitize';
|
|
41
61
|
export default {
|
|
62
|
+
components: {
|
|
63
|
+
UnnnicIcon,
|
|
64
|
+
},
|
|
42
65
|
|
|
43
66
|
props: {
|
|
44
67
|
size: {
|
|
@@ -47,18 +70,28 @@ export default {
|
|
|
47
70
|
validator: (size) => ['md', 'sm'].includes(size),
|
|
48
71
|
},
|
|
49
72
|
|
|
50
|
-
label:
|
|
73
|
+
label: String,
|
|
51
74
|
|
|
52
|
-
fixedLabel:
|
|
75
|
+
fixedLabel: Boolean,
|
|
53
76
|
|
|
54
77
|
error: {
|
|
55
78
|
type: [Boolean, String],
|
|
56
79
|
default: false,
|
|
57
80
|
},
|
|
58
81
|
|
|
59
|
-
message:
|
|
82
|
+
message: String,
|
|
83
|
+
|
|
84
|
+
disabled: Boolean,
|
|
85
|
+
},
|
|
60
86
|
|
|
61
|
-
|
|
87
|
+
data() {
|
|
88
|
+
return {};
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
computed: {
|
|
92
|
+
shouldShowErrorSection() {
|
|
93
|
+
return this.error && (this.error !== true || !!this.$slots.rightMessage);
|
|
94
|
+
},
|
|
62
95
|
},
|
|
63
96
|
methods: {
|
|
64
97
|
fullySanitize,
|
|
@@ -69,68 +102,75 @@ export default {
|
|
|
69
102
|
<style lang="scss" scoped>
|
|
70
103
|
@use '@/assets/scss/unnnic' as *;
|
|
71
104
|
|
|
72
|
-
* {
|
|
73
|
-
margin: $unnnic-space-0;
|
|
74
|
-
padding: $unnnic-space-0;
|
|
75
|
-
box-sizing: border-box;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
105
|
.unnnic-form-element {
|
|
79
106
|
&__label {
|
|
80
|
-
|
|
107
|
+
margin: 0;
|
|
108
|
+
margin-bottom: $unnnic-spacing-nano;
|
|
109
|
+
|
|
81
110
|
color: $unnnic-color-neutral-cloudy;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
font-family: $unnnic-font-family-secondary;
|
|
112
|
+
font-weight: $unnnic-font-weight-regular;
|
|
113
|
+
font-size: $unnnic-font-size-body-gt;
|
|
114
|
+
line-height: $unnnic-font-size-body-gt + $unnnic-line-height-md;
|
|
115
|
+
|
|
116
|
+
$label-bottom-spacing: 3px;
|
|
86
117
|
|
|
87
118
|
&--fixed {
|
|
88
|
-
margin-top: -$unnnic-font-size-body-gt - $unnnic-
|
|
89
|
-
$
|
|
119
|
+
margin-top: -$unnnic-font-size-body-gt - $unnnic-line-height-md +
|
|
120
|
+
$label-bottom-spacing;
|
|
90
121
|
}
|
|
91
122
|
|
|
92
123
|
&--fixed {
|
|
93
|
-
margin-bottom:
|
|
124
|
+
margin-bottom: 0;
|
|
94
125
|
position: absolute;
|
|
95
|
-
padding:
|
|
96
|
-
margin-left: $unnnic-
|
|
126
|
+
padding: 0 $unnnic-spacing-nano;
|
|
127
|
+
margin-left: $unnnic-spacing-xs;
|
|
97
128
|
|
|
98
129
|
&:after {
|
|
99
130
|
content: ' ';
|
|
100
131
|
position: absolute;
|
|
101
|
-
left:
|
|
102
|
-
bottom: $
|
|
132
|
+
left: 0;
|
|
133
|
+
bottom: $label-bottom-spacing - $unnnic-border-width-thinner;
|
|
103
134
|
width: 100%;
|
|
104
135
|
height: $unnnic-border-width-thinner;
|
|
105
|
-
background-color: $unnnic-color-white;
|
|
136
|
+
background-color: $unnnic-color-neutral-white;
|
|
106
137
|
}
|
|
107
138
|
}
|
|
108
139
|
}
|
|
109
140
|
|
|
141
|
+
&__error,
|
|
110
142
|
&__message {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
143
|
+
margin: 0;
|
|
144
|
+
margin-top: $unnnic-spacing-stack-nano;
|
|
145
|
+
|
|
146
|
+
color: $unnnic-color-neutral-cloudy;
|
|
147
|
+
font-family: $unnnic-font-family-secondary;
|
|
148
|
+
font-weight: $unnnic-font-weight-regular;
|
|
149
|
+
font-size: $unnnic-font-size-body-md;
|
|
150
|
+
line-height: $unnnic-font-size-body-md + $unnnic-line-height-md;
|
|
114
151
|
}
|
|
115
152
|
|
|
116
|
-
&
|
|
153
|
+
&__message {
|
|
117
154
|
display: flex;
|
|
118
|
-
|
|
119
|
-
margin-top: $unnnic-space-1;
|
|
120
|
-
font: $unnnic-font-caption-2;
|
|
121
|
-
color: $unnnic-color-fg-base;
|
|
155
|
+
column-gap: $unnnic-spacing-nano;
|
|
122
156
|
}
|
|
123
157
|
|
|
124
|
-
&
|
|
125
|
-
|
|
126
|
-
flex-direction: column;
|
|
127
|
-
gap: $unnnic-space-1;
|
|
158
|
+
&__right-message {
|
|
159
|
+
margin-left: auto;
|
|
128
160
|
}
|
|
129
161
|
|
|
162
|
+
&__error {
|
|
163
|
+
display: flex;
|
|
164
|
+
column-gap: $unnnic-spacing-nano;
|
|
165
|
+
align-items: center;
|
|
166
|
+
|
|
167
|
+
color: $unnnic-color-aux-red-500;
|
|
168
|
+
}
|
|
130
169
|
|
|
131
170
|
&--disabled .unnnic-form-element__label,
|
|
132
171
|
&--disabled .unnnic-form-element__message {
|
|
133
172
|
user-select: none;
|
|
173
|
+
color: $unnnic-color-neutral-cleanest;
|
|
134
174
|
}
|
|
135
175
|
}
|
|
136
176
|
</style>
|
|
@@ -1,98 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
| 'background-carpet'
|
|
6
|
-
| 'background-snow'
|
|
7
|
-
| 'background-lightest'
|
|
8
|
-
| 'background-white'
|
|
9
|
-
| 'neutral-black'
|
|
10
|
-
| 'neutral-darkest'
|
|
11
|
-
| 'neutral-dark'
|
|
12
|
-
| 'neutral-cloudy'
|
|
13
|
-
| 'neutral-cleanest'
|
|
14
|
-
| 'neutral-clean'
|
|
15
|
-
| 'neutral-soft'
|
|
16
|
-
| 'neutral-lightest'
|
|
17
|
-
| 'neutral-light'
|
|
18
|
-
| 'neutral-white'
|
|
19
|
-
| 'neutral-snow'
|
|
20
|
-
| 'feedback-red'
|
|
21
|
-
| 'feedback-green'
|
|
22
|
-
| 'feedback-yellow'
|
|
23
|
-
| 'feedback-blue'
|
|
24
|
-
| 'feedback-grey'
|
|
25
|
-
| 'aux-blue'
|
|
26
|
-
| 'aux-purple'
|
|
27
|
-
| 'aux-orange'
|
|
28
|
-
| 'aux-lemon'
|
|
29
|
-
| 'aux-pink'
|
|
30
|
-
| 'aux-baby-blue'
|
|
31
|
-
| 'aux-baby-yellow'
|
|
32
|
-
| 'aux-baby-red'
|
|
33
|
-
| 'aux-baby-green'
|
|
34
|
-
| 'aux-baby-pink'
|
|
35
|
-
| 'aux-green-100'
|
|
36
|
-
| 'aux-green-300'
|
|
37
|
-
| 'aux-green-500'
|
|
38
|
-
| 'aux-green-700'
|
|
39
|
-
| 'aux-green-900'
|
|
40
|
-
| 'aux-blue-100'
|
|
41
|
-
| 'aux-blue-300'
|
|
42
|
-
| 'aux-blue-500'
|
|
43
|
-
| 'aux-blue-700'
|
|
44
|
-
| 'aux-blue-900'
|
|
45
|
-
| 'aux-purple-100'
|
|
46
|
-
| 'aux-purple-300'
|
|
47
|
-
| 'aux-purple-500'
|
|
48
|
-
| 'aux-purple-700'
|
|
49
|
-
| 'aux-purple-900'
|
|
50
|
-
| 'aux-red-100'
|
|
51
|
-
| 'aux-red-300'
|
|
52
|
-
| 'aux-red-500'
|
|
53
|
-
| 'aux-red-700'
|
|
54
|
-
| 'aux-red-900'
|
|
55
|
-
| 'aux-orange-100'
|
|
56
|
-
| 'aux-orange-300'
|
|
57
|
-
| 'aux-orange-500'
|
|
58
|
-
| 'aux-orange-700'
|
|
59
|
-
| 'aux-orange-900'
|
|
60
|
-
| 'aux-yellow-100'
|
|
61
|
-
| 'aux-yellow-300'
|
|
62
|
-
| 'aux-yellow-500'
|
|
63
|
-
| 'aux-yellow-700'
|
|
64
|
-
| 'aux-yellow-900'
|
|
65
|
-
| 'fg-base'
|
|
66
|
-
| 'fg-emphasized'
|
|
67
|
-
| 'fg-muted'
|
|
68
|
-
| 'fg-critical'
|
|
69
|
-
| 'fg-success'
|
|
70
|
-
| 'fg-warning'
|
|
71
|
-
| 'fg-info'
|
|
72
|
-
| 'floweditor-blue'
|
|
73
|
-
| 'floweditor-purple'
|
|
74
|
-
| 'floweditor-wine'
|
|
75
|
-
| 'floweditor-orange'
|
|
76
|
-
| 'floweditor-pink'
|
|
77
|
-
| 'floweditor-turquoise'
|
|
78
|
-
| 'floweditor-green'
|
|
79
|
-
| 'weni-50'
|
|
80
|
-
| 'weni-100'
|
|
81
|
-
| 'weni-200'
|
|
82
|
-
| 'weni-300'
|
|
83
|
-
| 'weni-400'
|
|
84
|
-
| 'weni-500'
|
|
85
|
-
| 'weni-600'
|
|
86
|
-
| 'weni-700'
|
|
87
|
-
| 'weni-800'
|
|
88
|
-
| 'weni-900'
|
|
89
|
-
| 'weni-950'
|
|
90
|
-
| 'brand-weni'
|
|
91
|
-
| 'brand-weni-dark'
|
|
92
|
-
| 'brand-weni-soft'
|
|
93
|
-
| 'brand-sec-dark'
|
|
94
|
-
| 'brand-sec-soft'
|
|
95
|
-
| 'brand-sec';
|
|
1
|
+
import type { SchemeColor } from "@/types/scheme-colors";
|
|
2
|
+
|
|
3
|
+
// Re-export SchemeColor for backward compatibility
|
|
4
|
+
export type { SchemeColor };
|
|
96
5
|
|
|
97
6
|
export type IconSize =
|
|
98
7
|
| 'nano'
|