@skyservice-developers/vue-dev-kit 1.5.11 → 1.5.12
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/vue3/style.css +1 -1
- package/dist/vue3/vue-dev-kit.cjs +1 -1
- package/dist/vue3/vue-dev-kit.js +643 -704
- package/package.json +1 -1
- package/src/vue3/components/Modal.vue +1 -1
- package/src/vue3/components/SkySelect.vue +39 -152
package/package.json
CHANGED
|
@@ -21,95 +21,34 @@
|
|
|
21
21
|
>
|
|
22
22
|
{{ selectedOption ? selectedOption.label : placeholder }}
|
|
23
23
|
</span>
|
|
24
|
-
<svg
|
|
25
|
-
|
|
26
|
-
viewBox="0 0 16 16"
|
|
27
|
-
fill="none"
|
|
28
|
-
aria-hidden="true"
|
|
29
|
-
>
|
|
30
|
-
<path
|
|
31
|
-
d="M4 6l4 4 4-4"
|
|
32
|
-
stroke="currentColor"
|
|
33
|
-
stroke-width="1.5"
|
|
34
|
-
stroke-linecap="round"
|
|
35
|
-
stroke-linejoin="round"
|
|
36
|
-
/>
|
|
24
|
+
<svg class="sky-select-chevron" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
|
25
|
+
<path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
37
26
|
</svg>
|
|
38
27
|
</button>
|
|
39
28
|
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@mouseenter="focusedIdx = idx"
|
|
57
|
-
>
|
|
58
|
-
<span>{{ option.label }}</span>
|
|
59
|
-
<svg
|
|
60
|
-
v-if="option.value === modelValue"
|
|
61
|
-
class="sky-select-check"
|
|
62
|
-
viewBox="0 0 16 16"
|
|
63
|
-
fill="none"
|
|
64
|
-
aria-hidden="true"
|
|
65
|
-
>
|
|
66
|
-
<path
|
|
67
|
-
d="M3 8l4 4 6-6"
|
|
68
|
-
stroke="currentColor"
|
|
69
|
-
stroke-width="1.5"
|
|
70
|
-
stroke-linecap="round"
|
|
71
|
-
stroke-linejoin="round"
|
|
72
|
-
/>
|
|
73
|
-
</svg>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</Teleport>
|
|
77
|
-
<div v-else class="sky-select-dropdown">
|
|
78
|
-
<div
|
|
79
|
-
v-for="(option, idx) in normalizedOptions"
|
|
80
|
-
:key="option.value"
|
|
81
|
-
class="sky-select-option"
|
|
82
|
-
:class="{
|
|
83
|
-
'sky-select-option-selected': option.value === modelValue,
|
|
84
|
-
'sky-select-option-focused': idx === focusedIdx,
|
|
85
|
-
}"
|
|
86
|
-
@click="select(option)"
|
|
87
|
-
@mouseenter="focusedIdx = idx"
|
|
88
|
-
>
|
|
89
|
-
<span>{{ option.label }}</span>
|
|
90
|
-
<svg
|
|
91
|
-
v-if="option.value === modelValue"
|
|
92
|
-
class="sky-select-check"
|
|
93
|
-
viewBox="0 0 16 16"
|
|
94
|
-
fill="none"
|
|
95
|
-
aria-hidden="true"
|
|
96
|
-
>
|
|
97
|
-
<path
|
|
98
|
-
d="M3 8l4 4 6-6"
|
|
99
|
-
stroke="currentColor"
|
|
100
|
-
stroke-width="1.5"
|
|
101
|
-
stroke-linecap="round"
|
|
102
|
-
stroke-linejoin="round"
|
|
103
|
-
/>
|
|
104
|
-
</svg>
|
|
105
|
-
</div>
|
|
29
|
+
<div v-if="open" class="sky-select-dropdown">
|
|
30
|
+
<div
|
|
31
|
+
v-for="(option, idx) in normalizedOptions"
|
|
32
|
+
:key="option.value"
|
|
33
|
+
class="sky-select-option"
|
|
34
|
+
:class="{
|
|
35
|
+
'sky-select-option-selected': option.value === modelValue,
|
|
36
|
+
'sky-select-option-focused': idx === focusedIdx,
|
|
37
|
+
}"
|
|
38
|
+
@click="select(option)"
|
|
39
|
+
@mouseenter="focusedIdx = idx"
|
|
40
|
+
>
|
|
41
|
+
<span>{{ option.label }}</span>
|
|
42
|
+
<svg v-if="option.value === modelValue" class="sky-select-check" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
|
43
|
+
<path d="M3 8l4 4 6-6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
44
|
+
</svg>
|
|
106
45
|
</div>
|
|
107
|
-
</
|
|
46
|
+
</div>
|
|
108
47
|
</div>
|
|
109
48
|
</template>
|
|
110
49
|
|
|
111
50
|
<script setup>
|
|
112
|
-
import { ref, computed, onBeforeUnmount } from
|
|
51
|
+
import { ref, computed, onBeforeUnmount } from 'vue';
|
|
113
52
|
|
|
114
53
|
const props = defineProps({
|
|
115
54
|
modelValue: {
|
|
@@ -121,7 +60,7 @@ const props = defineProps({
|
|
|
121
60
|
},
|
|
122
61
|
placeholder: {
|
|
123
62
|
type: String,
|
|
124
|
-
default:
|
|
63
|
+
default: '',
|
|
125
64
|
},
|
|
126
65
|
disabled: {
|
|
127
66
|
type: Boolean,
|
|
@@ -131,41 +70,24 @@ const props = defineProps({
|
|
|
131
70
|
type: Boolean,
|
|
132
71
|
default: false,
|
|
133
72
|
},
|
|
134
|
-
teleport: {
|
|
135
|
-
type: Boolean,
|
|
136
|
-
default: false,
|
|
137
|
-
},
|
|
138
73
|
});
|
|
139
74
|
|
|
140
|
-
const emit = defineEmits([
|
|
75
|
+
const emit = defineEmits(['update:modelValue']);
|
|
141
76
|
|
|
142
77
|
const root = ref(null);
|
|
143
|
-
const dropdownEl = ref(null);
|
|
144
78
|
const open = ref(false);
|
|
145
79
|
const focusedIdx = ref(-1);
|
|
146
|
-
const dropdownStyle = ref({});
|
|
147
80
|
|
|
148
81
|
const normalizedOptions = computed(() =>
|
|
149
82
|
props.options.map((opt) =>
|
|
150
|
-
typeof opt ===
|
|
151
|
-
)
|
|
83
|
+
typeof opt === 'string' ? { label: opt, value: opt } : opt
|
|
84
|
+
)
|
|
152
85
|
);
|
|
153
86
|
|
|
154
|
-
const selectedOption = computed(
|
|
155
|
-
() =>
|
|
156
|
-
normalizedOptions.value.find((o) => o.value === props.modelValue) ?? null,
|
|
87
|
+
const selectedOption = computed(() =>
|
|
88
|
+
normalizedOptions.value.find((o) => o.value === props.modelValue) ?? null
|
|
157
89
|
);
|
|
158
90
|
|
|
159
|
-
function calcDropdownStyle() {
|
|
160
|
-
if (!props.teleport || !root.value) return;
|
|
161
|
-
const rect = root.value.getBoundingClientRect();
|
|
162
|
-
dropdownStyle.value = {
|
|
163
|
-
top: `${rect.bottom + 4}px`,
|
|
164
|
-
left: `${rect.left}px`,
|
|
165
|
-
width: `${rect.width}px`,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
91
|
function toggle() {
|
|
170
92
|
if (props.disabled) return;
|
|
171
93
|
open.value ? close() : openDropdown();
|
|
@@ -173,86 +95,51 @@ function toggle() {
|
|
|
173
95
|
|
|
174
96
|
function openDropdown() {
|
|
175
97
|
open.value = true;
|
|
176
|
-
focusedIdx.value = normalizedOptions.value.findIndex(
|
|
177
|
-
|
|
178
|
-
);
|
|
179
|
-
calcDropdownStyle();
|
|
180
|
-
document.addEventListener("mousedown", onOutsideClick);
|
|
181
|
-
if (props.teleport) {
|
|
182
|
-
window.addEventListener("scroll", onScrollOrResize, true);
|
|
183
|
-
window.addEventListener("resize", onScrollOrResize);
|
|
184
|
-
}
|
|
98
|
+
focusedIdx.value = normalizedOptions.value.findIndex((o) => o.value === props.modelValue);
|
|
99
|
+
document.addEventListener('mousedown', onOutsideClick);
|
|
185
100
|
}
|
|
186
101
|
|
|
187
102
|
function close() {
|
|
188
103
|
open.value = false;
|
|
189
|
-
document.removeEventListener(
|
|
190
|
-
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
191
|
-
window.removeEventListener("resize", onScrollOrResize);
|
|
104
|
+
document.removeEventListener('mousedown', onOutsideClick);
|
|
192
105
|
}
|
|
193
106
|
|
|
194
107
|
function select(option) {
|
|
195
|
-
emit(
|
|
108
|
+
emit('update:modelValue', option.value);
|
|
196
109
|
close();
|
|
197
110
|
}
|
|
198
111
|
|
|
199
112
|
function onOutsideClick(e) {
|
|
200
|
-
if (root.value?.contains(e.target))
|
|
201
|
-
if (dropdownEl.value?.contains(e.target)) return;
|
|
202
|
-
close();
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function onScrollOrResize() {
|
|
206
|
-
calcDropdownStyle();
|
|
113
|
+
if (!root.value?.contains(e.target)) close();
|
|
207
114
|
}
|
|
208
115
|
|
|
209
116
|
function onKeydown(e) {
|
|
210
117
|
if (!open.value) {
|
|
211
|
-
if (e.key ===
|
|
118
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
212
119
|
e.preventDefault();
|
|
213
120
|
openDropdown();
|
|
214
121
|
}
|
|
215
122
|
return;
|
|
216
123
|
}
|
|
217
|
-
if (e.key ===
|
|
124
|
+
if (e.key === 'Escape') {
|
|
218
125
|
close();
|
|
219
|
-
} else if (e.key ===
|
|
126
|
+
} else if (e.key === 'ArrowDown') {
|
|
220
127
|
e.preventDefault();
|
|
221
|
-
focusedIdx.value = Math.min(
|
|
222
|
-
|
|
223
|
-
normalizedOptions.value.length - 1,
|
|
224
|
-
);
|
|
225
|
-
} else if (e.key === "ArrowUp") {
|
|
128
|
+
focusedIdx.value = Math.min(focusedIdx.value + 1, normalizedOptions.value.length - 1);
|
|
129
|
+
} else if (e.key === 'ArrowUp') {
|
|
226
130
|
e.preventDefault();
|
|
227
131
|
focusedIdx.value = Math.max(focusedIdx.value - 1, 0);
|
|
228
|
-
} else if (e.key ===
|
|
132
|
+
} else if (e.key === 'Enter') {
|
|
229
133
|
e.preventDefault();
|
|
230
|
-
if (focusedIdx.value >= 0)
|
|
231
|
-
select(normalizedOptions.value[focusedIdx.value]);
|
|
134
|
+
if (focusedIdx.value >= 0) select(normalizedOptions.value[focusedIdx.value]);
|
|
232
135
|
}
|
|
233
136
|
}
|
|
234
137
|
|
|
235
138
|
onBeforeUnmount(() => {
|
|
236
|
-
document.removeEventListener(
|
|
237
|
-
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
238
|
-
window.removeEventListener("resize", onScrollOrResize);
|
|
139
|
+
document.removeEventListener('mousedown', onOutsideClick);
|
|
239
140
|
});
|
|
240
141
|
</script>
|
|
241
142
|
|
|
242
|
-
<style>
|
|
243
|
-
.sky-select-dropdown-teleported {
|
|
244
|
-
position: fixed;
|
|
245
|
-
z-index: var(--sky-select-dropdown-z-index, 9999);
|
|
246
|
-
background: var(--sky-select-dropdown-bg, #fff);
|
|
247
|
-
border: var(--sky-select-dropdown-border, 1px solid #d1d5db);
|
|
248
|
-
border-radius: var(--sky-select-dropdown-radius, 6px);
|
|
249
|
-
box-shadow: var(--sky-select-dropdown-shadow, 0 4px 12px rgba(0, 0, 0, 0.1));
|
|
250
|
-
max-height: var(--sky-select-dropdown-max-height, 220px);
|
|
251
|
-
overflow-y: auto;
|
|
252
|
-
padding: 4px;
|
|
253
|
-
}
|
|
254
|
-
</style>
|
|
255
|
-
|
|
256
143
|
<style scoped>
|
|
257
144
|
.sky-select {
|
|
258
145
|
position: relative;
|