@milaboratories/uikit 2.4.29 → 2.5.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/.turbo/turbo-build.log +45 -45
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/assets/images/required.svg.js +7 -0
- package/dist/assets/images/required.svg.js.map +1 -0
- package/dist/components/DataTable/TableComponent.vue.js +16 -19
- package/dist/components/DataTable/TableComponent.vue.js.map +1 -1
- package/dist/components/PlAutocomplete/PlAutocomplete.vue.js +67 -60
- package/dist/components/PlAutocomplete/PlAutocomplete.vue.js.map +1 -1
- package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js +76 -72
- package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js.map +1 -1
- package/dist/components/PlDropdown/PlDropdown.vue.js +65 -61
- package/dist/components/PlDropdown/PlDropdown.vue.js.map +1 -1
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js +27 -23
- package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js.map +1 -1
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js +65 -61
- package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js.map +1 -1
- package/dist/components/PlFileInput/PlFileInput.vue.js +47 -43
- package/dist/components/PlFileInput/PlFileInput.vue.js.map +1 -1
- package/dist/components/PlSlideModal/PlPureSlideModal.vue.js +3 -6
- package/dist/components/PlSlideModal/PlPureSlideModal.vue.js.map +1 -1
- package/dist/components/PlTextArea/PlTextArea.vue.js +43 -39
- package/dist/components/PlTextArea/PlTextArea.vue.js.map +1 -1
- package/dist/components/PlTextField/PlTextField.vue.js +41 -37
- package/dist/components/PlTextField/PlTextField.vue.js.map +1 -1
- package/dist/composition/filters/index.d.ts +2 -0
- package/dist/composition/filters/metadata.d.ts +862 -0
- package/dist/composition/filters/metadata.js +489 -0
- package/dist/composition/filters/metadata.js.map +1 -0
- package/dist/composition/filters/types.d.ts +44 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +114 -110
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/components/PlAutocomplete/PlAutocomplete.vue +4 -3
- package/src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue +14 -11
- package/src/components/PlDropdown/PlDropdown.vue +10 -9
- package/src/components/PlDropdownLegacy/PlDropdownLegacy.vue +3 -2
- package/src/components/PlDropdownMulti/PlDropdownMulti.vue +11 -10
- package/src/components/PlFileInput/PlFileInput.vue +6 -3
- package/src/components/PlTextArea/PlTextArea.vue +3 -2
- package/src/components/PlTextField/PlTextField.vue +7 -6
- package/src/composition/filters/index.ts +2 -0
- package/src/composition/filters/metadata.ts +476 -0
- package/src/composition/filters/types.ts +44 -0
- package/src/index.ts +2 -1
- package/dist/generated/components/svg/images/SvgRequired.vue.d.ts +0 -2
- package/dist/generated/components/svg/images/SvgRequired.vue.js +0 -17
- package/dist/generated/components/svg/images/SvgRequired.vue.js.map +0 -1
- package/dist/generated/components/svg/images/SvgRequired.vue3.js +0 -6
- package/dist/generated/components/svg/images/SvgRequired.vue3.js.map +0 -1
- package/scripts/create-svg-components.js +0 -125
- package/src/generated/components/svg/images/Svg16Add.vue +0 -13
- package/src/generated/components/svg/images/Svg16Attention.vue +0 -13
- package/src/generated/components/svg/images/Svg16Checkmark.vue +0 -13
- package/src/generated/components/svg/images/Svg16CheckmarkDark.vue +0 -13
- package/src/generated/components/svg/images/Svg16ChevronDown.vue +0 -13
- package/src/generated/components/svg/images/Svg16ChevronLeft.vue +0 -13
- package/src/generated/components/svg/images/Svg16ChevronRight.vue +0 -13
- package/src/generated/components/svg/images/Svg16ChevronUp.vue +0 -13
- package/src/generated/components/svg/images/Svg16Clear.vue +0 -13
- package/src/generated/components/svg/images/Svg16Clipboard.vue +0 -13
- package/src/generated/components/svg/images/Svg16Close.vue +0 -13
- package/src/generated/components/svg/images/Svg16Compare.vue +0 -13
- package/src/generated/components/svg/images/Svg16Down.vue +0 -13
- package/src/generated/components/svg/images/Svg16Import.vue +0 -13
- package/src/generated/components/svg/images/Svg16Info.vue +0 -13
- package/src/generated/components/svg/images/Svg16InfoDark.vue +0 -13
- package/src/generated/components/svg/images/Svg16Link.vue +0 -13
- package/src/generated/components/svg/images/Svg16Loading.vue +0 -13
- package/src/generated/components/svg/images/Svg16Maximise.vue +0 -13
- package/src/generated/components/svg/images/Svg16Play.vue +0 -13
- package/src/generated/components/svg/images/Svg16Up.vue +0 -13
- package/src/generated/components/svg/images/Svg24ArrowRight.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledChecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledIndeterminate.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledUnchecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledChecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledIndeterminate.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledUnchecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightDisabledChecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightDisabledIndeterminate.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightDisabledUnchecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightEnabledChecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightEnabledIndeterminate.vue +0 -13
- package/src/generated/components/svg/images/Svg24CheckboxLightEnabledUnchecked.vue +0 -13
- package/src/generated/components/svg/images/Svg24Clips.vue +0 -13
- package/src/generated/components/svg/images/Svg24Close.vue +0 -13
- package/src/generated/components/svg/images/Svg24Code.vue +0 -13
- package/src/generated/components/svg/images/Svg24Columns.vue +0 -13
- package/src/generated/components/svg/images/Svg24DarkMode.vue +0 -13
- package/src/generated/components/svg/images/Svg24Filters.vue +0 -13
- package/src/generated/components/svg/images/Svg24LightMode.vue +0 -13
- package/src/generated/components/svg/images/Svg24Local.vue +0 -13
- package/src/generated/components/svg/images/Svg24PaperClip.vue +0 -13
- package/src/generated/components/svg/images/Svg24Search.vue +0 -13
- package/src/generated/components/svg/images/Svg24ServerOn.vue +0 -13
- package/src/generated/components/svg/images/Svg24Settings2.vue +0 -13
- package/src/generated/components/svg/images/SvgAddGraphBg.vue +0 -13
- package/src/generated/components/svg/images/SvgColorSliderThumbBig.vue +0 -13
- package/src/generated/components/svg/images/SvgColorSliderThumbSmall.vue +0 -13
- package/src/generated/components/svg/images/SvgEmptyCat.vue +0 -13
- package/src/generated/components/svg/images/SvgNoDataCat.vue +0 -13
- package/src/generated/components/svg/images/SvgRequired.vue +0 -13
- package/src/generated/components/svg/svg-styles.css +0 -5
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document<"u"){var o=document.createElement("style");o.appendChild(document.createTextNode(`.pl-autocomplete-multi{--contour-color: var(--txt-01);--contour-border-width: 1px;--options-bg: #fff;--option-hover-bg: var(--btn-sec-hover-grey);--label-offset-left-x: 8px;--label-offset-right-x: 8px;--label-color: var(--txt-01);position:relative;outline:none;min-height:var(--control-height);border-radius:6px;font-family:var(--font-family-base);font-size:var(--font-size-base);font-weight:var(--font-weigh-base)}[data-theme=dark] .pl-autocomplete-multi{--options-bg: #1B1B1F}.pl-autocomplete-multi__envelope{font-family:var(--control-font-family);min-width:160px}.pl-autocomplete-multi label{display:flex;align-items:center;gap:4px;position:absolute;top:0;transform:translateY(-60%);left:var(--label-offset-left-x);padding:0 4px;max-width:calc(100% - 16px);overflow:hidden;white-space:pre;text-overflow:ellipsis;cursor:inherit;color:var(--label-color);font-size:12px;font-weight:500;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background:var(--bg-elevated-01)}.pl-autocomplete-multi label>span{overflow:hidden;white-space:pre;text-overflow:ellipsis}.pl-autocomplete-multi__container{position:absolute;top:0;left:0;right:0;border-radius:6px;min-height:var(--control-height);padding:1px;color:var(--txt-01)}.pl-autocomplete-multi__contour{border-radius:var(--border-radius-control);border:var(--contour-border-width) solid var(--contour-color);box-shadow:var(--contour-box-shadow);z-index:0;pointer-events:none}.pl-autocomplete-multi__options{position:absolute;z-index:var(--z-dropdown-options);border:1px solid var(--border-color-div-grey);background-color:var(--pl-dropdown-options-bg);border-radius:6px;max-height:244px;box-shadow:0 4px 12px -2px #0f244d14,0 6px 24px -2px #0f244d14;--thumb-color: var(--ic-02);overflow-y:auto}.pl-autocomplete-multi__options::-webkit-scrollbar{width:var(--scrollbar-width, 6px);height:5px;background-color:transparent;display:block}.pl-autocomplete-multi__options::-webkit-scrollbar-thumb{background:var(--thumb-color);border-radius:5px}.pl-autocomplete-multi__options::-webkit-scrollbar-thumb:hover{--thumb-color: var(--border-color-focus)}.pl-autocomplete-multi__options .nothing-found{padding:0 10px;height:var(--control-height);line-height:20px;background-color:#fff;opacity:.5;font-style:italic}.pl-autocomplete-multi__field{position:relative;border-radius:6px;overflow:hidden;background:transparent;padding-left:11px;min-height:var(--control-height);line-height:20px;cursor:pointer;display:flex;flex-direction:row;align-items:center}.pl-autocomplete-multi__field .chips-container{position:absolute;top:0;left:0;bottom:0;right:30px;overflow:hidden;padding:0 60px 0 11px;line-height:20px;color:var(--contour-color);display:flex;gap:8px;align-items:center}.pl-autocomplete-multi__field input{min-height:calc(var(--control-height) - 2px);line-height:20px;font-family:inherit;font-size:inherit;background-color:transparent;border:none;padding:0;width:calc(100% - 20px);color:var(--txt-01);caret-color:var(--border-color-focus)}.pl-autocomplete-multi__field input:focus{outline:none}.pl-autocomplete-multi__field input:placeholder-shown{text-overflow:ellipsis}.pl-autocomplete-multi__field input::placeholder{color:var(--color-placeholder)}.pl-autocomplete-multi__field:hover .clear{display:block}.pl-autocomplete-multi__controls{display:flex;flex-direction:row;align-items:center;gap:6px;margin-left:auto}.pl-autocomplete-multi__controls .mask-16,.pl-autocomplete-multi__controls .mask-24{--icon-color: var(--control-mask-fill);cursor:pointer}.pl-autocomplete-multi__controls .mask-loading{--icon-color: var(--ic-accent);animation:spin 2.5s linear infinite}.pl-autocomplete-multi__arrow-wrapper{display:flex;align-items:center;min-height:var(--control-height);padding-right:11px}.pl-autocomplete-multi .arrow-icon{cursor:pointer}.pl-autocomplete-multi .arrow-icon.arrow-icon-default{transition:transform .2s;background-color:var(--control-mask-fill);mask-image:url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M2.46967%206.53033L3.53033%205.46967L8%209.93934L12.4697%205.46967L13.5303%206.53033L8%2012.0607L2.46967%206.53033Z'%20fill='%23110529'/%3e%3c/svg%3e");-webkit-mask-image:url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M2.46967%206.53033L3.53033%205.46967L8%209.93934L12.4697%205.46967L13.5303%206.53033L8%2012.0607L2.46967%206.53033Z'%20fill='%23110529'/%3e%3c/svg%3e");mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-position:center;-webkit-mask-position:center;mask-size:16px;-webkit-mask-size:16px;width:16px;height:16px}.pl-autocomplete-multi__helper{font-size:12px;color:var(--txt-03);padding:2px 0 0;white-space:pre-wrap;text-overflow:ellipsis;font-weight:500;line-height:16px;margin-top:6px}.pl-autocomplete-multi__error{font-size:12px;color:var(--txt-error);padding:2px 0 0;white-space:pre-wrap;text-overflow:ellipsis;font-weight:500;line-height:16px;margin-top:6px}.pl-autocomplete-multi.open .arrow-icon.arrow-icon-default{background-color:var(--control-mask-fill);transform:rotate(-180deg)}.pl-autocomplete-multi .clear{display:none;position:absolute;top:50%;transform:translateY(-50%);right:36px;z-index:1;background:url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20clip-path='url(%23clip0_586_7851)'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M8%2016C12.4183%2016%2016%2012.4183%2016%208C16%203.58172%2012.4183%200%208%200C3.58172%200%200%203.58172%200%208C0%2012.4183%203.58172%2016%208%2016ZM4.46967%205.53033L6.93934%208L4.46967%2010.4697L5.53033%2011.5303L8%209.06066L10.4697%2011.5303L11.5303%2010.4697L9.06066%208L11.5303%205.53033L10.4697%204.46967L8%206.93934L5.53033%204.46967L4.46967%205.53033Z'%20fill='%23CFD1DB'/%3e%3c/g%3e%3cdefs%3e%3cclipPath%20id='clip0_586_7851'%3e%3crect%20width='16'%20height='16'%20fill='white'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e") no-repeat center;width:16px;height:16px;cursor:pointer}.pl-autocomplete-multi.open,.pl-autocomplete-multi:focus-within{z-index:1}.pl-autocomplete-multi.open .pl-autocomplete-multi__container .label,.pl-autocomplete-multi:focus-within .pl-autocomplete-multi__container .label{color:var(--txt-focus)}.pl-autocomplete-multi.open .pl-autocomplete-multi__container{z-index:1000}.pl-autocomplete-multi.open .pl-autocomplete-multi__field{border-radius:6px 6px 0 0}.pl-autocomplete-multi.open .arrow{background-color:var(--control-mask-fill);mask-image:url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M8%204.93933L13.5303%2010.4697L12.4697%2011.5303L8%207.06065L3.53033%2011.5303L2.46967%2010.4697L8%204.93933Z'%20fill='%23110529'/%3e%3c/svg%3e");-webkit-mask-image:url("data:image/svg+xml,%3csvg%20width='16'%20height='16'%20viewBox='0%200%2016%2016'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M8%204.93933L13.5303%2010.4697L12.4697%2011.5303L8%207.06065L3.53033%2011.5303L2.46967%2010.4697L8%204.93933Z'%20fill='%23110529'/%3e%3c/svg%3e");mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-position:center;-webkit-mask-position:center;mask-size:16px;-webkit-mask-size:16px;width:16px;height:16px}.pl-autocomplete-multi:hover{--contour-color: var(--control-hover-color)}.pl-autocomplete-multi:focus-within:not(.error){--label-color: var(--txt-focus);--contour-color: var(--border-color-focus);--contour-border-width: 2px;--contour-box-shadow: 0 0 0 4px var(--border-color-focus-shadow)}.pl-autocomplete-multi:focus-within.error{--contour-border-width: 2px;--contour-box-shadow: 0 0 0 4px var(--color-error-shadow)}.pl-autocomplete-multi.error{--contour-color: var(--txt-error);--label-color: var(--txt-error)}.pl-autocomplete-multi.disabled{--contour-color: var(--color-dis-01);--control-mask-fill: var(--color-dis-01);--label-color: var(--color-dis-01);cursor:not-allowed;pointer-events:none}.pl-autocomplete-multi.disabled .mask-loading{animation:spin 2.5s linear infinite;--icon-color: var(--ic-accent)}.pl-autocomplete-multi__open-chips-container{padding:12px}.pl-autocomplete-multi__open-chips-container .pl-chip{margin-right:4px;margin-bottom:4px}`)),document.head.appendChild(o)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
|
|
2
|
-
import { defineComponent as ne, useSlots as
|
|
2
|
+
import { defineComponent as ne, useSlots as re, ref as z, useTemplateRef as se, reactive as ae, watch as L, computed as u, toRef as ie, unref as i, createElementBlock as c, openBlock as s, createElementVNode as d, createCommentVNode as p, normalizeClass as ue, createBlock as f, createVNode as ce, withDirectives as de, vModelText as pe, Fragment as E, renderList as F, withModifiers as T, withCtx as O, createTextVNode as P, toDisplayString as m, renderSlot as U } from "vue";
|
|
3
3
|
|
|
4
|
-
import fe from "
|
|
5
|
-
import
|
|
4
|
+
import fe from "canonicalize";
|
|
5
|
+
import { useWatchFetch as K } from "../../composition/useWatchFetch.js";
|
|
6
|
+
import { getErrorMessage as x } from "../../helpers/error.js";
|
|
7
|
+
import { deepEqual as B, deepIncludes as W } from "../../helpers/objects.js";
|
|
6
8
|
import me from "../../utils/DoubleContour.vue.js";
|
|
7
|
-
import
|
|
8
|
-
import he from "
|
|
9
|
-
import
|
|
10
|
-
import
|
|
9
|
+
import ve from "../../utils/DropdownOverlay/DropdownOverlay.vue.js";
|
|
10
|
+
import { useLabelNotch as he } from "../../utils/useLabelNotch.js";
|
|
11
|
+
import _e from "../DropdownListItem.vue.js";
|
|
12
|
+
import H from "../PlChip/PlChip.vue.js";
|
|
11
13
|
import ye from "../PlIcon24/PlIcon24.vue.js";
|
|
12
|
-
import be from "
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve = { class: "pl-autocomplete-multi__field" }, we = ["disabled", "placeholder"], Re = {
|
|
14
|
+
import be from "../PlTooltip/PlTooltip.vue.js";
|
|
15
|
+
import ke from "../../assets/images/required.svg.js";
|
|
16
|
+
import ge from "../PlSvg/PlSvg.vue.js";
|
|
17
|
+
const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we = { class: "pl-autocomplete-multi__field" }, Re = ["disabled", "placeholder"], Ce = {
|
|
17
18
|
key: 0,
|
|
18
19
|
class: "chips-container"
|
|
19
|
-
},
|
|
20
|
+
}, Se = { class: "pl-autocomplete-multi__controls" }, $e = { key: 0 }, Ae = { class: "pl-autocomplete-multi__open-chips-container" }, Ee = {
|
|
20
21
|
key: 0,
|
|
21
22
|
class: "nothing-found"
|
|
22
|
-
},
|
|
23
|
+
}, Fe = {
|
|
23
24
|
key: 0,
|
|
24
25
|
class: "pl-autocomplete-multi__error"
|
|
25
|
-
},
|
|
26
|
+
}, Te = {
|
|
26
27
|
key: 1,
|
|
27
28
|
class: "pl-autocomplete-multi__helper"
|
|
28
|
-
},
|
|
29
|
+
}, xe = {
|
|
29
30
|
name: "PlAutocompleteMulti"
|
|
30
|
-
},
|
|
31
|
-
...
|
|
31
|
+
}, Je = /* @__PURE__ */ ne({
|
|
32
|
+
...xe,
|
|
32
33
|
props: {
|
|
33
34
|
modelValue: { default: () => [] },
|
|
34
35
|
optionsSearch: {},
|
|
@@ -46,7 +47,7 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
46
47
|
},
|
|
47
48
|
emits: ["update:modelValue"],
|
|
48
49
|
setup(j, { emit: G }) {
|
|
49
|
-
const J = G, D = (e) => J("update:modelValue", e), Q =
|
|
50
|
+
const J = G, D = (e) => J("update:modelValue", e), Q = re(), n = j, b = z(), k = z(), V = se("overlay"), l = ae({
|
|
50
51
|
search: "",
|
|
51
52
|
activeOption: -1,
|
|
52
53
|
open: !1,
|
|
@@ -55,40 +56,40 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
55
56
|
L(() => l.open, (e) => {
|
|
56
57
|
e || (l.search = "");
|
|
57
58
|
}, { flush: "sync" });
|
|
58
|
-
const
|
|
59
|
+
const g = u(() => Array.isArray(n.modelValue) ? n.modelValue : []), X = u(() => l.open && n.modelValue.length > 0 ? n.placeholder : n.modelValue.length > 0 ? "" : n.placeholder), I = ie(n, "debounce"), v = K(() => [l.search, l.open, n.sourceId], async ([e, t]) => n.optionsSearch(e), {
|
|
59
60
|
filterWatchResult: ([e, t]) => t,
|
|
60
61
|
debounce: I
|
|
61
|
-
}), h =
|
|
62
|
+
}), h = K(() => [n.modelValue, n.sourceId], async ([e]) => n.modelSearch(e), {
|
|
62
63
|
debounce: I
|
|
63
|
-
}), Y =
|
|
64
|
-
const e = h.value ?? [], t = v.value ?? [], o = /* @__PURE__ */ new Set(),
|
|
64
|
+
}), Y = u(() => {
|
|
65
|
+
const e = h.value ?? [], t = v.value ?? [], o = /* @__PURE__ */ new Set(), r = [], a = (A) => {
|
|
65
66
|
for (const _ of A) {
|
|
66
|
-
const y =
|
|
67
|
-
o.has(y) || (o.add(y),
|
|
67
|
+
const y = fe(_.value);
|
|
68
|
+
o.has(y) || (o.add(y), r.push(_));
|
|
68
69
|
}
|
|
69
70
|
};
|
|
70
|
-
return a(e), a(t),
|
|
71
|
-
}), w =
|
|
71
|
+
return a(e), a(t), r;
|
|
72
|
+
}), w = u(() => g.value.map((e) => Y.value.find((t) => B(t.value, e))).filter(
|
|
72
73
|
(e) => e !== void 0
|
|
73
|
-
)), R =
|
|
74
|
-
const e =
|
|
74
|
+
)), R = u(() => {
|
|
75
|
+
const e = i(g);
|
|
75
76
|
return [...v.value ?? []].map((o) => ({
|
|
76
77
|
...o,
|
|
77
78
|
selected: W(e, o.value)
|
|
78
79
|
}));
|
|
79
|
-
}), C =
|
|
80
|
+
}), C = u(() => v.loading || h.loading), S = u(() => h.value === void 0 ? !0 : n.disabled), Z = u(() => S.value ? void 0 : "0"), ee = () => {
|
|
80
81
|
l.activeOption = 0;
|
|
81
82
|
}, M = (e) => {
|
|
82
83
|
var o;
|
|
83
|
-
const t =
|
|
84
|
-
D(W(t, e) ? t.filter((
|
|
85
|
-
}, N = (e) => D(
|
|
84
|
+
const t = i(g);
|
|
85
|
+
D(W(t, e) ? t.filter((r) => !B(r, e)) : [...t, e]), n.resetSearchOnSelect && (l.search = ""), (o = k.value) == null || o.focus();
|
|
86
|
+
}, N = (e) => D(i(g).filter((t) => !B(t, e))), oe = () => {
|
|
86
87
|
var e;
|
|
87
88
|
return (e = k.value) == null ? void 0 : e.focus();
|
|
88
89
|
}, te = () => l.open = !l.open, q = (e) => {
|
|
89
|
-
var o,
|
|
90
|
+
var o, r, a;
|
|
90
91
|
const t = e.relatedTarget;
|
|
91
|
-
!((o = b.value) != null && o.contains(t)) && !((a = (
|
|
92
|
+
!((o = b.value) != null && o.contains(t)) && !((a = (r = V.value) == null ? void 0 : r.listRef) != null && a.contains(t)) && (l.open = !1);
|
|
92
93
|
}, le = (e) => {
|
|
93
94
|
var _;
|
|
94
95
|
const { open: t, activeOption: o } = l;
|
|
@@ -97,34 +98,34 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
100
|
e.code === "Escape" && (l.open = !1, (_ = k.value) == null || _.focus());
|
|
100
|
-
const
|
|
101
|
+
const r = i(R), { length: a } = r;
|
|
101
102
|
if (!a)
|
|
102
103
|
return;
|
|
103
|
-
["ArrowDown", "ArrowUp", "Enter"].includes(e.code) && e.preventDefault(), e.code === "Enter" && M(
|
|
104
|
+
["ArrowDown", "ArrowUp", "Enter"].includes(e.code) && e.preventDefault(), e.code === "Enter" && M(r[o].value);
|
|
104
105
|
const A = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0;
|
|
105
106
|
l.activeOption = Math.abs(o + A + a) % a, requestAnimationFrame(() => {
|
|
106
107
|
var y;
|
|
107
108
|
return (y = V.value) == null ? void 0 : y.scrollIntoActive();
|
|
108
109
|
});
|
|
109
110
|
};
|
|
110
|
-
|
|
111
|
+
he(b), L(
|
|
111
112
|
() => n.modelValue,
|
|
112
113
|
() => ee(),
|
|
113
114
|
{ immediate: !0 }
|
|
114
115
|
);
|
|
115
|
-
const $ =
|
|
116
|
+
const $ = u(() => {
|
|
116
117
|
if (!C.value) {
|
|
117
118
|
if (v.error)
|
|
118
|
-
return
|
|
119
|
+
return x(v.error);
|
|
119
120
|
if (h.error)
|
|
120
|
-
return
|
|
121
|
+
return x(h.error);
|
|
121
122
|
if (n.error)
|
|
122
|
-
return
|
|
123
|
+
return x(n.error);
|
|
123
124
|
if (n.modelValue.length && w.value.length !== n.modelValue.length)
|
|
124
125
|
return "The selected values are not one of the options";
|
|
125
126
|
}
|
|
126
127
|
});
|
|
127
|
-
return (e, t) => (
|
|
128
|
+
return (e, t) => (s(), c("div", {
|
|
128
129
|
class: "pl-autocomplete-multi__envelope",
|
|
129
130
|
onClick: oe
|
|
130
131
|
}, [
|
|
@@ -136,8 +137,8 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
136
137
|
onKeydown: le,
|
|
137
138
|
onFocusout: q
|
|
138
139
|
}, [
|
|
139
|
-
d("div",
|
|
140
|
-
d("div",
|
|
140
|
+
d("div", Ve, [
|
|
141
|
+
d("div", we, [
|
|
141
142
|
de(d("input", {
|
|
142
143
|
ref_key: "inputRef",
|
|
143
144
|
ref: k,
|
|
@@ -149,29 +150,29 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
149
150
|
spellcheck: "false",
|
|
150
151
|
autocomplete: "chrome-off",
|
|
151
152
|
onFocus: t[1] || (t[1] = (o) => l.open = !0)
|
|
152
|
-
}, null, 40,
|
|
153
|
+
}, null, 40, Re), [
|
|
153
154
|
[pe, l.search]
|
|
154
155
|
]),
|
|
155
|
-
l.open ? p("", !0) : (
|
|
156
|
-
(
|
|
157
|
-
key:
|
|
156
|
+
l.open ? p("", !0) : (s(), c("div", Ce, [
|
|
157
|
+
(s(!0), c(E, null, F(w.value, (o, r) => (s(), f(i(H), {
|
|
158
|
+
key: r,
|
|
158
159
|
closeable: "",
|
|
159
160
|
small: "",
|
|
160
161
|
onClick: t[2] || (t[2] = T((a) => l.open = !0, ["stop"])),
|
|
161
162
|
onClose: (a) => N(o.value)
|
|
162
163
|
}, {
|
|
163
|
-
default:
|
|
164
|
-
|
|
164
|
+
default: O(() => [
|
|
165
|
+
P(m(o.label || o.value), 1)
|
|
165
166
|
]),
|
|
166
167
|
_: 2
|
|
167
168
|
}, 1032, ["onClose"]))), 128))
|
|
168
169
|
])),
|
|
169
|
-
d("div",
|
|
170
|
-
C.value ? (
|
|
170
|
+
d("div", Se, [
|
|
171
|
+
C.value ? (s(), f(i(ye), {
|
|
171
172
|
key: 0,
|
|
172
173
|
name: "loading"
|
|
173
174
|
})) : p("", !0),
|
|
174
|
-
|
|
175
|
+
U(e.$slots, "append"),
|
|
175
176
|
d("div", {
|
|
176
177
|
class: "pl-autocomplete-multi__arrow-wrapper",
|
|
177
178
|
onClick: T(te, ["stop"])
|
|
@@ -180,21 +181,24 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
180
181
|
]))
|
|
181
182
|
])
|
|
182
183
|
]),
|
|
183
|
-
e.label ? (
|
|
184
|
-
e.required ? (
|
|
184
|
+
e.label ? (s(), c("label", $e, [
|
|
185
|
+
e.required ? (s(), f(i(ge), {
|
|
186
|
+
key: 0,
|
|
187
|
+
uri: i(ke)
|
|
188
|
+
}, null, 8, ["uri"])) : p("", !0),
|
|
185
189
|
d("span", null, m(e.label), 1),
|
|
186
|
-
|
|
190
|
+
i(Q).tooltip ? (s(), f(i(be), {
|
|
187
191
|
key: 1,
|
|
188
192
|
class: "info",
|
|
189
193
|
position: "top"
|
|
190
194
|
}, {
|
|
191
|
-
tooltip:
|
|
192
|
-
|
|
195
|
+
tooltip: O(() => [
|
|
196
|
+
U(e.$slots, "tooltip")
|
|
193
197
|
]),
|
|
194
198
|
_: 3
|
|
195
199
|
})) : p("", !0)
|
|
196
200
|
])) : p("", !0),
|
|
197
|
-
l.open ? (
|
|
201
|
+
l.open ? (s(), f(ve, {
|
|
198
202
|
key: 1,
|
|
199
203
|
ref_key: "overlay",
|
|
200
204
|
ref: V,
|
|
@@ -204,42 +208,42 @@ const Oe = ["tabindex"], ge = { class: "pl-autocomplete-multi__container" }, Ve
|
|
|
204
208
|
tabindex: "-1",
|
|
205
209
|
onFocusout: q
|
|
206
210
|
}, {
|
|
207
|
-
default:
|
|
208
|
-
d("div",
|
|
209
|
-
(
|
|
210
|
-
key:
|
|
211
|
+
default: O(() => [
|
|
212
|
+
d("div", Ae, [
|
|
213
|
+
(s(!0), c(E, null, F(w.value, (o, r) => (s(), f(i(H), {
|
|
214
|
+
key: r,
|
|
211
215
|
closeable: "",
|
|
212
216
|
small: "",
|
|
213
217
|
onClose: (a) => N(o.value)
|
|
214
218
|
}, {
|
|
215
|
-
default:
|
|
216
|
-
|
|
219
|
+
default: O(() => [
|
|
220
|
+
P(m(o.label || o.value), 1)
|
|
217
221
|
]),
|
|
218
222
|
_: 2
|
|
219
223
|
}, 1032, ["onClose"]))), 128))
|
|
220
224
|
]),
|
|
221
|
-
(
|
|
222
|
-
key:
|
|
225
|
+
(s(!0), c(E, null, F(R.value, (o, r) => (s(), f(_e, {
|
|
226
|
+
key: r,
|
|
223
227
|
option: o,
|
|
224
228
|
"text-item": "text",
|
|
225
229
|
"is-selected": o.selected,
|
|
226
|
-
"is-hovered": l.activeOption ==
|
|
230
|
+
"is-hovered": l.activeOption == r,
|
|
227
231
|
size: "medium",
|
|
228
232
|
"use-checkbox": "",
|
|
229
233
|
onClick: T((a) => M(o.value), ["stop"])
|
|
230
234
|
}, null, 8, ["option", "is-selected", "is-hovered", "onClick"]))), 128)),
|
|
231
|
-
!R.value.length && !C.value ? (
|
|
235
|
+
!R.value.length && !C.value ? (s(), c("div", Ee, m(e.emptyOptionsText), 1)) : p("", !0)
|
|
232
236
|
]),
|
|
233
237
|
_: 1
|
|
234
238
|
}, 8, ["root"])) : p("", !0),
|
|
235
239
|
ce(me, { class: "pl-autocomplete-multi__contour" })
|
|
236
240
|
])
|
|
237
241
|
], 42, Oe),
|
|
238
|
-
$.value ? (
|
|
242
|
+
$.value ? (s(), c("div", Fe, m($.value), 1)) : e.helper ? (s(), c("div", Te, m(e.helper), 1)) : p("", !0)
|
|
239
243
|
]));
|
|
240
244
|
}
|
|
241
245
|
});
|
|
242
246
|
export {
|
|
243
|
-
|
|
247
|
+
Je as default
|
|
244
248
|
};
|
|
245
249
|
//# sourceMappingURL=PlAutocompleteMulti.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlAutocompleteMulti.vue.js","sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: 'PlAutocompleteMulti',\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport './pl-autocomplete-multi.scss';\nimport { computed, reactive, ref, unref, useSlots, useTemplateRef, watch, toRef } from 'vue';\nimport { PlTooltip } from '../PlTooltip';\nimport { PlChip } from '../PlChip';\nimport DoubleContour from '../../utils/DoubleContour.vue';\nimport { useLabelNotch } from '../../utils/useLabelNotch';\nimport DropdownListItem from '../DropdownListItem.vue';\nimport { deepEqual, deepIncludes } from '../../helpers/objects';\nimport DropdownOverlay from '../../utils/DropdownOverlay/DropdownOverlay.vue';\nimport { PlMaskIcon24 } from '../PlMaskIcon24';\nimport SvgRequired from '../../generated/components/svg/images/SvgRequired.vue';\nimport { getErrorMessage } from '../../helpers/error.ts';\nimport { useWatchFetch } from '../../composition/useWatchFetch.ts';\nimport canonicalize from 'canonicalize';\nimport type { ListOptionBase } from '@platforma-sdk/model';\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit('update:modelValue', v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (s: string) => Promise<Readonly<ListOptionBase<M>[]>>;\n /**\n * Lambda for requesting options that correspond to the current model values.\n */\n modelSearch: (values: M[]) => Promise<Readonly<ListOptionBase<M>[]>>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: '...',\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: 'Nothing found',\n sourceId: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef('overlay');\n\nconst data = reactive({\n search: '',\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(() => data.open, (v) => {\n if (!v) {\n data.search = '';\n }\n}, { flush: 'sync' });\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? '' : props.placeholder;\n});\n\nconst debounce = toRef(props, 'debounce');\n\nconst searchOptionsRef = useWatchFetch(() => [data.search, data.open, props.sourceId] as const, async ([search, _open]) => {\n return props.optionsSearch(search);\n}, {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n});\n\nconst modelOptionsRef = useWatchFetch(() => [props.modelValue, props.sourceId] as const, async ([v]) => {\n return props.modelSearch(v);\n}, {\n debounce,\n});\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value.map((v) =>\n allOptionsRef.value.find((opt) => deepEqual(opt.value, v))).filter((v) => v !== undefined,\n );\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : '0'));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = '';\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) => emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => data.open = !data.open;\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === 'Enter') {\n data.open = true;\n }\n return;\n }\n\n if (e.code === 'Escape') {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if (['ArrowDown', 'ArrowUp', 'Enter'].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === 'Enter') {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === 'ArrowDown' ? 1 : e.code === 'ArrowUp' ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return 'The selected values are not one of the options';\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div class=\"pl-autocomplete-multi__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\">\n <PlChip v-for=\"(opt, i) in selectedOptionsRef\" :key=\"i\" closeable small @click.stop=\"data.open = true\" @close=\"unselectOption(opt.value)\">\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24 v-if=\"isOptionsLoading\" name=\"loading\" />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete-multi__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <SvgRequired v-if=\"required\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__open-chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n @click.stop=\"selectOption(item.value)\"\n />\n <div v-if=\"!filteredOptionsRef.length && !isOptionsLoading\" class=\"nothing-found\">{{ emptyOptionsText }}</div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete-multi__error\">{{ computedError }}</div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete-multi__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"names":["__default__","emit","__emit","emitModel","v","slots","useSlots","props","__props","rootRef","ref","inputRef","overlay","useTemplateRef","data","reactive","watch","selectedValuesRef","computed","placeholderRef","debounce","toRef","searchOptionsRef","useWatchFetch","search","_open","_search","open","modelOptionsRef","allOptionsRef","modelOptions","searchOptions","seenValues","result","addOptions","options","option","canonicalValue","canonicalize","selectedOptionsRef","opt","deepEqual","filteredOptionsRef","selectedValues","unref","deepIncludes","isOptionsLoading","isDisabled","tabindex","updateActiveOption","selectOption","values","it","_a","unselectOption","d","setFocusOnInput","toggleOpen","onFocusOut","event","relatedTarget","_c","_b","handleKeydown","activeOption","filteredOptions","length","useLabelNotch","computedError","getErrorMessage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlAutocompleteMulti.vue.js","sources":["../../../src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A multi-select autocomplete component that allows users to search and select multiple values from a list of options.\n * Supports async data fetching, keyboard navigation, and displays selected items as removable chips.\n *\n * @example\n * Basic usage:\n * <PlAutocompleteMulti\n * v-model=\"selectedUsers\"\n * :options-search=\"searchUsers\"\n * :model-search=\"getUsersByIds\"\n * label=\"Select Users\"\n * placeholder=\"Search for users...\"\n * required\n * :debounce=\"300\"\n * helper=\"Choose one or more users from the list\"\n * />\n *\n * With async functions:\n * const selectedUsers = ref([])\n *\n * const searchUsers = async (searchTerm) => {\n * const response = await fetch('/api/users/search?q=' + searchTerm)\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n *\n * const getUsersByIds = async (userIds) => {\n * if (!userIds.length) return []\n * const response = await fetch('/api/users?ids=' + userIds.join(','))\n * const users = await response.json()\n * return users.map(user => ({ value: user.id, label: user.name }))\n * }\n */\nexport default {\n name: 'PlAutocompleteMulti',\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport './pl-autocomplete-multi.scss';\n\nimport type { ListOptionBase } from '@platforma-sdk/model';\nimport canonicalize from 'canonicalize';\nimport { computed, reactive, ref, toRef, unref, useSlots, useTemplateRef, watch } from 'vue';\nimport { useWatchFetch } from '../../composition/useWatchFetch.ts';\nimport { getErrorMessage } from '../../helpers/error.ts';\nimport { deepEqual, deepIncludes } from '../../helpers/objects';\nimport DoubleContour from '../../utils/DoubleContour.vue';\nimport DropdownOverlay from '../../utils/DropdownOverlay/DropdownOverlay.vue';\nimport { useLabelNotch } from '../../utils/useLabelNotch';\nimport DropdownListItem from '../DropdownListItem.vue';\nimport { PlChip } from '../PlChip';\nimport { PlMaskIcon24 } from '../PlMaskIcon24';\nimport { PlTooltip } from '../PlTooltip';\n\nimport SvgRequired from '../../assets/images/required.svg?raw';\nimport { PlSvg } from '../PlSvg';\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: M[]): void;\n}>();\n\nconst emitModel = (v: M[]) => emit('update:modelValue', v);\n\nconst slots = useSlots();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected values.\n */\n modelValue: M[];\n /**\n * Lambda for requesting of available options for the dropdown by search string.\n */\n optionsSearch: (s: string) => Promise<Readonly<ListOptionBase<M>[]>>;\n /**\n * Lambda for requesting options that correspond to the current model values.\n */\n modelSearch: (values: M[]) => Promise<Readonly<ListOptionBase<M>[]>>;\n /**\n * Unique identifier for the source of the options, changing it will invalidate the options cache.\n */\n sourceId?: string;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * If `true`, the dropdown component is marked as required.\n */\n required?: boolean;\n /**\n * If `true`, the dropdown component is disabled and cannot be interacted with.\n */\n disabled?: boolean;\n /**\n * Debounce time in ms for the options search.\n */\n debounce?: number;\n /**\n * If `true`, the search input is reset and focus is set on it when the new option is selected.\n */\n resetSearchOnSelect?: boolean;\n /**\n * The text to display when no options are found.\n */\n emptyOptionsText?: string;\n }>(),\n {\n modelValue: () => [],\n label: undefined,\n helper: undefined,\n error: undefined,\n placeholder: '...',\n required: false,\n disabled: false,\n debounce: 300,\n emptyOptionsText: 'Nothing found',\n sourceId: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst inputRef = ref<HTMLInputElement | undefined>();\n\nconst overlay = useTemplateRef('overlay');\n\nconst data = reactive({\n search: '',\n activeOption: -1,\n open: false,\n optionsHeight: 0,\n});\n\nwatch(() => data.open, (v) => {\n if (!v) {\n data.search = '';\n }\n}, { flush: 'sync' });\n\nconst selectedValuesRef = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));\n\nconst placeholderRef = computed(() => {\n if (data.open && props.modelValue.length > 0) {\n return props.placeholder;\n }\n\n return props.modelValue.length > 0 ? '' : props.placeholder;\n});\n\nconst debounce = toRef(props, 'debounce');\n\nconst searchOptionsRef = useWatchFetch(() => [data.search, data.open, props.sourceId] as const, async ([search, _open]) => {\n return props.optionsSearch(search);\n}, {\n filterWatchResult: ([_search, open]) => open,\n debounce,\n});\n\nconst modelOptionsRef = useWatchFetch(() => [props.modelValue, props.sourceId] as const, async ([v]) => {\n return props.modelSearch(v);\n}, {\n debounce,\n});\n\nconst allOptionsRef = computed(() => {\n const modelOptions = modelOptionsRef.value ?? [];\n const searchOptions = searchOptionsRef.value ?? [];\n\n const seenValues = new Set<string | undefined>();\n const result = [] as ListOptionBase<M>[];\n\n const addOptions = (options: Readonly<ListOptionBase<M>[]>) => {\n for (const option of options) {\n const canonicalValue = canonicalize(option.value);\n if (!seenValues.has(canonicalValue)) {\n seenValues.add(canonicalValue);\n result.push(option);\n }\n }\n };\n\n addOptions(modelOptions);\n addOptions(searchOptions);\n\n return result;\n});\n\nconst selectedOptionsRef = computed(() => {\n return selectedValuesRef.value.map((v) =>\n allOptionsRef.value.find((opt) => deepEqual(opt.value, v))).filter((v) => v !== undefined,\n );\n});\n\nconst filteredOptionsRef = computed(() => {\n const selectedValues = unref(selectedValuesRef);\n\n const options = searchOptionsRef.value ?? [];\n\n return [...options].map((opt) => ({\n ...opt,\n selected: deepIncludes(selectedValues, opt.value),\n }));\n});\n\nconst isOptionsLoading = computed(() => searchOptionsRef.loading || modelOptionsRef.loading);\n\nconst isDisabled = computed(() => {\n if (modelOptionsRef.value === undefined) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : '0'));\n\nconst updateActiveOption = () => {\n data.activeOption = 0;\n};\n\nconst selectOption = (v: M) => {\n const values = unref(selectedValuesRef);\n emitModel(deepIncludes(values, v) ? values.filter((it) => !deepEqual(it, v)) : [...values, v]);\n if (props.resetSearchOnSelect) {\n data.search = '';\n }\n inputRef.value?.focus();\n};\n\nconst unselectOption = (d: M) => emitModel(unref(selectedValuesRef).filter((v) => !deepEqual(v, d)));\n\nconst setFocusOnInput = () => inputRef.value?.focus();\n\nconst toggleOpen = () => data.open = !data.open;\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !overlay.value?.listRef?.contains(relatedTarget)) {\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n const { open, activeOption } = data;\n\n if (!open) {\n if (e.code === 'Enter') {\n data.open = true;\n }\n return;\n }\n\n if (e.code === 'Escape') {\n data.open = false;\n inputRef.value?.focus();\n }\n\n const filteredOptions = unref(filteredOptionsRef);\n\n const { length } = filteredOptions;\n\n if (!length) {\n return;\n }\n\n if (['ArrowDown', 'ArrowUp', 'Enter'].includes(e.code)) {\n e.preventDefault();\n }\n\n if (e.code === 'Enter') {\n selectOption(filteredOptions[activeOption].value);\n }\n\n const d = e.code === 'ArrowDown' ? 1 : e.code === 'ArrowUp' ? -1 : 0;\n\n data.activeOption = Math.abs(activeOption + d + length) % length;\n\n requestAnimationFrame(() => overlay.value?.scrollIntoActive());\n};\n\nuseLabelNotch(rootRef);\n\nwatch(\n () => props.modelValue,\n () => updateActiveOption(),\n { immediate: true },\n);\n\nconst computedError = computed(() => {\n if (isOptionsLoading.value) {\n return undefined;\n }\n\n if (searchOptionsRef.error) {\n return getErrorMessage(searchOptionsRef.error);\n }\n\n if (modelOptionsRef.error) {\n return getErrorMessage(modelOptionsRef.error);\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue.length && selectedOptionsRef.value.length !== props.modelValue.length) {\n return 'The selected values are not one of the options';\n }\n\n return undefined;\n});\n</script>\n\n<template>\n <div class=\"pl-autocomplete-multi__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-autocomplete-multi\"\n :class=\"{ open: data.open, error: Boolean(computedError), disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__container\">\n <div class=\"pl-autocomplete-multi__field\">\n <input\n ref=\"inputRef\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"placeholderRef\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"data.open = true\"\n />\n <div v-if=\"!data.open\" class=\"chips-container\">\n <PlChip v-for=\"(opt, i) in selectedOptionsRef\" :key=\"i\" closeable small @click.stop=\"data.open = true\" @close=\"unselectOption(opt.value)\">\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n\n <div class=\"pl-autocomplete-multi__controls\">\n <PlMaskIcon24 v-if=\"isOptionsLoading\" name=\"loading\" />\n <slot name=\"append\" />\n <div class=\"pl-autocomplete-multi__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <div class=\"arrow-icon arrow-icon-default\" />\n </div>\n </div>\n </div>\n <label v-if=\"label\">\n <PlSvg v-if=\"required\" :uri=\"SvgRequired\" />\n <span>{{ label }}</span>\n <PlTooltip v-if=\"slots.tooltip\" class=\"info\" position=\"top\">\n <template #tooltip>\n <slot name=\"tooltip\" />\n </template>\n </PlTooltip>\n </label>\n <DropdownOverlay\n v-if=\"data.open\"\n ref=\"overlay\"\n :root=\"rootRef\"\n class=\"pl-autocomplete-multi__options\"\n :gap=\"5\"\n tabindex=\"-1\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-autocomplete-multi__open-chips-container\">\n <PlChip\n v-for=\"(opt, i) in selectedOptionsRef\"\n :key=\"i\"\n closeable\n small\n @close=\"unselectOption(opt.value)\"\n >\n {{ opt.label || opt.value }}\n </PlChip>\n </div>\n <DropdownListItem\n v-for=\"(item, index) in filteredOptionsRef\"\n :key=\"index\"\n :option=\"item\"\n :text-item=\"'text'\"\n :is-selected=\"item.selected\"\n :is-hovered=\"data.activeOption == index\"\n size=\"medium\"\n use-checkbox\n @click.stop=\"selectOption(item.value)\"\n />\n <div v-if=\"!filteredOptionsRef.length && !isOptionsLoading\" class=\"nothing-found\">{{ emptyOptionsText }}</div>\n </DropdownOverlay>\n <DoubleContour class=\"pl-autocomplete-multi__contour\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-autocomplete-multi__error\">{{ computedError }}</div>\n <div v-else-if=\"helper\" class=\"pl-autocomplete-multi__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"names":["__default__","emit","__emit","emitModel","v","slots","useSlots","props","__props","rootRef","ref","inputRef","overlay","useTemplateRef","data","reactive","watch","selectedValuesRef","computed","placeholderRef","debounce","toRef","searchOptionsRef","useWatchFetch","search","_open","_search","open","modelOptionsRef","allOptionsRef","modelOptions","searchOptions","seenValues","result","addOptions","options","option","canonicalValue","canonicalize","selectedOptionsRef","opt","deepEqual","filteredOptionsRef","selectedValues","unref","deepIncludes","isOptionsLoading","isDisabled","tabindex","updateActiveOption","selectOption","values","it","_a","unselectOption","d","setFocusOnInput","toggleOpen","onFocusOut","event","relatedTarget","_c","_b","handleKeydown","activeOption","filteredOptions","length","useLabelNotch","computedError","getErrorMessage"],"mappings":"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"}
|