@pgcorp/ui-kit 0.11.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 (72) hide show
  1. package/README.md +198 -11
  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/SButton.css_vue_type_style_index_0_src_a5d8f7e0_scoped_a5d8f7e0_lang.css +2 -0
  7. package/dist/assets/src/components/shared/controls/SChoiceCards.css_vue_type_style_index_0_src_af9fa9d1_scoped_af9fa9d1_lang.css +2 -0
  8. 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
  9. 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
  10. package/dist/assets/src/components/shared/controls/SMenuSurface.css_vue_type_style_index_0_src_ddcc5fbb_scoped_ddcc5fbb_lang.css +2 -0
  11. package/dist/assets/src/components/shared/data-display/{SCodeEditor.css_vue_type_style_index_0_src_124ca461_scoped_124ca461_lang.css → SCodeEditor.css_vue_type_style_index_0_src_3ad533d9_scoped_3ad533d9_lang.css} +1 -1
  12. package/dist/assets/src/components/shared/data-display/SStatus.css_vue_type_style_index_0_src_3ce41a12_scoped_3ce41a12_lang.css +2 -0
  13. package/dist/assets/src/components/shared/data-display/SVirtualList.css_vue_type_style_index_0_src_cee8c247_scoped_cee8c247_lang.css +2 -0
  14. package/dist/src/components/layout/SSideMenuButton.vue.d.ts +1 -1
  15. package/dist/src/components/shared/_internal/SMenuItem.vue.js +2 -2
  16. package/dist/src/components/shared/_internal/SMenuItem.vue_vue_type_script_setup_true_lang.js +88 -76
  17. package/dist/src/components/shared/_internal/dialogSurface.d.ts +1 -1
  18. package/dist/src/components/shared/_internal/dialogSurface.js +1 -0
  19. package/dist/src/components/shared/containers/SCollapsiblePanel.vue.d.ts +1 -1
  20. package/dist/src/components/shared/containers/SCollapsiblePanel.vue.js +2 -2
  21. package/dist/src/components/shared/containers/SCollapsiblePanel.vue_vue_type_script_setup_true_lang.js +60 -58
  22. package/dist/src/components/shared/containers/SModal.vue.js +2 -2
  23. package/dist/src/components/shared/containers/SModal.vue_vue_type_script_setup_true_lang.js +43 -37
  24. package/dist/src/components/shared/controls/SButton.vue.d.ts +3 -0
  25. package/dist/src/components/shared/controls/SButton.vue.js +2 -2
  26. package/dist/src/components/shared/controls/SButton.vue_vue_type_script_setup_true_lang.js +103 -99
  27. package/dist/src/components/shared/controls/SChoiceCards.vue.d.ts +1 -0
  28. package/dist/src/components/shared/controls/SChoiceCards.vue.js +2 -2
  29. package/dist/src/components/shared/controls/SChoiceCards.vue_vue_type_script_setup_true_lang.js +53 -49
  30. package/dist/src/components/shared/controls/SDropdownMenu.vue.d.ts +15 -4
  31. package/dist/src/components/shared/controls/SDropdownMenu.vue.js +2 -2
  32. package/dist/src/components/shared/controls/SDropdownMenu.vue_vue_type_script_setup_true_lang.js +98 -62
  33. package/dist/src/components/shared/controls/SInputText.vue.d.ts +2 -2
  34. package/dist/src/components/shared/controls/SInputText.vue.js +2 -2
  35. package/dist/src/components/shared/controls/SInputText.vue_vue_type_script_setup_true_lang.js +16 -25
  36. package/dist/src/components/shared/controls/SMenuSurface.vue.d.ts +2 -2
  37. package/dist/src/components/shared/controls/SMenuSurface.vue.js +2 -2
  38. package/dist/src/components/shared/controls/SMenuSurface.vue_vue_type_script_setup_true_lang.js +132 -110
  39. package/dist/src/components/shared/controls/STextarea.vue.d.ts +8 -0
  40. package/dist/src/components/shared/controls/STextarea.vue_vue_type_script_setup_true_lang.js +156 -145
  41. package/dist/src/components/shared/controls/menu.d.ts +9 -1
  42. package/dist/src/components/shared/controls/menu.js +43 -28
  43. package/dist/src/components/shared/data-display/SCodeEditor.vue.d.ts +90 -7
  44. package/dist/src/components/shared/data-display/SCodeEditor.vue.js +2 -2
  45. package/dist/src/components/shared/data-display/SStatus.vue.d.ts +7 -0
  46. package/dist/src/components/shared/data-display/SStatus.vue.js +2 -2
  47. package/dist/src/components/shared/data-display/SStatus.vue_vue_type_script_setup_true_lang.js +28 -21
  48. package/dist/src/components/shared/data-display/SVirtualList.vue.d.ts +2 -0
  49. package/dist/src/components/shared/data-display/SVirtualList.vue.js +2 -2
  50. package/dist/src/components/shared/data-display/SVirtualList.vue_vue_type_script_setup_true_lang.js +317 -210
  51. package/dist/src/composables/useDialogOverlay.d.ts +1 -0
  52. package/dist/src/composables/useDialogOverlay.js +5 -2
  53. package/dist/src/internal/textLengthConstraints.d.ts +9 -0
  54. package/dist/src/internal/textLengthConstraints.js +18 -0
  55. package/dist/src/internal/useBinaryInput.js +3 -2
  56. package/dist/src/internal/useMenuLayer.d.ts +2 -1
  57. package/dist/src/internal/useMenuLayer.js +20 -14
  58. package/docs/public-api.md +14 -2
  59. package/package.json +1 -1
  60. package/src/components/shared/_internal/SDialogSurface.css +4 -0
  61. package/src/components/shared/_internal/SMenuItem.css +22 -1
  62. package/src/components/shared/controls/SButton.css +28 -0
  63. package/src/components/shared/controls/SChoiceCards.css +10 -3
  64. package/src/components/shared/controls/SMenuSurface.css +20 -0
  65. package/src/components/shared/data-display/SStatus.css +4 -0
  66. package/src/components/shared/data-display/SVirtualList.css +12 -0
  67. package/dist/assets/src/components/shared/_internal/SMenuItem.css_vue_type_style_index_0_src_e5bd192e_scoped_e5bd192e_lang.css +0 -2
  68. package/dist/assets/src/components/shared/controls/SButton.css_vue_type_style_index_0_src_52ad38b1_scoped_52ad38b1_lang.css +0 -2
  69. package/dist/assets/src/components/shared/controls/SChoiceCards.css_vue_type_style_index_0_src_627a8628_scoped_627a8628_lang.css +0 -2
  70. package/dist/assets/src/components/shared/controls/SMenuSurface.css_vue_type_style_index_0_src_bc7c7be4_scoped_bc7c7be4_lang.css +0 -2
  71. package/dist/assets/src/components/shared/data-display/SStatus.css_vue_type_style_index_0_src_c76fa058_scoped_c76fa058_lang.css +0 -2
  72. package/dist/assets/src/components/shared/data-display/SVirtualList.css_vue_type_style_index_0_src_1717877d_scoped_1717877d_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,
