@pequity/squirrel 6.0.7 → 6.0.8
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/cjs/chunks/p-dropdown-select.js +26 -4
- package/dist/es/chunks/p-dropdown-select.js +27 -5
- package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +21 -4
- package/package.json +1 -1
- package/squirrel/components/p-dropdown-select/p-dropdown-select.spec.js +98 -0
- package/squirrel/components/p-dropdown-select/p-dropdown-select.stories.js +36 -0
- package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +27 -4
|
@@ -74,14 +74,14 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
/**
|
|
77
|
-
* Set property of **items
|
|
77
|
+
* Set property of **items**'s text value
|
|
78
78
|
*/
|
|
79
79
|
itemText: {
|
|
80
80
|
type: String,
|
|
81
81
|
default: "text"
|
|
82
82
|
},
|
|
83
83
|
/**
|
|
84
|
-
* Set property of **items
|
|
84
|
+
* Set property of **items**'s value - must be primitive.
|
|
85
85
|
*/
|
|
86
86
|
itemValue: {
|
|
87
87
|
type: [String, Number],
|
|
@@ -160,9 +160,16 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
160
160
|
disabledBy: {
|
|
161
161
|
type: String,
|
|
162
162
|
default: "disabled"
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Enables the ability to create new items when no search results are found
|
|
166
|
+
*/
|
|
167
|
+
creatable: {
|
|
168
|
+
type: Boolean,
|
|
169
|
+
default: false
|
|
163
170
|
}
|
|
164
171
|
},
|
|
165
|
-
emits: ["update:modelValue", "select"],
|
|
172
|
+
emits: ["update:modelValue", "select", "create"],
|
|
166
173
|
setup(__props, { emit: __emit }) {
|
|
167
174
|
const emit = __emit;
|
|
168
175
|
const props = __props;
|
|
@@ -264,6 +271,10 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
264
271
|
destroyNavigationSvc();
|
|
265
272
|
(_b = (_a = formControl.value) == null ? void 0 : _a.querySelector("button")) == null ? void 0 : _b.focus();
|
|
266
273
|
};
|
|
274
|
+
const handleCreate = () => {
|
|
275
|
+
emit("create", search.value);
|
|
276
|
+
dropdownShow.value = false;
|
|
277
|
+
};
|
|
267
278
|
return (_ctx, _cache) => {
|
|
268
279
|
const _directive_close_popper = vue.resolveDirective("close-popper");
|
|
269
280
|
return vue.openBlock(), vue.createElementBlock("div", {
|
|
@@ -398,7 +409,18 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
398
409
|
!vue.unref(computedItems).length ? vue.renderSlot(_ctx.$slots, "no-items", { key: 0 }, () => [
|
|
399
410
|
vue.createElementVNode("div", {
|
|
400
411
|
class: vue.normalizeClass(["flex items-center justify-center", vue.unref(pSelectList.SIZES)[__props.size]])
|
|
401
|
-
},
|
|
412
|
+
}, [
|
|
413
|
+
__props.creatable && vue.unref(search) ? (vue.openBlock(), vue.createElementBlock("button", {
|
|
414
|
+
key: 0,
|
|
415
|
+
class: "hover:text-primary-hover flex items-center gap-2 font-medium text-p-blue-40",
|
|
416
|
+
onClick: handleCreate
|
|
417
|
+
}, [
|
|
418
|
+
vue.createVNode(pIcon_vue_vue_type_script_setup_true_lang._sfc_main, { icon: "fe:plus-circle" }),
|
|
419
|
+
vue.createTextVNode(" Add '" + vue.toDisplayString(vue.unref(search)) + "' ", 1)
|
|
420
|
+
])) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
|
|
421
|
+
vue.createTextVNode("No items found")
|
|
422
|
+
], 64))
|
|
423
|
+
], 2)
|
|
402
424
|
]) : vue.createCommentVNode("", true)
|
|
403
425
|
], 6)
|
|
404
426
|
], 16)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, ref, useAttrs, computed, watch, onMounted, onUnmounted, resolveDirective, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, toDisplayString, createCommentVNode, createVNode, mergeProps, withCtx, createElementVNode, isRef, Fragment, renderList, withDirectives, renderSlot, withModifiers, vShow } from "vue";
|
|
1
|
+
import { defineComponent, ref, useAttrs, computed, watch, onMounted, onUnmounted, resolveDirective, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, toDisplayString, createCommentVNode, createVNode, mergeProps, withCtx, createElementVNode, isRef, Fragment, renderList, withDirectives, renderSlot, createTextVNode, withModifiers, vShow } from "vue";
|
|
2
2
|
import PDropdown from "../p-dropdown.js";
|
|
3
3
|
import { _ as _sfc_main$1 } from "./p-icon.js";
|
|
4
4
|
import PInputSearch from "../p-input-search.js";
|
|
@@ -73,14 +73,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
/**
|
|
76
|
-
* Set property of **items
|
|
76
|
+
* Set property of **items**'s text value
|
|
77
77
|
*/
|
|
78
78
|
itemText: {
|
|
79
79
|
type: String,
|
|
80
80
|
default: "text"
|
|
81
81
|
},
|
|
82
82
|
/**
|
|
83
|
-
* Set property of **items
|
|
83
|
+
* Set property of **items**'s value - must be primitive.
|
|
84
84
|
*/
|
|
85
85
|
itemValue: {
|
|
86
86
|
type: [String, Number],
|
|
@@ -159,9 +159,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
159
159
|
disabledBy: {
|
|
160
160
|
type: String,
|
|
161
161
|
default: "disabled"
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Enables the ability to create new items when no search results are found
|
|
165
|
+
*/
|
|
166
|
+
creatable: {
|
|
167
|
+
type: Boolean,
|
|
168
|
+
default: false
|
|
162
169
|
}
|
|
163
170
|
},
|
|
164
|
-
emits: ["update:modelValue", "select"],
|
|
171
|
+
emits: ["update:modelValue", "select", "create"],
|
|
165
172
|
setup(__props, { emit: __emit }) {
|
|
166
173
|
const emit = __emit;
|
|
167
174
|
const props = __props;
|
|
@@ -263,6 +270,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
263
270
|
destroyNavigationSvc();
|
|
264
271
|
(_b = (_a = formControl.value) == null ? void 0 : _a.querySelector("button")) == null ? void 0 : _b.focus();
|
|
265
272
|
};
|
|
273
|
+
const handleCreate = () => {
|
|
274
|
+
emit("create", search.value);
|
|
275
|
+
dropdownShow.value = false;
|
|
276
|
+
};
|
|
266
277
|
return (_ctx, _cache) => {
|
|
267
278
|
const _directive_close_popper = resolveDirective("close-popper");
|
|
268
279
|
return openBlock(), createElementBlock("div", {
|
|
@@ -397,7 +408,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
397
408
|
!unref(computedItems).length ? renderSlot(_ctx.$slots, "no-items", { key: 0 }, () => [
|
|
398
409
|
createElementVNode("div", {
|
|
399
410
|
class: normalizeClass(["flex items-center justify-center", unref(SIZES)[__props.size]])
|
|
400
|
-
},
|
|
411
|
+
}, [
|
|
412
|
+
__props.creatable && unref(search) ? (openBlock(), createElementBlock("button", {
|
|
413
|
+
key: 0,
|
|
414
|
+
class: "hover:text-primary-hover flex items-center gap-2 font-medium text-p-blue-40",
|
|
415
|
+
onClick: handleCreate
|
|
416
|
+
}, [
|
|
417
|
+
createVNode(_sfc_main$1, { icon: "fe:plus-circle" }),
|
|
418
|
+
createTextVNode(" Add '" + toDisplayString(unref(search)) + "' ", 1)
|
|
419
|
+
])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
420
|
+
createTextVNode("No items found")
|
|
421
|
+
], 64))
|
|
422
|
+
], 2)
|
|
401
423
|
]) : createCommentVNode("", true)
|
|
402
424
|
], 6)
|
|
403
425
|
], 16)
|
|
@@ -262,14 +262,14 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
262
262
|
validator(value: Size): boolean;
|
|
263
263
|
};
|
|
264
264
|
/**
|
|
265
|
-
* Set property of **items
|
|
265
|
+
* Set property of **items**'s text value
|
|
266
266
|
*/
|
|
267
267
|
itemText: {
|
|
268
268
|
type: StringConstructor;
|
|
269
269
|
default: string;
|
|
270
270
|
};
|
|
271
271
|
/**
|
|
272
|
-
* Set property of **items
|
|
272
|
+
* Set property of **items**'s value - must be primitive.
|
|
273
273
|
*/
|
|
274
274
|
itemValue: {
|
|
275
275
|
type: (StringConstructor | NumberConstructor)[];
|
|
@@ -349,9 +349,17 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
349
349
|
type: PropType<string>;
|
|
350
350
|
default: string;
|
|
351
351
|
};
|
|
352
|
+
/**
|
|
353
|
+
* Enables the ability to create new items when no search results are found
|
|
354
|
+
*/
|
|
355
|
+
creatable: {
|
|
356
|
+
type: BooleanConstructor;
|
|
357
|
+
default: boolean;
|
|
358
|
+
};
|
|
352
359
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
353
360
|
select: (...args: any[]) => void;
|
|
354
361
|
"update:modelValue": (...args: any[]) => void;
|
|
362
|
+
create: (...args: any[]) => void;
|
|
355
363
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
356
364
|
modelValue: {
|
|
357
365
|
type: PropType<ModelValue>;
|
|
@@ -392,14 +400,14 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
392
400
|
validator(value: Size): boolean;
|
|
393
401
|
};
|
|
394
402
|
/**
|
|
395
|
-
* Set property of **items
|
|
403
|
+
* Set property of **items**'s text value
|
|
396
404
|
*/
|
|
397
405
|
itemText: {
|
|
398
406
|
type: StringConstructor;
|
|
399
407
|
default: string;
|
|
400
408
|
};
|
|
401
409
|
/**
|
|
402
|
-
* Set property of **items
|
|
410
|
+
* Set property of **items**'s value - must be primitive.
|
|
403
411
|
*/
|
|
404
412
|
itemValue: {
|
|
405
413
|
type: (StringConstructor | NumberConstructor)[];
|
|
@@ -479,9 +487,17 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
479
487
|
type: PropType<string>;
|
|
480
488
|
default: string;
|
|
481
489
|
};
|
|
490
|
+
/**
|
|
491
|
+
* Enables the ability to create new items when no search results are found
|
|
492
|
+
*/
|
|
493
|
+
creatable: {
|
|
494
|
+
type: BooleanConstructor;
|
|
495
|
+
default: boolean;
|
|
496
|
+
};
|
|
482
497
|
}>> & Readonly<{
|
|
483
498
|
onSelect?: ((...args: any[]) => any) | undefined;
|
|
484
499
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
500
|
+
onCreate?: ((...args: any[]) => any) | undefined;
|
|
485
501
|
}>, {
|
|
486
502
|
size: "sm" | "md" | "lg";
|
|
487
503
|
label: string;
|
|
@@ -505,6 +521,7 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
|
|
|
505
521
|
placeholderSearch: string;
|
|
506
522
|
selectedTopShown: boolean;
|
|
507
523
|
disabledBy: string;
|
|
524
|
+
creatable: boolean;
|
|
508
525
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {
|
|
509
526
|
formControl: HTMLDivElement;
|
|
510
527
|
button: HTMLButtonElement;
|
package/package.json
CHANGED
|
@@ -713,4 +713,102 @@ describe('PDropdownSelect.vue', () => {
|
|
|
713
713
|
|
|
714
714
|
cleanup(wrapper);
|
|
715
715
|
});
|
|
716
|
+
|
|
717
|
+
describe('creatable functionality', () => {
|
|
718
|
+
it('shows create option when no items match search and creatable is true', async () => {
|
|
719
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
720
|
+
const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: true });
|
|
721
|
+
await wrapper.find('button').trigger('click');
|
|
722
|
+
await sleep(200);
|
|
723
|
+
const searchInput = wrapper.find('input.text-night');
|
|
724
|
+
await searchInput.setValue('New Item');
|
|
725
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
726
|
+
expect(createButton.exists()).toBe(true);
|
|
727
|
+
expect(createButton.text()).toBe("Add 'New Item'");
|
|
728
|
+
cleanup(wrapper);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('does not show create option when creatable is false', async () => {
|
|
732
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
733
|
+
const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: false });
|
|
734
|
+
await wrapper.find('button').trigger('click');
|
|
735
|
+
await sleep(200);
|
|
736
|
+
const searchInput = wrapper.find('input.text-night');
|
|
737
|
+
await searchInput.setValue('New Item');
|
|
738
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
739
|
+
expect(createButton.exists()).toBe(false);
|
|
740
|
+
expect(wrapper.text()).toContain('No items found');
|
|
741
|
+
cleanup(wrapper);
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
it('emits create event when clicking create option', async () => {
|
|
745
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
746
|
+
const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: true });
|
|
747
|
+
await wrapper.find('button').trigger('click');
|
|
748
|
+
await sleep(200);
|
|
749
|
+
const searchInput = wrapper.find('input.text-night');
|
|
750
|
+
await searchInput.setValue('New Item');
|
|
751
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
752
|
+
await createButton.trigger('click');
|
|
753
|
+
const pDropdownSelectCmp = wrapper.findComponent(PDropdownSelect);
|
|
754
|
+
expect(pDropdownSelectCmp.emitted().create[0]).toEqual(['New Item']);
|
|
755
|
+
expect(wrapper.find('.pdropdown-stub-popper').exists()).toBe(false);
|
|
756
|
+
cleanup(wrapper);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('does not update model value when creating new item', async () => {
|
|
760
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
761
|
+
const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: true });
|
|
762
|
+
await wrapper.find('button').trigger('click');
|
|
763
|
+
await sleep(200);
|
|
764
|
+
const searchInput = wrapper.find('input.text-night');
|
|
765
|
+
await searchInput.setValue('New Item');
|
|
766
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
767
|
+
await createButton.trigger('click');
|
|
768
|
+
const pDropdownSelectCmp = wrapper.findComponent(PDropdownSelect);
|
|
769
|
+
expect(pDropdownSelectCmp.emitted()['update:modelValue']).toBeFalsy();
|
|
770
|
+
expect(wrapper.vm.$data.selected).toBe(null);
|
|
771
|
+
cleanup(wrapper);
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('does not create object value when valueIsObject is true', async () => {
|
|
775
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
776
|
+
const wrapper = createWrapper({ selected: null }, { searchable: true, creatable: true, valueIsObject: true });
|
|
777
|
+
await wrapper.find('button').trigger('click');
|
|
778
|
+
await sleep(200);
|
|
779
|
+
const searchInput = wrapper.find('input.text-night');
|
|
780
|
+
await searchInput.setValue('New Item');
|
|
781
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
782
|
+
await createButton.trigger('click');
|
|
783
|
+
const pDropdownSelectCmp = wrapper.findComponent(PDropdownSelect);
|
|
784
|
+
expect(pDropdownSelectCmp.emitted().create[0]).toEqual(['New Item']);
|
|
785
|
+
expect(pDropdownSelectCmp.emitted()['update:modelValue']).toBeFalsy();
|
|
786
|
+
expect(wrapper.vm.$data.selected).toBe(null);
|
|
787
|
+
cleanup(wrapper);
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
it('emits create event with search value when using custom itemValue and itemText', async () => {
|
|
791
|
+
useVirtualizer.mockImplementation(() => createMockedVirtualizer(20));
|
|
792
|
+
const wrapper = createWrapper(
|
|
793
|
+
{ selected: null },
|
|
794
|
+
{
|
|
795
|
+
searchable: true,
|
|
796
|
+
creatable: true,
|
|
797
|
+
valueIsObject: true,
|
|
798
|
+
itemValue: 'customValue',
|
|
799
|
+
itemText: 'customText',
|
|
800
|
+
}
|
|
801
|
+
);
|
|
802
|
+
await wrapper.find('button').trigger('click');
|
|
803
|
+
await sleep(200);
|
|
804
|
+
const searchInput = wrapper.find('input.text-night');
|
|
805
|
+
await searchInput.setValue('New Item');
|
|
806
|
+
const createButton = wrapper.find('button.hover\\:text-primary-hover');
|
|
807
|
+
await createButton.trigger('click');
|
|
808
|
+
const pDropdownSelectCmp = wrapper.findComponent(PDropdownSelect);
|
|
809
|
+
expect(pDropdownSelectCmp.emitted().create[0]).toEqual(['New Item']);
|
|
810
|
+
expect(pDropdownSelectCmp.emitted()['update:modelValue']).toBeFalsy();
|
|
811
|
+
cleanup(wrapper);
|
|
812
|
+
});
|
|
813
|
+
});
|
|
716
814
|
});
|
|
@@ -312,3 +312,39 @@ export const ClearableMultiple = {
|
|
|
312
312
|
clearable: true,
|
|
313
313
|
},
|
|
314
314
|
};
|
|
315
|
+
|
|
316
|
+
export const Creatable = {
|
|
317
|
+
render: (args) => ({
|
|
318
|
+
components: { PDropdownSelect },
|
|
319
|
+
setup() {
|
|
320
|
+
const value = ref(null);
|
|
321
|
+
return { args, value };
|
|
322
|
+
},
|
|
323
|
+
template: `
|
|
324
|
+
<div>
|
|
325
|
+
<PDropdownSelect
|
|
326
|
+
v-model="value"
|
|
327
|
+
v-bind="args"
|
|
328
|
+
@create="(searchTerm) => alert('Create item: ' + searchTerm)"
|
|
329
|
+
/>
|
|
330
|
+
<div class="mt-4">Selected: {{ value }}</div>
|
|
331
|
+
</div>
|
|
332
|
+
`,
|
|
333
|
+
}),
|
|
334
|
+
parameters: {
|
|
335
|
+
docs: {
|
|
336
|
+
description: {
|
|
337
|
+
story:
|
|
338
|
+
'Example with creatable functionality enabled. When no search results are found, an option to create a new item is shown.',
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
args: {
|
|
343
|
+
...Default.args,
|
|
344
|
+
label: 'Creatable dropdown',
|
|
345
|
+
items: items2,
|
|
346
|
+
searchable: true,
|
|
347
|
+
creatable: true,
|
|
348
|
+
placeholder: 'Search or create an item...',
|
|
349
|
+
},
|
|
350
|
+
};
|
|
@@ -148,7 +148,18 @@
|
|
|
148
148
|
</div>
|
|
149
149
|
</div>
|
|
150
150
|
<slot v-if="!computedItems.length" name="no-items">
|
|
151
|
-
<div :class="['flex items-center justify-center', SIZES[size]]">
|
|
151
|
+
<div :class="['flex items-center justify-center', SIZES[size]]">
|
|
152
|
+
<template v-if="creatable && search">
|
|
153
|
+
<button
|
|
154
|
+
class="hover:text-primary-hover flex items-center gap-2 font-medium text-p-blue-40"
|
|
155
|
+
@click="handleCreate"
|
|
156
|
+
>
|
|
157
|
+
<PIcon icon="fe:plus-circle" />
|
|
158
|
+
Add '{{ search }}'
|
|
159
|
+
</button>
|
|
160
|
+
</template>
|
|
161
|
+
<template v-else>No items found</template>
|
|
162
|
+
</div>
|
|
152
163
|
</slot>
|
|
153
164
|
</div>
|
|
154
165
|
</div>
|
|
@@ -197,7 +208,7 @@ defineSlots<{
|
|
|
197
208
|
item(props: { item: any; isItemSelected: boolean; itemTextSplit: string[] }): unknown;
|
|
198
209
|
}>();
|
|
199
210
|
|
|
200
|
-
const emit = defineEmits(['update:modelValue', 'select']);
|
|
211
|
+
const emit = defineEmits(['update:modelValue', 'select', 'create']);
|
|
201
212
|
|
|
202
213
|
const props = defineProps({
|
|
203
214
|
modelValue: {
|
|
@@ -241,14 +252,14 @@ const props = defineProps({
|
|
|
241
252
|
},
|
|
242
253
|
},
|
|
243
254
|
/**
|
|
244
|
-
* Set property of **items
|
|
255
|
+
* Set property of **items**'s text value
|
|
245
256
|
*/
|
|
246
257
|
itemText: {
|
|
247
258
|
type: String,
|
|
248
259
|
default: 'text',
|
|
249
260
|
},
|
|
250
261
|
/**
|
|
251
|
-
* Set property of **items
|
|
262
|
+
* Set property of **items**'s value - must be primitive.
|
|
252
263
|
*/
|
|
253
264
|
itemValue: {
|
|
254
265
|
type: [String, Number],
|
|
@@ -328,6 +339,13 @@ const props = defineProps({
|
|
|
328
339
|
type: String as PropType<string>,
|
|
329
340
|
default: 'disabled',
|
|
330
341
|
},
|
|
342
|
+
/**
|
|
343
|
+
* Enables the ability to create new items when no search results are found
|
|
344
|
+
*/
|
|
345
|
+
creatable: {
|
|
346
|
+
type: Boolean,
|
|
347
|
+
default: false,
|
|
348
|
+
},
|
|
331
349
|
});
|
|
332
350
|
|
|
333
351
|
// Async helpers
|
|
@@ -453,4 +471,9 @@ const onHide = () => {
|
|
|
453
471
|
destroyNavigationSvc();
|
|
454
472
|
(formControl.value?.querySelector('button') as HTMLElement)?.focus();
|
|
455
473
|
};
|
|
474
|
+
|
|
475
|
+
const handleCreate = () => {
|
|
476
|
+
emit('create', search.value);
|
|
477
|
+
dropdownShow.value = false;
|
|
478
|
+
};
|
|
456
479
|
</script>
|