@milaboratories/uikit 2.6.5 → 2.7.1

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.
@@ -1,40 +1,40 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var o=document.createElement("style");o.appendChild(document.createTextNode(`.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}
2
2
  .ui-lt-container{min-width:0;white-space:nowrap;overflow:hidden;position:relative;border-radius:5px}.ui-lt-container span{display:inline-block;overflow:hidden;text-overflow:ellipsis;width:100%;vertical-align:bottom;pointer-events:all!important}.ui-lt-container .ui-lt-animate{position:relative;animation:left-to-right var(--v5deba9de) infinite alternate linear;overflow:unset!important;text-overflow:unset!important;width:fit-content!important}@keyframes left-to-right{0%{transform:translate(0);left:0%}to{transform:translate(-101%);left:101%}}
3
3
  .pl-dropdown__options{--option-hover-bg: var(--btn-sec-hover-grey);z-index:var(--z-dropdown-options);border:1px solid var(--border-color-div-grey);position:absolute;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-dropdown__options::-webkit-scrollbar{width:var(--scrollbar-width, 6px);height:5px;background-color:transparent;display:block}.pl-dropdown__options::-webkit-scrollbar-thumb{background:var(--thumb-color);border-radius:5px}.pl-dropdown__options::-webkit-scrollbar-thumb:hover{--thumb-color: var(--border-color-focus)}.pl-dropdown__options .nothing-found{padding:0 10px;height:var(--control-height);line-height:var(--control-height);background-color:#fff;opacity:.5;font-style:italic}.pl-dropdown__options .group-container{padding:4px 0}.pl-dropdown{--contour-color: var(--txt-01);--contour-border-width: 1px;--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)}.pl-dropdown__envelope{font-family:var(--control-font-family);min-width:160px}.pl-dropdown 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-dropdown label>span{overflow:hidden;white-space:pre;text-overflow:ellipsis}.pl-dropdown__container{position:absolute;top:0;left:0;right:0;border-radius:6px;min-height:var(--control-height);color:var(--txt-01)}.pl-dropdown__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-dropdown__field{position:relative;border-radius:6px;overflow:hidden;background:transparent;padding-left:11px;min-height:var(--control-height);line-height:var(--control-height);display:flex;flex-direction:row;align-items:center;cursor:pointer}.pl-dropdown__field .input-value{position:absolute;top:0;left:0;bottom:0;right:0;display:flex;flex-direction:row;align-items:center;padding:0 60px 0 11px;pointer-events:none;line-height:20px;color:var(--txt-01);overflow:hidden;white-space:pre;text-overflow:ellipsis;cursor:inherit}.pl-dropdown__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% - 40px);color:var(--txt-01);caret-color:var(--border-color-focus)}.pl-dropdown__field input:focus{outline:none}.pl-dropdown__field input:placeholder-shown{text-overflow:ellipsis}.pl-dropdown__field input::placeholder{color:var(--color-placeholder)}.pl-dropdown__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-dropdown__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-dropdown__controls{display:flex;flex-direction:row;align-items:center;gap:6px;margin-left:auto}.pl-dropdown__controls .mask-16,.pl-dropdown__controls .mask-24{cursor:pointer}.pl-dropdown__controls .clear{--icon-color: var(--ic-02)}.pl-dropdown__controls .mask-loading{--icon-color: var(--ic-accent);animation:spin 2.5s linear infinite}.pl-dropdown__arrow-wrapper{display:flex;align-items:center;min-height:var(--control-height);padding-right:11px}.pl-dropdown .arrow-icon{cursor:pointer}.pl-dropdown .arrow-icon.arrow-icon-default{transition:transform .2s}.pl-dropdown.open,.pl-dropdown:focus-within{z-index:1;--label-color: var(--txt-focus)}.pl-dropdown.open .pl-dropdown__container{z-index:1000}.pl-dropdown.open .pl-dropdown__field{border-radius:6px 6px 0 0}.pl-dropdown.open .arrow-icon.arrow-icon-default{transform:rotate(-180deg)}.pl-dropdown:hover{--contour-color: var(--control-hover-color)}.pl-dropdown: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-dropdown:focus-within.error{--contour-border-width: 2px;--contour-box-shadow: 0 0 0 4px var(--color-error-shadow)}.pl-dropdown.error{--contour-color: var(--txt-error);--label-color: var(--txt-error)}.pl-dropdown.disabled{--contour-color: var(--color-dis-01);--icon-color: var(--color-dis-01);--label-color: var(--color-dis-01);cursor:not-allowed;pointer-events:none;-webkit-user-select:none;user-select:none}.pl-dropdown.disabled .input-value{color:var(--dis-01)}`)),document.head.appendChild(o)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
4
- import { defineComponent as le, ref as B, useTemplateRef as ae, reactive as ie, computed as s, unref as i, watch as P, watchPostEffect as se, createElementBlock as v, openBlock as l, createElementVNode as f, createCommentVNode as c, normalizeClass as de, createBlock as u, createVNode as D, withDirectives as ce, vModelText as ue, withCtx as $, createTextVNode as pe, toDisplayString as h, renderSlot as z, withModifiers as M } from "vue";
5
- import fe from "../../assets/images/required.svg.js";
6
- import { getErrorMessage as me } from "../../helpers/error.js";
7
- import { tap as ve } from "../../helpers/functions.js";
4
+ import { defineComponent as ae, ref as P, useTemplateRef as ie, reactive as se, computed as i, unref as s, watch as D, watchPostEffect as de, createElementBlock as v, openBlock as l, createElementVNode as f, createCommentVNode as c, normalizeClass as ce, createBlock as u, createVNode as $, withDirectives as ue, vModelText as pe, withCtx as z, createTextVNode as fe, toDisplayString as h, renderSlot as M, withModifiers as T } from "vue";
5
+ import me from "../../assets/images/required.svg.js";
6
+ import { getErrorMessage as ve } from "../../helpers/error.js";
7
+ import { tap as he } from "../../helpers/functions.js";
8
8
  import { deepEqual as x } from "../../helpers/objects.js";
9
- import { normalizeListOptions as he } from "../../helpers/utils.js";
10
- import we from "../../utils/DoubleContour.vue.js";
9
+ import { normalizeListOptions as we } from "../../helpers/utils.js";
10
+ import ge from "../../utils/DoubleContour.vue.js";
11
11
 
12
- import { useLabelNotch as ge } from "../../utils/useLabelNotch.js";
13
- import ye from "../LongText.vue.js";
12
+ import { useLabelNotch as ye } from "../../utils/useLabelNotch.js";
13
+ import ke from "../LongText.vue.js";
14
14
 