@@ -76,6 +81,8 @@ var se = [
76
81
  "keydown",
77
82
  "keyup",
78
83
  "click",
84
+ "focus",
85
+ "blur",
79
86
  "paste",
80
87
  "compositionstart",
81
88
  "compositionupdate",
@@ -83,58 +90,58 @@ var se = [
83
90
  "selection-change",
84
91
  "state-change"
85
92
  ],
86
- setup(f, { expose: y, emit: ce }) {
87
- let le = ["default", "ghost"], ue = [
93
+ setup(d, { expose: _, emit: de }) {
94
+ let fe = ["default", "ghost"], pe = [
88
95
  "sm",
89
96
  "md",
90
97
  "lg"
91
- ], b = {
98
+ ], v = {
92
99
  minimum: 1,
93
100
  maximum: 100
94
- }, x = {
101
+ }, y = {
95
102
  minimum: 1,
96
103
  maximum: 4096
97
- }, de = [
104
+ }, me = [
98
105
  "list",
99
106
  "both",
100
107
  "inline",
101
108
  "none"
102
- ], fe = [
109
+ ], he = [
103
110
  "listbox",
104
111
  "grid",
105
112
  "tree",
106
113
  "dialog"
107
- ], S = [
114
+ ], b = [
108
115
  "forward",
109
116
  "backward",
110
117
  "none"
111
- ], pe = [
118
+ ], ge = [
112
119
  "select",
113
120
  "start",
114
121
  "end",
115
122
  "preserve"
116
- ], C = f, w = ce, T = t({
123
+ ], x = d, S = de, C = t({
117
124
  component: "STextarea",
118
125
  owner: "native textarea"
119
126
  });
120
127
  c({ owner: "STextarea" });
121
- 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(() => {
122
- if (C.suggestions === void 0) return;
123
- if (C.suggestions === null || typeof C.suggestions != "object" || Array.isArray(C.suggestions)) throw TypeError("STextarea: suggestions должен быть объектом. / STextarea: suggestions must be an object.");
124
- 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);
125
132
  return {
126
- controls: o("STextarea", "suggestions.controls", C.suggestions.controls),
133
+ controls: o("STextarea", "suggestions.controls", x.suggestions.controls),
127
134
  activeDescendant: e,
128
- autocomplete: s("STextarea", "suggestions.autocomplete", C.suggestions.autocomplete ?? "list", de),
129
- 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)
130
137
  };
131
- }), U = u(() => {
132
- 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;
133
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}.`);
134
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.");
135
142
  if (t !== void 0 && i !== void 0) throw TypeError("STextarea: maxRows и maxHeight являются альтернативными ограничителями; укажите один. / STextarea: maxRows and maxHeight are alternative bounds; provide one.");
136
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}.`);
137
- 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}.`);
138
145
  return e ? {
139
146
  mode: "content",
140
147
  autoResize: !0,
@@ -146,84 +153,84 @@ var se = [
146
153
  autoResize: !1
147
154
  };
148
155
  });
149
- function he(e) {
156
+ function ve(e) {
150
157
  return ee("STextarea", {
151
158
  kind: "textarea",
152
- appearance: I.value === "default" ? "field" : "ghost",
159
+ appearance: P.value === "default" ? "field" : "ghost",
153
160
  invalid: e.invalid,
154
161
  disabled: e.disabled,
155
162
  readonly: e.readonly
156
163
  });
157
164
  }
158
- function W(e, t) {
165
+ function U(e, t) {
159
166
  let n = Z(e.selectionStart, e.value.length, `${t} selectionStart`), r = Z(e.selectionEnd, e.value.length, `${t} selectionEnd`);
160
167
  if (r < n) throw RangeError(`STextarea: ${t} selectionEnd=${r} is below selectionStart=${n}.`);
161
168
  return {
162
169
  start: n,
163
170
  end: r,
164
- direction: s("STextarea", `${t} selectionDirection`, e.selectionDirection ?? "none", S)
171
+ direction: s("STextarea", `${t} selectionDirection`, e.selectionDirection ?? "none", b)
165
172
  };
166
173
  }
167
- function G(e) {
168
- let t = W(e, "state-change");
169
- w("state-change", {
174
+ function W(e) {
175
+ let t = U(e, "state-change");
176
+ S("state-change", {
170
177
  text: e.value,
171
178
  cursor: t.start,
172
179
  selection: t,
173
- composing: O.value
180
+ composing: E.value
174
181
  });
175
182
  }
176
- function ge(e) {
183
+ function ye(e) {
177
184
  let t = e.target, n = e instanceof InputEvent ? e.inputType : "";
178
- !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);
179
186
  }
180
- function K(e, t) {
187
+ function G(e, t) {
181
188
  return {
182
189
  text: e.value,
183
- selection: W(e, t)
190
+ selection: U(e, t)
184
191
  };
185
192
  }
186
- function q(e, t) {
187
- 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);
188
195
  }
189
- function _e(e, t) {
196
+ function q(e, t) {
190
197
  return e.value === t.text;
191
198
  }
192
- function ve(e, t) {
199
+ function be(e, t) {
193
200
  if (e.altKey || !(e.metaKey || e.ctrlKey)) return !1;
194
201
  let n = e.key.toLowerCase(), r = n === "z" && !e.shiftKey, i = n === "z" && e.shiftKey || n === "y" && !e.shiftKey;
195
202
  if (!r && !i) return !1;
196
- let a = r ? P : F, o = a[a.length - 1], s = r ? o?.after : o?.before;
197
- 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);
198
- }
199
- function ye(e) {
200
- w("keydown", e), !(e.defaultPrevented || O.value || C.disabled || C.readonly) && ve(e, e.currentTarget);
201
- }
202
- function be(e) {
203
- 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);
204
205
  }
205
206
  function xe(e) {
206
- w("click", e), G(e.currentTarget);
207
+ S("keydown", e), !(e.defaultPrevented || E.value || x.disabled || x.readonly) && be(e, e.currentTarget);
207
208
  }
208
209
  function Se(e) {
209
- let t = e.currentTarget, n = W(t, "selection-change");
210
- w("selection-change", n), G(t);
210
+ S("keyup", e), W(e.currentTarget);
211
211
  }
212
212
  function Ce(e) {
213
- O.value = !0, w("compositionstart", e), G(e.currentTarget);
213
+ S("click", e), W(e.currentTarget);
214
214
  }
215
215
  function we(e) {
216
- w("compositionupdate", e), G(e.currentTarget);
216
+ let t = e.currentTarget, n = U(t, "selection-change");
217
+ S("selection-change", n), W(t);
217
218
  }
218
219
  function Te(e) {
219
- 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();
220
227
  }
221
228
  function J() {
222
- let e = D.value, t = U.value;
229
+ let e = T.value, t = H.value;
223
230
  if (t.mode === "fixed" || !e || e.scrollHeight === 0) return;
224
- 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);
225
232
  if (c > 0 && c < s) throw RangeError(`STextarea: вычисленный maxHeight=${c} меньше minimumHeight=${s}. / STextarea: resolved maxHeight=${c} is below minimumHeight=${s}.`);
226
- if (C.disabled || C.modelValue === null || C.modelValue.length === 0) {
233
+ if (x.disabled || x.modelValue === null || x.modelValue.length === 0) {
227
234
  e.style.height = `${s}px`, e.style.overflowY = "hidden";
228
235
  return;
229
236
  }
@@ -236,15 +243,15 @@ var se = [
236
243
  e.style.height = `${Math.max(s, l)}px`, e.style.overflowY = "hidden";
237
244
  }
238
245
  function Y() {
239
- M === null && U.value.mode !== "fixed" && (M = window.requestAnimationFrame(() => {
240
- M = null, J();
246
+ A === null && H.value.mode !== "fixed" && (A = window.requestAnimationFrame(() => {
247
+ A = null, J();
241
248
  }));
242
249
  }
243
- function Ee() {
244
- D.value?.focus();
250
+ function Oe() {
251
+ T.value?.focus();
245
252
  }
246
253
  function X(e) {
247
- let t = D.value;
254
+ let t = T.value;
248
255
  if (!t) throw Error(`STextarea: textarea не готова для ${e}; дождитесь mount. / STextarea: textarea is not ready for ${e}; wait for mount.`);
249
256
  return t;
250
257
  }
@@ -254,12 +261,12 @@ var se = [
254
261
  maximum: t
255
262
  });
256
263
  }
257
- function De() {
264
+ function ke() {
258
265
  let e = X("getSelectionOffset");
259
266
  return Z(e.selectionStart, e.value.length, "getSelectionOffset");
260
267
  }
261
- function Oe() {
262
- return W(X("getSelection"), "getSelection");
268
+ function Ae() {
269
+ return U(X("getSelection"), "getSelection");
263
270
  }
264
271
  function Q(e, t, n) {
265
272
  if (typeof e != "object" || !e || Array.isArray(e)) throw TypeError(`STextarea: ${n} должен быть selection object. / STextarea: ${n} must be a selection object.`);
@@ -268,31 +275,31 @@ var se = [
268
275
  return {
269
276
  start: r,
270
277
  end: i,
271
- direction: s("STextarea", `${n}.direction`, e.direction, S)
278
+ direction: s("STextarea", `${n}.direction`, e.direction, b)
272
279
  };
273
280
  }
274
- function ke(e, t = !0) {
281
+ function je(e, t = !0) {
275
282
  let n = X("setSelection"), r = Q(e, n.value.length, "setSelection");
276
- 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);
277
284
  }
278
- function Ae(e) {
285
+ function Me(e) {
279
286
  let t = X("setSelectionOffset"), n = Z(e, t.value.length, "setSelectionOffset");
280
287
  t.focus(), t.setSelectionRange(n, n);
281
288
  }
282
289
  function $(e, t = {}) {
283
290
  let n = X("replaceSelection");
284
- if (C.disabled || C.readonly) throw Error("STextarea: replaceSelection недоступен для disabled/readonly поля. / STextarea: replaceSelection is unavailable for a disabled/readonly field.");
285
- 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.");
286
293
  if (typeof e != "string") throw TypeError("STextarea: replaceSelection text должен быть строкой. / STextarea: replaceSelection text must be a string.");
287
- 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);
288
295
  (t.focus ?? !0) && n.focus();
289
- let a = K(n, "replaceSelection before");
296
+ let a = G(n, "replaceSelection before");
290
297
  n.setRangeText(e, r.start, r.end, i);
291
- let o = K(n, "replaceSelection after");
292
- P.push({
298
+ let o = G(n, "replaceSelection after");
299
+ M.push({
293
300
  before: a,
294
301
  after: o
295
- }), P.length > v && P.shift(), F.splice(0), N = !0;
302
+ }), M.length > g && M.shift(), N.splice(0), j = !0;
296
303
  try {
297
304
  n.dispatchEvent(new InputEvent("input", {
298
305
  bubbles: !0,
@@ -301,101 +308,105 @@ var se = [
301
308
  inputType: "insertReplacementText"
302
309
  }));
303
310
  } finally {
304
- N = !1;
311
+ j = !1;
305
312
  }
306
- w("selection-change", o.selection);
313
+ S("selection-change", o.selection);
307
314
  let c = o.selection;
308
315
  return {
309
316
  text: n.value,
310
317
  cursor: c.start,
311
318
  selection: c,
312
- composing: O.value
319
+ composing: E.value
313
320
  };
314
321
  }
315
- function je() {
316
- C.disabled || C.readonly || $("\n");
322
+ function Ne() {
323
+ x.disabled || x.readonly || $("\n");
317
324
  }
318
- return y({
319
- focus: Ee,
320
- getSelection: Oe,
321
- getSelectionOffset: De,
322
- insertSoftLineBreak: je,
325
+ return _({
326
+ focus: Oe,
327
+ getSelection: Ae,
328
+ getSelectionOffset: ke,
329
+ insertSoftLineBreak: Ne,
323
330
  replaceSelection: $,
324
331
  resize: J,
325
- setSelection: ke,
326
- setSelectionOffset: Ae
327
- }), ie(() => {
328
- J(), A = D.value?.parentElement ?? null, typeof ResizeObserver < "u" && A && (k = new ResizeObserver((e) => {
329
- 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);
330
337
  if (!t) return;
331
338
  let n = t.contentRect.width;
332
- n !== j && (j = n, Y());
333
- }), k.observe(A));
334
- }), g(() => [
335
- C.modelValue,
336
- C.disabled,
337
- C.rows,
338
- C.maxRows,
339
- C.minHeight,
340
- 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
341
348
  ], () => {
342
- p(Y);
343
- }), g(() => C.modelValue, (e) => {
344
- let t = D.value;
345
- t && t.value !== (e ?? "") && (P.splice(0), F.splice(0));
346
- }), re(() => {
347
- M !== null && window.cancelAnimationFrame(M), k?.disconnect(), k = null, A = null, P.splice(0), F.splice(0);
348
- }), (t, n) => (ae(), d(l, {
349
- "control-id": E.value,
350
- label: f.label,
351
- required: f.required,
352
- "help-text": f.helpText,
353
- "error-message": f.errorMessage,
354
- invalid: f.invalid,
355
- disabled: f.disabled,
356
- readonly: f.readonly,
357
- 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"
358
365
  }, {
359
- default: _((t) => [te("textarea", ne({
360
- ...h(T).bindings(),
361
- ...he(t)
366
+ default: le((t) => [re("textarea", ie({
367
+ ...m(C).bindings(),
368
+ ...ve(t)
362
369
  }, {
363
- id: E.value,
370
+ id: w.value,
364
371
  ref_key: "textareaRef",
365
- ref: D,
372
+ ref: T,
366
373
  class: "s-textarea",
367
- "data-appearance": I.value,
368
- "data-size": L.value,
369
- "data-monospace": f.monospace || void 0,
370
- "data-auto-resize": U.value.mode === "content" || void 0,
371
- "data-max-rows": z.value,
372
- "data-min-height": B.value,
373
- "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,
374
381
  "data-invalid": t.invalid || void 0,
375
- value: f.modelValue,
376
- placeholder: f.placeholder,
382
+ value: d.modelValue,
383
+ placeholder: d.placeholder,
377
384
  disabled: t.disabled,
378
385
  readonly: t.readonly,
379
386
  required: t.required,
387
+ minlength: L.value.minLength,
388
+ maxlength: L.value.maxLength,
380
389
  "aria-invalid": t.invalid || void 0,
381
390
  "aria-required": t.required || void 0,
382
391
  "aria-readonly": t.readonly || void 0,
383
- "aria-describedby": h(e)(h(T).string("aria-describedby"), t.describedBy),
384
- "aria-controls": H.value?.controls,
385
- "aria-activedescendant": H.value?.activeDescendant,
386
- "aria-autocomplete": H.value?.autocomplete,
387
- "aria-haspopup": H.value?.popupRole,
388
- rows: R.value,
389
- onInput: ge,
390
- onKeydown: ye,
391
- onKeyup: be,
392
- onClick: xe,
393
- onSelect: Se,
394
- onPaste: n[0] ||= (e) => w("paste", e),
395
- onCompositionstart: Ce,
396
- onCompositionupdate: we,
397
- onCompositionend: Te
398
- }), 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)]),
399
410
  _: 1
400
411
  }, 8, [
401
412
  "control-id",
@@ -411,4 +422,4 @@ var se = [
411
422
  }
412
423
  });
413
424
  //#endregion
414
- 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) {