@stackline/vue-multiselect-dropdown 2.0.0 → 3.0.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/README.md +15 -15
- package/dist/index.cjs +74 -18
- package/dist/index.d.cts +14 -13
- package/dist/index.d.ts +14 -13
- package/dist/index.js +74 -18
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -1,48 +1,45 @@
|
|
|
1
1
|
# @stackline/vue-multiselect-dropdown
|
|
2
2
|
|
|
3
|
-
> A maintained Vue
|
|
3
|
+
> A maintained Vue 3 multiselect dropdown with controlled state, searchable/grouped options, lazy loading hooks, render functions, skins, body-overlay positioning, and ADA-friendly keyboard/ARIA behavior.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@stackline/vue-multiselect-dropdown)
|
|
6
6
|
[](https://github.com/alexandroit/vue-multiselect-dropdown/blob/main/LICENSE)
|
|
7
|
-
[](https://alexandro.net/docs/vue/multiselect/vue-3/)
|
|
8
8
|
|
|
9
|
-
**[Documentation & Live Demos](https://alexandro.net/docs/vue/multiselect/)** | **[Vue
|
|
9
|
+
**[Documentation & Live Demos](https://alexandro.net/docs/vue/multiselect/)** | **[Vue 3 Demo](https://alexandro.net/docs/vue/multiselect/vue-3/)** | **[npm](https://www.npmjs.com/package/@stackline/vue-multiselect-dropdown)** | **[Repository](https://github.com/alexandroit/vue-multiselect-dropdown)**
|
|
10
10
|
|
|
11
|
-
**Current validation package release:** `
|
|
11
|
+
**Current validation package release:** `3.0.0` for Vue `3.x`
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Why this library?
|
|
16
16
|
|
|
17
|
-
`@stackline/vue-multiselect-dropdown` provides a maintained Vue
|
|
17
|
+
`@stackline/vue-multiselect-dropdown` provides a maintained Vue 3 multiselect component for applications that need predictable selection state, search, grouping, skins, keyboard support, and live tested examples.
|
|
18
18
|
|
|
19
|
-
The package follows a familiar Stackline settings contract while staying idiomatic for Vue
|
|
19
|
+
The package follows a familiar Stackline settings contract while staying idiomatic for Vue 3: bind with `v-model`, pass `:data`, customize behavior through `:settings`, and listen for `@select`, `@de-select`, `@select-all`, `@de-select-all`, `@open`, and `@close`.
|
|
20
20
|
|
|
21
21
|
## Vue Version Compatibility
|
|
22
22
|
|
|
23
23
|
| Package family | Vue family | Peer range | First tested runtime | Demo link |
|
|
24
24
|
| :---: | :---: | :---: | :---: | :--- |
|
|
25
|
-
| **
|
|
25
|
+
| **3.x** | **Vue 3 only** | **`>=3.0.0 <4.0.0`** | **3.0.0** | [Vue 3 family docs](https://alexandro.net/docs/vue/multiselect/vue-3/) |
|
|
26
26
|
|
|
27
27
|
## Installation
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
npm install @stackline/vue-multiselect-dropdown@
|
|
30
|
+
npm install @stackline/vue-multiselect-dropdown@3.0.0 --save-exact
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Setup
|
|
34
34
|
|
|
35
35
|
```js
|
|
36
|
-
import
|
|
36
|
+
import { createApp } from 'vue';
|
|
37
37
|
import {
|
|
38
38
|
VueMultiselect,
|
|
39
39
|
VueMultiselectDropdown
|
|
40
40
|
} from '@stackline/vue-multiselect-dropdown';
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
new Vue({
|
|
45
|
-
el: '#app',
|
|
42
|
+
const app = createApp({
|
|
46
43
|
components: { VueMultiselectDropdown },
|
|
47
44
|
data() {
|
|
48
45
|
return {
|
|
@@ -63,6 +60,9 @@ new Vue({
|
|
|
63
60
|
};
|
|
64
61
|
}
|
|
65
62
|
});
|
|
63
|
+
|
|
64
|
+
app.use(VueMultiselect);
|
|
65
|
+
app.mount('#app');
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
```html
|
|
@@ -129,10 +129,10 @@ npm run build
|
|
|
129
129
|
npm test
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
Vue
|
|
132
|
+
Vue 3 docs:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
|
-
cd docs-src/vue-
|
|
135
|
+
cd docs-src/vue-3
|
|
136
136
|
npm install
|
|
137
137
|
npm run build
|
|
138
138
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,9 @@ __export(index_exports, {
|
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(index_exports);
|
|
29
29
|
|
|
30
|
+
// src/VueMultiselectDropdown.ts
|
|
31
|
+
var import_vue = require("vue");
|
|
32
|
+
|
|
30
33
|
// src/styles.ts
|
|
31
34
|
var STYLE_ID = "stackline-vue-multiselect-dropdown-styles";
|
|
32
35
|
var styles = `
|
|
@@ -1063,7 +1066,7 @@ var styles = `
|
|
|
1063
1066
|
}
|
|
1064
1067
|
}
|
|
1065
1068
|
|
|
1066
|
-
/* stackline-
|
|
1069
|
+
/* stackline-vue3-live-20260527 */
|
|
1067
1070
|
`;
|
|
1068
1071
|
function ensureDropdownStyles() {
|
|
1069
1072
|
if (typeof document === "undefined") {
|
|
@@ -1141,12 +1144,45 @@ function iconPath(name) {
|
|
|
1141
1144
|
}
|
|
1142
1145
|
return "M604.501,134.782c-9.999-10.05-26.222-10.05-36.221,0L306.014,422.558L43.721,134.782c-9.999-10.05-26.223-10.05-36.222,0s-9.999,26.35,0,36.399l279.103,306.241c5.331,5.357,12.422,7.652,19.386,7.296c6.988,0.356,14.055-1.939,19.386-7.296l279.128-306.268C614.5,161.106,614.5,144.832,604.501,134.782z";
|
|
1143
1146
|
}
|
|
1144
|
-
function renderIcon(
|
|
1147
|
+
function renderIcon(h2, name, className = "vmsd-icon") {
|
|
1145
1148
|
const viewBox = name === "remove" ? "0 0 47.971 47.971" : name === "clear" ? "0 0 51.976 51.976" : name === "search" ? "0 0 615.52 615.52" : "0 0 612 612";
|
|
1146
|
-
return
|
|
1147
|
-
|
|
1149
|
+
return h2("svg", { class: className, attrs: { viewBox, focusable: "false", "aria-hidden": "true" } }, [
|
|
1150
|
+
h2("path", { attrs: { d: iconPath(name) } })
|
|
1148
1151
|
]);
|
|
1149
1152
|
}
|
|
1153
|
+
function capitalize(value) {
|
|
1154
|
+
return value ? value.charAt(0).toUpperCase() + value.slice(1) : value;
|
|
1155
|
+
}
|
|
1156
|
+
function normalizeVue2RenderData(data) {
|
|
1157
|
+
if (!data) {
|
|
1158
|
+
return null;
|
|
1159
|
+
}
|
|
1160
|
+
const props = {};
|
|
1161
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1162
|
+
if (key === "attrs" || key === "domProps") {
|
|
1163
|
+
Object.assign(props, value);
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
if (key === "on" && value && typeof value === "object") {
|
|
1167
|
+
for (const [eventName, handler] of Object.entries(value)) {
|
|
1168
|
+
props[`on${capitalize(eventName)}`] = handler;
|
|
1169
|
+
}
|
|
1170
|
+
continue;
|
|
1171
|
+
}
|
|
1172
|
+
props[key] = value;
|
|
1173
|
+
}
|
|
1174
|
+
return props;
|
|
1175
|
+
}
|
|
1176
|
+
var h = (...args) => {
|
|
1177
|
+
const [tag, data, children] = args;
|
|
1178
|
+
if (args.length === 1) {
|
|
1179
|
+
return (0, import_vue.h)(tag);
|
|
1180
|
+
}
|
|
1181
|
+
if (args.length === 2 && (Array.isArray(data) || typeof data === "string" || typeof data === "number" || data == null)) {
|
|
1182
|
+
return (0, import_vue.h)(tag, null, data);
|
|
1183
|
+
}
|
|
1184
|
+
return (0, import_vue.h)(tag, normalizeVue2RenderData(data), children);
|
|
1185
|
+
};
|
|
1150
1186
|
function isPrimitiveItem(item) {
|
|
1151
1187
|
return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
|
|
1152
1188
|
}
|
|
@@ -1235,11 +1271,11 @@ function mergeUniqueItems(base, extra, settings) {
|
|
|
1235
1271
|
}
|
|
1236
1272
|
return Array.from(bucket.values());
|
|
1237
1273
|
}
|
|
1238
|
-
function callRenderFunction(renderFunction,
|
|
1274
|
+
function callRenderFunction(renderFunction, h2, item, context) {
|
|
1239
1275
|
if (!renderFunction) {
|
|
1240
1276
|
return null;
|
|
1241
1277
|
}
|
|
1242
|
-
return renderFunction(item, context,
|
|
1278
|
+
return renderFunction(item, context, h2);
|
|
1243
1279
|
}
|
|
1244
1280
|
function escapeSelectorValue(value) {
|
|
1245
1281
|
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
@@ -1259,15 +1295,31 @@ function isTextInputTarget(target) {
|
|
|
1259
1295
|
}
|
|
1260
1296
|
var VueMultiselectDropdown = {
|
|
1261
1297
|
name: "VueMultiselectDropdown",
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1298
|
+
emits: [
|
|
1299
|
+
"update:modelValue",
|
|
1300
|
+
"input",
|
|
1301
|
+
"update:selectedItems",
|
|
1302
|
+
"change",
|
|
1303
|
+
"select",
|
|
1304
|
+
"de-select",
|
|
1305
|
+
"select-all",
|
|
1306
|
+
"de-select-all",
|
|
1307
|
+
"group-select",
|
|
1308
|
+
"group-de-select",
|
|
1309
|
+
"scroll-to-end",
|
|
1310
|
+
"add-filter-new-item",
|
|
1311
|
+
"open",
|
|
1312
|
+
"close"
|
|
1313
|
+
],
|
|
1266
1314
|
props: {
|
|
1267
1315
|
data: {
|
|
1268
1316
|
type: Array,
|
|
1269
1317
|
default: () => []
|
|
1270
1318
|
},
|
|
1319
|
+
modelValue: {
|
|
1320
|
+
type: Array,
|
|
1321
|
+
default: void 0
|
|
1322
|
+
},
|
|
1271
1323
|
value: {
|
|
1272
1324
|
type: Array,
|
|
1273
1325
|
default: void 0
|
|
@@ -1333,6 +1385,9 @@ var VueMultiselectDropdown = {
|
|
|
1333
1385
|
if (Array.isArray(this.selectedItems)) {
|
|
1334
1386
|
return this.selectedItems;
|
|
1335
1387
|
}
|
|
1388
|
+
if (Array.isArray(this.modelValue)) {
|
|
1389
|
+
return this.modelValue;
|
|
1390
|
+
}
|
|
1336
1391
|
if (Array.isArray(this.value)) {
|
|
1337
1392
|
return this.value;
|
|
1338
1393
|
}
|
|
@@ -1397,7 +1452,7 @@ var VueMultiselectDropdown = {
|
|
|
1397
1452
|
window.addEventListener("resize", this.updateMenuPosition);
|
|
1398
1453
|
window.addEventListener("scroll", this.updateMenuPosition, true);
|
|
1399
1454
|
},
|
|
1400
|
-
|
|
1455
|
+
beforeUnmount() {
|
|
1401
1456
|
document.removeEventListener("click", this.onDocumentClick, true);
|
|
1402
1457
|
document.removeEventListener("keydown", this.onDocumentKeydown, true);
|
|
1403
1458
|
window.removeEventListener("resize", this.updateMenuPosition);
|
|
@@ -1419,9 +1474,10 @@ var VueMultiselectDropdown = {
|
|
|
1419
1474
|
return this.filteredItems.filter((item) => !isDisabledItem(item));
|
|
1420
1475
|
},
|
|
1421
1476
|
emitSelection(items) {
|
|
1422
|
-
if (!Array.isArray(this.selectedItems) && !Array.isArray(this.value)) {
|
|
1477
|
+
if (!Array.isArray(this.selectedItems) && !Array.isArray(this.modelValue) && !Array.isArray(this.value)) {
|
|
1423
1478
|
this.internalSelected = items;
|
|
1424
1479
|
}
|
|
1480
|
+
this.$emit("update:modelValue", items);
|
|
1425
1481
|
this.$emit("input", items);
|
|
1426
1482
|
this.$emit("update:selectedItems", items);
|
|
1427
1483
|
this.$emit("change", items);
|
|
@@ -1786,7 +1842,7 @@ var VueMultiselectDropdown = {
|
|
|
1786
1842
|
this.menuStyle = style;
|
|
1787
1843
|
}
|
|
1788
1844
|
},
|
|
1789
|
-
render(
|
|
1845
|
+
render() {
|
|
1790
1846
|
const settings = this.resolvedSettings;
|
|
1791
1847
|
const skin = String(settings.skin || settings.theme || "classic");
|
|
1792
1848
|
const skinFallbackClass = ["classic", "material", "dark", "custom"].includes(skin) ? "" : "theme-custom";
|
|
@@ -2074,11 +2130,11 @@ var StacklineVueMultiselect = VueMultiselectDropdown;
|
|
|
2074
2130
|
|
|
2075
2131
|
// src/plugin.ts
|
|
2076
2132
|
var VueMultiselect = {
|
|
2077
|
-
install(
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2133
|
+
install(app) {
|
|
2134
|
+
app.component("StacklineVueMultiselect", VueMultiselectDropdown);
|
|
2135
|
+
app.component("VueMultiselectDropdown", VueMultiselectDropdown);
|
|
2136
|
+
app.component("vue-multiselect-dropdown", VueMultiselectDropdown);
|
|
2137
|
+
app.component("stackline-vue-multiselect", VueMultiselectDropdown);
|
|
2082
2138
|
}
|
|
2083
2139
|
};
|
|
2084
2140
|
var plugin_default = VueMultiselect;
|
package/dist/index.d.cts
CHANGED
|
@@ -70,22 +70,22 @@ interface VueMultiselectPlugin {
|
|
|
70
70
|
install: (Vue: any) => void;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
type CreateElement = (...args: any[]) => any;
|
|
74
73
|
type GroupedItems<T> = Array<{
|
|
75
74
|
name: string;
|
|
76
75
|
items: T[];
|
|
77
76
|
}>;
|
|
78
77
|
declare const VueMultiselectDropdown: {
|
|
79
78
|
name: string;
|
|
80
|
-
|
|
81
|
-
prop: string;
|
|
82
|
-
event: string;
|
|
83
|
-
};
|
|
79
|
+
emits: string[];
|
|
84
80
|
props: {
|
|
85
81
|
data: {
|
|
86
82
|
type: ArrayConstructor;
|
|
87
83
|
default: () => never[];
|
|
88
84
|
};
|
|
85
|
+
modelValue: {
|
|
86
|
+
type: ArrayConstructor;
|
|
87
|
+
default: undefined;
|
|
88
|
+
};
|
|
89
89
|
value: {
|
|
90
90
|
type: ArrayConstructor;
|
|
91
91
|
default: undefined;
|
|
@@ -151,7 +151,7 @@ declare const VueMultiselectDropdown: {
|
|
|
151
151
|
};
|
|
152
152
|
};
|
|
153
153
|
mounted(this: any): void;
|
|
154
|
-
|
|
154
|
+
beforeUnmount(this: any): void;
|
|
155
155
|
methods: {
|
|
156
156
|
getLabel(this: any, item: DropdownItem): string;
|
|
157
157
|
getKey(this: any, item: DropdownItem): string;
|
|
@@ -183,19 +183,20 @@ declare const VueMultiselectDropdown: {
|
|
|
183
183
|
restoreMenuToComponent(this: any): void;
|
|
184
184
|
updateMenuPosition(this: any): void;
|
|
185
185
|
};
|
|
186
|
-
render(this: any
|
|
186
|
+
render(this: any): any;
|
|
187
187
|
};
|
|
188
188
|
declare const StacklineVueMultiselect: {
|
|
189
189
|
name: string;
|
|
190
|
-
|
|
191
|
-
prop: string;
|
|
192
|
-
event: string;
|
|
193
|
-
};
|
|
190
|
+
emits: string[];
|
|
194
191
|
props: {
|
|
195
192
|
data: {
|
|
196
193
|
type: ArrayConstructor;
|
|
197
194
|
default: () => never[];
|
|
198
195
|
};
|
|
196
|
+
modelValue: {
|
|
197
|
+
type: ArrayConstructor;
|
|
198
|
+
default: undefined;
|
|
199
|
+
};
|
|
199
200
|
value: {
|
|
200
201
|
type: ArrayConstructor;
|
|
201
202
|
default: undefined;
|
|
@@ -261,7 +262,7 @@ declare const StacklineVueMultiselect: {
|
|
|
261
262
|
};
|
|
262
263
|
};
|
|
263
264
|
mounted(this: any): void;
|
|
264
|
-
|
|
265
|
+
beforeUnmount(this: any): void;
|
|
265
266
|
methods: {
|
|
266
267
|
getLabel(this: any, item: DropdownItem): string;
|
|
267
268
|
getKey(this: any, item: DropdownItem): string;
|
|
@@ -293,7 +294,7 @@ declare const StacklineVueMultiselect: {
|
|
|
293
294
|
restoreMenuToComponent(this: any): void;
|
|
294
295
|
updateMenuPosition(this: any): void;
|
|
295
296
|
};
|
|
296
|
-
render(this: any
|
|
297
|
+
render(this: any): any;
|
|
297
298
|
};
|
|
298
299
|
|
|
299
300
|
declare const VueMultiselect: VueMultiselectPlugin;
|
package/dist/index.d.ts
CHANGED
|
@@ -70,22 +70,22 @@ interface VueMultiselectPlugin {
|
|
|
70
70
|
install: (Vue: any) => void;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
type CreateElement = (...args: any[]) => any;
|
|
74
73
|
type GroupedItems<T> = Array<{
|
|
75
74
|
name: string;
|
|
76
75
|
items: T[];
|
|
77
76
|
}>;
|
|
78
77
|
declare const VueMultiselectDropdown: {
|
|
79
78
|
name: string;
|
|
80
|
-
|
|
81
|
-
prop: string;
|
|
82
|
-
event: string;
|
|
83
|
-
};
|
|
79
|
+
emits: string[];
|
|
84
80
|
props: {
|
|
85
81
|
data: {
|
|
86
82
|
type: ArrayConstructor;
|
|
87
83
|
default: () => never[];
|
|
88
84
|
};
|
|
85
|
+
modelValue: {
|
|
86
|
+
type: ArrayConstructor;
|
|
87
|
+
default: undefined;
|
|
88
|
+
};
|
|
89
89
|
value: {
|
|
90
90
|
type: ArrayConstructor;
|
|
91
91
|
default: undefined;
|
|
@@ -151,7 +151,7 @@ declare const VueMultiselectDropdown: {
|
|
|
151
151
|
};
|
|
152
152
|
};
|
|
153
153
|
mounted(this: any): void;
|
|
154
|
-
|
|
154
|
+
beforeUnmount(this: any): void;
|
|
155
155
|
methods: {
|
|
156
156
|
getLabel(this: any, item: DropdownItem): string;
|
|
157
157
|
getKey(this: any, item: DropdownItem): string;
|
|
@@ -183,19 +183,20 @@ declare const VueMultiselectDropdown: {
|
|
|
183
183
|
restoreMenuToComponent(this: any): void;
|
|
184
184
|
updateMenuPosition(this: any): void;
|
|
185
185
|
};
|
|
186
|
-
render(this: any
|
|
186
|
+
render(this: any): any;
|
|
187
187
|
};
|
|
188
188
|
declare const StacklineVueMultiselect: {
|
|
189
189
|
name: string;
|
|
190
|
-
|
|
191
|
-
prop: string;
|
|
192
|
-
event: string;
|
|
193
|
-
};
|
|
190
|
+
emits: string[];
|
|
194
191
|
props: {
|
|
195
192
|
data: {
|
|
196
193
|
type: ArrayConstructor;
|
|
197
194
|
default: () => never[];
|
|
198
195
|
};
|
|
196
|
+
modelValue: {
|
|
197
|
+
type: ArrayConstructor;
|
|
198
|
+
default: undefined;
|
|
199
|
+
};
|
|
199
200
|
value: {
|
|
200
201
|
type: ArrayConstructor;
|
|
201
202
|
default: undefined;
|
|
@@ -261,7 +262,7 @@ declare const StacklineVueMultiselect: {
|
|
|
261
262
|
};
|
|
262
263
|
};
|
|
263
264
|
mounted(this: any): void;
|
|
264
|
-
|
|
265
|
+
beforeUnmount(this: any): void;
|
|
265
266
|
methods: {
|
|
266
267
|
getLabel(this: any, item: DropdownItem): string;
|
|
267
268
|
getKey(this: any, item: DropdownItem): string;
|
|
@@ -293,7 +294,7 @@ declare const StacklineVueMultiselect: {
|
|
|
293
294
|
restoreMenuToComponent(this: any): void;
|
|
294
295
|
updateMenuPosition(this: any): void;
|
|
295
296
|
};
|
|
296
|
-
render(this: any
|
|
297
|
+
render(this: any): any;
|
|
297
298
|
};
|
|
298
299
|
|
|
299
300
|
declare const VueMultiselect: VueMultiselectPlugin;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/VueMultiselectDropdown.ts
|
|
2
|
+
import { h as vueH } from "vue";
|
|
3
|
+
|
|
1
4
|
// src/styles.ts
|
|
2
5
|
var STYLE_ID = "stackline-vue-multiselect-dropdown-styles";
|
|
3
6
|
var styles = `
|
|
@@ -1034,7 +1037,7 @@ var styles = `
|
|
|
1034
1037
|
}
|
|
1035
1038
|
}
|
|
1036
1039
|
|
|
1037
|
-
/* stackline-
|
|
1040
|
+
/* stackline-vue3-live-20260527 */
|
|
1038
1041
|
`;
|
|
1039
1042
|
function ensureDropdownStyles() {
|
|
1040
1043
|
if (typeof document === "undefined") {
|
|
@@ -1112,12 +1115,45 @@ function iconPath(name) {
|
|
|
1112
1115
|
}
|
|
1113
1116
|
return "M604.501,134.782c-9.999-10.05-26.222-10.05-36.221,0L306.014,422.558L43.721,134.782c-9.999-10.05-26.223-10.05-36.222,0s-9.999,26.35,0,36.399l279.103,306.241c5.331,5.357,12.422,7.652,19.386,7.296c6.988,0.356,14.055-1.939,19.386-7.296l279.128-306.268C614.5,161.106,614.5,144.832,604.501,134.782z";
|
|
1114
1117
|
}
|
|
1115
|
-
function renderIcon(
|
|
1118
|
+
function renderIcon(h2, name, className = "vmsd-icon") {
|
|
1116
1119
|
const viewBox = name === "remove" ? "0 0 47.971 47.971" : name === "clear" ? "0 0 51.976 51.976" : name === "search" ? "0 0 615.52 615.52" : "0 0 612 612";
|
|
1117
|
-
return
|
|
1118
|
-
|
|
1120
|
+
return h2("svg", { class: className, attrs: { viewBox, focusable: "false", "aria-hidden": "true" } }, [
|
|
1121
|
+
h2("path", { attrs: { d: iconPath(name) } })
|
|
1119
1122
|
]);
|
|
1120
1123
|
}
|
|
1124
|
+
function capitalize(value) {
|
|
1125
|
+
return value ? value.charAt(0).toUpperCase() + value.slice(1) : value;
|
|
1126
|
+
}
|
|
1127
|
+
function normalizeVue2RenderData(data) {
|
|
1128
|
+
if (!data) {
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
const props = {};
|
|
1132
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1133
|
+
if (key === "attrs" || key === "domProps") {
|
|
1134
|
+
Object.assign(props, value);
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
if (key === "on" && value && typeof value === "object") {
|
|
1138
|
+
for (const [eventName, handler] of Object.entries(value)) {
|
|
1139
|
+
props[`on${capitalize(eventName)}`] = handler;
|
|
1140
|
+
}
|
|
1141
|
+
continue;
|
|
1142
|
+
}
|
|
1143
|
+
props[key] = value;
|
|
1144
|
+
}
|
|
1145
|
+
return props;
|
|
1146
|
+
}
|
|
1147
|
+
var h = (...args) => {
|
|
1148
|
+
const [tag, data, children] = args;
|
|
1149
|
+
if (args.length === 1) {
|
|
1150
|
+
return vueH(tag);
|
|
1151
|
+
}
|
|
1152
|
+
if (args.length === 2 && (Array.isArray(data) || typeof data === "string" || typeof data === "number" || data == null)) {
|
|
1153
|
+
return vueH(tag, null, data);
|
|
1154
|
+
}
|
|
1155
|
+
return vueH(tag, normalizeVue2RenderData(data), children);
|
|
1156
|
+
};
|
|
1121
1157
|
function isPrimitiveItem(item) {
|
|
1122
1158
|
return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
|
|
1123
1159
|
}
|
|
@@ -1206,11 +1242,11 @@ function mergeUniqueItems(base, extra, settings) {
|
|
|
1206
1242
|
}
|
|
1207
1243
|
return Array.from(bucket.values());
|
|
1208
1244
|
}
|
|
1209
|
-
function callRenderFunction(renderFunction,
|
|
1245
|
+
function callRenderFunction(renderFunction, h2, item, context) {
|
|
1210
1246
|
if (!renderFunction) {
|
|
1211
1247
|
return null;
|
|
1212
1248
|
}
|
|
1213
|
-
return renderFunction(item, context,
|
|
1249
|
+
return renderFunction(item, context, h2);
|
|
1214
1250
|
}
|
|
1215
1251
|
function escapeSelectorValue(value) {
|
|
1216
1252
|
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
@@ -1230,15 +1266,31 @@ function isTextInputTarget(target) {
|
|
|
1230
1266
|
}
|
|
1231
1267
|
var VueMultiselectDropdown = {
|
|
1232
1268
|
name: "VueMultiselectDropdown",
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1269
|
+
emits: [
|
|
1270
|
+
"update:modelValue",
|
|
1271
|
+
"input",
|
|
1272
|
+
"update:selectedItems",
|
|
1273
|
+
"change",
|
|
1274
|
+
"select",
|
|
1275
|
+
"de-select",
|
|
1276
|
+
"select-all",
|
|
1277
|
+
"de-select-all",
|
|
1278
|
+
"group-select",
|
|
1279
|
+
"group-de-select",
|
|
1280
|
+
"scroll-to-end",
|
|
1281
|
+
"add-filter-new-item",
|
|
1282
|
+
"open",
|
|
1283
|
+
"close"
|
|
1284
|
+
],
|
|
1237
1285
|
props: {
|
|
1238
1286
|
data: {
|
|
1239
1287
|
type: Array,
|
|
1240
1288
|
default: () => []
|
|
1241
1289
|
},
|
|
1290
|
+
modelValue: {
|
|
1291
|
+
type: Array,
|
|
1292
|
+
default: void 0
|
|
1293
|
+
},
|
|
1242
1294
|
value: {
|
|
1243
1295
|
type: Array,
|
|
1244
1296
|
default: void 0
|
|
@@ -1304,6 +1356,9 @@ var VueMultiselectDropdown = {
|
|
|
1304
1356
|
if (Array.isArray(this.selectedItems)) {
|
|
1305
1357
|
return this.selectedItems;
|
|
1306
1358
|
}
|
|
1359
|
+
if (Array.isArray(this.modelValue)) {
|
|
1360
|
+
return this.modelValue;
|
|
1361
|
+
}
|
|
1307
1362
|
if (Array.isArray(this.value)) {
|
|
1308
1363
|
return this.value;
|
|
1309
1364
|
}
|
|
@@ -1368,7 +1423,7 @@ var VueMultiselectDropdown = {
|
|
|
1368
1423
|
window.addEventListener("resize", this.updateMenuPosition);
|
|
1369
1424
|
window.addEventListener("scroll", this.updateMenuPosition, true);
|
|
1370
1425
|
},
|
|
1371
|
-
|
|
1426
|
+
beforeUnmount() {
|
|
1372
1427
|
document.removeEventListener("click", this.onDocumentClick, true);
|
|
1373
1428
|
document.removeEventListener("keydown", this.onDocumentKeydown, true);
|
|
1374
1429
|
window.removeEventListener("resize", this.updateMenuPosition);
|
|
@@ -1390,9 +1445,10 @@ var VueMultiselectDropdown = {
|
|
|
1390
1445
|
return this.filteredItems.filter((item) => !isDisabledItem(item));
|
|
1391
1446
|
},
|
|
1392
1447
|
emitSelection(items) {
|
|
1393
|
-
if (!Array.isArray(this.selectedItems) && !Array.isArray(this.value)) {
|
|
1448
|
+
if (!Array.isArray(this.selectedItems) && !Array.isArray(this.modelValue) && !Array.isArray(this.value)) {
|
|
1394
1449
|
this.internalSelected = items;
|
|
1395
1450
|
}
|
|
1451
|
+
this.$emit("update:modelValue", items);
|
|
1396
1452
|
this.$emit("input", items);
|
|
1397
1453
|
this.$emit("update:selectedItems", items);
|
|
1398
1454
|
this.$emit("change", items);
|
|
@@ -1757,7 +1813,7 @@ var VueMultiselectDropdown = {
|
|
|
1757
1813
|
this.menuStyle = style;
|
|
1758
1814
|
}
|
|
1759
1815
|
},
|
|
1760
|
-
render(
|
|
1816
|
+
render() {
|
|
1761
1817
|
const settings = this.resolvedSettings;
|
|
1762
1818
|
const skin = String(settings.skin || settings.theme || "classic");
|
|
1763
1819
|
const skinFallbackClass = ["classic", "material", "dark", "custom"].includes(skin) ? "" : "theme-custom";
|
|
@@ -2045,11 +2101,11 @@ var StacklineVueMultiselect = VueMultiselectDropdown;
|
|
|
2045
2101
|
|
|
2046
2102
|
// src/plugin.ts
|
|
2047
2103
|
var VueMultiselect = {
|
|
2048
|
-
install(
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2104
|
+
install(app) {
|
|
2105
|
+
app.component("StacklineVueMultiselect", VueMultiselectDropdown);
|
|
2106
|
+
app.component("VueMultiselectDropdown", VueMultiselectDropdown);
|
|
2107
|
+
app.component("vue-multiselect-dropdown", VueMultiselectDropdown);
|
|
2108
|
+
app.component("stackline-vue-multiselect", VueMultiselectDropdown);
|
|
2053
2109
|
}
|
|
2054
2110
|
};
|
|
2055
2111
|
var plugin_default = VueMultiselect;
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackline/vue-multiselect-dropdown",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A maintained Vue
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A maintained Vue 3 multiselect dropdown with controlled state, skins, live docs, body overlays, and ADA-friendly keyboard support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vue",
|
|
7
|
-
"vue
|
|
7
|
+
"vue 3",
|
|
8
8
|
"multiselect",
|
|
9
9
|
"multiselect-dropdown",
|
|
10
10
|
"multi-select",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"accessibility",
|
|
16
16
|
"aria"
|
|
17
17
|
],
|
|
18
|
-
"homepage": "https://alexandro.net/docs/vue/multiselect/vue-
|
|
18
|
+
"homepage": "https://alexandro.net/docs/vue/multiselect/vue-3/",
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/alexandroit/vue-multiselect-dropdown/issues"
|
|
21
21
|
},
|
|
@@ -43,16 +43,19 @@
|
|
|
43
43
|
"sideEffects": false,
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsup",
|
|
46
|
-
"clean": "rm -rf dist docs/vue-
|
|
46
|
+
"clean": "rm -rf dist docs/vue-3",
|
|
47
47
|
"docs:install:vue-2": "cd docs-src/vue-2 && npm install",
|
|
48
|
+
"docs:install:vue-3": "cd docs-src/vue-3 && npm install",
|
|
48
49
|
"build:docs:vue-2": "cd docs-src/vue-2 && npm run build",
|
|
49
|
-
"build:docs": "npm run build
|
|
50
|
+
"build:docs:vue-3": "cd docs-src/vue-3 && npm run build",
|
|
51
|
+
"build:docs": "npm run build:docs:vue-3",
|
|
50
52
|
"publish:verdaccio:vue-2": "npm run build && npm publish --registry=http://127.0.0.1:4873 --@stackline:registry=http://127.0.0.1:4873 --tag vue-2 --access public",
|
|
53
|
+
"publish:verdaccio:vue-3": "npm run build && npm publish --registry=http://127.0.0.1:4873 --@stackline:registry=http://127.0.0.1:4873 --tag vue-3 --access public",
|
|
51
54
|
"typecheck": "tsc --noEmit",
|
|
52
55
|
"test": "node --test tests/*.test.cjs"
|
|
53
56
|
},
|
|
54
57
|
"peerDependencies": {
|
|
55
|
-
"vue": ">=
|
|
58
|
+
"vue": ">=3.0.0 <4.0.0"
|
|
56
59
|
},
|
|
57
60
|
"publishConfig": {
|
|
58
61
|
"access": "public"
|
|
@@ -60,6 +63,6 @@
|
|
|
60
63
|
"devDependencies": {
|
|
61
64
|
"tsup": "8.5.1",
|
|
62
65
|
"typescript": "5.9.3",
|
|
63
|
-
"vue": "
|
|
66
|
+
"vue": "3.0.0"
|
|
64
67
|
}
|
|
65
68
|
}
|