@milaboratories/uikit 2.6.1 → 2.6.2

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 (64) hide show
  1. package/.turbo/turbo-build.log +48 -48
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +8 -0
  4. package/dist/components/DataTable/TableComponent.vue.js +4 -2
  5. package/dist/components/DataTable/TableComponent.vue.js.map +1 -1
  6. package/dist/components/PlAccordion/ExpandTransition.vue3.js +1 -1
  7. package/dist/components/PlAccordion/PlAccordionSection.vue2.js +1 -1
  8. package/dist/components/PlAutocomplete/PlAutocomplete.vue.d.ts +4 -0
  9. package/dist/components/PlAutocomplete/PlAutocomplete.vue.js +74 -68
  10. package/dist/components/PlAutocomplete/PlAutocomplete.vue.js.map +1 -1
  11. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.d.ts +4 -0
  12. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js +52 -46
  13. package/dist/components/PlAutocompleteMulti/PlAutocompleteMulti.vue.js.map +1 -1
  14. package/dist/components/PlDropdown/PlDropdown.vue.d.ts +8 -0
  15. package/dist/components/PlDropdown/PlDropdown.vue.js +67 -60
  16. package/dist/components/PlDropdown/PlDropdown.vue.js.map +1 -1
  17. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js +21 -19
  18. package/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js.map +1 -1
  19. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.d.ts +4 -0
  20. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js +47 -41
  21. package/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js.map +1 -1
  22. package/dist/components/PlElementList/PlElementList.vue.d.ts +20 -0
  23. package/dist/components/PlElementList/PlElementList.vue2.js +180 -135
  24. package/dist/components/PlElementList/PlElementList.vue2.js.map +1 -1
  25. package/dist/components/PlElementList/PlElementListItem.vue.d.ts +20 -0
  26. package/dist/components/PlElementList/PlElementListItem.vue2.js +99 -74
  27. package/dist/components/PlElementList/PlElementListItem.vue2.js.map +1 -1
  28. package/dist/components/PlFileInput/PlFileInput.vue.js +24 -22
  29. package/dist/components/PlFileInput/PlFileInput.vue.js.map +1 -1
  30. package/dist/components/PlLogView/PlLogView.vue.js +24 -22
  31. package/dist/components/PlLogView/PlLogView.vue.js.map +1 -1
  32. package/dist/components/PlNumberField/PlNumberField.vue.d.ts +5 -0
  33. package/dist/components/PlNumberField/PlNumberField.vue.js +60 -54
  34. package/dist/components/PlNumberField/PlNumberField.vue.js.map +1 -1
  35. package/dist/components/PlSlideModal/PlPureSlideModal.vue.js +4 -2
  36. package/dist/components/PlSlideModal/PlPureSlideModal.vue.js.map +1 -1
  37. package/dist/components/PlTextArea/PlTextArea.vue.js +15 -13
  38. package/dist/components/PlTextArea/PlTextArea.vue.js.map +1 -1
  39. package/dist/components/PlTextField/PlTextField.vue.d.ts +4 -0
  40. package/dist/components/PlTextField/PlTextField.vue.js +45 -39
  41. package/dist/components/PlTextField/PlTextField.vue.js.map +1 -1
  42. package/dist/composition/filters/metadata.d.ts +205 -0
  43. package/dist/composition/filters/metadata.js +129 -19
  44. package/dist/composition/filters/metadata.js.map +1 -1
  45. package/dist/utils/DoubleContour.vue.d.ts +7 -1
  46. package/dist/utils/DoubleContour.vue.js +20 -13
  47. package/dist/utils/DoubleContour.vue.js.map +1 -1
  48. package/dist/utils/DoubleContour.vue2.js +19 -3
  49. package/dist/utils/DoubleContour.vue2.js.map +1 -1
  50. package/dist/utils/DoubleContour.vue3.js +7 -0
  51. package/dist/utils/DoubleContour.vue3.js.map +1 -0
  52. package/package.json +4 -4
  53. package/src/components/PlAutocomplete/PlAutocomplete.vue +6 -1
  54. package/src/components/PlAutocompleteMulti/PlAutocompleteMulti.vue +6 -1
  55. package/src/components/PlDropdown/PlDropdown.vue +12 -2
  56. package/src/components/PlDropdownMulti/PlDropdownMulti.vue +6 -1
  57. package/src/components/PlElementList/PlElementList.vue +40 -6
  58. package/src/components/PlElementList/PlElementListItem.vue +64 -47
  59. package/src/components/PlNumberField/PlNumberField.vue +4 -1
  60. package/src/components/PlTextField/PlTextField.vue +5 -1
  61. package/src/composition/filters/metadata.ts +105 -0
  62. package/src/utils/DoubleContour.vue +68 -2
  63. package/dist/components/PlAccordion/ExpandTransition.vue.js +0 -27
  64. package/dist/components/PlAccordion/ExpandTransition.vue.js.map +0 -1
