@volverjs/ui-vue 0.0.10-beta.53 → 0.0.10-beta.55
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/components/VvCheckboxGroup/VvCheckboxGroup.es.js +13 -1
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +9 -0
- package/dist/components/VvCheckboxGroup/index.d.ts +4 -0
- package/dist/components/VvCombobox/VvCombobox.es.js +357 -357
- package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
- package/dist/components/VvInputFile/VvInputFile.es.js +17 -3
- package/dist/components/VvInputFile/VvInputFile.umd.js +1 -1
- package/dist/components/VvInputFile/VvInputFile.vue.d.ts +9 -0
- package/dist/components/VvInputFile/index.d.ts +4 -0
- package/dist/components/VvInputText/VvInputText.es.js +18 -20
- package/dist/components/VvInputText/VvInputText.umd.js +1 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.es.js +13 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +9 -0
- package/dist/components/VvRadioGroup/index.d.ts +4 -0
- package/dist/components/VvTextarea/VvTextarea.es.js +1296 -397
- package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
- package/dist/components/VvTextarea/VvTextarea.vue.d.ts +52 -0
- package/dist/components/VvTextarea/index.d.ts +37 -1
- package/dist/components/index.es.js +421 -261
- package/dist/components/index.umd.js +1 -1
- package/dist/icons.es.js +3 -3
- package/dist/icons.umd.js +1 -1
- package/dist/props/index.d.ts +8 -1
- package/dist/stories/InputText/InputText.stories.d.ts +2 -0
- package/dist/stories/InputText/InputText.test.d.ts +2 -0
- package/package.json +23 -23
- package/src/assets/icons/detailed.json +1 -1
- package/src/assets/icons/normal.json +1 -1
- package/src/assets/icons/simple.json +1 -1
- package/src/components/VvCheckbox/VvCheckbox.vue +2 -2
- package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +2 -0
- package/src/components/VvCombobox/VvCombobox.vue +3 -3
- package/src/components/VvInputFile/VvInputFile.vue +12 -8
- package/src/components/VvInputFile/index.ts +2 -0
- package/src/components/VvInputText/VvInputText.vue +20 -22
- package/src/components/VvRadio/VvRadio.vue +2 -2
- package/src/components/VvRadioGroup/VvRadioGroup.vue +2 -0
- package/src/components/VvTextarea/VvTextarea.vue +109 -6
- package/src/components/VvTextarea/index.ts +32 -1
- package/src/props/index.ts +2 -1
- package/src/stories/InputText/InputText.stories.ts +37 -1
- package/src/stories/InputText/InputText.test.ts +18 -0
- package/src/stories/Textarea/Textarea.stories.ts +1 -1
|
@@ -1,134 +1,8 @@
|
|
|
1
|
-
import { unref, computed, isRef, defineComponent, h,
|
|
1
|
+
import { unref, computed, isRef, defineComponent, h, useId, provide, Fragment, ref, toRefs, useAttrs, onMounted, watch, nextTick, openBlock, createElementBlock, createVNode, withCtx, renderSlot, normalizeProps, guardReactiveProps, Transition, mergeProps, toHandlers, withDirectives, createElementVNode, normalizeStyle, normalizeClass, createCommentVNode, vShow, inject, createBlock, createTextVNode, toDisplayString, mergeDefaults, useSlots, vModelText, createSlots, renderList, withModifiers } from "vue";
|
|
2
|
+
import { autoPlacement, flip, shift, size, offset, arrow, useFloating, autoUpdate } from "@floating-ui/vue";
|
|
3
|
+
import { useMutationObserver, useVModel, onClickOutside, useFocusWithin, useElementHover, onKeyStroke, useFocus, useStorage, useElementVisibility } from "@vueuse/core";
|
|
4
|
+
import mitt from "mitt";
|
|
2
5
|
import { iconExists, Icon, addIcon } from "@iconify/vue";
|
|
3
|
-
import { useFocus, useElementVisibility } from "@vueuse/core";
|
|
4
|
-
function isEmpty(value) {
|
|
5
|
-
return ((value2) => value2 === null || value2 === void 0 || value2 === "" || Array.isArray(value2) && value2.length === 0 || !(value2 instanceof Date) && typeof value2 === "object" && Object.keys(value2).length === 0)(unref(value));
|
|
6
|
-
}
|
|
7
|
-
function isString(value) {
|
|
8
|
-
return typeof value === "string" || value instanceof String;
|
|
9
|
-
}
|
|
10
|
-
function joinLines(items) {
|
|
11
|
-
if (Array.isArray(items)) {
|
|
12
|
-
return items.filter((item) => isString(item)).join(" ");
|
|
13
|
-
}
|
|
14
|
-
return items;
|
|
15
|
-
}
|
|
16
|
-
function HintSlotFactory(propsOrRef, slots) {
|
|
17
|
-
const props = computed(() => {
|
|
18
|
-
if (isRef(propsOrRef)) {
|
|
19
|
-
return propsOrRef.value;
|
|
20
|
-
}
|
|
21
|
-
return propsOrRef;
|
|
22
|
-
});
|
|
23
|
-
const invalidLabel = computed(() => joinLines(props.value.invalidLabel));
|
|
24
|
-
const validLabel = computed(() => joinLines(props.value.validLabel));
|
|
25
|
-
const loadingLabel = computed(() => props.value.loadingLabel);
|
|
26
|
-
const hintLabel = computed(() => props.value.hintLabel);
|
|
27
|
-
const hasLoadingLabelOrSlot = computed(
|
|
28
|
-
() => Boolean(props.value.loading && (slots.loading || loadingLabel.value))
|
|
29
|
-
);
|
|
30
|
-
const hasInvalidLabelOrSlot = computed(
|
|
31
|
-
() => !hasLoadingLabelOrSlot.value && Boolean(
|
|
32
|
-
props.value.invalid && (slots.invalid || invalidLabel.value)
|
|
33
|
-
)
|
|
34
|
-
);
|
|
35
|
-
const hasValidLabelOrSlot = computed(
|
|
36
|
-
() => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && Boolean(props.value.valid && (slots.valid || validLabel.value))
|
|
37
|
-
);
|
|
38
|
-
const hasHintLabelOrSlot = computed(
|
|
39
|
-
() => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && !hasValidLabelOrSlot.value && Boolean(slots.hint || hintLabel.value)
|
|
40
|
-
);
|
|
41
|
-
const isVisible = computed(
|
|
42
|
-
() => hasInvalidLabelOrSlot.value || hasValidLabelOrSlot.value || hasLoadingLabelOrSlot.value || hasHintLabelOrSlot.value
|
|
43
|
-
);
|
|
44
|
-
const hintSlotScope = computed(() => ({
|
|
45
|
-
modelValue: props.value.modelValue,
|
|
46
|
-
valid: props.value.valid,
|
|
47
|
-
invalid: props.value.invalid,
|
|
48
|
-
loading: props.value.loading
|
|
49
|
-
}));
|
|
50
|
-
const HintSlot = defineComponent({
|
|
51
|
-
name: "HintSlot",
|
|
52
|
-
props: {
|
|
53
|
-
tag: {
|
|
54
|
-
type: String,
|
|
55
|
-
default: "small"
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
setup() {
|
|
59
|
-
return {
|
|
60
|
-
isVisible,
|
|
61
|
-
invalidLabel,
|
|
62
|
-
validLabel,
|
|
63
|
-
loadingLabel,
|
|
64
|
-
hintLabel,
|
|
65
|
-
hasInvalidLabelOrSlot,
|
|
66
|
-
hasValidLabelOrSlot,
|
|
67
|
-
hasLoadingLabelOrSlot,
|
|
68
|
-
hasHintLabelOrSlot
|
|
69
|
-
};
|
|
70
|
-
},
|
|
71
|
-
render() {
|
|
72
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
73
|
-
if (this.isVisible) {
|
|
74
|
-
let role;
|
|
75
|
-
if (this.hasInvalidLabelOrSlot) {
|
|
76
|
-
role = "alert";
|
|
77
|
-
}
|
|
78
|
-
if (this.hasValidLabelOrSlot) {
|
|
79
|
-
role = "status";
|
|
80
|
-
}
|
|
81
|
-
if (this.hasLoadingLabelOrSlot) {
|
|
82
|
-
return h(
|
|
83
|
-
this.tag,
|
|
84
|
-
{
|
|
85
|
-
role
|
|
86
|
-
},
|
|
87
|
-
((_b = (_a = this.$slots).loading) == null ? void 0 : _b.call(_a)) ?? this.loadingLabel
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
if (this.hasInvalidLabelOrSlot) {
|
|
91
|
-
return h(
|
|
92
|
-
this.tag,
|
|
93
|
-
{
|
|
94
|
-
role
|
|
95
|
-
},
|
|
96
|
-
((_d = (_c = this.$slots).invalid) == null ? void 0 : _d.call(_c)) ?? this.$slots.invalid ?? this.invalidLabel
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
if (this.hasValidLabelOrSlot) {
|
|
100
|
-
return h(
|
|
101
|
-
this.tag,
|
|
102
|
-
{
|
|
103
|
-
role
|
|
104
|
-
},
|
|
105
|
-
((_f = (_e = this.$slots).valid) == null ? void 0 : _f.call(_e)) ?? this.validLabel
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
return h(
|
|
109
|
-
this.tag,
|
|
110
|
-
{
|
|
111
|
-
role
|
|
112
|
-
},
|
|
113
|
-
((_h = (_g = this.$slots).hint) == null ? void 0 : _h.call(_g)) ?? this.$slots.hint ?? this.hintLabel
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
return {
|
|
120
|
-
hasInvalidLabelOrSlot,
|
|
121
|
-
hasHintLabelOrSlot,
|
|
122
|
-
hasValidLabelOrSlot,
|
|
123
|
-
hasLoadingLabelOrSlot,
|
|
124
|
-
hintSlotScope,
|
|
125
|
-
HintSlot
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
const VvIconPropsDefaults = {
|
|
129
|
-
prefix: "normal"
|
|
130
|
-
/* normal */
|
|
131
|
-
};
|
|
132
6
|
var StorageType = /* @__PURE__ */ ((StorageType2) => {
|
|
133
7
|
StorageType2["local"] = "local";
|
|
134
8
|
StorageType2["session"] = "session";
|
|
@@ -175,169 +49,55 @@ var ActionTag = /* @__PURE__ */ ((ActionTag2) => {
|
|
|
175
49
|
ActionTag2["button"] = "button";
|
|
176
50
|
return ActionTag2;
|
|
177
51
|
})(ActionTag || {});
|
|
52
|
+
var ActionRoles = /* @__PURE__ */ ((ActionRoles2) => {
|
|
53
|
+
ActionRoles2["button"] = "button";
|
|
54
|
+
ActionRoles2["link"] = "link";
|
|
55
|
+
ActionRoles2["menuitem"] = "menuitem";
|
|
56
|
+
return ActionRoles2;
|
|
57
|
+
})(ActionRoles || {});
|
|
58
|
+
var DropdownRole = /* @__PURE__ */ ((DropdownRole2) => {
|
|
59
|
+
DropdownRole2["listbox"] = "listbox";
|
|
60
|
+
DropdownRole2["menu"] = "menu";
|
|
61
|
+
return DropdownRole2;
|
|
62
|
+
})(DropdownRole || {});
|
|
63
|
+
var DropdownItemRole = /* @__PURE__ */ ((DropdownItemRole2) => {
|
|
64
|
+
DropdownItemRole2["option"] = "option";
|
|
65
|
+
DropdownItemRole2["presentation"] = "presentation";
|
|
66
|
+
return DropdownItemRole2;
|
|
67
|
+
})(DropdownItemRole || {});
|
|
178
68
|
const INJECTION_KEY_VOLVER = Symbol.for("volver");
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
name: {},
|
|
212
|
-
color: {},
|
|
213
|
-
width: {},
|
|
214
|
-
height: {},
|
|
215
|
-
provider: {},
|
|
216
|
-
prefix: {},
|
|
217
|
-
src: {},
|
|
218
|
-
horizontalFlip: { type: Boolean },
|
|
219
|
-
verticalFlip: { type: Boolean },
|
|
220
|
-
flip: {},
|
|
221
|
-
mode: {},
|
|
222
|
-
inline: { type: Boolean },
|
|
223
|
-
rotate: {},
|
|
224
|
-
onLoad: { type: Function },
|
|
225
|
-
svg: {},
|
|
226
|
-
modifiers: {}
|
|
227
|
-
}, VvIconPropsDefaults),
|
|
228
|
-
setup(__props) {
|
|
229
|
-
const props = __props;
|
|
230
|
-
const hasRotate = computed(() => {
|
|
231
|
-
if (typeof props.rotate === "string") {
|
|
232
|
-
return Number.parseFloat(props.rotate);
|
|
233
|
-
}
|
|
234
|
-
return props.rotate;
|
|
235
|
-
});
|
|
236
|
-
const show = ref(true);
|
|
237
|
-
const volver = useVolver();
|
|
238
|
-
const { modifiers } = toRefs(props);
|
|
239
|
-
const bemCssClasses = useModifiers("vv-icon", modifiers);
|
|
240
|
-
const provider = computed(() => {
|
|
241
|
-
return props.provider || (volver == null ? void 0 : volver.iconsProvider);
|
|
242
|
-
});
|
|
243
|
-
const icon = computed(() => {
|
|
244
|
-
const name = props.name ?? "";
|
|
245
|
-
const iconName = `@${provider.value}:${props.prefix}:${name}`;
|
|
246
|
-
if (iconExists(iconName)) {
|
|
247
|
-
return iconName;
|
|
248
|
-
}
|
|
249
|
-
const iconsCollection = volver == null ? void 0 : volver.iconsCollections.find(
|
|
250
|
-
(iconsCollection2) => {
|
|
251
|
-
const icon2 = `@${provider.value}:${iconsCollection2.prefix}:${name}`;
|
|
252
|
-
return iconExists(icon2);
|
|
253
|
-
}
|
|
254
|
-
);
|
|
255
|
-
if (iconsCollection) {
|
|
256
|
-
return `@${provider.value}:${iconsCollection.prefix}:${name}`;
|
|
257
|
-
}
|
|
258
|
-
return name;
|
|
259
|
-
});
|
|
260
|
-
function getSvgContent(svg) {
|
|
261
|
-
let dom;
|
|
262
|
-
if (typeof window === "undefined") {
|
|
263
|
-
const { JSDOM } = require("jsdom");
|
|
264
|
-
dom = new JSDOM().window;
|
|
265
|
-
}
|
|
266
|
-
const domParser = dom ? new dom.DOMParser() : new window.DOMParser();
|
|
267
|
-
const svgDomString = domParser.parseFromString(svg, "text/html");
|
|
268
|
-
const svgEl = svgDomString.querySelector("svg");
|
|
269
|
-
return svgEl;
|
|
270
|
-
}
|
|
271
|
-
function addIconFromSvg(svg) {
|
|
272
|
-
const svgContentEl = getSvgContent(svg);
|
|
273
|
-
const svgContent = (svgContentEl == null ? void 0 : svgContentEl.innerHTML.trim()) || "";
|
|
274
|
-
if (svgContentEl && svgContent) {
|
|
275
|
-
addIcon(`@${provider.value}:${props.prefix}:${props.name}`, {
|
|
276
|
-
body: svgContent,
|
|
277
|
-
// Set height and width from svg content
|
|
278
|
-
height: svgContentEl.viewBox.baseVal.height,
|
|
279
|
-
width: svgContentEl.viewBox.baseVal.width
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (volver) {
|
|
284
|
-
if (props.src && !iconExists(`@${provider.value}:${props.prefix}:${props.name}`)) {
|
|
285
|
-
show.value = false;
|
|
286
|
-
volver.fetchIcon(props.src).then((svg) => {
|
|
287
|
-
if (svg) {
|
|
288
|
-
addIconFromSvg(svg);
|
|
289
|
-
show.value = true;
|
|
290
|
-
}
|
|
291
|
-
}).catch((e) => {
|
|
292
|
-
throw new Error(`Error during fetch icon: ${e == null ? void 0 : e.message}`);
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
if (props.svg) {
|
|
297
|
-
addIconFromSvg(props.svg);
|
|
298
|
-
}
|
|
299
|
-
return (_ctx, _cache) => {
|
|
300
|
-
return unref(show) ? (openBlock(), createBlock(unref(Icon), mergeProps({
|
|
301
|
-
key: 0,
|
|
302
|
-
class: unref(bemCssClasses)
|
|
303
|
-
}, {
|
|
304
|
-
inline: _ctx.inline,
|
|
305
|
-
width: _ctx.width,
|
|
306
|
-
height: _ctx.height,
|
|
307
|
-
horizontalFlip: _ctx.horizontalFlip,
|
|
308
|
-
verticalFlip: _ctx.verticalFlip,
|
|
309
|
-
flip: _ctx.flip,
|
|
310
|
-
rotate: unref(hasRotate),
|
|
311
|
-
color: _ctx.color,
|
|
312
|
-
onLoad: _ctx.onLoad,
|
|
313
|
-
icon: unref(icon)
|
|
314
|
-
}), null, 16, ["class"])) : createCommentVNode("v-if", true);
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
const LinkProps = {
|
|
319
|
-
/**
|
|
320
|
-
* The router-link/nuxt-link property, if it is defined the button is rendered as a ruouter-link or nuxt-link.
|
|
321
|
-
* @see Documentation of [router-link](https://router.vuejs.org/api/#router-link) and [nuxt-link](https://nuxtjs.org/api/components-nuxt-link/)
|
|
322
|
-
*/
|
|
323
|
-
to: {
|
|
324
|
-
type: [String, Object]
|
|
325
|
-
},
|
|
326
|
-
/**
|
|
327
|
-
* Anchor href
|
|
328
|
-
*/
|
|
329
|
-
href: String,
|
|
330
|
-
/**
|
|
331
|
-
* Anchor target
|
|
332
|
-
*/
|
|
333
|
-
target: String,
|
|
334
|
-
/**
|
|
335
|
-
* Anchor rel
|
|
336
|
-
*/
|
|
337
|
-
rel: {
|
|
338
|
-
type: String,
|
|
339
|
-
default: "noopener noreferrer"
|
|
340
|
-
}
|
|
69
|
+
const INJECTION_KEY_DROPDOWN_TRIGGER = Symbol.for(
|
|
70
|
+
"dropdownTrigger"
|
|
71
|
+
);
|
|
72
|
+
const INJECTION_KEY_DROPDOWN_ITEM = Symbol.for(
|
|
73
|
+
"dropdownItem"
|
|
74
|
+
);
|
|
75
|
+
const INJECTION_KEY_DROPDOWN_ACTION = Symbol.for(
|
|
76
|
+
"dropdownAction"
|
|
77
|
+
);
|
|
78
|
+
const LinkProps = {
|
|
79
|
+
/**
|
|
80
|
+
* The router-link/nuxt-link property, if it is defined the button is rendered as a ruouter-link or nuxt-link.
|
|
81
|
+
* @see Documentation of [router-link](https://router.vuejs.org/api/#router-link) and [nuxt-link](https://nuxtjs.org/api/components-nuxt-link/)
|
|
82
|
+
*/
|
|
83
|
+
to: {
|
|
84
|
+
type: [String, Object]
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Anchor href
|
|
88
|
+
*/
|
|
89
|
+
href: String,
|
|
90
|
+
/**
|
|
91
|
+
* Anchor target
|
|
92
|
+
*/
|
|
93
|
+
target: String,
|
|
94
|
+
/**
|
|
95
|
+
* Anchor rel
|
|
96
|
+
*/
|
|
97
|
+
rel: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: "noopener noreferrer"
|
|
100
|
+
}
|
|
341
101
|
};
|
|
342
102
|
const ValidProps = {
|
|
343
103
|
/**
|
|
@@ -396,6 +156,15 @@ const RequiredProps = {
|
|
|
396
156
|
default: false
|
|
397
157
|
}
|
|
398
158
|
};
|
|
159
|
+
const SelectedProps = {
|
|
160
|
+
/**
|
|
161
|
+
* Whether the item is selected
|
|
162
|
+
*/
|
|
163
|
+
selected: {
|
|
164
|
+
type: Boolean,
|
|
165
|
+
default: false
|
|
166
|
+
}
|
|
167
|
+
};
|
|
399
168
|
const ActiveProps = {
|
|
400
169
|
/**
|
|
401
170
|
* Whether the item is active
|
|
@@ -506,6 +275,12 @@ const FloatingLabelProps = {
|
|
|
506
275
|
default: false
|
|
507
276
|
}
|
|
508
277
|
};
|
|
278
|
+
const UnselectableProps = {
|
|
279
|
+
/**
|
|
280
|
+
* If true the input will be unselectable
|
|
281
|
+
*/
|
|
282
|
+
unselectable: { type: Boolean, default: true }
|
|
283
|
+
};
|
|
509
284
|
const IdProps = {
|
|
510
285
|
/**
|
|
511
286
|
* Global attribute id
|
|
@@ -513,7 +288,7 @@ const IdProps = {
|
|
|
513
288
|
*/
|
|
514
289
|
id: [String, Number]
|
|
515
290
|
};
|
|
516
|
-
|
|
291
|
+
const DropdownProps = {
|
|
517
292
|
/**
|
|
518
293
|
* Dropdown placement
|
|
519
294
|
*/
|
|
@@ -606,7 +381,7 @@ const IdProps = {
|
|
|
606
381
|
type: Boolean,
|
|
607
382
|
default: false
|
|
608
383
|
}
|
|
609
|
-
}
|
|
384
|
+
};
|
|
610
385
|
const IdNameProps = {
|
|
611
386
|
...IdProps,
|
|
612
387
|
/**
|
|
@@ -712,56 +487,1001 @@ const InputTextareaProps = {
|
|
|
712
487
|
default: ActionTag.button
|
|
713
488
|
}
|
|
714
489
|
});
|
|
715
|
-
|
|
716
|
-
storageType: {
|
|
717
|
-
type: String,
|
|
718
|
-
default: StorageType.local,
|
|
719
|
-
validator: (value) => Object.values(StorageType).includes(value)
|
|
720
|
-
},
|
|
721
|
-
storageKey: String
|
|
722
|
-
}
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
490
|
+
const StorageProps = {
|
|
491
|
+
storageType: {
|
|
492
|
+
type: String,
|
|
493
|
+
default: StorageType.local,
|
|
494
|
+
validator: (value) => Object.values(StorageType).includes(value)
|
|
495
|
+
},
|
|
496
|
+
storageKey: String
|
|
497
|
+
};
|
|
498
|
+
const ACTION_ICONS = {
|
|
499
|
+
showPassword: "eye-on",
|
|
500
|
+
hidePassword: "eye-off",
|
|
501
|
+
showDatePicker: "calendar",
|
|
502
|
+
showTimePicker: "time",
|
|
503
|
+
showColorPicker: "color",
|
|
504
|
+
clear: "close",
|
|
505
|
+
add: "add",
|
|
506
|
+
remove: "trash",
|
|
507
|
+
edit: "edit",
|
|
508
|
+
download: "download"
|
|
509
|
+
};
|
|
510
|
+
const VvIconPropsDefaults = {
|
|
511
|
+
prefix: "normal"
|
|
512
|
+
/* normal */
|
|
513
|
+
};
|
|
514
|
+
const WRAP = {
|
|
515
|
+
hard: "hard",
|
|
516
|
+
soft: "soft"
|
|
517
|
+
};
|
|
518
|
+
const SPELLCHECK = {
|
|
519
|
+
true: true,
|
|
520
|
+
false: false,
|
|
521
|
+
default: "default"
|
|
522
|
+
};
|
|
523
|
+
const VvTextareaEvents = ["update:modelValue", "focus", "blur", "keyup"];
|
|
524
|
+
const VvTextareaProps = {
|
|
525
|
+
...InputTextareaProps,
|
|
526
|
+
...StorageProps,
|
|
527
|
+
/**
|
|
528
|
+
* Textarea value
|
|
529
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#value
|
|
530
|
+
*/
|
|
531
|
+
modelValue: String,
|
|
532
|
+
/**
|
|
533
|
+
* The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20.
|
|
534
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#cols
|
|
535
|
+
*/
|
|
536
|
+
cols: { type: [String, Number], default: 20 },
|
|
537
|
+
/**
|
|
538
|
+
* The number of visible text lines for the control. If it is specified, it must be a positive integer. If it is not specified, the default value is 2.
|
|
539
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#rows
|
|
540
|
+
*/
|
|
541
|
+
rows: { type: [String, Number], default: 2 },
|
|
542
|
+
/**
|
|
543
|
+
* Indicates how the control should wrap the value for form submission.
|
|
544
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
|
|
545
|
+
*/
|
|
546
|
+
wrap: { type: String, default: WRAP.soft },
|
|
547
|
+
/**
|
|
548
|
+
* Specifies whether the <textarea> is subject to spell checking by the underlying browser/OS.
|
|
549
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#wrap
|
|
550
|
+
*/
|
|
551
|
+
spellcheck: { type: [Boolean, String], default: SPELLCHECK.default },
|
|
552
|
+
/**
|
|
553
|
+
* VvIcon name for remove suggestion button
|
|
554
|
+
* @see VVIcon
|
|
555
|
+
*/
|
|
556
|
+
iconRemoveSuggestion: {
|
|
557
|
+
type: [String, Object],
|
|
558
|
+
default: ACTION_ICONS.remove
|
|
559
|
+
},
|
|
560
|
+
/**
|
|
561
|
+
* Label for remove suggestion button
|
|
562
|
+
*/
|
|
563
|
+
labelRemoveSuggestion: {
|
|
564
|
+
type: String,
|
|
565
|
+
default: "Remove suggestion"
|
|
566
|
+
},
|
|
567
|
+
/**
|
|
568
|
+
* Maximum number of suggestions
|
|
569
|
+
*/
|
|
570
|
+
maxSuggestions: {
|
|
571
|
+
type: Number,
|
|
572
|
+
default: 5
|
|
573
|
+
},
|
|
574
|
+
/**
|
|
575
|
+
* Select input text on focus
|
|
576
|
+
*/
|
|
577
|
+
selectOnFocus: {
|
|
578
|
+
type: Boolean,
|
|
579
|
+
default: false
|
|
580
|
+
},
|
|
581
|
+
/**
|
|
582
|
+
* If true, the textarea will be resizable
|
|
583
|
+
*/
|
|
584
|
+
resizable: Boolean
|
|
585
|
+
};
|
|
586
|
+
function isEmpty(value) {
|
|
587
|
+
return ((value2) => value2 === null || value2 === void 0 || value2 === "" || Array.isArray(value2) && value2.length === 0 || !(value2 instanceof Date) && typeof value2 === "object" && Object.keys(value2).length === 0)(unref(value));
|
|
588
|
+
}
|
|
589
|
+
function isString(value) {
|
|
590
|
+
return typeof value === "string" || value instanceof String;
|
|
591
|
+
}
|
|
592
|
+
function joinLines(items) {
|
|
593
|
+
if (Array.isArray(items)) {
|
|
594
|
+
return items.filter((item) => isString(item)).join(" ");
|
|
595
|
+
}
|
|
596
|
+
return items;
|
|
597
|
+
}
|
|
598
|
+
function HintSlotFactory(propsOrRef, slots) {
|
|
599
|
+
const props = computed(() => {
|
|
600
|
+
if (isRef(propsOrRef)) {
|
|
601
|
+
return propsOrRef.value;
|
|
602
|
+
}
|
|
603
|
+
return propsOrRef;
|
|
604
|
+
});
|
|
605
|
+
const invalidLabel = computed(() => joinLines(props.value.invalidLabel));
|
|
606
|
+
const validLabel = computed(() => joinLines(props.value.validLabel));
|
|
607
|
+
const loadingLabel = computed(() => props.value.loadingLabel);
|
|
608
|
+
const hintLabel = computed(() => props.value.hintLabel);
|
|
609
|
+
const hasLoadingLabelOrSlot = computed(
|
|
610
|
+
() => Boolean(props.value.loading && (slots.loading || loadingLabel.value))
|
|
611
|
+
);
|
|
612
|
+
const hasInvalidLabelOrSlot = computed(
|
|
613
|
+
() => !hasLoadingLabelOrSlot.value && Boolean(
|
|
614
|
+
props.value.invalid && (slots.invalid || invalidLabel.value)
|
|
615
|
+
)
|
|
616
|
+
);
|
|
617
|
+
const hasValidLabelOrSlot = computed(
|
|
618
|
+
() => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && Boolean(props.value.valid && (slots.valid || validLabel.value))
|
|
619
|
+
);
|
|
620
|
+
const hasHintLabelOrSlot = computed(
|
|
621
|
+
() => !hasLoadingLabelOrSlot.value && !hasInvalidLabelOrSlot.value && !hasValidLabelOrSlot.value && Boolean(slots.hint || hintLabel.value)
|
|
622
|
+
);
|
|
623
|
+
const isVisible = computed(
|
|
624
|
+
() => hasInvalidLabelOrSlot.value || hasValidLabelOrSlot.value || hasLoadingLabelOrSlot.value || hasHintLabelOrSlot.value
|
|
625
|
+
);
|
|
626
|
+
const hintSlotScope = computed(() => ({
|
|
627
|
+
modelValue: props.value.modelValue,
|
|
628
|
+
valid: props.value.valid,
|
|
629
|
+
invalid: props.value.invalid,
|
|
630
|
+
loading: props.value.loading
|
|
631
|
+
}));
|
|
632
|
+
const HintSlot = defineComponent({
|
|
633
|
+
name: "HintSlot",
|
|
634
|
+
props: {
|
|
635
|
+
tag: {
|
|
636
|
+
type: String,
|
|
637
|
+
default: "small"
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
setup() {
|
|
641
|
+
return {
|
|
642
|
+
isVisible,
|
|
643
|
+
invalidLabel,
|
|
644
|
+
validLabel,
|
|
645
|
+
loadingLabel,
|
|
646
|
+
hintLabel,
|
|
647
|
+
hasInvalidLabelOrSlot,
|
|
648
|
+
hasValidLabelOrSlot,
|
|
649
|
+
hasLoadingLabelOrSlot,
|
|
650
|
+
hasHintLabelOrSlot
|
|
651
|
+
};
|
|
652
|
+
},
|
|
653
|
+
render() {
|
|
654
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
655
|
+
if (this.isVisible) {
|
|
656
|
+
let role;
|
|
657
|
+
if (this.hasInvalidLabelOrSlot) {
|
|
658
|
+
role = "alert";
|
|
659
|
+
}
|
|
660
|
+
if (this.hasValidLabelOrSlot) {
|
|
661
|
+
role = "status";
|
|
662
|
+
}
|
|
663
|
+
if (this.hasLoadingLabelOrSlot) {
|
|
664
|
+
return h(
|
|
665
|
+
this.tag,
|
|
666
|
+
{
|
|
667
|
+
role
|
|
668
|
+
},
|
|
669
|
+
((_b = (_a = this.$slots).loading) == null ? void 0 : _b.call(_a)) ?? this.loadingLabel
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
if (this.hasInvalidLabelOrSlot) {
|
|
673
|
+
return h(
|
|
674
|
+
this.tag,
|
|
675
|
+
{
|
|
676
|
+
role
|
|
677
|
+
},
|
|
678
|
+
((_d = (_c = this.$slots).invalid) == null ? void 0 : _d.call(_c)) ?? this.$slots.invalid ?? this.invalidLabel
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
if (this.hasValidLabelOrSlot) {
|
|
682
|
+
return h(
|
|
683
|
+
this.tag,
|
|
684
|
+
{
|
|
685
|
+
role
|
|
686
|
+
},
|
|
687
|
+
((_f = (_e = this.$slots).valid) == null ? void 0 : _f.call(_e)) ?? this.validLabel
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
return h(
|
|
691
|
+
this.tag,
|
|
692
|
+
{
|
|
693
|
+
role
|
|
694
|
+
},
|
|
695
|
+
((_h = (_g = this.$slots).hint) == null ? void 0 : _h.call(_g)) ?? this.$slots.hint ?? this.hintLabel
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
return {
|
|
702
|
+
hasInvalidLabelOrSlot,
|
|
703
|
+
hasHintLabelOrSlot,
|
|
704
|
+
hasValidLabelOrSlot,
|
|
705
|
+
hasLoadingLabelOrSlot,
|
|
706
|
+
hintSlotScope,
|
|
707
|
+
HintSlot
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
const VvDropdownProps = {
|
|
711
|
+
...IdProps,
|
|
712
|
+
...DropdownProps,
|
|
713
|
+
...ModifiersProps,
|
|
714
|
+
/**
|
|
715
|
+
* Show / hide dropdown programmatically
|
|
716
|
+
*/
|
|
717
|
+
modelValue: {
|
|
718
|
+
type: Boolean,
|
|
719
|
+
default: void 0
|
|
720
|
+
},
|
|
721
|
+
/**
|
|
722
|
+
* Dropdown trigger element
|
|
723
|
+
*/
|
|
724
|
+
reference: {
|
|
725
|
+
type: Object,
|
|
726
|
+
default: null
|
|
727
|
+
},
|
|
728
|
+
/**
|
|
729
|
+
* Dropdown role
|
|
730
|
+
*/
|
|
731
|
+
role: {
|
|
732
|
+
type: String,
|
|
733
|
+
default: DropdownRole.menu,
|
|
734
|
+
validator: (value) => Object.values(DropdownRole).includes(value)
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
const VvDropdownItemProps = {
|
|
738
|
+
focusOnHover: {
|
|
739
|
+
type: Boolean,
|
|
740
|
+
default: false
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
const VvDropdownOptionProps = {
|
|
744
|
+
...DisabledProps,
|
|
745
|
+
...SelectedProps,
|
|
746
|
+
...UnselectableProps,
|
|
747
|
+
...ModifiersProps,
|
|
748
|
+
deselectHintLabel: {
|
|
749
|
+
type: String
|
|
750
|
+
},
|
|
751
|
+
selectHintLabel: {
|
|
752
|
+
type: String
|
|
753
|
+
},
|
|
754
|
+
selectedHintLabel: {
|
|
755
|
+
type: String
|
|
756
|
+
},
|
|
757
|
+
focusOnHover: {
|
|
758
|
+
type: Boolean,
|
|
759
|
+
default: false
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
function useUniqueId(id) {
|
|
763
|
+
return computed(() => String((id == null ? void 0 : id.value) || useId()));
|
|
764
|
+
}
|
|
765
|
+
function useDropdownProvideTrigger({
|
|
766
|
+
reference,
|
|
767
|
+
id,
|
|
768
|
+
expanded,
|
|
769
|
+
aria
|
|
770
|
+
}) {
|
|
771
|
+
const bus = mitt();
|
|
772
|
+
const component = defineComponent({
|
|
773
|
+
name: "VvDropdownTriggerProvider",
|
|
774
|
+
setup() {
|
|
775
|
+
provide(INJECTION_KEY_DROPDOWN_TRIGGER, {
|
|
776
|
+
reference,
|
|
777
|
+
id,
|
|
778
|
+
expanded,
|
|
779
|
+
aria,
|
|
780
|
+
bus
|
|
781
|
+
});
|
|
782
|
+
},
|
|
783
|
+
render() {
|
|
784
|
+
var _a, _b;
|
|
785
|
+
return h(Fragment, {}, (_b = (_a = this.$slots).default) == null ? void 0 : _b.call(_a));
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
return {
|
|
789
|
+
bus,
|
|
790
|
+
component
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
function useDropdownProvideItem({
|
|
794
|
+
role,
|
|
795
|
+
...others
|
|
796
|
+
}) {
|
|
797
|
+
const itemRole = computed(
|
|
798
|
+
() => role.value === DropdownRole.listbox ? DropdownItemRole.option : DropdownItemRole.presentation
|
|
799
|
+
);
|
|
800
|
+
provide(INJECTION_KEY_DROPDOWN_ITEM, {
|
|
801
|
+
role: itemRole,
|
|
802
|
+
...others
|
|
803
|
+
});
|
|
804
|
+
return { itemRole };
|
|
805
|
+
}
|
|
806
|
+
function useDropdownProvideAction({
|
|
807
|
+
expanded
|
|
808
|
+
}) {
|
|
809
|
+
provide(INJECTION_KEY_DROPDOWN_ACTION, {
|
|
810
|
+
role: ref(ActionRoles.menuitem),
|
|
811
|
+
expanded
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
function useModifiers(prefix, modifiers, others) {
|
|
815
|
+
return computed(() => {
|
|
816
|
+
const toReturn = {
|
|
817
|
+
[prefix]: true
|
|
818
|
+
};
|
|
819
|
+
const modifiersArray = typeof (modifiers == null ? void 0 : modifiers.value) === "string" ? modifiers.value.split(" ") : modifiers == null ? void 0 : modifiers.value;
|
|
820
|
+
if (modifiersArray) {
|
|
821
|
+
if (Array.isArray(modifiersArray)) {
|
|
822
|
+
modifiersArray.forEach((modifier) => {
|
|
823
|
+
if (modifier) {
|
|
824
|
+
toReturn[`${prefix}--${modifier}`] = true;
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if (others) {
|
|
830
|
+
Object.keys(others.value).forEach((key) => {
|
|
831
|
+
toReturn[`${prefix}--${key}`] = unref(others.value[key]);
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
return toReturn;
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
const _hoisted_1$2 = ["id", "tabindex", "role", "aria-labelledby"];
|
|
838
|
+
const __default__$4 = {
|
|
839
|
+
name: "VvDropdown",
|
|
840
|
+
inheritAttrs: false
|
|
841
|
+
};
|
|
842
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
843
|
+
...__default__$4,
|
|
844
|
+
props: VvDropdownProps,
|
|
845
|
+
emits: [
|
|
846
|
+
"update:modelValue",
|
|
847
|
+
"beforeEnter",
|
|
848
|
+
"afterLeave",
|
|
849
|
+
"beforeExpand",
|
|
850
|
+
"beforeCollapse",
|
|
851
|
+
"afterExpand",
|
|
852
|
+
"afterCollapse",
|
|
853
|
+
"before-enter",
|
|
854
|
+
"after-leave",
|
|
855
|
+
"enter",
|
|
856
|
+
"afterEnter",
|
|
857
|
+
"enterCancelled",
|
|
858
|
+
"beforeLeave",
|
|
859
|
+
"leave",
|
|
860
|
+
"leaveCancelled"
|
|
861
|
+
],
|
|
862
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
863
|
+
const props = __props;
|
|
864
|
+
const emit = __emit;
|
|
865
|
+
const { id } = toRefs(props);
|
|
866
|
+
const hasId = useUniqueId(id);
|
|
867
|
+
const attrs = useAttrs();
|
|
868
|
+
const maxWidth = ref("auto");
|
|
869
|
+
const maxHeight = ref("auto");
|
|
870
|
+
const localReferenceEl = ref();
|
|
871
|
+
const floatingEl = ref();
|
|
872
|
+
const arrowEl = ref();
|
|
873
|
+
const listEl = ref();
|
|
874
|
+
const referenceEl = computed({
|
|
875
|
+
get: () => props.reference ?? localReferenceEl.value,
|
|
876
|
+
set: (newValue) => {
|
|
877
|
+
localReferenceEl.value = newValue;
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
const hasCustomPosition = ref(false);
|
|
881
|
+
onMounted(() => {
|
|
882
|
+
useMutationObserver(
|
|
883
|
+
floatingEl.value,
|
|
884
|
+
() => {
|
|
885
|
+
var _a;
|
|
886
|
+
hasCustomPosition.value = ((_a = window.getComputedStyle(floatingEl.value).getPropertyValue("--dropdown-custom-position")) == null ? void 0 : _a.trim()) === "true";
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
attributeFilter: ["style"],
|
|
890
|
+
window
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
});
|
|
894
|
+
const middleware = computed(() => {
|
|
895
|
+
const toReturn = [];
|
|
896
|
+
if (props.autoPlacement) {
|
|
897
|
+
if (typeof props.autoPlacement === "boolean") {
|
|
898
|
+
toReturn.push(autoPlacement());
|
|
899
|
+
} else {
|
|
900
|
+
toReturn.push(
|
|
901
|
+
autoPlacement(props.autoPlacement)
|
|
902
|
+
);
|
|
903
|
+
}
|
|
904
|
+
} else if (props.flip) {
|
|
905
|
+
if (typeof props.flip === "boolean") {
|
|
906
|
+
toReturn.push(flip({ fallbackStrategy: "initialPlacement" }));
|
|
907
|
+
} else {
|
|
908
|
+
toReturn.push(flip(props.flip));
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
if (props.shift) {
|
|
912
|
+
if (typeof props.shift === "boolean") {
|
|
913
|
+
toReturn.push(shift());
|
|
914
|
+
} else {
|
|
915
|
+
toReturn.push(shift(props.shift));
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (props.size) {
|
|
919
|
+
const apply = ({
|
|
920
|
+
availableWidth,
|
|
921
|
+
availableHeight
|
|
922
|
+
}) => {
|
|
923
|
+
maxWidth.value = `${availableWidth}px`;
|
|
924
|
+
maxHeight.value = `${availableHeight}px`;
|
|
925
|
+
};
|
|
926
|
+
if (typeof props.size === "boolean") {
|
|
927
|
+
toReturn.push(
|
|
928
|
+
size({
|
|
929
|
+
apply
|
|
930
|
+
})
|
|
931
|
+
);
|
|
932
|
+
} else {
|
|
933
|
+
toReturn.push(
|
|
934
|
+
size({
|
|
935
|
+
...props.size,
|
|
936
|
+
apply
|
|
937
|
+
})
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
if (props.offset) {
|
|
942
|
+
toReturn.push(offset(Number(props.offset)));
|
|
943
|
+
if (["string", "number"].includes(typeof props.offset)) {
|
|
944
|
+
toReturn.push(offset(Number(props.offset)));
|
|
945
|
+
} else {
|
|
946
|
+
toReturn.push(offset(props.offset));
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
if (props.arrow) {
|
|
950
|
+
toReturn.push(
|
|
951
|
+
arrow({
|
|
952
|
+
element: arrowEl
|
|
953
|
+
})
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
return toReturn;
|
|
957
|
+
});
|
|
958
|
+
const { x, y, middlewareData, placement, strategy } = useFloating(
|
|
959
|
+
referenceEl,
|
|
960
|
+
floatingEl,
|
|
961
|
+
{
|
|
962
|
+
whileElementsMounted: (...args) => {
|
|
963
|
+
return autoUpdate(...args, {
|
|
964
|
+
animationFrame: props.strategy === Strategy.fixed
|
|
965
|
+
});
|
|
966
|
+
},
|
|
967
|
+
placement: computed(() => props.placement),
|
|
968
|
+
strategy: computed(() => props.strategy),
|
|
969
|
+
middleware
|
|
970
|
+
}
|
|
971
|
+
);
|
|
972
|
+
const dropdownPlacement = computed(() => {
|
|
973
|
+
var _a;
|
|
974
|
+
if (hasCustomPosition.value) {
|
|
975
|
+
return void 0;
|
|
976
|
+
}
|
|
977
|
+
const width = props.triggerWidth && referenceEl.value ? `${(_a = referenceEl.value) == null ? void 0 : _a.offsetWidth}px` : void 0;
|
|
978
|
+
return {
|
|
979
|
+
position: strategy.value,
|
|
980
|
+
top: `${y.value ?? 0}px`,
|
|
981
|
+
left: `${x.value ?? 0}px`,
|
|
982
|
+
maxWidth: width ? void 0 : maxWidth.value,
|
|
983
|
+
maxHeight: maxHeight.value,
|
|
984
|
+
width
|
|
985
|
+
};
|
|
986
|
+
});
|
|
987
|
+
const side = computed(
|
|
988
|
+
() => placement.value.split("-")[0]
|
|
989
|
+
);
|
|
990
|
+
const arrowPlacement = computed(() => {
|
|
991
|
+
var _a, _b, _c, _d, _e;
|
|
992
|
+
if (hasCustomPosition.value) {
|
|
993
|
+
return void 0;
|
|
994
|
+
}
|
|
995
|
+
const staticSide = {
|
|
996
|
+
[Side.top]: Side.bottom,
|
|
997
|
+
[Side.right]: Side.left,
|
|
998
|
+
[Side.bottom]: Side.top,
|
|
999
|
+
[Side.left]: Side.right
|
|
1000
|
+
}[side.value];
|
|
1001
|
+
return {
|
|
1002
|
+
left: ((_a = middlewareData.value.arrow) == null ? void 0 : _a.x) !== void 0 ? `${(_b = middlewareData.value.arrow) == null ? void 0 : _b.x}px` : void 0,
|
|
1003
|
+
top: ((_c = middlewareData.value.arrow) == null ? void 0 : _c.y) !== void 0 ? `${(_d = middlewareData.value.arrow) == null ? void 0 : _d.y}px` : void 0,
|
|
1004
|
+
[staticSide]: `${-(((_e = arrowEl.value) == null ? void 0 : _e.offsetWidth) ?? 0) / 2}px`
|
|
1005
|
+
};
|
|
1006
|
+
});
|
|
1007
|
+
const modelValue = useVModel(props, "modelValue", emit);
|
|
1008
|
+
const localModelValue = ref(false);
|
|
1009
|
+
const expanded = computed({
|
|
1010
|
+
get: () => modelValue.value ?? localModelValue.value,
|
|
1011
|
+
set: (newValue) => {
|
|
1012
|
+
if (modelValue.value === void 0) {
|
|
1013
|
+
localModelValue.value = newValue;
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
modelValue.value = newValue;
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
function show() {
|
|
1020
|
+
expanded.value = true;
|
|
1021
|
+
}
|
|
1022
|
+
function hide() {
|
|
1023
|
+
expanded.value = false;
|
|
1024
|
+
}
|
|
1025
|
+
function toggle() {
|
|
1026
|
+
expanded.value = !expanded.value;
|
|
1027
|
+
}
|
|
1028
|
+
function init(el) {
|
|
1029
|
+
referenceEl.value = el;
|
|
1030
|
+
}
|
|
1031
|
+
__expose({
|
|
1032
|
+
toggle,
|
|
1033
|
+
show,
|
|
1034
|
+
hide,
|
|
1035
|
+
init,
|
|
1036
|
+
customPosition: hasCustomPosition
|
|
1037
|
+
});
|
|
1038
|
+
watch(expanded, (newValue) => {
|
|
1039
|
+
if (newValue && props.autofocusFirst) {
|
|
1040
|
+
nextTick(() => {
|
|
1041
|
+
const focusableElements = getKeyboardFocusableElements(
|
|
1042
|
+
floatingEl.value
|
|
1043
|
+
);
|
|
1044
|
+
if (focusableElements.length > 0) {
|
|
1045
|
+
focusableElements[0].focus({
|
|
1046
|
+
preventScroll: true
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
onClickOutside(
|
|
1053
|
+
floatingEl,
|
|
1054
|
+
() => {
|
|
1055
|
+
if (!props.keepOpen && expanded.value) {
|
|
1056
|
+
expanded.value = false;
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
{ ignore: [referenceEl] }
|
|
1060
|
+
);
|
|
1061
|
+
const hasAriaLabelledby = computed(() => {
|
|
1062
|
+
var _a, _b;
|
|
1063
|
+
return ((_b = (_a = referenceEl.value) == null ? void 0 : _a.getAttribute) == null ? void 0 : _b.call(_a, "id")) ?? void 0;
|
|
1064
|
+
});
|
|
1065
|
+
const referenceAria = computed(() => ({
|
|
1066
|
+
"aria-controls": hasId.value,
|
|
1067
|
+
"aria-haspopup": true,
|
|
1068
|
+
"aria-expanded": expanded.value
|
|
1069
|
+
}));
|
|
1070
|
+
const { component: VvDropdownTriggerProvider, bus } = useDropdownProvideTrigger({
|
|
1071
|
+
reference: referenceEl,
|
|
1072
|
+
id: hasId,
|
|
1073
|
+
expanded,
|
|
1074
|
+
aria: referenceAria
|
|
1075
|
+
});
|
|
1076
|
+
bus.on("click", toggle);
|
|
1077
|
+
const { role, modifiers } = toRefs(props);
|
|
1078
|
+
const bemCssClasses = useModifiers(
|
|
1079
|
+
"vv-dropdown",
|
|
1080
|
+
modifiers,
|
|
1081
|
+
computed(() => ({
|
|
1082
|
+
arrow: props.arrow
|
|
1083
|
+
}))
|
|
1084
|
+
);
|
|
1085
|
+
const { focused } = useFocusWithin(floatingEl);
|
|
1086
|
+
function getKeyboardFocusableElements(element) {
|
|
1087
|
+
if (!element) {
|
|
1088
|
+
return [];
|
|
1089
|
+
}
|
|
1090
|
+
return [
|
|
1091
|
+
...element.querySelectorAll(
|
|
1092
|
+
'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
|
|
1093
|
+
)
|
|
1094
|
+
].filter(
|
|
1095
|
+
(el) => !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden")
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
function focusNext() {
|
|
1099
|
+
nextTick(() => {
|
|
1100
|
+
if (focused.value) {
|
|
1101
|
+
const focusableElements = getKeyboardFocusableElements(
|
|
1102
|
+
floatingEl.value
|
|
1103
|
+
);
|
|
1104
|
+
if (focusableElements.length === 0 || !document.activeElement) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const activeElementIndex = focusableElements.indexOf(
|
|
1108
|
+
document.activeElement
|
|
1109
|
+
);
|
|
1110
|
+
if (activeElementIndex < focusableElements.length - 1) {
|
|
1111
|
+
focusableElements[activeElementIndex + 1].focus({
|
|
1112
|
+
preventScroll: true
|
|
1113
|
+
});
|
|
1114
|
+
} else {
|
|
1115
|
+
focusableElements[0].focus({
|
|
1116
|
+
preventScroll: true
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
function focusPrev() {
|
|
1123
|
+
nextTick(() => {
|
|
1124
|
+
if (focused.value) {
|
|
1125
|
+
const focusableElements = getKeyboardFocusableElements(
|
|
1126
|
+
floatingEl.value
|
|
1127
|
+
);
|
|
1128
|
+
if (focusableElements.length === 0 || !document.activeElement) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
const activeElementIndex = focusableElements.indexOf(
|
|
1132
|
+
document.activeElement
|
|
1133
|
+
);
|
|
1134
|
+
if (activeElementIndex > 0) {
|
|
1135
|
+
focusableElements[activeElementIndex - 1].focus({
|
|
1136
|
+
preventScroll: true
|
|
1137
|
+
});
|
|
1138
|
+
} else {
|
|
1139
|
+
focusableElements[focusableElements.length - 1].focus({
|
|
1140
|
+
preventScroll: true
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
const hovered = useElementHover(floatingEl);
|
|
1147
|
+
const { itemRole } = useDropdownProvideItem({
|
|
1148
|
+
role,
|
|
1149
|
+
expanded,
|
|
1150
|
+
focused,
|
|
1151
|
+
hovered
|
|
1152
|
+
});
|
|
1153
|
+
onKeyStroke("Escape", (e) => {
|
|
1154
|
+
if (expanded.value) {
|
|
1155
|
+
e.preventDefault();
|
|
1156
|
+
hide();
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
onKeyStroke("ArrowDown", (e) => {
|
|
1160
|
+
if (expanded.value && focused.value) {
|
|
1161
|
+
e.preventDefault();
|
|
1162
|
+
focusNext();
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
onKeyStroke("ArrowUp", (e) => {
|
|
1166
|
+
if (expanded.value && focused.value) {
|
|
1167
|
+
e.preventDefault();
|
|
1168
|
+
focusPrev();
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
onKeyStroke([" ", "Enter"], (e) => {
|
|
1172
|
+
const htmlEl = e.target;
|
|
1173
|
+
if (expanded.value && focused.value && htmlEl) {
|
|
1174
|
+
htmlEl == null ? void 0 : htmlEl.click();
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
const dropdownTransitionHandlers = {
|
|
1178
|
+
"before-enter": () => {
|
|
1179
|
+
emit(expanded.value ? "beforeExpand" : "beforeCollapse");
|
|
1180
|
+
emit("beforeEnter");
|
|
1181
|
+
},
|
|
1182
|
+
"after-leave": () => {
|
|
1183
|
+
emit(expanded.value ? "afterExpand" : "afterCollapse");
|
|
1184
|
+
emit("afterLeave");
|
|
1185
|
+
},
|
|
1186
|
+
"enter": () => {
|
|
1187
|
+
emit("enter");
|
|
1188
|
+
},
|
|
1189
|
+
"after-enter": () => {
|
|
1190
|
+
emit("afterEnter");
|
|
1191
|
+
},
|
|
1192
|
+
"enter-cancelled": () => {
|
|
1193
|
+
emit("enterCancelled");
|
|
1194
|
+
},
|
|
1195
|
+
"before-leave": () => {
|
|
1196
|
+
emit("beforeLeave");
|
|
1197
|
+
},
|
|
1198
|
+
"leave": () => {
|
|
1199
|
+
emit("leave");
|
|
1200
|
+
},
|
|
1201
|
+
"leave-cancelled": () => {
|
|
1202
|
+
emit("leaveCancelled");
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
return (_ctx, _cache) => {
|
|
1206
|
+
return openBlock(), createElementBlock(
|
|
1207
|
+
Fragment,
|
|
1208
|
+
null,
|
|
1209
|
+
[
|
|
1210
|
+
createVNode(unref(VvDropdownTriggerProvider), null, {
|
|
1211
|
+
default: withCtx(() => [
|
|
1212
|
+
renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps({ init, show, hide, toggle, expanded: unref(expanded), aria: unref(referenceAria) })))
|
|
1213
|
+
]),
|
|
1214
|
+
_: 3
|
|
1215
|
+
/* FORWARDED */
|
|
1216
|
+
}),
|
|
1217
|
+
createVNode(Transition, mergeProps({ name: _ctx.transitionName }, toHandlers(dropdownTransitionHandlers), { persisted: "" }), {
|
|
1218
|
+
default: withCtx(() => [
|
|
1219
|
+
withDirectives(createElementVNode(
|
|
1220
|
+
"div",
|
|
1221
|
+
{
|
|
1222
|
+
ref_key: "floatingEl",
|
|
1223
|
+
ref: floatingEl,
|
|
1224
|
+
style: normalizeStyle(unref(dropdownPlacement)),
|
|
1225
|
+
class: normalizeClass(unref(bemCssClasses))
|
|
1226
|
+
},
|
|
1227
|
+
[
|
|
1228
|
+
props.arrow ? (openBlock(), createElementBlock(
|
|
1229
|
+
"div",
|
|
1230
|
+
{
|
|
1231
|
+
key: 0,
|
|
1232
|
+
ref_key: "arrowEl",
|
|
1233
|
+
ref: arrowEl,
|
|
1234
|
+
style: normalizeStyle(unref(arrowPlacement)),
|
|
1235
|
+
class: "vv-dropdown__arrow"
|
|
1236
|
+
},
|
|
1237
|
+
null,
|
|
1238
|
+
4
|
|
1239
|
+
/* STYLE */
|
|
1240
|
+
)) : createCommentVNode("v-if", true),
|
|
1241
|
+
renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps({ expanded: unref(expanded) }))),
|
|
1242
|
+
createElementVNode("div", mergeProps(unref(attrs), {
|
|
1243
|
+
id: unref(hasId),
|
|
1244
|
+
ref_key: "listEl",
|
|
1245
|
+
ref: listEl,
|
|
1246
|
+
tabindex: !unref(expanded) ? -1 : void 0,
|
|
1247
|
+
role: unref(role),
|
|
1248
|
+
"aria-labelledby": unref(hasAriaLabelledby),
|
|
1249
|
+
class: "vv-dropdown__list"
|
|
1250
|
+
}), [
|
|
1251
|
+
renderSlot(_ctx.$slots, "items", normalizeProps(guardReactiveProps({
|
|
1252
|
+
role: unref(itemRole)
|
|
1253
|
+
})))
|
|
1254
|
+
], 16, _hoisted_1$2),
|
|
1255
|
+
renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps({ expanded: unref(expanded) })))
|
|
1256
|
+
],
|
|
1257
|
+
6
|
|
1258
|
+
/* CLASS, STYLE */
|
|
1259
|
+
), [
|
|
1260
|
+
[vShow, unref(expanded)]
|
|
1261
|
+
])
|
|
1262
|
+
]),
|
|
1263
|
+
_: 3
|
|
1264
|
+
/* FORWARDED */
|
|
1265
|
+
}, 16, ["name"])
|
|
1266
|
+
],
|
|
1267
|
+
64
|
|
1268
|
+
/* STABLE_FRAGMENT */
|
|
1269
|
+
);
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
function useInjectedDropdownItem() {
|
|
1274
|
+
return inject(INJECTION_KEY_DROPDOWN_ITEM, {});
|
|
1275
|
+
}
|
|
1276
|
+
const __default__$3 = {
|
|
1277
|
+
name: "VvDropdownItem"
|
|
726
1278
|
};
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
1279
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
1280
|
+
...__default__$3,
|
|
1281
|
+
props: VvDropdownItemProps,
|
|
1282
|
+
setup(__props) {
|
|
1283
|
+
const props = __props;
|
|
1284
|
+
const { role, expanded } = useInjectedDropdownItem();
|
|
1285
|
+
const element = ref(null);
|
|
1286
|
+
useDropdownProvideAction({ expanded });
|
|
1287
|
+
const hovered = useElementHover(element);
|
|
1288
|
+
const { focused } = useFocus(element);
|
|
1289
|
+
const { focused: focusedWithin } = useFocusWithin(element);
|
|
1290
|
+
watch(hovered, (newValue) => {
|
|
1291
|
+
if (newValue && props.focusOnHover) {
|
|
1292
|
+
focused.value = true;
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
return (_ctx, _cache) => {
|
|
1296
|
+
return openBlock(), createElementBlock(
|
|
1297
|
+
"div",
|
|
1298
|
+
mergeProps({ role: unref(role) }, {
|
|
1299
|
+
ref_key: "element",
|
|
1300
|
+
ref: element,
|
|
1301
|
+
class: ["vv-dropdown__item", { "focus-visible": unref(focused) || unref(focusedWithin) }]
|
|
1302
|
+
}),
|
|
1303
|
+
[
|
|
1304
|
+
renderSlot(_ctx.$slots, "default")
|
|
1305
|
+
],
|
|
1306
|
+
16
|
|
1307
|
+
/* FULL_PROPS */
|
|
1308
|
+
);
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
const _hoisted_1$1 = ["title"];
|
|
1313
|
+
const __default__$2 = {
|
|
1314
|
+
name: "VvDropdownOption"
|
|
731
1315
|
};
|
|
732
|
-
const
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1316
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
1317
|
+
...__default__$2,
|
|
1318
|
+
props: VvDropdownOptionProps,
|
|
1319
|
+
setup(__props) {
|
|
1320
|
+
const props = __props;
|
|
1321
|
+
const { modifiers } = toRefs(props);
|
|
1322
|
+
const bemCssClasses = useModifiers(
|
|
1323
|
+
"vv-dropdown-option",
|
|
1324
|
+
modifiers,
|
|
1325
|
+
computed(() => ({
|
|
1326
|
+
disabled: props.disabled,
|
|
1327
|
+
selected: props.selected,
|
|
1328
|
+
unselectable: props.unselectable && props.selected
|
|
1329
|
+
}))
|
|
1330
|
+
);
|
|
1331
|
+
const hintLabel = computed(() => {
|
|
1332
|
+
if (props.selected) {
|
|
1333
|
+
return props.unselectable ? props.deselectHintLabel : props.selectedHintLabel;
|
|
1334
|
+
}
|
|
1335
|
+
if (!props.disabled) {
|
|
1336
|
+
return props.selectHintLabel;
|
|
1337
|
+
}
|
|
1338
|
+
return "";
|
|
1339
|
+
});
|
|
1340
|
+
return (_ctx, _cache) => {
|
|
1341
|
+
return openBlock(), createBlock(_sfc_main$3, {
|
|
1342
|
+
class: normalizeClass(unref(bemCssClasses)),
|
|
1343
|
+
tabindex: _ctx.disabled ? -1 : 0,
|
|
1344
|
+
"aria-selected": _ctx.selected,
|
|
1345
|
+
"aria-disabled": _ctx.disabled,
|
|
1346
|
+
"focus-on-hover": _ctx.focusOnHover
|
|
1347
|
+
}, {
|
|
1348
|
+
default: withCtx(() => [
|
|
1349
|
+
renderSlot(_ctx.$slots, "default"),
|
|
1350
|
+
createElementVNode("span", {
|
|
1351
|
+
class: "vv-dropdown-option__hint",
|
|
1352
|
+
title: unref(hintLabel)
|
|
1353
|
+
}, [
|
|
1354
|
+
renderSlot(_ctx.$slots, "hint", normalizeProps(guardReactiveProps({ disabled: _ctx.disabled, selected: _ctx.selected, unselectable: _ctx.unselectable })), () => [
|
|
1355
|
+
createTextVNode(
|
|
1356
|
+
toDisplayString(unref(hintLabel)),
|
|
1357
|
+
1
|
|
1358
|
+
/* TEXT */
|
|
1359
|
+
)
|
|
1360
|
+
])
|
|
1361
|
+
], 8, _hoisted_1$1)
|
|
1362
|
+
]),
|
|
1363
|
+
_: 3
|
|
1364
|
+
/* FORWARDED */
|
|
1365
|
+
}, 8, ["class", "tabindex", "aria-selected", "aria-disabled", "focus-on-hover"]);
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
});
|
|
1369
|
+
function useVolver() {
|
|
1370
|
+
return inject(INJECTION_KEY_VOLVER);
|
|
1371
|
+
}
|
|
1372
|
+
const __default__$1 = {
|
|
1373
|
+
name: "VvIcon"
|
|
764
1374
|
};
|
|
1375
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
1376
|
+
...__default__$1,
|
|
1377
|
+
props: /* @__PURE__ */ mergeDefaults({
|
|
1378
|
+
name: {},
|
|
1379
|
+
color: {},
|
|
1380
|
+
width: {},
|
|
1381
|
+
height: {},
|
|
1382
|
+
provider: {},
|
|
1383
|
+
prefix: {},
|
|
1384
|
+
src: {},
|
|
1385
|
+
horizontalFlip: { type: Boolean },
|
|
1386
|
+
verticalFlip: { type: Boolean },
|
|
1387
|
+
flip: {},
|
|
1388
|
+
mode: {},
|
|
1389
|
+
inline: { type: Boolean },
|
|
1390
|
+
rotate: {},
|
|
1391
|
+
onLoad: { type: Function },
|
|
1392
|
+
svg: {},
|
|
1393
|
+
modifiers: {}
|
|
1394
|
+
}, VvIconPropsDefaults),
|
|
1395
|
+
setup(__props) {
|
|
1396
|
+
const props = __props;
|
|
1397
|
+
const hasRotate = computed(() => {
|
|
1398
|
+
if (typeof props.rotate === "string") {
|
|
1399
|
+
return Number.parseFloat(props.rotate);
|
|
1400
|
+
}
|
|
1401
|
+
return props.rotate;
|
|
1402
|
+
});
|
|
1403
|
+
const show = ref(true);
|
|
1404
|
+
const volver = useVolver();
|
|
1405
|
+
const { modifiers } = toRefs(props);
|
|
1406
|
+
const bemCssClasses = useModifiers("vv-icon", modifiers);
|
|
1407
|
+
const provider = computed(() => {
|
|
1408
|
+
return props.provider || (volver == null ? void 0 : volver.iconsProvider);
|
|
1409
|
+
});
|
|
1410
|
+
const icon = computed(() => {
|
|
1411
|
+
const name = props.name ?? "";
|
|
1412
|
+
const iconName = `@${provider.value}:${props.prefix}:${name}`;
|
|
1413
|
+
if (iconExists(iconName)) {
|
|
1414
|
+
return iconName;
|
|
1415
|
+
}
|
|
1416
|
+
const iconsCollection = volver == null ? void 0 : volver.iconsCollections.find(
|
|
1417
|
+
(iconsCollection2) => {
|
|
1418
|
+
const icon2 = `@${provider.value}:${iconsCollection2.prefix}:${name}`;
|
|
1419
|
+
return iconExists(icon2);
|
|
1420
|
+
}
|
|
1421
|
+
);
|
|
1422
|
+
if (iconsCollection) {
|
|
1423
|
+
return `@${provider.value}:${iconsCollection.prefix}:${name}`;
|
|
1424
|
+
}
|
|
1425
|
+
return name;
|
|
1426
|
+
});
|
|
1427
|
+
function getSvgContent(svg) {
|
|
1428
|
+
let dom;
|
|
1429
|
+
if (typeof window === "undefined") {
|
|
1430
|
+
const { JSDOM } = require("jsdom");
|
|
1431
|
+
dom = new JSDOM().window;
|
|
1432
|
+
}
|
|
1433
|
+
const domParser = dom ? new dom.DOMParser() : new window.DOMParser();
|
|
1434
|
+
const svgDomString = domParser.parseFromString(svg, "text/html");
|
|
1435
|
+
const svgEl = svgDomString.querySelector("svg");
|
|
1436
|
+
return svgEl;
|
|
1437
|
+
}
|
|
1438
|
+
function addIconFromSvg(svg) {
|
|
1439
|
+
const svgContentEl = getSvgContent(svg);
|
|
1440
|
+
const svgContent = (svgContentEl == null ? void 0 : svgContentEl.innerHTML.trim()) || "";
|
|
1441
|
+
if (svgContentEl && svgContent) {
|
|
1442
|
+
addIcon(`@${provider.value}:${props.prefix}:${props.name}`, {
|
|
1443
|
+
body: svgContent,
|
|
1444
|
+
// Set height and width from svg content
|
|
1445
|
+
height: svgContentEl.viewBox.baseVal.height,
|
|
1446
|
+
width: svgContentEl.viewBox.baseVal.width
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
if (volver) {
|
|
1451
|
+
if (props.src && !iconExists(`@${provider.value}:${props.prefix}:${props.name}`)) {
|
|
1452
|
+
show.value = false;
|
|
1453
|
+
volver.fetchIcon(props.src).then((svg) => {
|
|
1454
|
+
if (svg) {
|
|
1455
|
+
addIconFromSvg(svg);
|
|
1456
|
+
show.value = true;
|
|
1457
|
+
}
|
|
1458
|
+
}).catch((e) => {
|
|
1459
|
+
throw new Error(`Error during fetch icon: ${e == null ? void 0 : e.message}`);
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
if (props.svg) {
|
|
1464
|
+
addIconFromSvg(props.svg);
|
|
1465
|
+
}
|
|
1466
|
+
return (_ctx, _cache) => {
|
|
1467
|
+
return unref(show) ? (openBlock(), createBlock(unref(Icon), mergeProps({
|
|
1468
|
+
key: 0,
|
|
1469
|
+
class: unref(bemCssClasses)
|
|
1470
|
+
}, {
|
|
1471
|
+
inline: _ctx.inline,
|
|
1472
|
+
width: _ctx.width,
|
|
1473
|
+
height: _ctx.height,
|
|
1474
|
+
horizontalFlip: _ctx.horizontalFlip,
|
|
1475
|
+
verticalFlip: _ctx.verticalFlip,
|
|
1476
|
+
flip: _ctx.flip,
|
|
1477
|
+
rotate: unref(hasRotate),
|
|
1478
|
+
color: _ctx.color,
|
|
1479
|
+
onLoad: _ctx.onLoad,
|
|
1480
|
+
icon: unref(icon)
|
|
1481
|
+
}), null, 16, ["class"])) : createCommentVNode("v-if", true);
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
765
1485
|
function useDefaults(componentName, propsDefinition, props) {
|
|
766
1486
|
const volver = useVolver();
|
|
767
1487
|
const volverComponentDefaults = computed(() => {
|
|
@@ -815,9 +1535,6 @@ function useDefaults(componentName, propsDefinition, props) {
|
|
|
815
1535
|
}, {});
|
|
816
1536
|
});
|
|
817
1537
|
}
|
|
818
|
-
function useUniqueId(id) {
|
|
819
|
-
return computed(() => String((id == null ? void 0 : id.value) || useId()));
|
|
820
|
-
}
|
|
821
1538
|
function useDebouncedInput(modelValue, emit, ms = 0, {
|
|
822
1539
|
getter = (value) => value,
|
|
823
1540
|
setter = (value) => value
|
|
@@ -916,22 +1633,83 @@ function useTextCount(text, options) {
|
|
|
916
1633
|
formatted
|
|
917
1634
|
};
|
|
918
1635
|
}
|
|
1636
|
+
function usePersistence(storageKey, storageType = StorageType.local, defaultValue) {
|
|
1637
|
+
const localValue = ref();
|
|
1638
|
+
if (defaultValue) {
|
|
1639
|
+
localValue.value = defaultValue;
|
|
1640
|
+
}
|
|
1641
|
+
let storageValue;
|
|
1642
|
+
if (storageKey) {
|
|
1643
|
+
watch(
|
|
1644
|
+
storageKey,
|
|
1645
|
+
(newKey, oldKey) => {
|
|
1646
|
+
const storage = unref(storageType) === StorageType.session ? sessionStorage : localStorage;
|
|
1647
|
+
if (oldKey && oldKey !== newKey) {
|
|
1648
|
+
storage.removeItem(oldKey);
|
|
1649
|
+
}
|
|
1650
|
+
if (newKey) {
|
|
1651
|
+
storageValue = useStorage(
|
|
1652
|
+
newKey,
|
|
1653
|
+
(storageValue == null ? void 0 : storageValue.value) ?? localValue.value,
|
|
1654
|
+
storage
|
|
1655
|
+
);
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
storageValue = void 0;
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
immediate: true
|
|
1662
|
+
}
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
if (isRef(storageType)) {
|
|
1666
|
+
watch(storageType, (newType, oldType) => {
|
|
1667
|
+
if (storageKey == null ? void 0 : storageKey.value) {
|
|
1668
|
+
if (newType) {
|
|
1669
|
+
const storage = newType === StorageType.session ? sessionStorage : localStorage;
|
|
1670
|
+
storageValue = useStorage(
|
|
1671
|
+
storageKey.value,
|
|
1672
|
+
(storageValue == null ? void 0 : storageValue.value) ?? localValue.value,
|
|
1673
|
+
storage
|
|
1674
|
+
);
|
|
1675
|
+
}
|
|
1676
|
+
if (oldType && oldType !== newType) {
|
|
1677
|
+
const oldStorage = oldType === StorageType.session ? sessionStorage : localStorage;
|
|
1678
|
+
oldStorage.removeItem(storageKey.value);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
return computed({
|
|
1684
|
+
get: () => {
|
|
1685
|
+
return (storageValue == null ? void 0 : storageValue.value) ?? localValue.value;
|
|
1686
|
+
},
|
|
1687
|
+
set: (value) => {
|
|
1688
|
+
if (storageValue) {
|
|
1689
|
+
storageValue.value = value;
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
localValue.value = value;
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
919
1696
|
const _hoisted_1 = ["for"];
|
|
920
|
-
const _hoisted_2 = {
|
|
921
|
-
const _hoisted_3 = {
|
|
1697
|
+
const _hoisted_2 = {
|
|
922
1698
|
key: 0,
|
|
923
1699
|
class: "vv-textarea__input-before"
|
|
924
1700
|
};
|
|
925
|
-
const
|
|
926
|
-
const
|
|
927
|
-
const
|
|
1701
|
+
const _hoisted_3 = { class: "vv-textarea__inner" };
|
|
1702
|
+
const _hoisted_4 = ["id"];
|
|
1703
|
+
const _hoisted_5 = {
|
|
928
1704
|
key: 1,
|
|
929
1705
|
class: "vv-textarea__input-after"
|
|
930
1706
|
};
|
|
931
|
-
const
|
|
1707
|
+
const _hoisted_6 = {
|
|
932
1708
|
key: 2,
|
|
933
1709
|
class: "vv-textarea__limit"
|
|
934
1710
|
};
|
|
1711
|
+
const _hoisted_7 = { class: "flex-1" };
|
|
1712
|
+
const _hoisted_8 = ["title", "onClick"];
|
|
935
1713
|
const __default__ = {
|
|
936
1714
|
name: "VvTextarea"
|
|
937
1715
|
};
|
|
@@ -948,11 +1726,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
948
1726
|
VvTextareaProps,
|
|
949
1727
|
props
|
|
950
1728
|
);
|
|
951
|
-
const
|
|
1729
|
+
const textareaEl = ref();
|
|
1730
|
+
const wrapperEl = ref();
|
|
1731
|
+
const suggestionsDropdownEl = ref();
|
|
952
1732
|
const {
|
|
953
1733
|
id,
|
|
954
1734
|
icon,
|
|
955
1735
|
iconPosition,
|
|
1736
|
+
iconRemoveSuggestion,
|
|
1737
|
+
labelRemoveSuggestion,
|
|
956
1738
|
label,
|
|
957
1739
|
modelValue,
|
|
958
1740
|
count,
|
|
@@ -962,7 +1744,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
962
1744
|
modifiers,
|
|
963
1745
|
debounce,
|
|
964
1746
|
minlength,
|
|
965
|
-
maxlength
|
|
1747
|
+
maxlength,
|
|
1748
|
+
storageKey,
|
|
1749
|
+
storageType
|
|
966
1750
|
} = toRefs(props);
|
|
967
1751
|
const hasId = useUniqueId(id);
|
|
968
1752
|
const hasHintId = computed(() => `${hasId.value}-hint`);
|
|
@@ -971,8 +1755,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
971
1755
|
);
|
|
972
1756
|
const localModelValue = useDebouncedInput(modelValue, emit, debounce == null ? void 0 : debounce.value);
|
|
973
1757
|
const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition);
|
|
974
|
-
const {
|
|
975
|
-
const
|
|
1758
|
+
const { hasIcon: hasIconRemoveSuggestion } = useComponentIcon(iconRemoveSuggestion);
|
|
1759
|
+
const { focused } = useComponentFocus(textareaEl, emit);
|
|
1760
|
+
const isFocused = computed(
|
|
1761
|
+
() => focused.value && !props.disabled && !props.readonly
|
|
1762
|
+
);
|
|
1763
|
+
watch(isFocused, (newValue) => {
|
|
1764
|
+
var _a, _b;
|
|
1765
|
+
if (newValue && propsDefaults.value.selectOnFocus && textareaEl.value) {
|
|
1766
|
+
textareaEl.value.select();
|
|
1767
|
+
}
|
|
1768
|
+
if (newValue && ((_a = suggestions.value) == null ? void 0 : _a.size)) {
|
|
1769
|
+
(_b = suggestionsDropdownEl.value) == null ? void 0 : _b.show();
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
if (isDirty.value && suggestions.value) {
|
|
1773
|
+
const suggestionsLimit = props.maxSuggestions;
|
|
1774
|
+
if (suggestions.value.size >= suggestionsLimit && !suggestions.value.has(localModelValue.value)) {
|
|
1775
|
+
suggestions.value = new Set(
|
|
1776
|
+
[...suggestions.value].slice(
|
|
1777
|
+
suggestions.value.size - suggestionsLimit + 1
|
|
1778
|
+
)
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
suggestions.value.add(localModelValue.value);
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
const isVisible = useElementVisibility(textareaEl);
|
|
976
1785
|
watch(isVisible, (newValue) => {
|
|
977
1786
|
if (newValue && props.autofocus) {
|
|
978
1787
|
focused.value = true;
|
|
@@ -997,6 +1806,31 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
997
1806
|
}
|
|
998
1807
|
return void 0;
|
|
999
1808
|
});
|
|
1809
|
+
const suggestions = usePersistence(
|
|
1810
|
+
storageKey,
|
|
1811
|
+
storageType,
|
|
1812
|
+
/* @__PURE__ */ new Set()
|
|
1813
|
+
);
|
|
1814
|
+
const filteredSuggestions = computed(() => {
|
|
1815
|
+
if (!suggestions.value) {
|
|
1816
|
+
return [];
|
|
1817
|
+
}
|
|
1818
|
+
return [...suggestions.value].filter(
|
|
1819
|
+
(suggestion) => isEmpty(localModelValue.value) || `${suggestion}`.toLowerCase().includes(`${localModelValue.value}`.toLowerCase()) && suggestion !== localModelValue.value
|
|
1820
|
+
).reverse();
|
|
1821
|
+
});
|
|
1822
|
+
const hasSuggestions = computed(
|
|
1823
|
+
() => (storageKey == null ? void 0 : storageKey.value) && suggestions.value && suggestions.value.size > 0
|
|
1824
|
+
);
|
|
1825
|
+
function onSuggestionSelect(suggestion) {
|
|
1826
|
+
var _a;
|
|
1827
|
+
localModelValue.value = suggestion;
|
|
1828
|
+
(_a = suggestionsDropdownEl.value) == null ? void 0 : _a.hide();
|
|
1829
|
+
}
|
|
1830
|
+
function onSuggestionRemove(suggestion) {
|
|
1831
|
+
var _a;
|
|
1832
|
+
(_a = suggestions.value) == null ? void 0 : _a.delete(suggestion);
|
|
1833
|
+
}
|
|
1000
1834
|
const {
|
|
1001
1835
|
HintSlot,
|
|
1002
1836
|
hasHintLabelOrSlot,
|
|
@@ -1065,49 +1899,59 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1065
1899
|
for: unref(hasId),
|
|
1066
1900
|
class: "vv-textarea__label"
|
|
1067
1901
|
}, toDisplayString(unref(label)), 9, _hoisted_1)) : createCommentVNode("v-if", true),
|
|
1068
|
-
createElementVNode(
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1902
|
+
createElementVNode(
|
|
1903
|
+
"div",
|
|
1904
|
+
{
|
|
1905
|
+
ref_key: "wrapperEl",
|
|
1906
|
+
ref: wrapperEl,
|
|
1907
|
+
class: "vv-textarea__wrapper"
|
|
1908
|
+
},
|
|
1909
|
+
[
|
|
1910
|
+
_ctx.$slots.before ? (openBlock(), createElementBlock("div", _hoisted_2, [
|
|
1911
|
+
renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps(unref(slotProps))))
|
|
1912
|
+
])) : createCommentVNode("v-if", true),
|
|
1913
|
+
createElementVNode("div", _hoisted_3, [
|
|
1914
|
+
unref(hasIconBefore) ? (openBlock(), createBlock(
|
|
1915
|
+
_sfc_main$1,
|
|
1916
|
+
mergeProps({ key: 0 }, unref(hasIconBefore), { class: "vv-textarea__icon" }),
|
|
1917
|
+
null,
|
|
1918
|
+
16
|
|
1919
|
+
/* FULL_PROPS */
|
|
1920
|
+
)) : createCommentVNode("v-if", true),
|
|
1921
|
+
withDirectives(createElementVNode("textarea", mergeProps({
|
|
1922
|
+
id: unref(hasId),
|
|
1923
|
+
ref_key: "textareaEl",
|
|
1924
|
+
ref: textareaEl,
|
|
1925
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(localModelValue) ? localModelValue.value = $event : null)
|
|
1926
|
+
}, unref(hasAttrs), {
|
|
1927
|
+
onKeyup: _cache[1] || (_cache[1] = ($event) => emit("keyup", $event))
|
|
1928
|
+
}), null, 16, _hoisted_4), [
|
|
1929
|
+
[vModelText, unref(localModelValue)]
|
|
1930
|
+
]),
|
|
1931
|
+
unref(hasIconAfter) ? (openBlock(), createBlock(
|
|
1932
|
+
_sfc_main$1,
|
|
1933
|
+
mergeProps({ key: 1 }, unref(hasIconAfter), { class: "vv-textarea__icon vv-textarea__icon-after" }),
|
|
1934
|
+
null,
|
|
1935
|
+
16
|
|
1936
|
+
/* FULL_PROPS */
|
|
1937
|
+
)) : createCommentVNode("v-if", true)
|
|
1089
1938
|
]),
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
/* TEXT */
|
|
1107
|
-
)
|
|
1108
|
-
])
|
|
1109
|
-
])) : createCommentVNode("v-if", true)
|
|
1110
|
-
]),
|
|
1939
|
+
_ctx.$slots.after ? (openBlock(), createElementBlock("div", _hoisted_5, [
|
|
1940
|
+
renderSlot(_ctx.$slots, "after", normalizeProps(guardReactiveProps(unref(slotProps))))
|
|
1941
|
+
])) : createCommentVNode("v-if", true),
|
|
1942
|
+
unref(count) ? (openBlock(), createElementBlock("span", _hoisted_6, [
|
|
1943
|
+
renderSlot(_ctx.$slots, "count", normalizeProps(guardReactiveProps(unref(slotProps))), () => [
|
|
1944
|
+
createTextVNode(
|
|
1945
|
+
toDisplayString(unref(countFormatted)),
|
|
1946
|
+
1
|
|
1947
|
+
/* TEXT */
|
|
1948
|
+
)
|
|
1949
|
+
])
|
|
1950
|
+
])) : createCommentVNode("v-if", true)
|
|
1951
|
+
],
|
|
1952
|
+
512
|
|
1953
|
+
/* NEED_PATCH */
|
|
1954
|
+
),
|
|
1111
1955
|
createVNode(unref(HintSlot), {
|
|
1112
1956
|
id: unref(hasHintId),
|
|
1113
1957
|
class: "vv-textarea__hint"
|
|
@@ -1143,7 +1987,62 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
1143
1987
|
]),
|
|
1144
1988
|
key: "3"
|
|
1145
1989
|
} : void 0
|
|
1146
|
-
]), 1032, ["id"])
|
|
1990
|
+
]), 1032, ["id"]),
|
|
1991
|
+
unref(hasSuggestions) ? (openBlock(), createBlock(_sfc_main$4, {
|
|
1992
|
+
key: 1,
|
|
1993
|
+
ref_key: "suggestionsDropdownEl",
|
|
1994
|
+
ref: suggestionsDropdownEl,
|
|
1995
|
+
reference: unref(wrapperEl),
|
|
1996
|
+
"autofocus-first": false,
|
|
1997
|
+
"trigger-width": true
|
|
1998
|
+
}, {
|
|
1999
|
+
items: withCtx(() => [
|
|
2000
|
+
(openBlock(true), createElementBlock(
|
|
2001
|
+
Fragment,
|
|
2002
|
+
null,
|
|
2003
|
+
renderList(unref(filteredSuggestions), (value) => {
|
|
2004
|
+
return openBlock(), createBlock(_sfc_main$2, {
|
|
2005
|
+
key: value,
|
|
2006
|
+
onClick: withModifiers(($event) => onSuggestionSelect(value), ["stop"])
|
|
2007
|
+
}, {
|
|
2008
|
+
default: withCtx(() => [
|
|
2009
|
+
createElementVNode("div", _hoisted_7, [
|
|
2010
|
+
renderSlot(_ctx.$slots, "suggestion", mergeProps({ ref_for: true }, { value }), () => [
|
|
2011
|
+
createTextVNode(
|
|
2012
|
+
toDisplayString(value),
|
|
2013
|
+
1
|
|
2014
|
+
/* TEXT */
|
|
2015
|
+
)
|
|
2016
|
+
])
|
|
2017
|
+
]),
|
|
2018
|
+
unref(suggestions) && unref(hasIconRemoveSuggestion) ? (openBlock(), createElementBlock("button", {
|
|
2019
|
+
key: 0,
|
|
2020
|
+
type: "button",
|
|
2021
|
+
tabindex: "-1",
|
|
2022
|
+
class: "cursor-pointer",
|
|
2023
|
+
title: unref(labelRemoveSuggestion),
|
|
2024
|
+
onClick: withModifiers(($event) => onSuggestionRemove(value), ["stop"])
|
|
2025
|
+
}, [
|
|
2026
|
+
createVNode(
|
|
2027
|
+
_sfc_main$1,
|
|
2028
|
+
mergeProps({ ref_for: true }, unref(hasIconRemoveSuggestion)),
|
|
2029
|
+
null,
|
|
2030
|
+
16
|
|
2031
|
+
/* FULL_PROPS */
|
|
2032
|
+
)
|
|
2033
|
+
], 8, _hoisted_8)) : createCommentVNode("v-if", true)
|
|
2034
|
+
]),
|
|
2035
|
+
_: 2
|
|
2036
|
+
/* DYNAMIC */
|
|
2037
|
+
}, 1032, ["onClick"]);
|
|
2038
|
+
}),
|
|
2039
|
+
128
|
|
2040
|
+
/* KEYED_FRAGMENT */
|
|
2041
|
+
))
|
|
2042
|
+
]),
|
|
2043
|
+
_: 3
|
|
2044
|
+
/* FORWARDED */
|
|
2045
|
+
}, 8, ["reference"])) : createCommentVNode("v-if", true)
|
|
1147
2046
|
],
|
|
1148
2047
|
2
|
|
1149
2048
|
/* CLASS */
|