@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.
Files changed (105) hide show
  1. package/.turbo/turbo-build.log +45 -45
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +18 -0
  4. package/dist/assets/images/required.svg.js +7 -0
  5. package/dist/assets/images/required.svg.js.map +1 -0
  6. package/dist/components/DataTable/TableComponent.vue.js +16 -19
  7. package/dist/components/DataTable/TableComponent.vue.js.map +1 -1
  8. package/dist/components/PlAutocomplete/PlAutocomplete.vue.js +67 -60
  9. package/dist/components/PlAutocomplete/PlAutocomplete.vue.js.map +1 -1
  10. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js +76 -72
  11. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js.map +1 -1
  12. package/dist/components/PlDropdown/PlDropdown.vue.js +65 -61
  13. package/dist/components/PlDropdown/PlDropdown.vue.js.map +1 -1
  14. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js +27 -23
  15. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js.map +1 -1
  16. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js +65 -61
  17. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js.map +1 -1
  18. package/dist/components/PlFileInput/PlFileInput.vue.js +47 -43
  19. package/dist/components/PlFileInput/PlFileInput.vue.js.map +1 -1
  20. package/dist/components/PlSlideModal/PlPureSlideModal.vue.js +3 -6
  21. package/dist/components/PlSlideModal/PlPureSlideModal.vue.js.map +1 -1
  22. package/dist/components/PlTextArea/PlTextArea.vue.js +43 -39
  23. package/dist/components/PlTextArea/PlTextArea.vue.js.map +1 -1
  24. package/dist/components/PlTextField/PlTextField.vue.js +41 -37
  25. package/dist/components/PlTextField/PlTextField.vue.js.map +1 -1
  26. package/dist/composition/filters/index.d.ts +2 -0
  27. package/dist/composition/filters/metadata.d.ts +862 -0
  28. package/dist/composition/filters/metadata.js +489 -0
  29. package/dist/composition/filters/metadata.js.map +1 -0
  30. package/dist/composition/filters/types.d.ts +44 -0
  31. package/dist/index.d.ts +2 -1
  32. package/dist/index.js +114 -110
  33. package/dist/index.js.map +1 -1
  34. package/package.json +4 -4
  35. package/src/components/PlAutocomplete/PlAutocomplete.vue +4 -3
  36. package/src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue +14 -11
  37. package/src/components/PlDropdown/PlDropdown.vue +10 -9
  38. package/src/components/PlDropdownLegacy/PlDropdownLegacy.vue +3 -2
  39. package/src/components/PlDropdownMulti/PlDropdownMulti.vue +11 -10
  40. package/src/components/PlFileInput/PlFileInput.vue +6 -3
  41. package/src/components/PlTextArea/PlTextArea.vue +3 -2
  42. package/src/components/PlTextField/PlTextField.vue +7 -6
  43. package/src/composition/filters/index.ts +2 -0
  44. package/src/composition/filters/metadata.ts +476 -0
  45. package/src/composition/filters/types.ts +44 -0
  46. package/src/index.ts +2 -1
  47. package/dist/generated/components/svg/images/SvgRequired.vue.d.ts +0 -2
  48. package/dist/generated/components/svg/images/SvgRequired.vue.js +0 -17
  49. package/dist/generated/components/svg/images/SvgRequired.vue.js.map +0 -1
  50. package/dist/generated/components/svg/images/SvgRequired.vue3.js +0 -6
  51. package/dist/generated/components/svg/images/SvgRequired.vue3.js.map +0 -1
  52. package/scripts/create-svg-components.js +0 -125
  53. package/src/generated/components/svg/images/Svg16Add.vue +0 -13
  54. package/src/generated/components/svg/images/Svg16Attention.vue +0 -13
  55. package/src/generated/components/svg/images/Svg16Checkmark.vue +0 -13
  56. package/src/generated/components/svg/images/Svg16CheckmarkDark.vue +0 -13
  57. package/src/generated/components/svg/images/Svg16ChevronDown.vue +0 -13
  58. package/src/generated/components/svg/images/Svg16ChevronLeft.vue +0 -13
  59. package/src/generated/components/svg/images/Svg16ChevronRight.vue +0 -13
  60. package/src/generated/components/svg/images/Svg16ChevronUp.vue +0 -13
  61. package/src/generated/components/svg/images/Svg16Clear.vue +0 -13
  62. package/src/generated/components/svg/images/Svg16Clipboard.vue +0 -13
  63. package/src/generated/components/svg/images/Svg16Close.vue +0 -13
  64. package/src/generated/components/svg/images/Svg16Compare.vue +0 -13
  65. package/src/generated/components/svg/images/Svg16Down.vue +0 -13
  66. package/src/generated/components/svg/images/Svg16Import.vue +0 -13
  67. package/src/generated/components/svg/images/Svg16Info.vue +0 -13
  68. package/src/generated/components/svg/images/Svg16InfoDark.vue +0 -13
  69. package/src/generated/components/svg/images/Svg16Link.vue +0 -13
  70. package/src/generated/components/svg/images/Svg16Loading.vue +0 -13
  71. package/src/generated/components/svg/images/Svg16Maximise.vue +0 -13
  72. package/src/generated/components/svg/images/Svg16Play.vue +0 -13
  73. package/src/generated/components/svg/images/Svg16Up.vue +0 -13
  74. package/src/generated/components/svg/images/Svg24ArrowRight.vue +0 -13
  75. package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledChecked.vue +0 -13
  76. package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledIndeterminate.vue +0 -13
  77. package/src/generated/components/svg/images/Svg24CheckboxDarkDisabledUnchecked.vue +0 -13
  78. package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledChecked.vue +0 -13
  79. package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledIndeterminate.vue +0 -13
  80. package/src/generated/components/svg/images/Svg24CheckboxDarkEnabledUnchecked.vue +0 -13
  81. package/src/generated/components/svg/images/Svg24CheckboxLightDisabledChecked.vue +0 -13
  82. package/src/generated/components/svg/images/Svg24CheckboxLightDisabledIndeterminate.vue +0 -13
  83. package/src/generated/components/svg/images/Svg24CheckboxLightDisabledUnchecked.vue +0 -13
  84. package/src/generated/components/svg/images/Svg24CheckboxLightEnabledChecked.vue +0 -13
  85. package/src/generated/components/svg/images/Svg24CheckboxLightEnabledIndeterminate.vue +0 -13
  86. package/src/generated/components/svg/images/Svg24CheckboxLightEnabledUnchecked.vue +0 -13
  87. package/src/generated/components/svg/images/Svg24Clips.vue +0 -13
  88. package/src/generated/components/svg/images/Svg24Close.vue +0 -13
  89. package/src/generated/components/svg/images/Svg24Code.vue +0 -13
  90. package/src/generated/components/svg/images/Svg24Columns.vue +0 -13
  91. package/src/generated/components/svg/images/Svg24DarkMode.vue +0 -13
  92. package/src/generated/components/svg/images/Svg24Filters.vue +0 -13
  93. package/src/generated/components/svg/images/Svg24LightMode.vue +0 -13
  94. package/src/generated/components/svg/images/Svg24Local.vue +0 -13
  95. package/src/generated/components/svg/images/Svg24PaperClip.vue +0 -13
  96. package/src/generated/components/svg/images/Svg24Search.vue +0 -13
  97. package/src/generated/components/svg/images/Svg24ServerOn.vue +0 -13
  98. package/src/generated/components/svg/images/Svg24Settings2.vue +0 -13
  99. package/src/generated/components/svg/images/SvgAddGraphBg.vue +0 -13
  100. package/src/generated/components/svg/images/SvgColorSliderThumbBig.vue +0 -13
  101. package/src/generated/components/svg/images/SvgColorSliderThumbSmall.vue +0 -13
  102. package/src/generated/components/svg/images/SvgEmptyCat.vue +0 -13
  103. package/src/generated/components/svg/images/SvgNoDataCat.vue +0 -13
  104. package/src/generated/components/svg/images/SvgRequired.vue +0 -13
  105. 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 se, ref as z, useTemplateRef as re, reactive as ae, watch as L, computed as i, toRef as ie, unref as u, createElementBlock as c, openBlock as r, 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 g, createTextVNode as U, toDisplayString as m, renderSlot as K } from "vue";
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 "../PlTooltip/PlTooltip.vue.js";
5
- import P from "../PlChip/PlChip.vue.js";
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 { useLabelNotch as ve } from "../../utils/useLabelNotch.js";
8
- import he from "../DropdownListItem.vue.js";
9
- import { deepEqual as x, deepIncludes as W } from "../../helpers/objects.js";
10
- import _e from "../../utils/DropdownOverlay/DropdownOverlay.vue.js";
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 "../../generated/components/svg/images/SvgRequired.vue.js";
13
- import { getErrorMessage as B } from "../../helpers/error.js";
14
- import { useWatchFetch as H } from "../../composition/useWatchFetch.js";
15
- import ke from "canonicalize";
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
- }, Ce = { class: "pl-autocomplete-multi__controls" }, Se = { key: 0 }, $e = { class: "pl-autocomplete-multi__open-chips-container" }, Ae = {
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
- }, Ee = {
23
+ }, Fe = {
23
24
  key: 0,
24
25
  class: "pl-autocomplete-multi__error"
25
- }, Fe = {
26
+ }, Te = {
26
27
  key: 1,
27
28
  class: "pl-autocomplete-multi__helper"
28
- }, Te = {
29
+ }, xe = {
29
30
  name: "PlAutocompleteMulti"
30
- }, je = /* @__PURE__ */ ne({
31
- ...Te,
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 = se(), n = j, b = z(), k = z(), V = re("overlay"), l = ae({
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 O = i(() => Array.isArray(n.modelValue) ? n.modelValue : []), X = i(() => l.open && n.modelValue.length > 0 ? n.placeholder : n.modelValue.length > 0 ? "" : n.placeholder), I = ie(n, "debounce"), v = H(() => [l.search, l.open, n.sourceId], async ([e, t]) => n.optionsSearch(e), {
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 = H(() => [n.modelValue, n.sourceId], async ([e]) => n.modelSearch(e), {
62
+ }), h = K(() => [n.modelValue, n.sourceId], async ([e]) => n.modelSearch(e), {
62
63
  debounce: I
63
- }), Y = i(() => {
64
- const e = h.value ?? [], t = v.value ?? [], o = /* @__PURE__ */ new Set(), s = [], a = (A) => {
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 = ke(_.value);
67
- o.has(y) || (o.add(y), s.push(_));
67
+ const y = fe(_.value);
68
+ o.has(y) || (o.add(y), r.push(_));
68
69
  }
69
70
  };
70
- return a(e), a(t), s;
71
- }), w = i(() => O.value.map((e) => Y.value.find((t) => x(t.value, e))).filter(
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 = i(() => {
74
- const e = u(O);
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 = i(() => v.loading || h.loading), S = i(() => h.value === void 0 ? !0 : n.disabled), Z = i(() => S.value ? void 0 : "0"), ee = () => {
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 = u(O);
84
- D(W(t, e) ? t.filter((s) => !x(s, e)) : [...t, e]), n.resetSearchOnSelect && (l.search = ""), (o = k.value) == null || o.focus();
85
- }, N = (e) => D(u(O).filter((t) => !x(t, e))), oe = () => {
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, s, a;
90
+ var o, r, a;
90
91
  const t = e.relatedTarget;
91
- !((o = b.value) != null && o.contains(t)) && !((a = (s = V.value) == null ? void 0 : s.listRef) != null && a.contains(t)) && (l.open = !1);
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 s = u(R), { length: a } = s;
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(s[o].value);
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
- ve(b), L(
111
+ he(b), L(
111
112
  () => n.modelValue,
112
113
  () => ee(),
113
114
  { immediate: !0 }
114
115
  );
115
- const $ = i(() => {
116
+ const $ = u(() => {
116
117
  if (!C.value) {
117
118
  if (v.error)
118
- return B(v.error);
119
+ return x(v.error);
119
120
  if (h.error)
120
- return B(h.error);
121
+ return x(h.error);
121
122
  if (n.error)
122
- return B(n.error);
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) => (r(), c("div", {
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", ge, [
140
- d("div", Ve, [
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, we), [
153
+ }, null, 40, Re), [
153
154
  [pe, l.search]
154
155
  ]),
155
- l.open ? p("", !0) : (r(), c("div", Re, [
156
- (r(!0), c(E, null, F(w.value, (o, s) => (r(), f(u(P), {
157
- key: s,
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: g(() => [
164
- U(m(o.label || o.value), 1)
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", Ce, [
170
- C.value ? (r(), f(u(ye), {
170
+ d("div", Se, [
171
+ C.value ? (s(), f(i(ye), {
171
172
  key: 0,
172
173
  name: "loading"
173
174
  })) : p("", !0),
174
- K(e.$slots, "append"),
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 ? (r(), c("label", Se, [
184
- e.required ? (r(), f(be, { key: 0 })) : p("", !0),
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
- u(Q).tooltip ? (r(), f(u(fe), {
190
+ i(Q).tooltip ? (s(), f(i(be), {
187
191
  key: 1,
188
192
  class: "info",
189
193
  position: "top"
190
194
  }, {
191
- tooltip: g(() => [
192
- K(e.$slots, "tooltip")
195
+ tooltip: O(() => [
196
+ U(e.$slots, "tooltip")
193
197
  ]),
194
198
  _: 3
195
199
  })) : p("", !0)
196
200
  ])) : p("", !0),
197
- l.open ? (r(), f(_e, {
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: g(() => [
208
- d("div", $e, [
209
- (r(!0), c(E, null, F(w.value, (o, s) => (r(), f(u(P), {
210
- key: s,
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: g(() => [
216
- U(m(o.label || o.value), 1)
219
+ default: O(() => [
220
+ P(m(o.label || o.value), 1)
217
221
  ]),
218
222
  _: 2
219
223
  }, 1032, ["onClose"]))), 128))
220
224
  ]),
221
- (r(!0), c(E, null, F(R.value, (o, s) => (r(), f(he, {
222
- key: s,
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 == s,
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 ? (r(), c("div", Ae, m(e.emptyOptionsText), 1)) : p("", !0)
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 ? (r(), c("div", Ee, m($.value), 1)) : e.helper ? (r(), c("div", Fe, m(e.helper), 1)) : p("", !0)
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
- je as default
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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"}