@pgcorp/ui-kit 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +62 -0
  2. package/dist/assets/src/components/shared/_internal/SDialogSurface.css_vue_type_style_index_0_src_d1b65adf_scoped_d1b65adf_lang.css +1 -1
  3. package/dist/assets/src/components/shared/_internal/SMenuItem.css_vue_type_style_index_0_src_af485607_scoped_af485607_lang.css +2 -0
  4. package/dist/assets/src/components/shared/containers/{SCollapsiblePanel.css_vue_type_style_index_0_src_4882f962_scoped_4882f962_lang.css → SCollapsiblePanel.css_vue_type_style_index_0_src_71824088_scoped_71824088_lang.css} +1 -1
  5. package/dist/assets/src/components/shared/containers/{SModal.css_vue_type_style_index_0_src_23373daf_scoped_23373daf_lang.css → SModal.css_vue_type_style_index_0_src_0dc51b74_scoped_0dc51b74_lang.css} +1 -1
  6. package/dist/assets/src/components/shared/controls/{SDropdownMenu.css_vue_type_style_index_0_src_b854a89e_scoped_b854a89e_lang.css → SDropdownMenu.css_vue_type_style_index_0_src_1ccb9efc_scoped_1ccb9efc_lang.css} +1 -1
  7. package/dist/assets/src/components/shared/controls/{SInputText.css_vue_type_style_index_0_src_a9c5f1aa_scoped_a9c5f1aa_lang.css → SInputText.css_vue_type_style_index_0_src_023c25d0_scoped_023c25d0_lang.css} +1 -1
  8. package/dist/assets/src/components/shared/controls/SMenuSurface.css_vue_type_style_index_0_src_ddcc5fbb_scoped_ddcc5fbb_lang.css +2 -0
  9. package/dist/src/components/shared/_internal/SMenuItem.vue.js +2 -2
  10. package/dist/src/components/shared/_internal/SMenuItem.vue_vue_type_script_setup_true_lang.js +88 -76
  11. package/dist/src/components/shared/_internal/dialogSurface.d.ts +1 -1
  12. package/dist/src/components/shared/_internal/dialogSurface.js +1 -0
  13. package/dist/src/components/shared/containers/SCollapsiblePanel.vue.d.ts +1 -1
  14. package/dist/src/components/shared/containers/SCollapsiblePanel.vue.js +2 -2
  15. package/dist/src/components/shared/containers/SCollapsiblePanel.vue_vue_type_script_setup_true_lang.js +60 -58
  16. package/dist/src/components/shared/containers/SModal.vue.js +2 -2
  17. package/dist/src/components/shared/containers/SModal.vue_vue_type_script_setup_true_lang.js +43 -37
  18. package/dist/src/components/shared/controls/SDropdownMenu.vue.d.ts +15 -4
  19. package/dist/src/components/shared/controls/SDropdownMenu.vue.js +2 -2
  20. package/dist/src/components/shared/controls/SDropdownMenu.vue_vue_type_script_setup_true_lang.js +98 -62
  21. package/dist/src/components/shared/controls/SInputText.vue.d.ts +2 -2
  22. package/dist/src/components/shared/controls/SInputText.vue.js +2 -2
  23. package/dist/src/components/shared/controls/SInputText.vue_vue_type_script_setup_true_lang.js +16 -25
  24. package/dist/src/components/shared/controls/SMenuSurface.vue.js +2 -2
  25. package/dist/src/components/shared/controls/SMenuSurface.vue_vue_type_script_setup_true_lang.js +132 -110
  26. package/dist/src/components/shared/controls/STextarea.vue.d.ts +4 -0
  27. package/dist/src/components/shared/controls/STextarea.vue_vue_type_script_setup_true_lang.js +154 -147
  28. package/dist/src/components/shared/controls/menu.d.ts +9 -1
  29. package/dist/src/components/shared/controls/menu.js +43 -28
  30. package/dist/src/composables/useDialogOverlay.d.ts +1 -0
  31. package/dist/src/composables/useDialogOverlay.js +5 -2
  32. package/dist/src/internal/textLengthConstraints.d.ts +9 -0
  33. package/dist/src/internal/textLengthConstraints.js +18 -0
  34. package/dist/src/internal/useMenuLayer.d.ts +2 -1
  35. package/dist/src/internal/useMenuLayer.js +20 -14
  36. package/docs/public-api.md +14 -2
  37. package/package.json +1 -1
  38. package/src/components/shared/_internal/SDialogSurface.css +4 -0
  39. package/src/components/shared/_internal/SMenuItem.css +22 -1
  40. package/src/components/shared/controls/SMenuSurface.css +20 -0
  41. package/dist/assets/src/components/shared/_internal/SMenuItem.css_vue_type_style_index_0_src_e5bd192e_scoped_e5bd192e_lang.css +0 -2
  42. package/dist/assets/src/components/shared/controls/SMenuSurface.css_vue_type_style_index_0_src_bc7c7be4_scoped_bc7c7be4_lang.css +0 -2
