@antify/ui-module 1.1.4 → 1.2.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/module.d.mts +2 -0
- package/dist/module.d.ts +2 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -0
- package/dist/runtime/components/AntAccordionItem.vue +1 -1
- package/dist/runtime/components/AntTag.vue +3 -3
- package/dist/runtime/components/AntToast.vue +1 -0
- package/dist/runtime/components/{Main.stories.mdx → Main.mdx} +3 -2
- package/dist/runtime/components/Main.stories.d.ts +7 -0
- package/dist/runtime/components/Main.stories.mjs +8 -0
- package/dist/runtime/components/__stories/AntAccordion.stories.mjs +13 -10
- package/dist/runtime/components/__stories/AntKeycap.stories.d.ts +1 -1
- package/dist/runtime/components/__stories/AntKeycap.stories.mjs +15 -12
- package/dist/runtime/components/__types/AntIcon.types.d.ts +1 -0
- package/dist/runtime/components/__types/AntIcon.types.mjs +1 -0
- package/dist/runtime/components/buttons/__stories/AntButton.stories.mjs +3 -0
- package/dist/runtime/components/form/AntCheckboxWidget/__stories/AntCheckbox.stories.mjs +3 -0
- package/dist/runtime/components/form/AntSelect.vue +4 -51
- package/dist/runtime/components/form/AntSwitch.vue +8 -3
- package/dist/runtime/components/form/AntTagInput.vue +306 -0
- package/dist/runtime/components/form/Elements/AntDropDown.vue +53 -23
- package/dist/runtime/components/form/Elements/AntField.vue +2 -2
- package/dist/runtime/components/form/Elements/__stories/AntBaseInput.stories.mjs +3 -0
- package/dist/runtime/components/form/Elements/__types/AntBaseInput.type.d.ts +1 -0
- package/dist/runtime/components/form/Elements/__types/AntBaseInput.type.mjs +1 -0
- package/dist/runtime/components/form/__stories/AntSelect.stories.mjs +3 -0
- package/dist/runtime/components/form/__stories/AntSwitch.stories.mjs +3 -0
- package/dist/runtime/components/form/__stories/AntSwitcher.stories.mjs +3 -0
- package/dist/runtime/components/form/__stories/AntTagInput.stories.d.ts +9 -0
- package/dist/runtime/components/form/__stories/AntTagInput.stories.mjs +106 -0
- package/dist/runtime/components/form/__stories/AntTextarea.stories.mjs +3 -0
- package/dist/runtime/components/form/index.d.ts +2 -1
- package/dist/runtime/components/form/index.mjs +2 -0
- package/dist/runtime/tailwind.config.d.ts +1 -0
- package/dist/runtime/tailwind.config.mjs +1 -0
- package/dist/runtime/types/AntTag.type.d.ts +1 -2
- package/dist/runtime/types/AntTag.type.mjs +1 -2
- package/package.json +20 -21
- package/src/runtime/components/AntAccordionItem.vue +2 -2
- package/src/runtime/components/AntTag.vue +3 -3
- package/src/runtime/components/AntToast.vue +1 -0
- package/src/runtime/components/form/AntSelect.vue +4 -51
- package/src/runtime/components/form/AntSwitch.vue +8 -3
- package/src/runtime/components/form/AntTagInput.vue +306 -0
- package/src/runtime/components/form/Elements/AntDropDown.vue +53 -23
- package/src/runtime/components/form/Elements/AntField.vue +2 -2
|
@@ -7,30 +7,34 @@
|
|
|
7
7
|
* TODO:: if the dropdown is open and the user types something, the element with a matching value should be focused.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { computed, nextTick, ref, watch } from 'vue';
|
|
10
|
+
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
11
11
|
import { InputColorType, Size } from '../../../enums';
|
|
12
12
|
import type { SelectOption } from '../__types';
|
|
13
13
|
import { useVModel } from '@vueuse/core';
|
|
14
14
|
import type { Validator } from '@antify/validate';
|
|
15
15
|
|
|
16
|
-
const emit = defineEmits(['update:open', 'update:modelValue']);
|
|
16
|
+
const emit = defineEmits([ 'update:open', 'update:modelValue', 'update:focused', 'selectElement' ]);
|
|
17
17
|
const props = withDefaults(defineProps<{
|
|
18
|
-
modelValue: string | number | null;
|
|
18
|
+
modelValue: string | string[] | number | number[] | null;
|
|
19
|
+
focused: string | number | null;
|
|
19
20
|
open: boolean;
|
|
20
21
|
options: SelectOption[];
|
|
21
22
|
colorType?: InputColorType;
|
|
22
23
|
validator?: Validator;
|
|
23
24
|
size?: Size;
|
|
24
|
-
inputRef?: HTMLElement | null
|
|
25
|
+
inputRef?: HTMLElement | null;
|
|
26
|
+
closeOnEnter?: boolean;
|
|
27
|
+
autoSelectFirstOnOpen?: boolean;
|
|
25
28
|
}>(), {
|
|
26
29
|
colorType: InputColorType.base,
|
|
30
|
+
focusOnOpen: true,
|
|
31
|
+
closeOnEnter: false,
|
|
32
|
+
autoSelectFirstOnOpen: true
|
|
27
33
|
});
|
|
28
34
|
|
|
29
35
|
const _modelValue = useVModel(props, 'modelValue', emit);
|
|
30
36
|
const isOpen = useVModel(props, 'open', emit);
|
|
31
|
-
|
|
32
|
-
const focusedDropDownItem = ref<string | number | null>(null);
|
|
33
|
-
const dropDownRef = ref<HTMLElement | null>(null);
|
|
37
|
+
const focusedDropDownItem = useVModel(props, 'focused', emit);
|
|
34
38
|
|
|
35
39
|
const dropdownClasses = computed(() => {
|
|
36
40
|
const variants: Record<InputColorType, string> = {
|
|
@@ -68,28 +72,45 @@ const dropDownItemClasses = computed(() => {
|
|
|
68
72
|
};
|
|
69
73
|
});
|
|
70
74
|
|
|
71
|
-
watch(isOpen, (
|
|
75
|
+
watch(isOpen, () => {
|
|
72
76
|
nextTick(() => {
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
if (props.autoSelectFirstOnOpen) {
|
|
78
|
+
focusedDropDownItem.value =
|
|
79
|
+
typeof _modelValue.value === 'string' || typeof _modelValue.value === 'number' ? _modelValue.value :
|
|
80
|
+
Array.isArray(_modelValue.value) ? _modelValue.value[0] :
|
|
81
|
+
props.options[0].value;
|
|
82
|
+
} else {
|
|
83
|
+
focusedDropDownItem.value = null;
|
|
76
84
|
}
|
|
77
85
|
});
|
|
78
86
|
});
|
|
79
87
|
|
|
88
|
+
onMounted(() => {
|
|
89
|
+
nextTick(() => {
|
|
90
|
+
props.inputRef?.addEventListener('keydown', onKeyDownDropDown);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
onUnmounted(() => {
|
|
95
|
+
props.inputRef?.removeEventListener('keydown', onKeyDownDropDown);
|
|
96
|
+
});
|
|
97
|
+
|
|
80
98
|
function onKeyDownDropDown(e: KeyboardEvent) {
|
|
81
99
|
if (e.key === 'Enter') {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
if (props.closeOnEnter) {
|
|
101
|
+
isOpen.value = false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
emit('selectElement', focusedDropDownItem.value);
|
|
85
105
|
}
|
|
86
106
|
|
|
87
107
|
if (e.key === 'Escape') {
|
|
88
108
|
isOpen.value = false;
|
|
89
|
-
props.inputRef?.focus();
|
|
90
109
|
}
|
|
91
110
|
|
|
92
111
|
if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
|
|
112
|
+
isOpen.value = true;
|
|
113
|
+
|
|
93
114
|
const index = props.options.findIndex(option => option.value === focusedDropDownItem.value);
|
|
94
115
|
const option = props.options[index + 1];
|
|
95
116
|
|
|
@@ -101,6 +122,8 @@ function onKeyDownDropDown(e: KeyboardEvent) {
|
|
|
101
122
|
}
|
|
102
123
|
|
|
103
124
|
if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
|
|
125
|
+
isOpen.value = true;
|
|
126
|
+
|
|
104
127
|
const index = props.options.findIndex(option => option.value === focusedDropDownItem.value);
|
|
105
128
|
const option = props.options[index - 1];
|
|
106
129
|
|
|
@@ -123,7 +146,7 @@ function getActiveDropDownItemClasses(option: SelectOption) {
|
|
|
123
146
|
[InputColorType.danger]: 'bg-danger-100/25',
|
|
124
147
|
};
|
|
125
148
|
|
|
126
|
-
return option.value === focusedDropDownItem.value ? {[variants[props.colorType]]: true} : {};
|
|
149
|
+
return option.value === focusedDropDownItem.value ? { [variants[props.colorType]]: true } : {};
|
|
127
150
|
}
|
|
128
151
|
|
|
129
152
|
function onClickDropDownItem(e: MouseEvent, value: string | number | null) {
|
|
@@ -131,17 +154,19 @@ function onClickDropDownItem(e: MouseEvent, value: string | number | null) {
|
|
|
131
154
|
props.inputRef?.focus();
|
|
132
155
|
|
|
133
156
|
isOpen.value = false;
|
|
157
|
+
emit('selectElement', value);
|
|
134
158
|
_modelValue.value = value;
|
|
135
159
|
}
|
|
160
|
+
|
|
161
|
+
watch(_modelValue, (val) => {
|
|
162
|
+
focusedDropDownItem.value = Array.isArray(val) ? val[0] : val;
|
|
163
|
+
});
|
|
136
164
|
</script>
|
|
137
165
|
|
|
138
166
|
<template>
|
|
139
167
|
<div
|
|
140
168
|
v-if="isOpen"
|
|
141
169
|
:class="dropdownClasses"
|
|
142
|
-
@keydown="onKeyDownDropDown"
|
|
143
|
-
ref="dropDownRef"
|
|
144
|
-
tabindex="0"
|
|
145
170
|
>
|
|
146
171
|
<div
|
|
147
172
|
v-for="(option, index) in options"
|
|
@@ -152,9 +177,14 @@ function onClickDropDownItem(e: MouseEvent, value: string | number | null) {
|
|
|
152
177
|
>
|
|
153
178
|
{{ option.label }}
|
|
154
179
|
</div>
|
|
180
|
+
|
|
181
|
+
<div
|
|
182
|
+
v-if="options.length === 0"
|
|
183
|
+
:class="{...dropDownItemClasses}"
|
|
184
|
+
>
|
|
185
|
+
<slot name="empty">
|
|
186
|
+
No options available
|
|
187
|
+
</slot>
|
|
188
|
+
</div>
|
|
155
189
|
</div>
|
|
156
190
|
</template>
|
|
157
|
-
|
|
158
|
-
<style scoped>
|
|
159
|
-
|
|
160
|
-
</style>
|
|
@@ -7,7 +7,7 @@ import {handleEnumValidation} from '../../../handler';
|
|
|
7
7
|
import AntInputLimiter from './AntInputLimiter.vue';
|
|
8
8
|
import {InputColorType} from '../../../enums';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
defineEmits(['clickLabel', 'validate']);
|
|
11
11
|
const props = withDefaults(defineProps<{
|
|
12
12
|
label?: string;
|
|
13
13
|
description?: string;
|
|
@@ -25,7 +25,7 @@ const props = withDefaults(defineProps<{
|
|
|
25
25
|
skeleton: false,
|
|
26
26
|
size: Size.md,
|
|
27
27
|
showMessageOnError: true,
|
|
28
|
-
errors: [],
|
|
28
|
+
errors: () => [],
|
|
29
29
|
expanded: true
|
|
30
30
|
});
|
|
31
31
|
|