15
15
  import _ from "../PlIcon16/PlIcon16.vue.js";
16
- import T from "../PlIcon24/PlIcon24.vue.js";
17
- import ke from "../PlSvg/PlSvg.vue.js";
18
- import Ie from "../PlTooltip/PlTooltip.vue.js";
19
- import xe from "./OptionList.vue.js";
16
+ import F from "../PlIcon24/PlIcon24.vue.js";
17
+ import Ie from "../PlSvg/PlSvg.vue.js";
18
+ import xe from "../PlTooltip/PlTooltip.vue.js";
19
+ import _e from "./OptionList.vue.js";
20
20
 
21
- import { useGroupBy as _e } from "./useGroupBy.js";
22
- const Ve = ["tabindex"], be = { class: "pl-dropdown__container" }, Le = { class: "pl-dropdown__field" }, Ce = ["disabled", "placeholder"], Ee = {
21
+ import { useGroupBy as be } from "./useGroupBy.js";
22
+ const Ve = ["tabindex"], Le = { class: "pl-dropdown__container" }, Ce = { class: "pl-dropdown__field" }, Ee = ["disabled", "placeholder"], Re = {
23
23
  key: 0,
24
24
  class: "input-value"
25
- }, Re = { class: "pl-dropdown__controls" }, Oe = { key: 0 }, Se = {
25
+ }, Se = { class: "pl-dropdown__controls" }, Oe = { key: 0 }, Ae = {
26
26
  key: 0,
27
27
  class: "pl-dropdown__error"
28
- }, Ae = {
28
+ }, Be = {
29
29
  key: 1,
30
30
  class: "pl-dropdown__helper"
31
- }, Be = {
31
+ }, Pe = {
32
32
  key: 2,
33
33
  class: "pl-dropdown__helper"
34
- }, Pe = {
34
+ }, De = {
35
35
  name: "PlDropdown"
36
- }, Ze = /* @__PURE__ */ le({
37
- ...Pe,
36
+ }, eo = /* @__PURE__ */ ae({
37
+ ...De,
38
38
  props: {
39
39
  modelValue: {},
40
40
  label: { default: "" },
@@ -53,54 +53,54 @@ const Ve = ["tabindex"], be = { class: "pl-dropdown__container" }, Le = { class:
53
53
  groupPosition: { default: void 0 }
54
54
  },
55
55
  emits: ["update:modelValue"],
56
- setup(n, { emit: F }) {
57
- const V = F, r = n, d = B(), g = B(), y = ae("optionListRef"), o = ie({
56
+ setup(r, { emit: N }) {
57
+ const b = N, n = r, d = P(), w = P(), g = ie("optionListRef"), o = se({
58
58
  search: "",
59
59
  activeIndex: -1,
60
60
  open: !1,
61
61
  optionsHeight: 0
62
- }), N = () => ve(
63
- R.value.findIndex((e) => x(e.value, r.modelValue)),
62
+ }), q = () => he(
63
+ S.value.findIndex((e) => x(e.value, n.modelValue)),
64
64
  (e) => e < 0 ? 0 : e
65
- ), q = () => o.activeIndex = N(), w = s(() => r.options === void 0), k = s(() => w.value ? !0 : r.disabled), b = s(() => (r.options ?? []).findIndex((e) => x(e.value, r.modelValue))), L = s(() => {
66
- if (!w.value) {
67
- if (r.error)
68
- return me(r.error);
69
- if (r.modelValue !== void 0 && b.value === -1)
65
+ ), H = () => o.activeIndex = q(), y = i(() => n.options === void 0), V = i(() => !n.disabled && y.value), k = i(() => y.value ? !0 : n.disabled), L = i(() => (n.options ?? []).findIndex((e) => x(e.value, n.modelValue))), C = i(() => {
66
+ if (!y.value) {
67
+ if (n.error)
68
+ return ve(n.error);
69
+ if (n.modelValue !== void 0 && L.value === -1)
70
70
  return "The selected value is not one of the options";
71
71
  }
72
- }), C = s(
73
- () => he(r.options ?? []).map((e, t) => ({
72
+ }), E = i(
73
+ () => we(n.options ?? []).map((e, t) => ({
74
74
  ...e,
75
75
  index: t,
76
- isSelected: t === b.value,
76
+ isSelected: t === L.value,
77
77
  isActive: t === o.activeIndex
78
78
  }))
79
- ), E = s(() => {
80
- const t = i(C).find((a) => x(a.value, r.modelValue));
81
- return (t == null ? void 0 : t.label) || r.modelValue;
82
- }), H = s(() => !o.open && r.modelValue !== void 0 ? "" : r.modelValue ? String(E.value) : r.placeholder), U = s(() => r.modelValue !== void 0 && r.modelValue !== null), K = s(() => {
83
- const e = C.value;
79
+ ), R = i(() => {
80
+ const t = s(E).find((a) => x(a.value, n.modelValue));
81
+ return (t == null ? void 0 : t.label) || n.modelValue;
82
+ }), U = i(() => !o.open && n.modelValue !== void 0 ? "" : n.modelValue ? String(R.value) : n.placeholder), K = i(() => n.modelValue !== void 0 && n.modelValue !== null), G = i(() => {
83
+ const e = E.value;
84
84
  return o.search ? e.filter((t) => {
85
85
  const a = o.search.toLowerCase();
86
86
  return t.label.toLowerCase().includes(a) || t.description && t.description.toLowerCase().includes(a) ? !0 : typeof t.value == "string" ? t.value.toLowerCase().includes(a) : t.value === o.search;
87
87
  }) : e;
88
- }), { orderedRef: R, groupsRef: G, restRef: W } = _e(K, "group"), j = s(() => k.value ? void 0 : "0"), O = (e) => {
88
+ }), { orderedRef: S, groupsRef: W, restRef: j } = be(G, "group"), J = i(() => k.value ? void 0 : "0"), O = (e) => {
89
89
  var t;
90
- V("update:modelValue", e), o.search = "", o.open = !1, (t = d == null ? void 0 : d.value) == null || t.focus();
91
- }, J = (e) => {
90
+ b("update:modelValue", e), o.search = "", o.open = !1, (t = d == null ? void 0 : d.value) == null || t.focus();
91
+ }, Q = (e) => {
92
92
  O(e);
93
- }, Q = () => V("update:modelValue", void 0), X = () => {
93
+ }, X = () => b("update:modelValue", void 0), Y = () => {
94
94
  var e;
95
- return (e = g.value) == null ? void 0 : e.focus();
96
- }, Y = () => {
95
+ return (e = w.value) == null ? void 0 : e.focus();
96
+ }, Z = () => {
97
97
  o.open = !o.open, o.open || (o.search = "");
98
- }, Z = () => o.open = !0, ee = (e) => {
98
+ }, ee = () => o.open = !0, oe = (e) => {
99
99
  var a, p, m;
100
100
  const t = e.relatedTarget;
101
- !((a = d.value) != null && a.contains(t)) && !((m = (p = y.value) == null ? void 0 : p.listRef) != null && m.contains(t)) && (o.search = "", o.open = !1);
102
- }, oe = (e) => {
103
- var S, A;
101
+ !((a = d.value) != null && a.contains(t)) && !((m = (p = g.value) == null ? void 0 : p.listRef) != null && m.contains(t)) && (o.search = "", o.open = !1);
102
+ }, te = (e) => {
103
+ var A, B;
104
104
  if (["ArrowDown", "ArrowUp", "Enter", "Escape"].includes(e.code))
105
105
  e.preventDefault();
106
106
  else
@@ -110,84 +110,84 @@ const Ve = ["tabindex"], be = { class: "pl-dropdown__container" }, Le = { class:
110
110
  e.code === "Enter" && (o.open = !0);
111
111
  return;
112
112
  }
113
- e.code === "Escape" && (o.open = !1, (S = d.value) == null || S.focus());
114
- const p = R.value, { length: m } = p;
113
+ e.code === "Escape" && (o.open = !1, (A = d.value) == null || A.focus());
114
+ const p = S.value, { length: m } = p;
115
115
  if (!m)
116
116
  return;
117
- e.code === "Enter" && O((A = p.find((I) => I.index === a)) == null ? void 0 : A.value);
118
- const te = p.findIndex((I) => I.index === a) ?? -1, ne = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0, re = Math.abs(te + ne + m) % m;
119
- o.activeIndex = p[re].index ?? -1;
117
+ e.code === "Enter" && O((B = p.find((I) => I.index === a)) == null ? void 0 : B.value);
118
+ const ne = p.findIndex((I) => I.index === a) ?? -1, re = e.code === "ArrowDown" ? 1 : e.code === "ArrowUp" ? -1 : 0, le = Math.abs(ne + re + m) % m;
119
+ o.activeIndex = p[le].index ?? -1;
120
120
  };
121
- return ge(d), P(() => r.modelValue, q, { immediate: !0 }), P(
121
+ return ye(d), D(() => n.modelValue, H, { immediate: !0 }), D(
122
122
  () => o.open,
123
123
  (e) => {
124
124
  var t;
125
- return e ? (t = g.value) == null ? void 0 : t.focus() : "";
125
+ return e ? (t = w.value) == null ? void 0 : t.focus() : "";
126
126
  }
127
- ), se(() => {
127
+ ), de(() => {
128
128
  var e;
129
- o.search, o.activeIndex >= 0 && o.open && ((e = y.value) == null || e.scrollIntoActive());
129
+ o.search, o.activeIndex >= 0 && o.open && ((e = g.value) == null || e.scrollIntoActive());
130
130
  }), (e, t) => (l(), v("div", {
131
131
  class: "pl-dropdown__envelope",
132
- onClick: X
132
+ onClick: Y
133
133
  }, [
134
134
  f("div", {
135
135
  ref_key: "rootRef",
136
136
  ref: d,
137
- tabindex: j.value,
138
- class: de(["pl-dropdown", { open: o.open, error: n.error || n.errorStatus, disabled: k.value }]),
139
- onKeydown: oe,
140
- onFocusout: ee
137
+ tabindex: J.value,
138
+ class: ce(["pl-dropdown", { open: o.open, error: r.error || r.errorStatus, disabled: k.value }]),
139
+ onKeydown: te,
140
+ onFocusout: oe
141
141
  }, [
142
- f("div", be, [
143
- f("div", Le, [
144
- ce(f("input", {
142
+ f("div", Le, [
143
+ f("div", Ce, [
144
+ ue(f("input", {
145
145
  ref_key: "input",
146
- ref: g,
146
+ ref: w,
147
147
  "onUpdate:modelValue": t[0] || (t[0] = (a) => o.search = a),
148
148
  type: "text",
149
149
  tabindex: "-1",
150
150
  disabled: k.value,
151
- placeholder: H.value,
151
+ placeholder: U.value,
152
152
  spellcheck: "false",
153
153
  autocomplete: "chrome-off",
154
- onFocus: Z
155
- }, null, 40, Ce), [
156
- [ue, o.search]
154
+ onFocus: ee
155
+ }, null, 40, Ee), [
156
+ [pe, o.search]
157
157
  ]),
158
- o.open ? c("", !0) : (l(), v("div", Ee, [
159
- D(ye, null, {
160
- default: $(() => [
161
- pe(h(E.value), 1)
158
+ o.open ? c("", !0) : (l(), v("div", Re, [
159
+ $(ke, null, {
160
+ default: z(() => [
161
+ fe(h(R.value), 1)
162
162
  ]),
163
163
  _: 1
164
164
  })
165
165
  ])),
166
- f("div", Re, [
167
- w.value ? (l(), u(i(T), {
166
+ f("div", Se, [
167
+ V.value ? (l(), u(s(F), {
168
168
  key: 0,
169
169
  name: "loading"
170
170
  })) : c("", !0),
171
- n.clearable && U.value ? (l(), u(i(_), {
171
+ r.clearable && K.value ? (l(), u(s(_), {
172
172
  key: 1,
173
173
  class: "clear",
174
174
  name: "delete-clear",
175
- onClick: M(Q, ["stop"])
175
+ onClick: T(X, ["stop"])
176
176
  })) : c("", !0),
177
- z(e.$slots, "append"),
177
+ M(e.$slots, "append"),
178
178
  f("div", {
179
179
  class: "pl-dropdown__arrow-wrapper",
180
- onClick: M(Y, ["stop"])
180
+ onClick: T(Z, ["stop"])
181
181
  }, [
182
- n.arrowIconLarge ? (l(), u(i(T), {
182
+ r.arrowIconLarge ? (l(), u(s(F), {
183
183
  key: 0,
184
- name: n.arrowIconLarge,
184
+ name: r.arrowIconLarge,
185
185
  class: "arrow-icon"
186
- }, null, 8, ["name"])) : n.arrowIcon ? (l(), u(i(_), {
186
+ }, null, 8, ["name"])) : r.arrowIcon ? (l(), u(s(_), {
187
187
  key: 1,
188
- name: n.arrowIcon,
188
+ name: r.arrowIcon,
189
189
  class: "arrow-icon"
190
- }, null, 8, ["name"])) : (l(), u(i(_), {
190
+ }, null, 8, ["name"])) : (l(), u(s(_), {
191
191
  key: 2,
192
192
  name: "chevron-down",
193
193
  class: "arrow-icon arrow-icon-default"
@@ -195,44 +195,44 @@ const Ve = ["tabindex"], be = { class: "pl-dropdown__container" }, Le = { class:
195
195
  ])
196
196
  ])
197
197
  ]),
198
- n.label ? (l(), v("label", Oe, [
199
- n.required ? (l(), u(i(ke), {
198
+ r.label ? (l(), v("label", Oe, [
199
+ r.required ? (l(), u(s(Ie), {
200
200
  key: 0,
201
- uri: i(fe)
201
+ uri: s(me)
202
202
  }, null, 8, ["uri"])) : c("", !0),
203
- f("span", null, h(n.label), 1),
204
- e.$slots.tooltip ? (l(), u(i(Ie), {
203
+ f("span", null, h(r.label), 1),
204
+ e.$slots.tooltip ? (l(), u(s(xe), {
205
205
  key: 1,
206
206
  class: "info",
207
207
  position: "top"
208
208
  }, {
209
- tooltip: $(() => [
210
- z(e.$slots, "tooltip")
209
+ tooltip: z(() => [
210
+ M(e.$slots, "tooltip")
211
211
  ]),
212
212
  _: 3
213
213
  })) : c("", !0)
214
214
  ])) : c("", !0),
215
- o.open ? (l(), u(xe, {
215
+ o.open ? (l(), u(_e, {
216
216
  key: 1,
217
217
  ref_key: "optionListRef",
218
- ref: y,
218
+ ref: g,
219
219
  "root-ref": d.value,
220
- groups: i(G),
221
- rest: i(W),
222
- "option-size": n.optionSize,
223
- "select-option": J
220
+ groups: s(W),
221
+ rest: s(j),
222
+ "option-size": r.optionSize,
223
+ "select-option": Q
224
224
  }, null, 8, ["root-ref", "groups", "rest", "option-size"])) : c("", !0),
225
- D(we, {
225
+ $(ge, {
226
226
  class: "pl-dropdown__contour",
227
- "group-position": n.groupPosition
227
+ "group-position": r.groupPosition
228
228
  }, null, 8, ["group-position"])
229
229
  ])
230
230
  ], 42, Ve),
231
- L.value ? (l(), v("div", Se, h(L.value), 1)) : w.value && n.loadingOptionsHelper ? (l(), v("div", Ae, h(n.loadingOptionsHelper), 1)) : n.helper ? (l(), v("div", Be, h(n.helper), 1)) : c("", !0)
231
+ C.value ? (l(), v("div", Ae, h(C.value), 1)) : V.value && r.loadingOptionsHelper ? (l(), v("div", Be, h(r.loadingOptionsHelper), 1)) : r.helper ? (l(), v("div", Pe, h(r.helper), 1)) : c("", !0)
232
232
  ]));
233
233
  }
234
234
  });
235
235
  export {
236
- Ze as default
236
+ eo as default
237
237
  };
238
238
  //# sourceMappingURL=PlDropdown.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlDropdown.vue.js","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a list of options\n */\nexport default {\n name: 'PlDropdown',\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from 'vue';\nimport SvgRequired from '../../assets/images/required.svg?raw';\nimport { getErrorMessage } from '../../helpers/error.ts';\nimport { tap } from '../../helpers/functions';\nimport { deepEqual } from '../../helpers/objects';\nimport { normalizeListOptions } from '../../helpers/utils';\nimport type { ListOption, ListOptionNormalized, MaskIconName16, MaskIconName24 } from '../../types';\nimport DoubleContour from '../../utils/DoubleContour.vue';\nimport { useLabelNotch } from '../../utils/useLabelNotch';\nimport LongText from '../LongText.vue';\nimport { PlIcon16 } from '../PlIcon16';\nimport { PlIcon24 } from '../PlIcon24';\nimport { PlSvg } from '../PlSvg';\nimport { PlTooltip } from '../PlTooltip';\nimport OptionList from './OptionList.vue';\nimport './pl-dropdown.scss';\nimport type { LOption } from './types';\nimport { useGroupBy } from './useGroupBy';\n\nconst emit = defineEmits<{\n /**\n * Emitted when the model value is updated.\n */\n (e: 'update:modelValue', value: M | undefined): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected value of the dropdown.\n */\n modelValue: M;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * List of available options for the dropdown\n */\n options?: Readonly<ListOption<M>[]>;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Shows red border even without an error message\n */\n errorStatus?: boolean;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\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 * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: MaskIconName16;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: MaskIconName24;\n /**\n * Option list item size\n */\n optionSize?: 'small' | 'medium';\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 label: '',\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n showErrorMessage: true,\n placeholder: '...',\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: 'small',\n options: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst optionListRef = useTemplateRef<InstanceType<typeof OptionList>>('optionListRef');\n\nconst data = reactive({\n search: '',\n activeIndex: -1,\n open: false,\n optionsHeight: 0,\n});\n\nconst findActiveIndex = () =>\n tap(\n orderedRef.value.findIndex((o) => deepEqual(o.value, props.modelValue)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst isLoadingOptions = computed(() => {\n return props.options === undefined;\n});\n\nconst isDisabled = computed(() => {\n if (isLoadingOptions.value) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return (props.options ?? []).findIndex((o) => deepEqual(o.value, props.modelValue));\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue !== undefined && selectedIndex.value === -1) {\n return 'The selected value is not one of the options';\n }\n\n return undefined;\n});\n\nconst optionsRef = computed<LOption<M>[]>(() =>\n normalizeListOptions(props.options ?? []).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })),\n);\n\nconst textValue = computed(() => {\n const options = unref(optionsRef);\n\n const item: ListOption | undefined = options.find((o) => deepEqual(o.value, props.modelValue));\n\n return item?.label || props.modelValue; // @todo show inner value?\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && props.modelValue !== undefined) {\n return '';\n }\n\n return props.modelValue ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\n});\n\nconst filteredRef = computed(() => {\n const options = optionsRef.value;\n\n if (data.search) {\n return options.filter((o: ListOptionNormalized) => {\n const search = data.search.toLowerCase();\n\n if (o.label.toLowerCase().includes(search)) {\n return true;\n }\n\n if (o.description && o.description.toLowerCase().includes(search)) {\n return true;\n }\n\n if (typeof o.value === 'string') {\n return o.value.toLowerCase().includes(search);\n }\n\n return o.value === data.search;\n });\n }\n\n return options;\n});\n\nconst { orderedRef, groupsRef, restRef } = useGroupBy(filteredRef, 'group');\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : '0'));\n\nconst selectOption = (v: M | undefined) => {\n emit('update:modelValue', v);\n data.search = '';\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst selectOptionWrapper = (v: unknown) => {\n selectOption(v as M | undefined);\n};\n\nconst clear = () => emit('update:modelValue', undefined);\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n if (!data.open) {\n data.search = '';\n }\n};\n\nconst onInputFocus = () => (data.open = true);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !optionListRef.value?.listRef?.contains(relatedTarget)) {\n data.search = '';\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (!['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = 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 rootRef.value?.focus();\n }\n\n const ordered = orderedRef.value;\n\n const { length } = ordered;\n\n if (!length) {\n return;\n }\n\n if (e.code === 'Enter') {\n selectOption(ordered.find((it) => it.index === activeIndex)?.value);\n }\n\n const localIndex = ordered.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === 'ArrowDown' ? 1 : e.code === 'ArrowUp' ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = ordered[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => props.modelValue, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : ''),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n data.search; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n optionListRef.value?.scrollIntoActive();\n }\n});\n</script>\n\n<template>\n <div class=\"pl-dropdown__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\n :class=\"{ open: data.open, error: error || errorStatus, disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-dropdown__container\">\n <div class=\"pl-dropdown__field\">\n <input\n ref=\"input\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"isLoadingOptions\" name=\"loading\" />\n <PlIcon16 v-if=\"clearable && hasValue\" class=\"clear\" name=\"delete-clear\" @click.stop=\"clear\" />\n <slot name=\"append\" />\n <div class=\"pl-dropdown__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <PlIcon24 v-if=\"arrowIconLarge\" :name=\"arrowIconLarge\" class=\"arrow-icon\" />\n <PlIcon16 v-else-if=\"arrowIcon\" :name=\"arrowIcon\" class=\"arrow-icon\" />\n <PlIcon16 v-else name=\"chevron-down\" 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 <OptionList\n v-if=\"data.open\"\n ref=\"optionListRef\"\n :root-ref=\"rootRef!\"\n :groups=\"groupsRef\"\n :rest=\"restRef\"\n :option-size=\"optionSize\"\n :select-option=\"selectOptionWrapper\"\n />\n <DoubleContour class=\"pl-dropdown__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-dropdown__error\">{{ computedError }}</div>\n <div v-else-if=\"isLoadingOptions && loadingOptionsHelper\" class=\"pl-dropdown__helper\">{{ loadingOptionsHelper }}</div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"names":["__default__","emit","__emit","props","__props","rootRef","ref","input","optionListRef","useTemplateRef","data","reactive","findActiveIndex","tap","orderedRef","o","deepEqual","v","updateActive","isLoadingOptions","computed","isDisabled","selectedIndex","computedError","getErrorMessage","optionsRef","normalizeListOptions","opt","index","textValue","item","unref","computedPlaceholder","hasValue","filteredRef","options","search","groupsRef","restRef","useGroupBy","tabindex","selectOption","_a","selectOptionWrapper","clear","setFocusOnInput","toggleOpen","onInputFocus","onFocusOut","event","relatedTarget","_c","_b","handleKeydown","open","activeIndex","ordered","length","it","localIndex","delta","newIndex","useLabelNotch","watch","watchPostEffect","_createElementBlock","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_cache","$event","_vModelText","_openBlock","_hoisted_5","_createVNode","LongText","_hoisted_6","_createBlock","_unref","PlIcon24","PlIcon16","_renderSlot","_ctx","_hoisted_7","PlSvg","SvgRequired","$slots","PlTooltip","OptionList","DoubleContour","_hoisted_8","_toDisplayString","_hoisted_9","_hoisted_10"],"mappings":"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"}
1
+ {"version":3,"file":"PlDropdown.vue.js","sources":["../../../src/components/PlDropdown/PlDropdown.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * A component for selecting one value from a list of options\n */\nexport default {\n name: 'PlDropdown',\n};\n</script>\n\n<script lang=\"ts\" setup generic=\"M = unknown\">\nimport { computed, reactive, ref, unref, useTemplateRef, watch, watchPostEffect } from 'vue';\nimport SvgRequired from '../../assets/images/required.svg?raw';\nimport { getErrorMessage } from '../../helpers/error.ts';\nimport { tap } from '../../helpers/functions';\nimport { deepEqual } from '../../helpers/objects';\nimport { normalizeListOptions } from '../../helpers/utils';\nimport type { ListOption, ListOptionNormalized, MaskIconName16, MaskIconName24 } from '../../types';\nimport DoubleContour from '../../utils/DoubleContour.vue';\nimport { useLabelNotch } from '../../utils/useLabelNotch';\nimport LongText from '../LongText.vue';\nimport { PlIcon16 } from '../PlIcon16';\nimport { PlIcon24 } from '../PlIcon24';\nimport { PlSvg } from '../PlSvg';\nimport { PlTooltip } from '../PlTooltip';\nimport OptionList from './OptionList.vue';\nimport './pl-dropdown.scss';\nimport type { LOption } from './types';\nimport { useGroupBy } from './useGroupBy';\n\nconst emit = defineEmits<{\n /**\n * Emitted when the model value is updated.\n */\n (e: 'update:modelValue', value: M | undefined): void;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n /**\n * The current selected value of the dropdown.\n */\n modelValue: M;\n /**\n * The label text for the dropdown field (optional)\n */\n label?: string;\n /**\n * List of available options for the dropdown\n */\n options?: Readonly<ListOption<M>[]>;\n /**\n * A helper text displayed below the dropdown when there are no errors (optional).\n */\n helper?: string;\n /**\n * A helper text displayed below the dropdown when there are no options yet or options is undefined (optional).\n */\n loadingOptionsHelper?: string;\n /**\n * Error message displayed below the dropdown (optional)\n */\n error?: unknown;\n /**\n * Shows red border even without an error message\n */\n errorStatus?: boolean;\n /**\n * Placeholder text shown when no value is selected.\n */\n placeholder?: string;\n /**\n * Enables a button to clear the selected value (default: false)\n */\n clearable?: boolean;\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 * Custom icon (16px) class for the dropdown arrow (optional)\n */\n arrowIcon?: MaskIconName16;\n /**\n * Custom icon (24px) class for the dropdown arrow (optional)\n */\n arrowIconLarge?: MaskIconName24;\n /**\n * Option list item size\n */\n optionSize?: 'small' | 'medium';\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 label: '',\n helper: undefined,\n loadingOptionsHelper: undefined,\n error: undefined,\n showErrorMessage: true,\n placeholder: '...',\n clearable: false,\n required: false,\n disabled: false,\n arrowIcon: undefined,\n arrowIconLarge: undefined,\n optionSize: 'small',\n options: undefined,\n groupPosition: undefined,\n },\n);\n\nconst rootRef = ref<HTMLElement | undefined>();\nconst input = ref<HTMLInputElement | undefined>();\n\nconst optionListRef = useTemplateRef<InstanceType<typeof OptionList>>('optionListRef');\n\nconst data = reactive({\n search: '',\n activeIndex: -1,\n open: false,\n optionsHeight: 0,\n});\n\nconst findActiveIndex = () =>\n tap(\n orderedRef.value.findIndex((o) => deepEqual(o.value, props.modelValue)),\n (v) => (v < 0 ? 0 : v),\n );\n\nconst updateActive = () => (data.activeIndex = findActiveIndex());\n\nconst isLoadingOptions = computed(() => {\n return props.options === undefined;\n});\n\n/**\n * Loading spinner should not be shown when the dropdown is explicitly disabled,\n * even if options are undefined. The disabled state takes precedence.\n */\nconst showLoadingSpinner = computed(() => {\n return !props.disabled && isLoadingOptions.value;\n});\n\nconst isDisabled = computed(() => {\n if (isLoadingOptions.value) {\n return true;\n }\n\n return props.disabled;\n});\n\nconst selectedIndex = computed(() => {\n return (props.options ?? []).findIndex((o) => deepEqual(o.value, props.modelValue));\n});\n\nconst computedError = computed(() => {\n if (isLoadingOptions.value) {\n return undefined;\n }\n\n if (props.error) {\n return getErrorMessage(props.error);\n }\n\n if (props.modelValue !== undefined && selectedIndex.value === -1) {\n return 'The selected value is not one of the options';\n }\n\n return undefined;\n});\n\nconst optionsRef = computed<LOption<M>[]>(() =>\n normalizeListOptions(props.options ?? []).map((opt, index) => ({\n ...opt,\n index,\n isSelected: index === selectedIndex.value,\n isActive: index === data.activeIndex,\n })),\n);\n\nconst textValue = computed(() => {\n const options = unref(optionsRef);\n\n const item: ListOption | undefined = options.find((o) => deepEqual(o.value, props.modelValue));\n\n return item?.label || props.modelValue; // @todo show inner value?\n});\n\nconst computedPlaceholder = computed(() => {\n if (!data.open && props.modelValue !== undefined) {\n return '';\n }\n\n return props.modelValue ? String(textValue.value) : props.placeholder;\n});\n\nconst hasValue = computed(() => {\n return props.modelValue !== undefined && props.modelValue !== null;\n});\n\nconst filteredRef = computed(() => {\n const options = optionsRef.value;\n\n if (data.search) {\n return options.filter((o: ListOptionNormalized) => {\n const search = data.search.toLowerCase();\n\n if (o.label.toLowerCase().includes(search)) {\n return true;\n }\n\n if (o.description && o.description.toLowerCase().includes(search)) {\n return true;\n }\n\n if (typeof o.value === 'string') {\n return o.value.toLowerCase().includes(search);\n }\n\n return o.value === data.search;\n });\n }\n\n return options;\n});\n\nconst { orderedRef, groupsRef, restRef } = useGroupBy(filteredRef, 'group');\n\nconst tabindex = computed(() => (isDisabled.value ? undefined : '0'));\n\nconst selectOption = (v: M | undefined) => {\n emit('update:modelValue', v);\n data.search = '';\n data.open = false;\n rootRef?.value?.focus();\n};\n\nconst selectOptionWrapper = (v: unknown) => {\n selectOption(v as M | undefined);\n};\n\nconst clear = () => emit('update:modelValue', undefined);\n\nconst setFocusOnInput = () => input.value?.focus();\n\nconst toggleOpen = () => {\n data.open = !data.open;\n if (!data.open) {\n data.search = '';\n }\n};\n\nconst onInputFocus = () => (data.open = true);\n\nconst onFocusOut = (event: FocusEvent) => {\n const relatedTarget = event.relatedTarget as Node | null;\n\n if (!rootRef.value?.contains(relatedTarget) && !optionListRef.value?.listRef?.contains(relatedTarget)) {\n data.search = '';\n data.open = false;\n }\n};\n\nconst handleKeydown = (e: { code: string; preventDefault(): void }) => {\n if (!['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.code)) {\n return;\n } else {\n e.preventDefault();\n }\n\n const { open, activeIndex } = 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 rootRef.value?.focus();\n }\n\n const ordered = orderedRef.value;\n\n const { length } = ordered;\n\n if (!length) {\n return;\n }\n\n if (e.code === 'Enter') {\n selectOption(ordered.find((it) => it.index === activeIndex)?.value);\n }\n\n const localIndex = ordered.findIndex((it) => it.index === activeIndex) ?? -1;\n\n const delta = e.code === 'ArrowDown' ? 1 : e.code === 'ArrowUp' ? -1 : 0;\n\n const newIndex = Math.abs(localIndex + delta + length) % length;\n\n data.activeIndex = ordered[newIndex].index ?? -1;\n};\n\nuseLabelNotch(rootRef);\n\nwatch(() => props.modelValue, updateActive, { immediate: true });\n\nwatch(\n () => data.open,\n (open) => (open ? input.value?.focus() : ''),\n);\n\nwatchPostEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n data.search; // to watch\n\n if (data.activeIndex >= 0 && data.open) {\n optionListRef.value?.scrollIntoActive();\n }\n});\n</script>\n\n<template>\n <div class=\"pl-dropdown__envelope\" @click=\"setFocusOnInput\">\n <div\n ref=\"rootRef\"\n :tabindex=\"tabindex\"\n class=\"pl-dropdown\"\n :class=\"{ open: data.open, error: error || errorStatus, disabled: isDisabled }\"\n @keydown=\"handleKeydown\"\n @focusout=\"onFocusOut\"\n >\n <div class=\"pl-dropdown__container\">\n <div class=\"pl-dropdown__field\">\n <input\n ref=\"input\"\n v-model=\"data.search\"\n type=\"text\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :placeholder=\"computedPlaceholder\"\n spellcheck=\"false\"\n autocomplete=\"chrome-off\"\n @focus=\"onInputFocus\"\n />\n\n <div v-if=\"!data.open\" class=\"input-value\">\n <LongText> {{ textValue }} </LongText>\n </div>\n\n <div class=\"pl-dropdown__controls\">\n <PlIcon24 v-if=\"showLoadingSpinner\" name=\"loading\" />\n <PlIcon16 v-if=\"clearable && hasValue\" class=\"clear\" name=\"delete-clear\" @click.stop=\"clear\" />\n <slot name=\"append\" />\n <div class=\"pl-dropdown__arrow-wrapper\" @click.stop=\"toggleOpen\">\n <PlIcon24 v-if=\"arrowIconLarge\" :name=\"arrowIconLarge\" class=\"arrow-icon\" />\n <PlIcon16 v-else-if=\"arrowIcon\" :name=\"arrowIcon\" class=\"arrow-icon\" />\n <PlIcon16 v-else name=\"chevron-down\" 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 <OptionList\n v-if=\"data.open\"\n ref=\"optionListRef\"\n :root-ref=\"rootRef!\"\n :groups=\"groupsRef\"\n :rest=\"restRef\"\n :option-size=\"optionSize\"\n :select-option=\"selectOptionWrapper\"\n />\n <DoubleContour class=\"pl-dropdown__contour\" :group-position=\"groupPosition\" />\n </div>\n </div>\n <div v-if=\"computedError\" class=\"pl-dropdown__error\">{{ computedError }}</div>\n <div v-else-if=\"showLoadingSpinner && loadingOptionsHelper\" class=\"pl-dropdown__helper\">{{ loadingOptionsHelper }}</div>\n <div v-else-if=\"helper\" class=\"pl-dropdown__helper\">{{ helper }}</div>\n </div>\n</template>\n"],"names":["__default__","emit","__emit","props","__props","rootRef","ref","input","optionListRef","useTemplateRef","data","reactive","findActiveIndex","tap","orderedRef","o","deepEqual","v","updateActive","isLoadingOptions","computed","showLoadingSpinner","isDisabled","selectedIndex","computedError","getErrorMessage","optionsRef","normalizeListOptions","opt","index","textValue","item","unref","computedPlaceholder","hasValue","filteredRef","options","search","groupsRef","restRef","useGroupBy","tabindex","selectOption","_a","selectOptionWrapper","clear","setFocusOnInput","toggleOpen","onInputFocus","onFocusOut","event","relatedTarget","_c","_b","handleKeydown","open","activeIndex","ordered","length","it","localIndex","delta","newIndex","useLabelNotch","watch","watchPostEffect","_createElementBlock","_createElementVNode","_normalizeClass","_hoisted_2","_hoisted_3","_cache","$event","_vModelText","_openBlock","_hoisted_5","_createVNode","LongText","_hoisted_6","_createBlock","_unref","PlIcon24","PlIcon16","_renderSlot","_ctx","_hoisted_7","PlSvg","SvgRequired","$slots","PlTooltip","OptionList","DoubleContour","_hoisted_8","_toDisplayString","_hoisted_9","_hoisted_10"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/uikit",
3
- "version": "2.6.5",
3
+ "version": "2.7.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -32,7 +32,7 @@
32
32
  "resize-observer-polyfill": "^1.5.1",
33
33
  "canonicalize": "~2.1.0",
34
34
  "@milaboratories/helpers": "1.12.0",
35
- "@platforma-sdk/model": "1.45.45"
35
+ "@platforma-sdk/model": "1.46.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "jsdom": "^25.0.1",
@@ -40,10 +40,10 @@
40
40
  "yarpm": "^1.2.0",
41
41
  "svgo": "^3.3.2",
42
42
  "typescript": "~5.6.3",
43
- "@milaboratories/ts-configs": "1.0.6",
43
+ "@milaboratories/eslint-config": "1.0.5",
44
44
  "@milaboratories/build-configs": "1.0.8",
45
- "@milaboratories/ts-builder": "1.0.5",
46
- "@milaboratories/eslint-config": "1.0.5"
45
+ "@milaboratories/ts-configs": "1.0.6",
46
+ "@milaboratories/ts-builder": "1.0.5"
47
47
  },
48
48
  "scripts": {
49
49
  "dev": "ts-builder serve --target browser-lib --build-config ./build.browser-lib.config.js",
@@ -39,11 +39,7 @@ const props = withDefaults(
39
39
  /**
40
40
  * Lambda for requesting of available options for the dropdown by search string.
41
41
  */
42
- optionsSearch: (s: string) => Promise<ListOption<M>[]>;
43
- /**
44
- * Lambda for requesting of corresponding option for current model value. If empty, optionsSearch is used for this.
45
- */
46
- modelSearch?: (v: NonNullable<M>) => Promise<ListOption<NonNullable<M>>>;
42
+ optionsSearch: (string: string, type: 'value' | 'label') => Promise<ListOption<M>[]>;
47
43
  /**
48
44
  * The label text for the dropdown field (optional)
49
45
  */
@@ -301,17 +297,14 @@ const searchDebounced = refDebounced(search, 300, { maxWait: 1000 });
301
297
 
302
298
  const optionsRequest = useWatchFetch(() => searchDebounced.value, async (v) => {
303
299
  if (v !== null) { // search is null when dropdown is closed;
304
- return props.optionsSearch(v);
300
+ return props.optionsSearch(v, 'label');
305
301
  }
306
302
  return undefined;
307
303
  });
308
304
 
309
305
  const modelOptionRequest = useWatchFetch(() => model.value, async (v) => {
310
306
  if (v != null && !deepEqual(modelOptionRef.value?.value, v)) { // load label for selected value if it was updated from outside the component
311
- if (props.modelSearch) {
312
- return props.modelSearch(v);
313
- }
314
- return (await props.optionsSearch(String(v)))?.[0];
307
+ return (await props.optionsSearch(String(v), 'value'))?.[0];
315
308
  }
316
309
  return modelOptionRef.value;
317
310
  });
@@ -65,6 +65,11 @@ const emitModel = (v: M[]) => emit('update:modelValue', v);
65
65
 
66
66
  const slots = useSlots();
67
67
 
68
+ interface OptionsSearch {
69
+ (s: string, type: 'label'): Promise<Readonly<ListOptionBase<M>[]>>;
70
+ (s: M[], type: 'value'): Promise<Readonly<ListOptionBase<M>[]>>;
71
+ }
72
+
68
73
  const props = withDefaults(
69
74
  defineProps<{
70
75
  /**
@@ -74,11 +79,7 @@ const props = withDefaults(
74
79
  /**
75
80
  * Lambda for requesting of available options for the dropdown by search string.
76
81
  */
77
- optionsSearch: (s: string) => Promise<Readonly<ListOptionBase<M>[]>>;
78
- /**
79
- * Lambda for requesting options that correspond to the current model values.
80
- */
81
- modelSearch: (values: M[]) => Promise<Readonly<ListOptionBase<M>[]>>;
82
+ optionsSearch: OptionsSearch;
82
83
  /**
83
84
  * Unique identifier for the source of the options, changing it will invalidate the options cache.
84
85
  */
@@ -170,14 +171,14 @@ const placeholderRef = computed(() => {
170
171
  const debounce = toRef(props, 'debounce');
171
172
 
172
173
  const searchOptionsRef = useWatchFetch(() => [data.search, data.open, props.sourceId] as const, async ([search, _open]) => {
173
- return props.optionsSearch(search);
174
+ return props.optionsSearch(search, 'label');
174
175
  }, {
175
176
  filterWatchResult: ([_search, open]) => open,
176
177
  debounce,
177
178
  });
178
179
 
179
180
  const modelOptionsRef = useWatchFetch(() => [props.modelValue, props.sourceId] as const, async ([v]) => {
180
- return props.modelSearch(v);
181
+ return props.optionsSearch(v, 'value');
181
182
  }, {
182
183
  debounce,
183
184
  });
@@ -11,12 +11,6 @@ describe('PlAutocompleteMulti', () => {
11
11
  'modelValue': [1],
12
12
  'onUpdate:modelValue': (e) => wrapper.setProps({ modelValue: e }),
13
13
  'debounce': 0,
14
- 'modelSearch': async (values) => {
15
- return [
16
- { label: 'Option 1', value: 1 },
17
- { label: 'Option 2', value: 2 },
18
- ].filter((v) => values.includes(v.value));
19
- },
20
14
  'optionsSearch': async () => {
21
15
  return [
22
16
  { label: 'Option 1', value: 1 },
@@ -139,6 +139,14 @@ const isLoadingOptions = computed(() => {
139
139
  return props.options === undefined;
140
140
  });
141
141
 
142
+ /**
143
+ * Loading spinner should not be shown when the dropdown is explicitly disabled,
144
+ * even if options are undefined. The disabled state takes precedence.
145
+ */
146
+ const showLoadingSpinner = computed(() => {
147
+ return !props.disabled && isLoadingOptions.value;
148
+ });
149
+
142
150
  const isDisabled = computed(() => {
143
151
  if (isLoadingOptions.value) {
144
152
  return true;
@@ -349,7 +357,7 @@ watchPostEffect(() => {
349
357
  </div>
350
358
 
351
359
  <div class="pl-dropdown__controls">
352
- <PlIcon24 v-if="isLoadingOptions" name="loading" />
360
+ <PlIcon24 v-if="showLoadingSpinner" name="loading" />
353
361
  <PlIcon16 v-if="clearable && hasValue" class="clear" name="delete-clear" @click.stop="clear" />
354
362
  <slot name="append" />
355
363
  <div class="pl-dropdown__arrow-wrapper" @click.stop="toggleOpen">
@@ -381,7 +389,7 @@ watchPostEffect(() => {
381
389
  </div>
382
390
  </div>
383
391
  <div v-if="computedError" class="pl-dropdown__error">{{ computedError }}</div>
384
- <div v-else-if="isLoadingOptions && loadingOptionsHelper" class="pl-dropdown__helper">{{ loadingOptionsHelper }}</div>
392
+ <div v-else-if="showLoadingSpinner && loadingOptionsHelper" class="pl-dropdown__helper">{{ loadingOptionsHelper }}</div>
385
393
  <div v-else-if="helper" class="pl-dropdown__helper">{{ helper }}</div>
386
394
  </div>
387
395
  </template>
@@ -1,27 +0,0 @@
1
- import { defineComponent as n, createBlock as r, openBlock as a, Transition as s, withCtx as p, renderSlot as c } from "vue";
2
- const f = /* @__PURE__ */ n({
3
- __name: "ExpandTransition",
4
- setup(l) {
5
- const t = (e) => {
6
- e.classList.add("expand-collapse-fix"), e.style.setProperty("--component-height", e.scrollHeight + "px");
7
- }, o = (e) => {
8
- e.style.removeProperty("--component-height"), e.classList.remove("expand-collapse-fix");
9
- };
10
- return (e, i) => (a(), r(s, {
11
- name: "expand-collapse",
12
- onEnter: t,
13
- onLeave: t,
14
- onAfterEnter: o,
15
- onAfterLeave: o
16
- }, {
17
- default: p(() => [
18
- c(e.$slots, "default")
19
- ]),
20
- _: 3
21
- }));
22
- }
23
- });
24
- export {
25
- f as default
26
- };
27
- //# sourceMappingURL=ExpandTransition.vue2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExpandTransition.vue2.js","sources":["../../../src/components/PlAccordion/ExpandTransition.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nconst onStart = (el: Element) => {\n el.classList.add('expand-collapse-fix');\n (el as HTMLElement).style.setProperty('--component-height', el.scrollHeight + 'px');\n};\n\nconst onAfter = (el: Element) => {\n (el as HTMLElement).style.removeProperty('--component-height');\n el.classList.remove('expand-collapse-fix');\n};\n</script>\n\n<template>\n <Transition name=\"expand-collapse\" @enter=\"onStart\" @leave=\"onStart\" @after-enter=\"onAfter\" @after-leave=\"onAfter\">\n <slot/>\n </Transition>\n</template>\n\n<style>\n.expand-collapse-fix {\n overflow: hidden;\n}\n\n.expand-collapse-enter-active,\n.expand-collapse-leave-active {\n transition:\n height 0.2s ease-in-out,\n opacity 0.2s ease-in-out;\n height: var(--component-height);\n}\n\n.expand-collapse-enter-from,\n.expand-collapse-leave-to {\n opacity: 0.5;\n height: 0;\n}\n</style>\n"],"names":["onStart","el","onAfter","_createBlock","_Transition","_renderSlot","_ctx"],"mappings":";;;;AACA,UAAMA,IAAU,CAACC,MAAgB;AAC/B,MAAAA,EAAG,UAAU,IAAI,qBAAqB,GACrCA,EAAmB,MAAM,YAAY,sBAAsBA,EAAG,eAAe,IAAI;AAAA,IACpF,GAEMC,IAAU,CAACD,MAAgB;AAC9B,MAAAA,EAAmB,MAAM,eAAe,oBAAoB,GAC7DA,EAAG,UAAU,OAAO,qBAAqB;AAAA,IAC3C;2BAIEE,EAEaC,GAAA;AAAA,MAFD,MAAK;AAAA,MAAmB,SAAOJ;AAAA,MAAU,SAAOA;AAAA,MAAU,cAAaE;AAAA,MAAU,cAAaA;AAAA,IAAA;iBACxG,MAAO;AAAA,QAAPG,EAAOC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;"}