@@ -1,23 +1,25 @@
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 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";
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}
2
+ .double-contour.top>div{border-bottom-right-radius:0;border-bottom-left-radius:0}.double-contour.bottom>div{border-top-right-radius:0;border-top-left-radius:0}.double-contour.left>div{border-top-right-radius:0;border-bottom-right-radius:0}.double-contour.right>div{border-top-left-radius:0;border-bottom-left-radius:0}.double-contour.top-left>div{border-top-right-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.double-contour.top-right>div{border-bottom-right-radius:0;border-top-left-radius:0;border-top-right-radius:0}.double-contour.bottom-left>div{border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:0}.double-contour.bottom-right>div{border-top-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0}.double-contour.middle>div{border-radius:0}`)),document.head.appendChild(o)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
3
+ import { defineComponent as ne, useSlots as re, ref as P, useTemplateRef as se, reactive as ae, watch as z, 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 L, toDisplayString as m, renderSlot as U } from "vue";
3
4
 
4
5
  import fe from "canonicalize";
5
6
  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";
7
+ import { getErrorMessage as B } from "../../helpers/error.js";
8
+ import { deepEqual as I, deepIncludes as W } from "../../helpers/objects.js";
8
9
  import me from "../../utils/DoubleContour.vue.js";
10
+
9
11
  import ve from "../../utils/DropdownOverlay/DropdownOverlay.vue.js";
10
12
  import { useLabelNotch as he } from "../../utils/useLabelNotch.js";
11
13
  import _e from "../DropdownListItem.vue.js";
12
14
  import H from "../PlChip/PlChip.vue.js";
13
15
  import ye from "../PlIcon24/PlIcon24.vue.js";
14
- import be from "../PlTooltip/PlTooltip.vue.js";
16
+ import ge from "../PlTooltip/PlTooltip.vue.js";
15
17
  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 = {
18
+ import be from "../PlSvg/PlSvg.vue.js";
19
+ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we = { class: "pl-autocomplete-multi__field" }, Re = ["disabled", "placeholder"], Se = {
18
20
  key: 0,
19
21
  class: "chips-container"
20
- }, Se = { class: "pl-autocomplete-multi__controls" }, $e = { key: 0 }, Ae = { class: "pl-autocomplete-multi__open-chips-container" }, Ee = {
22
+ }, Ce = { class: "pl-autocomplete-multi__controls" }, $e = { key: 0 }, Ae = { class: "pl-autocomplete-multi__open-chips-container" }, Ee = {
21
23
  key: 0,
22
24
  class: "nothing-found"
23
25
  }, Fe = {
@@ -26,10 +28,10 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
26
28
  }, Te = {
27
29
  key: 1,
28
30
  class: "pl-autocomplete-multi__helper"
29
- }, xe = {
31
+ }, Be = {
30
32
  name: "PlAutocompleteMulti"
31
- }, Je = /* @__PURE__ */ ne({
32
- ...xe,
33
+ }, Qe = /* @__PURE__ */ ne({
34
+ ...Be,
33
35
  props: {
34
36
  modelValue: { default: () => [] },
35
37
  optionsSearch: {},
@@ -43,24 +45,25 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
43
45
  disabled: { type: Boolean, default: !1 },
44
46
  debounce: { default: 300 },
45
47
  resetSearchOnSelect: { type: Boolean },
46
- emptyOptionsText: { default: "Nothing found" }
48
+ emptyOptionsText: { default: "Nothing found" },
49
+ groupPosition: { default: void 0 }
47
50
  },
48
51
  emits: ["update:modelValue"],
49
52
  setup(j, { emit: G }) {
50
- const J = G, D = (e) => J("update:modelValue", e), Q = re(), n = j, b = z(), k = z(), V = se("overlay"), l = ae({
53
+ const J = G, M = (e) => J("update:modelValue", e), Q = re(), n = j, g = P(), k = P(), V = se("overlay"), l = ae({
51
54
  search: "",
52
55
  activeOption: -1,
53
56
  open: !1,
54
57
  optionsHeight: 0
55
58
  });
56
- L(() => l.open, (e) => {
59
+ z(() => l.open, (e) => {
57
60
  e || (l.search = "");
58
61
  }, { flush: "sync" });
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), {
62
+ const b = u(() => Array.isArray(n.modelValue) ? n.modelValue : []), X = u(() => l.open && n.modelValue.length > 0 ? n.placeholder : n.modelValue.length > 0 ? "" : n.placeholder), x = ie(n, "debounce"), v = K(() => [l.search, l.open, n.sourceId], async ([e, t]) => n.optionsSearch(e), {
60
63
  filterWatchResult: ([e, t]) => t,
61
- debounce: I
64
+ debounce: x
62
65
  }), h = K(() => [n.modelValue, n.sourceId], async ([e]) => n.modelSearch(e), {
63
- debounce: I
66
+ debounce: x
64
67
  }), Y = u(() => {
65
68
  const e = h.value ?? [], t = v.value ?? [], o = /* @__PURE__ */ new Set(), r = [], a = (A) => {
66
69
  for (const _ of A) {
@@ -69,27 +72,27 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
69
72
  }
70
73
  };
71
74
  return a(e), a(t), r;
72
- }), w = u(() => g.value.map((e) => Y.value.find((t) => B(t.value, e))).filter(
75
+ }), w = u(() => b.value.map((e) => Y.value.find((t) => I(t.value, e))).filter(
73
76
  (e) => e !== void 0
74
77
  )), R = u(() => {
75
- const e = i(g);
78
+ const e = i(b);
76
79
  return [...v.value ?? []].map((o) => ({
77
80
  ...o,
78
81
  selected: W(e, o.value)
79
82
  }));
80
- }), C = u(() => v.loading || h.loading), S = u(() => h.value === void 0 ? !0 : n.disabled), Z = u(() => S.value ? void 0 : "0"), ee = () => {
83
+ }), S = u(() => v.loading || h.loading), C = u(() => h.value === void 0 ? !0 : n.disabled), Z = u(() => C.value ? void 0 : "0"), ee = () => {
81
84
  l.activeOption = 0;
82
- }, M = (e) => {
85
+ }, D = (e) => {
83
86
  var o;
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 = () => {
87
+ const t = i(b);
88
+ M(W(t, e) ? t.filter((r) => !I(r, e)) : [...t, e]), n.resetSearchOnSelect && (l.search = ""), (o = k.value) == null || o.focus();
89
+ }, N = (e) => M(i(b).filter((t) => !I(t, e))), oe = () => {
87
90
  var e;
88
91
  return (e = k.value) == null ? void 0 : e.focus();
89
92
  }, te = () => l.open = !l.open, q = (e) => {
90
93
  var o, r, a;
91
94
  const t = e.relatedTarget;
92
- !((o = b.value) != null && o.contains(t)) && !((a = (r = V.value) == null ? void 0 : r.listRef) != null && a.contains(t)) && (l.open = !1);
95
+ !((o = g.value) != null && o.contains(t)) && !((a = (r = V.value) == null ? void 0 : r.listRef) != null && a.contains(t)) && (l.open = !1);
93
96
  }, le = (e) => {
94
97
  var _;
95
98
  const { open: t, activeOption: o } = l;
@@ -101,26 +104,26 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
101
104
  const r = i(R), { length: a } = r;
102
105
  if (!a)
103
106
  return;
104
- ["ArrowDown", "ArrowUp", "Enter"].includes(e.code) && e.preventDefault(), e.code === "Enter" && M(r[o].value);
107
+ ["ArrowDown", "ArrowUp", "Enter"].includes(e.code) && e.preventDefault(), e.code === "Enter" && D(r[o].value);
105
108
  const A = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0;
106
109
  l.activeOption = Math.abs(o + A + a) % a, requestAnimationFrame(() => {
107
110
  var y;
108
111
  return (y = V.value) == null ? void 0 : y.scrollIntoActive();
109
112
  });
110
113
  };
111
- he(b), L(
114
+ he(g), z(
112
115
  () => n.modelValue,
113
116
  () => ee(),
114
117
  { immediate: !0 }
115
118
  );
116
119
  const $ = u(() => {
117
- if (!C.value) {
120
+ if (!S.value) {
118
121
  if (v.error)
119
- return x(v.error);
122
+ return B(v.error);
120
123
  if (h.error)
121
- return x(h.error);
124
+ return B(h.error);
122
125
  if (n.error)
123
- return x(n.error);
126
+ return B(n.error);
124
127
  if (n.modelValue.length && w.value.length !== n.modelValue.length)
125
128
  return "The selected values are not one of the options";
126
129
  }
@@ -131,9 +134,9 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
131
134
  }, [
132
135
  d("div", {
133
136
  ref_key: "rootRef",
134
- ref: b,
137
+ ref: g,
135
138
  tabindex: Z.value,
136
- class: ue(["pl-autocomplete-multi", { open: l.open, error: !!$.value, disabled: S.value }]),
139
+ class: ue(["pl-autocomplete-multi", { open: l.open, error: !!$.value, disabled: C.value }]),
137
140
  onKeydown: le,
138
141
  onFocusout: q
139
142
  }, [
@@ -145,7 +148,7 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
145
148
  "onUpdate:modelValue": t[0] || (t[0] = (o) => l.search = o),
146
149
  type: "text",
147
150
  tabindex: "-1",
148
- disabled: S.value,
151
+ disabled: C.value,
149
152
  placeholder: X.value,
150
153
  spellcheck: "false",
151
154
  autocomplete: "chrome-off",
@@ -153,7 +156,7 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
153
156
  }, null, 40, Re), [
154
157
  [pe, l.search]
155
158
  ]),
156
- l.open ? p("", !0) : (s(), c("div", Ce, [
159
+ l.open ? p("", !0) : (s(), c("div", Se, [
157
160
  (s(!0), c(E, null, F(w.value, (o, r) => (s(), f(i(H), {
158
161
  key: r,
159
162
  closeable: "",
@@ -162,13 +165,13 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
162
165
  onClose: (a) => N(o.value)
163
166
  }, {
164
167
  default: O(() => [
165
- P(m(o.label || o.value), 1)
168
+ L(m(o.label || o.value), 1)
166
169
  ]),
167
170
  _: 2
168
171
  }, 1032, ["onClose"]))), 128))
169
172
  ])),
170
- d("div", Se, [
171
- C.value ? (s(), f(i(ye), {
173
+ d("div", Ce, [
174
+ S.value ? (s(), f(i(ye), {
172
175
  key: 0,
173
176
  name: "loading"
174
177
  })) : p("", !0),
@@ -182,12 +185,12 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
182
185
  ])
183
186
  ]),
184
187
  e.label ? (s(), c("label", $e, [
185
- e.required ? (s(), f(i(ge), {
188
+ e.required ? (s(), f(i(be), {
186
189
  key: 0,
187
190
  uri: i(ke)
188
191
  }, null, 8, ["uri"])) : p("", !0),
189
192
  d("span", null, m(e.label), 1),
190
- i(Q).tooltip ? (s(), f(i(be), {
193
+ i(Q).tooltip ? (s(), f(i(ge), {
191
194
  key: 1,
192
195
  class: "info",
193
196
  position: "top"
@@ -202,7 +205,7 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
202
205
  key: 1,
203
206
  ref_key: "overlay",
204
207
  ref: V,
205
- root: b.value,
208
+ root: g.value,
206
209
  class: "pl-autocomplete-multi__options",
207
210
  gap: 5,
208
211
  tabindex: "-1",
@@ -217,7 +220,7 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
217
220
  onClose: (a) => N(o.value)
218
221
  }, {
219
222
  default: O(() => [
220
- P(m(o.label || o.value), 1)
223
+ L(m(o.label || o.value), 1)
221
224
  ]),
222
225
  _: 2
223
226
  }, 1032, ["onClose"]))), 128))
@@ -230,13 +233,16 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
230
233
  "is-hovered": l.activeOption == r,
231
234
  size: "medium",
232
235
  "use-checkbox": "",
233
- onClick: T((a) => M(o.value), ["stop"])
236
+ onClick: T((a) => D(o.value), ["stop"])
234
237
  }, null, 8, ["option", "is-selected", "is-hovered", "onClick"]))), 128)),
235
- !R.value.length && !C.value ? (s(), c("div", Ee, m(e.emptyOptionsText), 1)) : p("", !0)
238
+ !R.value.length && !S.value ? (s(), c("div", Ee, m(e.emptyOptionsText), 1)) : p("", !0)
236
239
  ]),
237
240
  _: 1
238
241
  }, 8, ["root"])) : p("", !0),
239
- ce(me, { class: "pl-autocomplete-multi__contour" })
242
+ ce(me, {
243
+ class: "pl-autocomplete-multi__contour",
244
+ "group-position": e.groupPosition
245
+ }, null, 8, ["group-position"])
240
246
  ])
241
247
  ], 42, Oe),
242
248
  $.value ? (s(), c("div", Fe, m($.value), 1)) : e.helper ? (s(), c("div", Te, m(e.helper), 1)) : p("", !0)
@@ -244,6 +250,6 @@ const Oe = ["tabindex"], Ve = { class: "pl-autocomplete-multi__container" }, we
244
250
  }
245
251
  });
246
252
  export {
247
- Je as default
253
+ Qe as default
248
254
  };
249
255
  //# 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';\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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"}
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 * Makes some of corners not rounded\n * */\n groupPosition?: 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'middle';\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 groupPosition: 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\" :group-position=\"groupPosition\" />\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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"}
@@ -30,6 +30,10 @@ declare const _default: <M = unknown>(__VLS_props: NonNullable<Awaited<typeof __
30
30
  * Error message displayed below the dropdown (optional)
31
31
  */
32
32
  error?: unknown;
33
+ /**
34
+ * Shows red border even without an error message
35
+ */
36
+ errorStatus?: boolean;
33
37
  /**
34
38
  * Placeholder text shown when no value is selected.
35
39
  */
@@ -58,6 +62,10 @@ declare const _default: <M = unknown>(__VLS_props: NonNullable<Awaited<typeof __
58
62
  * Option list item size
59
63
  */
60
64
  optionSize?: "small" | "medium";
65
+ /**
66
+ * Makes some of corners not rounded
67
+ * */
68
+ groupPosition?: "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle";
61
69
  } & Partial<{}>> & import('vue').PublicProps;
62
70
  expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
63
71
  attrs: any;