@@ -3,9 +3,10 @@ import { resolveOptionalDomId as n, validateBoolean as r, validateBoundedInteger
3
3
  import { useInteractiveLeafRegistration as c } from "../../../internal/passiveContentContract.js";
4
4
  import l from "./SField.vue.js";
5
5
  import { resolveFieldSurfaceBindings as ee } from "../../../internal/fieldSurface.js";
6
- import { computed as u, createBlock as d, createElementVNode as te, defineComponent as f, mergeProps as ne, nextTick as p, onBeforeUnmount as re, onMounted as ie, openBlock as ae, ref as m, unref as h, useId as oe, watch as g, withCtx as _ } from "vue";
6
+ import { resolveTextLengthConstraints as te } from "../../../internal/textLengthConstraints.js";
7
+ import { computed as u, createBlock as ne, createElementVNode as re, defineComponent as d, mergeProps as ie, nextTick as f, onBeforeUnmount as ae, onMounted as oe, openBlock as se, ref as p, unref as m, useId as ce, watch as h, withCtx as le } from "vue";
7
8
  //#region src/components/shared/controls/STextarea.vue?vue&type=script&setup=true&lang.ts
8
- var se = [
9
+ var ue = [
9
10
  "id",
10
11
  "data-appearance",
11
12
  "data-size",
@@ -20,6 +21,8 @@ var se = [
20
21
  "disabled",
21
22
  "readonly",
22
23
  "required",
24
+ "minlength",
25
+ "maxlength",
23
26
  "aria-invalid",
24
27
  "aria-required",
25
28
  "aria-readonly",
@@ -29,7 +32,7 @@ var se = [
29
32
  "aria-autocomplete",
30
33
  "aria-haspopup",
31
34
  "rows"
32
- ], v = 100, y = /*@__PURE__*/ f({
35
+ ], g = 100, _ = /*@__PURE__*/ d({
33
36
  inheritAttrs: !1,
34
37
  __name: "STextarea",
35
38
  props: {
@@ -56,6 +59,8 @@ var se = [
56
59
  helpText: { default: void 0 },
57
60
  id: { default: void 0 },
58
61
  rows: { default: 3 },
62
+ minLength: { default: void 0 },
63
+ maxLength: { default: void 0 },
59
64
  size: { default: "md" },
60
65
  autoResize: {
61
66
  type: Boolean,
@@ -85,58 +90,58 @@ var se = [
85
90
  "selection-change",
86
91
  "state-change"
87
92
  ],
88
- setup(f, { expose: y, emit: ce }) {
89
- let le = ["default", "ghost"], ue = [
93
+ setup(d, { expose: _, emit: de }) {
94
+ let fe = ["default", "ghost"], pe = [
90
95
  "sm",
91
96
  "md",
92
97
  "lg"
93
- ], b = {
98
+ ], v = {
94
99
  minimum: 1,
95
100
  maximum: 100
96
- }, x = {
101
+ }, y = {
97
102
  minimum: 1,
98
103
  maximum: 4096
99
- }, de = [
104
+ }, me = [
100
105
  "list",
101
106
  "both",
102
107
  "inline",
103
108
  "none"
104
- ], fe = [
109
+ ], he = [
105
110
  "listbox",
106
111
  "grid",
107
112
  "tree",
108
113
  "dialog"
109
- ], S = [
114
+ ], b = [
110
115
  "forward",
111
116
  "backward",
112
117
  "none"
113
- ], pe = [
118
+ ], ge = [
114
119
  "select",
115
120
  "start",
116
121
  "end",
117
122
  "preserve"
118
- ], C = f, w = ce, T = t({
123
+ ], x = d, S = de, C = t({
119
124
  component: "STextarea",
120
125
  owner: "native textarea"
121
126
  });
122
127
  c({ owner: "STextarea" });
123
- let me = oe(), E = u(() => n("STextarea", "id", C.id, `s-textarea-${me}`)), D = m(null), O = m(!1), k = null, A = null, j = null, M = null, N = !1, P = [], F = [], I = u(() => s("STextarea", "appearance", C.appearance, le)), L = u(() => s("STextarea", "size", C.size, ue)), R = u(() => i("STextarea", "rows", C.rows, b)), z = u(() => C.maxRows === void 0 ? void 0 : i("STextarea", "maxRows", C.maxRows, b)), B = u(() => C.minHeight === void 0 ? void 0 : a("STextarea", "minHeight", C.minHeight, x)), V = u(() => C.maxHeight === void 0 ? void 0 : a("STextarea", "maxHeight", C.maxHeight, x)), H = u(() => {
124
- if (C.suggestions === void 0) return;
125
- if (C.suggestions === null || typeof C.suggestions != "object" || Array.isArray(C.suggestions)) throw TypeError("STextarea: suggestions должен быть объектом. / STextarea: suggestions must be an object.");
126
- let e = C.suggestions.activeDescendant === void 0 ? void 0 : o("STextarea", "suggestions.activeDescendant", C.suggestions.activeDescendant);
128
+ let _e = ce(), w = u(() => n("STextarea", "id", x.id, `s-textarea-${_e}`)), T = p(null), E = p(!1), D = null, O = null, k = null, A = null, j = !1, M = [], N = [], P = u(() => s("STextarea", "appearance", x.appearance, fe)), F = u(() => s("STextarea", "size", x.size, pe)), I = u(() => i("STextarea", "rows", x.rows, v)), L = u(() => te("STextarea", x.minLength, x.maxLength)), R = u(() => x.maxRows === void 0 ? void 0 : i("STextarea", "maxRows", x.maxRows, v)), z = u(() => x.minHeight === void 0 ? void 0 : a("STextarea", "minHeight", x.minHeight, y)), B = u(() => x.maxHeight === void 0 ? void 0 : a("STextarea", "maxHeight", x.maxHeight, y)), V = u(() => {
129
+ if (x.suggestions === void 0) return;
130
+ if (x.suggestions === null || typeof x.suggestions != "object" || Array.isArray(x.suggestions)) throw TypeError("STextarea: suggestions должен быть объектом. / STextarea: suggestions must be an object.");
131
+ let e = x.suggestions.activeDescendant === void 0 ? void 0 : o("STextarea", "suggestions.activeDescendant", x.suggestions.activeDescendant);
127
132
  return {
128
- controls: o("STextarea", "suggestions.controls", C.suggestions.controls),
133
+ controls: o("STextarea", "suggestions.controls", x.suggestions.controls),
129
134
  activeDescendant: e,
130
- autocomplete: s("STextarea", "suggestions.autocomplete", C.suggestions.autocomplete ?? "list", de),
131
- popupRole: s("STextarea", "suggestions.popupRole", C.suggestions.popupRole ?? "listbox", fe)
135
+ autocomplete: s("STextarea", "suggestions.autocomplete", x.suggestions.autocomplete ?? "list", me),
136
+ popupRole: s("STextarea", "suggestions.popupRole", x.suggestions.popupRole ?? "listbox", he)
132
137
  };
133
- }), U = u(() => {
134
- let e = r("STextarea", "autoResize", C.autoResize), t = z.value, n = B.value, i = V.value;
138
+ }), H = u(() => {
139
+ let e = r("STextarea", "autoResize", x.autoResize), t = R.value, n = z.value, i = B.value;
135
140
  if (!e && t !== void 0 && n === void 0 && i === void 0) throw TypeError(`STextarea: maxRows применяется только при autoResize=true; получено autoResize=false, maxRows=${t}. / STextarea: maxRows applies only when autoResize=true; received autoResize=false, maxRows=${t}.`);
136
141
  if (!e && (n !== void 0 || i !== void 0)) throw TypeError("STextarea: maxRows/minHeight/maxHeight применяются только при autoResize=true. / STextarea: maxRows/minHeight/maxHeight apply only when autoResize=true.");
137
142
  if (t !== void 0 && i !== void 0) throw TypeError("STextarea: maxRows и maxHeight являются альтернативными ограничителями; укажите один. / STextarea: maxRows and maxHeight are alternative bounds; provide one.");
138
143
  if (n !== void 0 && i !== void 0 && i < n) throw TypeError(`STextarea: maxHeight не может быть меньше minHeight; получено minHeight=${n}, maxHeight=${i}. / STextarea: maxHeight cannot be below minHeight; received minHeight=${n}, maxHeight=${i}.`);
139
- if (t !== void 0 && t < R.value) throw TypeError(`STextarea: maxRows не может быть меньше rows; получено rows=${R.value}, maxRows=${t}. / STextarea: maxRows cannot be less than rows; received rows=${R.value}, maxRows=${t}.`);
144
+ if (t !== void 0 && t < I.value) throw TypeError(`STextarea: maxRows не может быть меньше rows; получено rows=${I.value}, maxRows=${t}. / STextarea: maxRows cannot be less than rows; received rows=${I.value}, maxRows=${t}.`);
140
145
  return e ? {
141
146
  mode: "content",
142
147
  autoResize: !0,
@@ -148,84 +153,84 @@ var se = [
148
153
  autoResize: !1
149
154
  };
150
155
  });
151
- function he(e) {
156
+ function ve(e) {
152
157
  return ee("STextarea", {
153
158
  kind: "textarea",
154
- appearance: I.value === "default" ? "field" : "ghost",
159
+ appearance: P.value === "default" ? "field" : "ghost",
155
160
  invalid: e.invalid,
156
161
  disabled: e.disabled,
157
162
  readonly: e.readonly
158
163
  });
159
164
  }
160
- function W(e, t) {
165
+ function U(e, t) {
161
166
  let n = Z(e.selectionStart, e.value.length, `${t} selectionStart`), r = Z(e.selectionEnd, e.value.length, `${t} selectionEnd`);
162
167
  if (r < n) throw RangeError(`STextarea: ${t} selectionEnd=${r} is below selectionStart=${n}.`);
163
168
  return {
164
169
  start: n,
165
170
  end: r,
166
- direction: s("STextarea", `${t} selectionDirection`, e.selectionDirection ?? "none", S)
171
+ direction: s("STextarea", `${t} selectionDirection`, e.selectionDirection ?? "none", b)
167
172
  };
168
173
  }
169
- function G(e) {
170
- let t = W(e, "state-change");
171
- w("state-change", {
174
+ function W(e) {
175
+ let t = U(e, "state-change");
176
+ S("state-change", {
172
177
  text: e.value,
173
178
  cursor: t.start,
174
179
  selection: t,
175
- composing: O.value
180
+ composing: E.value
176
181
  });
177
182
  }
178
- function ge(e) {
183
+ function ye(e) {
179
184
  let t = e.target, n = e instanceof InputEvent ? e.inputType : "";
180
- !N && n !== "historyUndo" && n !== "historyRedo" && F.splice(0), w("update:modelValue", t.value), G(t), p(Y);
185
+ !j && n !== "historyUndo" && n !== "historyRedo" && N.splice(0), S("update:modelValue", t.value), W(t), f(Y);
181
186
  }
182
- function K(e, t) {
187
+ function G(e, t) {
183
188
  return {
184
189
  text: e.value,
185
- selection: W(e, t)
190
+ selection: U(e, t)
186
191
  };
187
192
  }
188
- function q(e, t) {
189
- e.value = t.text, e.focus(), e.setSelectionRange(t.selection.start, t.selection.end, t.selection.direction), w("update:modelValue", t.text), w("selection-change", t.selection), G(e), p(Y);
193
+ function K(e, t) {
194
+ e.value = t.text, e.focus(), e.setSelectionRange(t.selection.start, t.selection.end, t.selection.direction), S("update:modelValue", t.text), S("selection-change", t.selection), W(e), f(Y);
190
195
  }
191
- function _e(e, t) {
196
+ function q(e, t) {
192
197
  return e.value === t.text;
193
198
  }
194
- function ve(e, t) {
199
+ function be(e, t) {
195
200
  if (e.altKey || !(e.metaKey || e.ctrlKey)) return !1;
196
201
  let n = e.key.toLowerCase(), r = n === "z" && !e.shiftKey, i = n === "z" && e.shiftKey || n === "y" && !e.shiftKey;
197
202
  if (!r && !i) return !1;
198
- let a = r ? P : F, o = a[a.length - 1], s = r ? o?.after : o?.before;
199
- return !o || !s || !_e(t, s) ? !1 : (e.preventDefault(), a.pop(), r ? (F.push(o), q(t, o.before)) : (P.push(o), q(t, o.after)), !0);
200
- }
201
- function ye(e) {
202
- w("keydown", e), !(e.defaultPrevented || O.value || C.disabled || C.readonly) && ve(e, e.currentTarget);
203
- }
204
- function be(e) {
205
- w("keyup", e), G(e.currentTarget);
203
+ let a = r ? M : N, o = a[a.length - 1], s = r ? o?.after : o?.before;
204
+ return !o || !s || !q(t, s) ? !1 : (e.preventDefault(), a.pop(), r ? (N.push(o), K(t, o.before)) : (M.push(o), K(t, o.after)), !0);
206
205
  }
207
206
  function xe(e) {
208
- w("click", e), G(e.currentTarget);
207
+ S("keydown", e), !(e.defaultPrevented || E.value || x.disabled || x.readonly) && be(e, e.currentTarget);
209
208
  }
210
209
  function Se(e) {
211
- let t = e.currentTarget, n = W(t, "selection-change");
212
- w("selection-change", n), G(t);
210
+ S("keyup", e), W(e.currentTarget);
213
211
  }
214
212
  function Ce(e) {
215
- O.value = !0, w("compositionstart", e), G(e.currentTarget);
213
+ S("click", e), W(e.currentTarget);
216
214
  }
217
215
  function we(e) {
218
- w("compositionupdate", e), G(e.currentTarget);
216
+ let t = e.currentTarget, n = U(t, "selection-change");
217
+ S("selection-change", n), W(t);
219
218
  }
220
219
  function Te(e) {
221
- O.value = !1, w("compositionend", e), G(e.currentTarget), Y();
220
+ E.value = !0, S("compositionstart", e), W(e.currentTarget);
221
+ }
222
+ function Ee(e) {
223
+ S("compositionupdate", e), W(e.currentTarget);
224
+ }
225
+ function De(e) {
226
+ E.value = !1, S("compositionend", e), W(e.currentTarget), Y();
222
227
  }
223
228
  function J() {
224
- let e = D.value, t = U.value;
229
+ let e = T.value, t = H.value;
225
230
  if (t.mode === "fixed" || !e || e.scrollHeight === 0) return;
226
- let n = window.getComputedStyle(e), r = Number.parseFloat(n.lineHeight) || Number.parseFloat(n.fontSize) * 1.5, i = Number.parseFloat(n.paddingTop) || 0, a = Number.parseFloat(n.paddingBottom) || 0, o = R.value * r + i + a, s = t.minHeight ?? o, c = t.maxHeight ?? (t.maxRows === void 0 ? 0 : t.maxRows * r + i + a);
231
+ let n = window.getComputedStyle(e), r = Number.parseFloat(n.lineHeight) || Number.parseFloat(n.fontSize) * 1.5, i = Number.parseFloat(n.paddingTop) || 0, a = Number.parseFloat(n.paddingBottom) || 0, o = I.value * r + i + a, s = t.minHeight ?? o, c = t.maxHeight ?? (t.maxRows === void 0 ? 0 : t.maxRows * r + i + a);
227
232
  if (c > 0 && c < s) throw RangeError(`STextarea: вычисленный maxHeight=${c} меньше minimumHeight=${s}. / STextarea: resolved maxHeight=${c} is below minimumHeight=${s}.`);
228
- if (C.disabled || C.modelValue === null || C.modelValue.length === 0) {
233
+ if (x.disabled || x.modelValue === null || x.modelValue.length === 0) {
229
234
  e.style.height = `${s}px`, e.style.overflowY = "hidden";
230
235
  return;
231
236
  }
@@ -238,15 +243,15 @@ var se = [
238
243
  e.style.height = `${Math.max(s, l)}px`, e.style.overflowY = "hidden";
239
244
  }
240
245
  function Y() {
241
- M === null && U.value.mode !== "fixed" && (M = window.requestAnimationFrame(() => {
242
- M = null, J();
246
+ A === null && H.value.mode !== "fixed" && (A = window.requestAnimationFrame(() => {
247
+ A = null, J();
243
248
  }));
244
249
  }
245
- function Ee() {
246
- D.value?.focus();
250
+ function Oe() {
251
+ T.value?.focus();
247
252
  }
248
253
  function X(e) {
249
- let t = D.value;
254
+ let t = T.value;
250
255
  if (!t) throw Error(`STextarea: textarea не готова для ${e}; дождитесь mount. / STextarea: textarea is not ready for ${e}; wait for mount.`);
251
256
  return t;
252
257
  }
@@ -256,12 +261,12 @@ var se = [
256
261
  maximum: t
257
262
  });
258
263
  }
259
- function De() {
264
+ function ke() {
260
265
  let e = X("getSelectionOffset");
261
266
  return Z(e.selectionStart, e.value.length, "getSelectionOffset");
262
267
  }
263
- function Oe() {
264
- return W(X("getSelection"), "getSelection");
268
+ function Ae() {
269
+ return U(X("getSelection"), "getSelection");
265
270
  }
266
271
  function Q(e, t, n) {
267
272
  if (typeof e != "object" || !e || Array.isArray(e)) throw TypeError(`STextarea: ${n} должен быть selection object. / STextarea: ${n} must be a selection object.`);
@@ -270,31 +275,31 @@ var se = [
270
275
  return {
271
276
  start: r,
272
277
  end: i,
273
- direction: s("STextarea", `${n}.direction`, e.direction, S)
278
+ direction: s("STextarea", `${n}.direction`, e.direction, b)
274
279
  };
275
280
  }
276
- function ke(e, t = !0) {
281
+ function je(e, t = !0) {
277
282
  let n = X("setSelection"), r = Q(e, n.value.length, "setSelection");
278
- t && n.focus(), n.setSelectionRange(r.start, r.end, r.direction), w("selection-change", r), G(n);
283
+ t && n.focus(), n.setSelectionRange(r.start, r.end, r.direction), S("selection-change", r), W(n);
279
284
  }
280
- function Ae(e) {
285
+ function Me(e) {
281
286
  let t = X("setSelectionOffset"), n = Z(e, t.value.length, "setSelectionOffset");
282
287
  t.focus(), t.setSelectionRange(n, n);
283
288
  }
284
289
  function $(e, t = {}) {
285
290
  let n = X("replaceSelection");
286
- if (C.disabled || C.readonly) throw Error("STextarea: replaceSelection недоступен для disabled/readonly поля. / STextarea: replaceSelection is unavailable for a disabled/readonly field.");
287
- if (O.value) throw Error("STextarea: replaceSelection недоступен во время IME composition. / STextarea: replaceSelection is unavailable during IME composition.");
291
+ if (x.disabled || x.readonly) throw Error("STextarea: replaceSelection недоступен для disabled/readonly поля. / STextarea: replaceSelection is unavailable for a disabled/readonly field.");
292
+ if (E.value) throw Error("STextarea: replaceSelection недоступен во время IME composition. / STextarea: replaceSelection is unavailable during IME composition.");
288
293
  if (typeof e != "string") throw TypeError("STextarea: replaceSelection text должен быть строкой. / STextarea: replaceSelection text must be a string.");
289
- let r = t.selection === void 0 ? W(n, "replaceSelection") : Q(t.selection, n.value.length, "replaceSelection.selection"), i = s("STextarea", "replaceSelection.selectionMode", t.selectionMode ?? "end", pe);
294
+ let r = t.selection === void 0 ? U(n, "replaceSelection") : Q(t.selection, n.value.length, "replaceSelection.selection"), i = s("STextarea", "replaceSelection.selectionMode", t.selectionMode ?? "end", ge);
290
295
  (t.focus ?? !0) && n.focus();
291
- let a = K(n, "replaceSelection before");
296
+ let a = G(n, "replaceSelection before");
292
297
  n.setRangeText(e, r.start, r.end, i);
293
- let o = K(n, "replaceSelection after");
294
- P.push({
298
+ let o = G(n, "replaceSelection after");
299
+ M.push({
295
300
  before: a,
296
301
  after: o
297
- }), P.length > v && P.shift(), F.splice(0), N = !0;
302
+ }), M.length > g && M.shift(), N.splice(0), j = !0;
298
303
  try {
299
304
  n.dispatchEvent(new InputEvent("input", {
300
305
  bubbles: !0,
@@ -303,103 +308,105 @@ var se = [
303
308
  inputType: "insertReplacementText"
304
309
  }));
305
310
  } finally {
306
- N = !1;
311
+ j = !1;
307
312
  }
308
- w("selection-change", o.selection);
313
+ S("selection-change", o.selection);
309
314
  let c = o.selection;
310
315
  return {
311
316
  text: n.value,
312
317
  cursor: c.start,
313
318
  selection: c,
314
- composing: O.value
319
+ composing: E.value
315
320
  };
316
321
  }
317
- function je() {
318
- C.disabled || C.readonly || $("\n");
322
+ function Ne() {
323
+ x.disabled || x.readonly || $("\n");
319
324
  }
320
- return y({
321
- focus: Ee,
322
- getSelection: Oe,
323
- getSelectionOffset: De,
324
- insertSoftLineBreak: je,
325
+ return _({
326
+ focus: Oe,
327
+ getSelection: Ae,
328
+ getSelectionOffset: ke,
329
+ insertSoftLineBreak: Ne,
325
330
  replaceSelection: $,
326
331
  resize: J,
327
- setSelection: ke,
328
- setSelectionOffset: Ae
329
- }), ie(() => {
330
- J(), A = D.value?.parentElement ?? null, typeof ResizeObserver < "u" && A && (k = new ResizeObserver((e) => {
331
- let t = e.find((e) => e.target === A);
332
+ setSelection: je,
333
+ setSelectionOffset: Me
334
+ }), oe(() => {
335
+ J(), O = T.value?.parentElement ?? null, typeof ResizeObserver < "u" && O && (D = new ResizeObserver((e) => {
336
+ let t = e.find((e) => e.target === O);
332
337
  if (!t) return;
333
338
  let n = t.contentRect.width;
334
- n !== j && (j = n, Y());
335
- }), k.observe(A));
336
- }), g(() => [
337
- C.modelValue,
338
- C.disabled,
339
- C.rows,
340
- C.maxRows,
341
- C.minHeight,
342
- C.maxHeight
339
+ n !== k && (k = n, Y());
340
+ }), D.observe(O));
341
+ }), h(() => [
342
+ x.modelValue,
343
+ x.disabled,
344
+ x.rows,
345
+ x.maxRows,
346
+ x.minHeight,
347
+ x.maxHeight
343
348
  ], () => {
344
- p(Y);
345
- }), g(() => C.modelValue, (e) => {
346
- let t = D.value;
347
- t && t.value !== (e ?? "") && (P.splice(0), F.splice(0));
348
- }), re(() => {
349
- M !== null && window.cancelAnimationFrame(M), k?.disconnect(), k = null, A = null, P.splice(0), F.splice(0);
350
- }), (t, n) => (ae(), d(l, {
351
- "control-id": E.value,
352
- label: f.label,
353
- required: f.required,
354
- "help-text": f.helpText,
355
- "error-message": f.errorMessage,
356
- invalid: f.invalid,
357
- disabled: f.disabled,
358
- readonly: f.readonly,
359
- fill: I.value === "ghost" ? "container" : "content"
349
+ f(Y);
350
+ }), h(() => x.modelValue, (e) => {
351
+ let t = T.value;
352
+ t && t.value !== (e ?? "") && (M.splice(0), N.splice(0));
353
+ }), ae(() => {
354
+ A !== null && window.cancelAnimationFrame(A), D?.disconnect(), D = null, O = null, M.splice(0), N.splice(0);
355
+ }), (t, n) => (se(), ne(l, {
356
+ "control-id": w.value,
357
+ label: d.label,
358
+ required: d.required,
359
+ "help-text": d.helpText,
360
+ "error-message": d.errorMessage,
361
+ invalid: d.invalid,
362
+ disabled: d.disabled,
363
+ readonly: d.readonly,
364
+ fill: P.value === "ghost" ? "container" : "content"
360
365
  }, {
361
- default: _((t) => [te("textarea", ne({
362
- ...h(T).bindings(),
363
- ...he(t)
366
+ default: le((t) => [re("textarea", ie({
367
+ ...m(C).bindings(),
368
+ ...ve(t)
364
369
  }, {
365
- id: E.value,
370
+ id: w.value,
366
371
  ref_key: "textareaRef",
367
- ref: D,
372
+ ref: T,
368
373
  class: "s-textarea",
369
- "data-appearance": I.value,
370
- "data-size": L.value,
371
- "data-monospace": f.monospace || void 0,
372
- "data-auto-resize": U.value.mode === "content" || void 0,
373
- "data-max-rows": z.value,
374
- "data-min-height": B.value,
375
- "data-max-height": V.value,
374
+ "data-appearance": P.value,
375
+ "data-size": F.value,
376
+ "data-monospace": d.monospace || void 0,
377
+ "data-auto-resize": H.value.mode === "content" || void 0,
378
+ "data-max-rows": R.value,
379
+ "data-min-height": z.value,
380
+ "data-max-height": B.value,
376
381
  "data-invalid": t.invalid || void 0,
377
- value: f.modelValue,
378
- placeholder: f.placeholder,
382
+ value: d.modelValue,
383
+ placeholder: d.placeholder,
379
384
  disabled: t.disabled,
380
385
  readonly: t.readonly,
381
386
  required: t.required,
387
+ minlength: L.value.minLength,
388
+ maxlength: L.value.maxLength,
382
389
  "aria-invalid": t.invalid || void 0,
383
390
  "aria-required": t.required || void 0,
384
391
  "aria-readonly": t.readonly || void 0,
385
- "aria-describedby": h(e)(h(T).string("aria-describedby"), t.describedBy),
386
- "aria-controls": H.value?.controls,
387
- "aria-activedescendant": H.value?.activeDescendant,
388
- "aria-autocomplete": H.value?.autocomplete,
389
- "aria-haspopup": H.value?.popupRole,
390
- rows: R.value,
391
- onInput: ge,
392
- onKeydown: ye,
393
- onKeyup: be,
394
- onClick: xe,
395
- onFocus: n[0] ||= (e) => w("focus", e),
396
- onBlur: n[1] ||= (e) => w("blur", e),
397
- onSelect: Se,
398
- onPaste: n[2] ||= (e) => w("paste", e),
399
- onCompositionstart: Ce,
400
- onCompositionupdate: we,
401
- onCompositionend: Te
402
- }), null, 16, se)]),
392
+ "aria-describedby": m(e)(m(C).string("aria-describedby"), t.describedBy),
393
+ "aria-controls": V.value?.controls,
394
+ "aria-activedescendant": V.value?.activeDescendant,
395
+ "aria-autocomplete": V.value?.autocomplete,
396
+ "aria-haspopup": V.value?.popupRole,
397
+ rows: I.value,
398
+ onInput: ye,
399
+ onKeydown: xe,
400
+ onKeyup: Se,
401
+ onClick: Ce,
402
+ onFocus: n[0] ||= (e) => S("focus", e),
403
+ onBlur: n[1] ||= (e) => S("blur", e),
404
+ onSelect: we,
405
+ onPaste: n[2] ||= (e) => S("paste", e),
406
+ onCompositionstart: Te,
407
+ onCompositionupdate: Ee,
408
+ onCompositionend: De
409
+ }), null, 16, ue)]),
403
410
  _: 1
404
411
  }, 8, [
405
412
  "control-id",
@@ -415,4 +422,4 @@ var se = [
415
422
  }
416
423
  });
417
424
  //#endregion
418
- export { y as default };
425
+ export { _ as default };
@@ -9,6 +9,7 @@ interface SMenuLabelledEntry {
9
9
  readonly label: string;
10
10
  readonly icon?: Component;
11
11
  readonly disabled?: boolean;
12
+ readonly description?: string;
12
13
  readonly shortcut?: string;
13
14
  readonly badge?: string | number;
14
15
  readonly badgeSeverity?: BadgeSeverity;
@@ -44,9 +45,16 @@ export interface SMenuSeparatorEntry {
44
45
  readonly kind: 'separator';
45
46
  readonly id: string;
46
47
  }
48
+ /** Видимая и семантическая группа menu items без дополнительного focus owner. / A visible semantic menu-item group without another focus owner. */
49
+ export interface SMenuGroupEntry {
50
+ readonly kind: 'group';
51
+ readonly id: string;
52
+ readonly label: string;
53
+ readonly children: readonly SMenuInteractiveEntry[];
54
+ }
47
55
  export type SMenuSelectableEntry = SMenuAction | SMenuDestination | SMenuCheckbox | SMenuRadio;
48
56
  export type SMenuInteractiveEntry = SMenuSelectableEntry | SMenuSubmenu;
49
- export type SMenuEntry = SMenuInteractiveEntry | SMenuSeparatorEntry;
57
+ export type SMenuEntry = SMenuInteractiveEntry | SMenuSeparatorEntry | SMenuGroupEntry;
50
58
  /** Проверяет полный recursive discriminated menu contract без coercion/fallback. / Validates the complete recursive discriminated menu contract without coercion/fallback. */
51
59
  export declare function validateSMenuEntries(value: unknown): asserts value is readonly SMenuEntry[];
52
60
  export {};
@@ -7,7 +7,8 @@ var i = [
7
7
  "checkbox",
8
8
  "radio",
9
9
  "separator",
10
- "submenu"
10
+ "submenu",
11
+ "group"
11
12
  ], a = ["row", "tile"], o = [
12
13
  "secondary",
13
14
  "success",
@@ -21,6 +22,7 @@ var i = [
21
22
  "label",
22
23
  "icon",
23
24
  "disabled",
25
+ "description",
24
26
  "shortcut",
25
27
  "badge",
26
28
  "badgeSeverity",
@@ -37,7 +39,8 @@ var i = [
37
39
  checkbox: ["checked"],
38
40
  radio: ["groupId", "checked"],
39
41
  separator: [],
40
- submenu: ["children"]
42
+ submenu: ["children"],
43
+ group: ["children"]
41
44
  };
42
45
  function l(e, t) {
43
46
  if (typeof e != "object" || !e || Array.isArray(e)) throw TypeError(`SMenuSurface: ${t} must be an object`);
@@ -49,43 +52,55 @@ function d(e, t, r) {
49
52
  e[t] !== void 0 && n("SMenuSurface", `${r}.${t}`, e[t]);
50
53
  }
51
54
  function f(e, r) {
52
- if (n("SMenuSurface", `${r}.id`, e.id), n("SMenuSurface", `${r}.label`, e.label), u(e, "disabled", r), d(e, "shortcut", r), e.icon !== void 0 && typeof e.icon != "object" && typeof e.icon != "function") throw TypeError(`SMenuSurface: ${r}.icon must be a Vue component`);
55
+ if (n("SMenuSurface", `${r}.id`, e.id), n("SMenuSurface", `${r}.label`, e.label), u(e, "disabled", r), d(e, "description", r), d(e, "shortcut", r), e.icon !== void 0 && typeof e.icon != "object" && typeof e.icon != "function") throw TypeError(`SMenuSurface: ${r}.icon must be a Vue component`);
53
56
  if (e.badge !== void 0 && (typeof e.badge != "string" || e.badge.length === 0) && (typeof e.badge != "number" || !Number.isFinite(e.badge))) throw TypeError(`SMenuSurface: ${r}.badge must be a non-empty string or finite number`);
54
57
  e.badgeSeverity !== void 0 && t("SMenuSurface", `${r}.badgeSeverity`, e.badgeSeverity, o), e.layout !== void 0 && t("SMenuSurface", `${r}.layout`, e.layout, a);
55
58
  }
56
59
  function p(e, t, n) {
57
- let r = new Set(t === "separator" ? ["kind", "id"] : [...s, ...c[t]]);
60
+ let r = new Set(t === "separator" ? ["kind", "id"] : t === "group" ? [
61
+ "kind",
62
+ "id",
63
+ "label",
64
+ "children"
65
+ ] : [...s, ...c[t]]);
58
66
  for (let t of Object.keys(e)) if (!r.has(t)) throw TypeError(`SMenuSurface: ${n} has unsupported field '${t}'`);
59
67
  }
60
- function m(a, o, s) {
68
+ function m(a, o, s, c = !0) {
61
69
  if (!Array.isArray(a)) throw TypeError(`SMenuSurface: ${o} must be an array`);
62
70
  if (o !== "items" && a.length === 0) throw TypeError(`SMenuSurface: ${o} children must be a non-empty array`);
63
- let c = /* @__PURE__ */ new Set(), d = !1;
64
- for (let [h, g] of a.entries()) {
65
- let _ = `${o}[${h}]`;
66
- l(g, _);
67
- let v = t("SMenuSurface", `${_}.kind`, g.kind, i);
68
- p(g, v, _);
69
- let y = n("SMenuSurface", `${_}.id`, g.id);
70
- if (s.has(y)) throw TypeError(`SMenuSurface: duplicate entry id '${y}'`);
71
- if (s.add(y), v === "separator") {
72
- if (h === 0 || h === a.length - 1 || d) throw TypeError("SMenuSurface: separator cannot be first, last, or consecutive");
73
- d = !0;
71
+ let d = /* @__PURE__ */ new Set(), h = !1;
72
+ for (let [g, _] of a.entries()) {
73
+ let v = `${o}[${g}]`;
74
+ l(_, v);
75
+ let y = t("SMenuSurface", `${v}.kind`, _.kind, i);
76
+ p(_, y, v);
77
+ let b = n("SMenuSurface", `${v}.id`, _.id);
78
+ if (s.has(b)) throw TypeError(`SMenuSurface: duplicate entry id '${b}'`);
79
+ if (s.add(b), y === "separator") {
80
+ if (!c) throw TypeError(`SMenuSurface: ${v} separator is not allowed inside a group`);
81
+ if (g === 0 || g === a.length - 1 || h) throw TypeError("SMenuSurface: separator cannot be first, last, or consecutive");
82
+ h = !0;
74
83
  continue;
75
84
  }
76
- if (d = !1, f(g, _), (v === "action" || v === "destination") && u(g, "current", _), v === "destination" && r({
77
- owner: `SMenuSurface: ${_}`,
78
- href: g.href,
79
- to: g.to,
80
- target: g.target,
81
- rel: g.rel
82
- }), v === "checkbox" && g.checked !== "mixed" && typeof g.checked != "boolean") throw TypeError(`SMenuSurface: ${_}.checked must be a boolean or "mixed"`);
83
- if (v === "radio") {
84
- let t = n("SMenuSurface", `${_}.groupId`, g.groupId), r = e("SMenuSurface", `${_}.checked`, g.checked);
85
- if (r && c.has(t)) throw TypeError(`SMenuSurface: radio group '${t}' has more than one checked entry`);
86
- r && c.add(t);
85
+ if (y === "group") {
86
+ if (!c) throw TypeError(`SMenuSurface: ${v} nested group is not allowed`);
87
+ if (n("SMenuSurface", `${v}.label`, _.label), !Array.isArray(_.children) || _.children.length === 0) throw TypeError(`SMenuSurface: ${v}.children must be a non-empty array`);
88
+ m(_.children, `${v}.children`, s, !1), h = !1;
89
+ continue;
90
+ }
91
+ if (h = !1, f(_, v), (y === "action" || y === "destination") && u(_, "current", v), y === "destination" && r({
92
+ owner: `SMenuSurface: ${v}`,
93
+ href: _.href,
94
+ to: _.to,
95
+ target: _.target,
96
+ rel: _.rel
97
+ }), y === "checkbox" && _.checked !== "mixed" && typeof _.checked != "boolean") throw TypeError(`SMenuSurface: ${v}.checked must be a boolean or "mixed"`);
98
+ if (y === "radio") {
99
+ let t = n("SMenuSurface", `${v}.groupId`, _.groupId), r = e("SMenuSurface", `${v}.checked`, _.checked);
100
+ if (r && d.has(t)) throw TypeError(`SMenuSurface: radio group '${t}' has more than one checked entry`);
101
+ r && d.add(t);
87
102
  }
88
- v === "submenu" && m(g.children, `${_}.children`, s);
103
+ y === "submenu" && m(_.children, `${v}.children`, s);
89
104
  }
90
105
  }
91
106
  function h(e) {
@@ -11,6 +11,7 @@ export interface DialogOverlayController {
11
11
  setPanelElement: (element: Element | ComponentPublicInstance | null) => void;
12
12
  backdropStyle: Readonly<Ref<Record<string, string>>>;
13
13
  surfaceStyle: Readonly<Ref<Record<string, string>>>;
14
+ dispose: () => void;
14
15
  }
15
16
  /**
16
17
  * Владеет modal-регистрацией, focus trap, body lock и восстановлением фокуса.