@1337exp/taoui 1.5.0 → 1.6.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.
package/dist/index.cjs CHANGED
@@ -2,17 +2,17 @@
2
2
  typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue")) : typeof define === "function" && define.amd ? define(["exports", "vue"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.TaoUI = {}, global.Vue));
3
3
  })(this, function(exports2, vue) {
4
4
  "use strict";
5
- const _hoisted_1$M = ["type", "disabled"];
6
- const _hoisted_2$F = {
5
+ const _hoisted_1$N = ["type", "disabled"];
6
+ const _hoisted_2$G = {
7
7
  key: 0,
8
8
  class: "tao-button__loader"
9
9
  };
10
- const _hoisted_3$y = {
10
+ const _hoisted_3$A = {
11
11
  key: 1,
12
12
  class: "tao-button__icon"
13
13
  };
14
- const _hoisted_4$r = { class: "tao-button__content" };
15
- const _sfc_main$U = /* @__PURE__ */ vue.defineComponent({
14
+ const _hoisted_4$u = { class: "tao-button__content" };
15
+ const _sfc_main$V = /* @__PURE__ */ vue.defineComponent({
16
16
  ...{ name: "TaoButton" },
17
17
  __name: "TaoButton",
18
18
  props: {
@@ -51,12 +51,12 @@
51
51
  disabled: __props.disabled || __props.loading,
52
52
  onClick: handleClick
53
53
  }, [
54
- __props.loading ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$F)) : vue.createCommentVNode("", true),
55
- __props.icon ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$y, vue.toDisplayString(__props.icon), 1)) : vue.createCommentVNode("", true),
56
- vue.createElementVNode("span", _hoisted_4$r, [
54
+ __props.loading ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$G)) : vue.createCommentVNode("", true),
55
+ __props.icon ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$A, vue.toDisplayString(__props.icon), 1)) : vue.createCommentVNode("", true),
56
+ vue.createElementVNode("span", _hoisted_4$u, [
57
57
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
58
58
  ])
59
- ], 10, _hoisted_1$M);
59
+ ], 10, _hoisted_1$N);
60
60
  };
61
61
  }
62
62
  });
@@ -67,8 +67,8 @@
67
67
  }
68
68
  return target;
69
69
  };
70
- const TaoButton = /* @__PURE__ */ _export_sfc(_sfc_main$U, [["__scopeId", "data-v-c3034f66"]]);
71
- const _sfc_main$T = /* @__PURE__ */ vue.defineComponent({
70
+ const TaoButton = /* @__PURE__ */ _export_sfc(_sfc_main$V, [["__scopeId", "data-v-c3034f66"]]);
71
+ const _sfc_main$U = /* @__PURE__ */ vue.defineComponent({
72
72
  ...{ name: "TaoBlock" },
73
73
  __name: "TaoBlock",
74
74
  props: {
@@ -100,24 +100,24 @@
100
100
  };
101
101
  }
102
102
  });
103
- const TaoBlock = /* @__PURE__ */ _export_sfc(_sfc_main$T, [["__scopeId", "data-v-feb87e36"]]);
103
+ const TaoBlock = /* @__PURE__ */ _export_sfc(_sfc_main$U, [["__scopeId", "data-v-feb87e36"]]);
104
104
  const formFieldKey = Symbol("taoFormField");
105
- const _hoisted_1$L = { class: "tao-input-wrapper" };
106
- const _hoisted_2$E = ["for"];
107
- const _hoisted_3$x = {
105
+ const _hoisted_1$M = { class: "tao-input-wrapper" };
106
+ const _hoisted_2$F = ["for"];
107
+ const _hoisted_3$z = {
108
108
  key: 0,
109
109
  class: "tao-input__affix tao-input__affix--prefix"
110
110
  };
111
- const _hoisted_4$q = ["id", "type", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby"];
112
- const _hoisted_5$i = {
111
+ const _hoisted_4$t = ["id", "type", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby"];
112
+ const _hoisted_5$l = {
113
113
  key: 1,
114
114
  class: "tao-input__affix tao-input__affix--suffix"
115
115
  };
116
- const _hoisted_6$e = {
116
+ const _hoisted_6$g = {
117
117
  key: 1,
118
118
  class: "tao-input__error"
119
119
  };
120
- const _sfc_main$S = /* @__PURE__ */ vue.defineComponent({
120
+ const _sfc_main$T = /* @__PURE__ */ vue.defineComponent({
121
121
  ...{ name: "TaoInput" },
122
122
  __name: "TaoInput",
123
123
  props: {
@@ -153,12 +153,12 @@
153
153
  emit("focus", event);
154
154
  }
155
155
  return (_ctx, _cache) => {
156
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$L, [
156
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$M, [
157
157
  __props.label && !vue.unref(field) ? (vue.openBlock(), vue.createElementBlock("label", {
158
158
  key: 0,
159
159
  class: "tao-input__label",
160
160
  for: controlId.value
161
- }, vue.toDisplayString(__props.label), 9, _hoisted_2$E)) : vue.createCommentVNode("", true),
161
+ }, vue.toDisplayString(__props.label), 9, _hoisted_2$F)) : vue.createCommentVNode("", true),
162
162
  vue.createElementVNode("div", {
163
163
  class: vue.normalizeClass(["tao-input-shell", {
164
164
  "tao-input-shell--focused": focused.value,
@@ -168,7 +168,7 @@
168
168
  "tao-input-shell--suffix": _ctx.$slots.suffix
169
169
  }])
170
170
  }, [
171
- _ctx.$slots.prefix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$x, [
171
+ _ctx.$slots.prefix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$z, [
172
172
  vue.renderSlot(_ctx.$slots, "prefix", {}, void 0, true)
173
173
  ])) : vue.createCommentVNode("", true),
174
174
  vue.createElementVNode("input", {
@@ -183,27 +183,27 @@
183
183
  onInput: handleInput,
184
184
  onBlur: handleBlur,
185
185
  onFocus: handleFocus
186
- }, null, 42, _hoisted_4$q),
187
- _ctx.$slots.suffix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$i, [
186
+ }, null, 42, _hoisted_4$t),
187
+ _ctx.$slots.suffix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$l, [
188
188
  vue.renderSlot(_ctx.$slots, "suffix", {}, void 0, true)
189
189
  ])) : vue.createCommentVNode("", true)
190
190
  ], 2),
191
- __props.error && __props.errorMessage ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$e, vue.toDisplayString(__props.errorMessage), 1)) : vue.createCommentVNode("", true)
191
+ __props.error && __props.errorMessage ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$g, vue.toDisplayString(__props.errorMessage), 1)) : vue.createCommentVNode("", true)
192
192
  ]);
193
193
  };
194
194
  }
195
195
  });
196
- const TaoInput = /* @__PURE__ */ _export_sfc(_sfc_main$S, [["__scopeId", "data-v-b522e041"]]);
197
- const _hoisted_1$K = {
196
+ const TaoInput = /* @__PURE__ */ _export_sfc(_sfc_main$T, [["__scopeId", "data-v-b522e041"]]);
197
+ const _hoisted_1$L = {
198
198
  key: 0,
199
199
  class: "tao-input-group__addon tao-input-group__addon--before"
200
200
  };
201
- const _hoisted_2$D = { class: "tao-input-group__field" };
202
- const _hoisted_3$w = {
201
+ const _hoisted_2$E = { class: "tao-input-group__field" };
202
+ const _hoisted_3$y = {
203
203
  key: 1,
204
204
  class: "tao-input-group__addon tao-input-group__addon--after"
205
205
  };
206
- const _sfc_main$R = /* @__PURE__ */ vue.defineComponent({
206
+ const _sfc_main$S = /* @__PURE__ */ vue.defineComponent({
207
207
  ...{ name: "TaoInputGroup" },
208
208
  __name: "TaoInputGroup",
209
209
  setup(__props) {
@@ -225,28 +225,30 @@
225
225
  onFocusin: onFocusIn,
226
226
  onFocusout: onFocusOut
227
227
  }, [
228
- _ctx.$slots.before ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$K, [
228
+ _ctx.$slots.before ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$L, [
229
229
  vue.renderSlot(_ctx.$slots, "before", {}, void 0, true)
230
230
  ])) : vue.createCommentVNode("", true),
231
- vue.createElementVNode("div", _hoisted_2$D, [
231
+ vue.createElementVNode("div", _hoisted_2$E, [
232
232
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
233
233
  ]),
234
- _ctx.$slots.after ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$w, [
234
+ _ctx.$slots.after ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$y, [
235
235
  vue.renderSlot(_ctx.$slots, "after", {}, void 0, true)
236
236
  ])) : vue.createCommentVNode("", true)
237
237
  ], 34);
238
238
  };
239
239
  }
240
240
  });
241
- const TaoInputGroup = /* @__PURE__ */ _export_sfc(_sfc_main$R, [["__scopeId", "data-v-f06bb3b1"]]);
242
- const _hoisted_1$J = ["id", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
243
- const _hoisted_2$C = {
241
+ const TaoInputGroup = /* @__PURE__ */ _export_sfc(_sfc_main$S, [["__scopeId", "data-v-f06bb3b1"]]);
242
+ const _hoisted_1$K = ["id", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
243
+ const _hoisted_2$D = {
244
244
  key: 0,
245
245
  class: "tao-input-number__steppers"
246
246
  };
247
- const _hoisted_3$v = ["disabled"];
248
- const _hoisted_4$p = ["disabled"];
249
- const _sfc_main$Q = /* @__PURE__ */ vue.defineComponent({
247
+ const _hoisted_3$x = ["aria-label", "disabled"];
248
+ const _hoisted_4$s = { "aria-hidden": "true" };
249
+ const _hoisted_5$k = ["aria-label", "disabled"];
250
+ const _hoisted_6$f = { "aria-hidden": "true" };
251
+ const _sfc_main$R = /* @__PURE__ */ vue.defineComponent({
250
252
  ...{ name: "TaoInputNumber" },
251
253
  __name: "TaoInputNumber",
252
254
  props: {
@@ -257,7 +259,9 @@
257
259
  precision: {},
258
260
  disabled: { type: Boolean, default: false },
259
261
  placeholder: { default: "" },
260
- controls: { type: Boolean, default: true }
262
+ controls: { type: Boolean, default: true },
263
+ incrementLabel: { default: "Увеличить" },
264
+ decrementLabel: { default: "Уменьшить" }
261
265
  },
262
266
  emits: ["update:modelValue", "blur", "focus"],
263
267
  setup(__props, { emit: __emit }) {
@@ -395,34 +399,48 @@
395
399
  onFocus,
396
400
  onBlur,
397
401
  onKeydown
398
- }, null, 40, _hoisted_1$J),
399
- __props.controls ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$C, [
402
+ }, null, 40, _hoisted_1$K),
403
+ __props.controls ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$D, [
400
404
  vue.createElementVNode("button", {
401
405
  type: "button",
402
406
  class: "tao-input-number__step",
403
- "aria-label": "Увеличить",
407
+ "aria-label": __props.incrementLabel,
404
408
  tabindex: "-1",
405
409
  disabled: __props.disabled || atMax.value,
406
410
  onClick: _cache[0] || (_cache[0] = ($event) => bump(1))
407
- }, " + ", 8, _hoisted_3$v),
411
+ }, [
412
+ vue.createElementVNode("span", _hoisted_4$s, [
413
+ vue.renderSlot(_ctx.$slots, "increment-icon", {}, () => [
414
+ _cache[2] || (_cache[2] = vue.createTextVNode("+", -1))
415
+ ], true)
416
+ ])
417
+ ], 8, _hoisted_3$x),
408
418
  vue.createElementVNode("button", {
409
419
  type: "button",
410
420
  class: "tao-input-number__step",
411
- "aria-label": "Уменьшить",
421
+ "aria-label": __props.decrementLabel,
412
422
  tabindex: "-1",
413
423
  disabled: __props.disabled || atMin.value,
414
424
  onClick: _cache[1] || (_cache[1] = ($event) => bump(-1))
415
- }, " − ", 8, _hoisted_4$p)
425
+ }, [
426
+ vue.createElementVNode("span", _hoisted_6$f, [
427
+ vue.renderSlot(_ctx.$slots, "decrement-icon", {}, () => [
428
+ _cache[3] || (_cache[3] = vue.createTextVNode("−", -1))
429
+ ], true)
430
+ ])
431
+ ], 8, _hoisted_5$k)
416
432
  ])) : vue.createCommentVNode("", true)
417
433
  ], 2);
418
434
  };
419
435
  }
420
436
  });
421
- const TaoInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$Q, [["__scopeId", "data-v-55b65a4d"]]);
422
- const _hoisted_1$I = ["aria-label", "disabled"];
423
- const _hoisted_2$B = ["id", "value", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
424
- const _hoisted_3$u = ["disabled"];
425
- const _sfc_main$P = /* @__PURE__ */ vue.defineComponent({
437
+ const TaoInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$R, [["__scopeId", "data-v-331dd958"]]);
438
+ const _hoisted_1$J = ["aria-label", "disabled"];
439
+ const _hoisted_2$C = { "aria-hidden": "true" };
440
+ const _hoisted_3$w = ["id", "value", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
441
+ const _hoisted_4$r = ["aria-label", "disabled"];
442
+ const _hoisted_5$j = { "aria-hidden": "true" };
443
+ const _sfc_main$Q = /* @__PURE__ */ vue.defineComponent({
426
444
  ...{ name: "TaoQuantity" },
427
445
  __name: "TaoQuantity",
428
446
  props: {
@@ -431,7 +449,10 @@
431
449
  max: {},
432
450
  disabled: { type: Boolean, default: false },
433
451
  allowRemove: { type: Boolean, default: true },
434
- forceMaxLimit: { type: Boolean, default: true }
452
+ forceMaxLimit: { type: Boolean, default: true },
453
+ decrementLabel: { default: "Уменьшить" },
454
+ removeLabel: { default: "Убрать" },
455
+ incrementLabel: { default: "Увеличить" }
435
456
  },
436
457
  emits: ["update:modelValue", "change", "dec", "inc", "blur", "focus"],
437
458
  setup(__props, { emit: __emit }) {
@@ -540,7 +561,7 @@
540
561
  const atMax = vue.computed(() => props.modelValue >= ceiling.value);
541
562
  const minusDisabled = vue.computed(() => props.disabled || !props.allowRemove && atMin.value);
542
563
  const plusDisabled = vue.computed(() => props.disabled || atMax.value);
543
- const minusLabel = vue.computed(() => atMin.value && props.allowRemove ? "Убрать" : "Уменьшить");
564
+ const minusLabel = vue.computed(() => atMin.value && props.allowRemove ? props.removeLabel : props.decrementLabel);
544
565
  return (_ctx, _cache) => {
545
566
  return vue.openBlock(), vue.createElementBlock("div", {
546
567
  class: vue.normalizeClass(["tao-quantity", {
@@ -555,7 +576,13 @@
555
576
  "aria-label": minusLabel.value,
556
577
  disabled: minusDisabled.value,
557
578
  onClick: onDec
558
- }, " − ", 8, _hoisted_1$I),
579
+ }, [
580
+ vue.createElementVNode("span", _hoisted_2$C, [
581
+ vue.renderSlot(_ctx.$slots, "decrement-icon", {}, () => [
582
+ _cache[0] || (_cache[0] = vue.createTextVNode("−", -1))
583
+ ], true)
584
+ ])
585
+ ], 8, _hoisted_1$J),
559
586
  vue.createElementVNode("input", {
560
587
  id: controlId.value,
561
588
  class: "tao-quantity__input",
@@ -575,49 +602,55 @@
575
602
  onFocus,
576
603
  onBlur,
577
604
  onKeydown
578
- }, null, 40, _hoisted_2$B),
605
+ }, null, 40, _hoisted_3$w),
579
606
  vue.createElementVNode("button", {
580
607
  type: "button",
581
608
  class: "tao-quantity__btn tao-quantity__btn--inc",
582
- "aria-label": "Увеличить",
609
+ "aria-label": __props.incrementLabel,
583
610
  disabled: plusDisabled.value,
584
611
  onClick: onInc
585
- }, " + ", 8, _hoisted_3$u)
612
+ }, [
613
+ vue.createElementVNode("span", _hoisted_5$j, [
614
+ vue.renderSlot(_ctx.$slots, "increment-icon", {}, () => [
615
+ _cache[1] || (_cache[1] = vue.createTextVNode("+", -1))
616
+ ], true)
617
+ ])
618
+ ], 8, _hoisted_4$r)
586
619
  ], 2);
587
620
  };
588
621
  }
589
622
  });
590
- const TaoQuantity = /* @__PURE__ */ _export_sfc(_sfc_main$P, [["__scopeId", "data-v-df6baf04"]]);
591
- const _hoisted_1$H = {
623
+ const TaoQuantity = /* @__PURE__ */ _export_sfc(_sfc_main$Q, [["__scopeId", "data-v-c9c7c8b4"]]);
624
+ const _hoisted_1$I = {
592
625
  key: 0,
593
626
  class: "tao-card__cover"
594
627
  };
595
- const _hoisted_2$A = {
628
+ const _hoisted_2$B = {
596
629
  key: 0,
597
630
  class: "tao-card__header-title"
598
631
  };
599
- const _hoisted_3$t = { key: 0 };
600
- const _hoisted_4$o = {
632
+ const _hoisted_3$v = { key: 0 };
633
+ const _hoisted_4$q = {
601
634
  key: 2,
602
635
  class: "tao-card__title-block"
603
636
  };
604
- const _hoisted_5$h = {
637
+ const _hoisted_5$i = {
605
638
  key: 0,
606
639
  class: "tao-card__title"
607
640
  };
608
- const _hoisted_6$d = {
641
+ const _hoisted_6$e = {
609
642
  key: 1,
610
643
  class: "tao-card__sub"
611
644
  };
612
- const _hoisted_7$9 = {
645
+ const _hoisted_7$c = {
613
646
  key: 3,
614
647
  class: "tao-card__body"
615
648
  };
616
- const _hoisted_8$7 = {
649
+ const _hoisted_8$b = {
617
650
  key: 4,
618
651
  class: "tao-card__footer"
619
652
  };
620
- const _sfc_main$O = /* @__PURE__ */ vue.defineComponent({
653
+ const _sfc_main$P = /* @__PURE__ */ vue.defineComponent({
621
654
  ...{ name: "TaoCard" },
622
655
  __name: "TaoCard",
623
656
  props: {
@@ -649,14 +682,14 @@
649
682
  }]),
650
683
  style: vue.normalizeStyle(radiusStyle.value)
651
684
  }, [
652
- _ctx.$slots.cover ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$H, [
685
+ _ctx.$slots.cover ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$I, [
653
686
  vue.renderSlot(_ctx.$slots, "cover", {}, void 0, true)
654
687
  ])) : vue.createCommentVNode("", true),
655
688
  vue.createElementVNode("div", {
656
689
  class: "tao-card__content",
657
690
  style: vue.normalizeStyle(paddingStyle.value)
658
691
  }, [
659
- _ctx.$slots.headerTitle ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_2$A, [
692
+ _ctx.$slots.headerTitle ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_2$B, [
660
693
  vue.renderSlot(_ctx.$slots, "headerTitle", {}, void 0, true)
661
694
  ])) : vue.createCommentVNode("", true),
662
695
  _ctx.$slots.header || _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -666,22 +699,22 @@
666
699
  vue.createElementVNode("span", null, [
667
700
  vue.renderSlot(_ctx.$slots, "header", {}, void 0, true)
668
701
  ]),
669
- _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$t, [
702
+ _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$v, [
670
703
  vue.renderSlot(_ctx.$slots, "headerSecondary", {}, void 0, true)
671
704
  ])) : vue.createCommentVNode("", true)
672
705
  ], 2)) : vue.createCommentVNode("", true),
673
- _ctx.$slots.title || _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$o, [
674
- _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_5$h, [
706
+ _ctx.$slots.title || _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$q, [
707
+ _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_5$i, [
675
708
  vue.renderSlot(_ctx.$slots, "title", {}, void 0, true)
676
709
  ])) : vue.createCommentVNode("", true),
677
- _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$d, [
710
+ _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$e, [
678
711
  vue.renderSlot(_ctx.$slots, "sub", {}, void 0, true)
679
712
  ])) : vue.createCommentVNode("", true)
680
713
  ])) : vue.createCommentVNode("", true),
681
- _ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$9, [
714
+ _ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$c, [
682
715
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
683
716
  ])) : vue.createCommentVNode("", true),
684
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$7, [
717
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$b, [
685
718
  vue.renderSlot(_ctx.$slots, "footer", {}, void 0, true)
686
719
  ])) : vue.createCommentVNode("", true)
687
720
  ], 4)
@@ -689,7 +722,7 @@
689
722
  };
690
723
  }
691
724
  });
692
- const TaoCard = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["__scopeId", "data-v-2ff3d055"]]);
725
+ const TaoCard = /* @__PURE__ */ _export_sfc(_sfc_main$P, [["__scopeId", "data-v-2ff3d055"]]);
693
726
  const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
694
727
  function getFocusable(root) {
695
728
  return [...root.querySelectorAll(FOCUSABLE)].filter(
@@ -718,25 +751,53 @@
718
751
  first.focus();
719
752
  }
720
753
  }
721
- const _hoisted_1$G = ["aria-labelledby"];
722
- const _hoisted_2$z = {
754
+ let locks = 0;
755
+ let previousOverflow = "";
756
+ function isBrowser() {
757
+ return typeof document !== "undefined";
758
+ }
759
+ function lockBodyScroll() {
760
+ if (!isBrowser()) {
761
+ return;
762
+ }
763
+ if (locks === 0) {
764
+ previousOverflow = document.body.style.overflow;
765
+ document.body.style.overflow = "hidden";
766
+ }
767
+ locks += 1;
768
+ }
769
+ function unlockBodyScroll() {
770
+ if (!isBrowser() || locks === 0) {
771
+ return;
772
+ }
773
+ locks -= 1;
774
+ if (locks === 0) {
775
+ document.body.style.overflow = previousOverflow;
776
+ previousOverflow = "";
777
+ }
778
+ }
779
+ const _hoisted_1$H = ["aria-labelledby"];
780
+ const _hoisted_2$A = {
723
781
  key: 0,
724
782
  class: "tao-modal__header"
725
783
  };
726
- const _hoisted_3$s = ["id"];
727
- const _hoisted_4$n = { key: 1 };
728
- const _hoisted_5$g = { class: "tao-modal__content" };
729
- const _hoisted_6$c = {
784
+ const _hoisted_3$u = ["id"];
785
+ const _hoisted_4$p = { key: 1 };
786
+ const _hoisted_5$h = ["aria-label"];
787
+ const _hoisted_6$d = { "aria-hidden": "true" };
788
+ const _hoisted_7$b = { class: "tao-modal__content" };
789
+ const _hoisted_8$a = {
730
790
  key: 1,
731
791
  class: "tao-modal__footer"
732
792
  };
733
- const _sfc_main$N = /* @__PURE__ */ vue.defineComponent({
793
+ const _sfc_main$O = /* @__PURE__ */ vue.defineComponent({
734
794
  ...{ name: "TaoModal" },
735
795
  __name: "TaoModal",
736
796
  props: {
737
797
  modelValue: { type: Boolean },
738
798
  title: { default: "" },
739
- closable: { type: Boolean, default: true }
799
+ closable: { type: Boolean, default: true },
800
+ closeLabel: { default: "Закрыть" }
740
801
  },
741
802
  emits: ["update:modelValue", "close"],
742
803
  setup(__props, { emit: __emit }) {
@@ -744,9 +805,8 @@
744
805
  const emit = __emit;
745
806
  const panelRef = vue.ref(null);
746
807
  const titleId = vue.useId();
747
- let previousOverflow = "";
748
808
  let previousFocus = null;
749
- let scrollLocked = false;
809
+ let scrollHeld = false;
750
810
  function close() {
751
811
  if (!props.closable) {
752
812
  return;
@@ -754,21 +814,19 @@
754
814
  emit("update:modelValue", false);
755
815
  emit("close");
756
816
  }
757
- function lockBodyScroll() {
758
- if (scrollLocked) {
817
+ function holdScroll() {
818
+ if (scrollHeld || !isBrowser()) {
759
819
  return;
760
820
  }
761
- previousOverflow = document.body.style.overflow;
762
- document.body.style.overflow = "hidden";
763
- scrollLocked = true;
821
+ lockBodyScroll();
822
+ scrollHeld = true;
764
823
  }
765
- function unlockBodyScroll() {
766
- if (!scrollLocked) {
824
+ function releaseScroll() {
825
+ if (!scrollHeld) {
767
826
  return;
768
827
  }
769
- document.body.style.overflow = previousOverflow;
770
- previousOverflow = "";
771
- scrollLocked = false;
828
+ unlockBodyScroll();
829
+ scrollHeld = false;
772
830
  }
773
831
  function restoreFocus() {
774
832
  var _a;
@@ -786,6 +844,9 @@
786
844
  }
787
845
  function onKeydown(event) {
788
846
  if (event.key === "Escape") {
847
+ if (!props.closable) {
848
+ return;
849
+ }
789
850
  event.preventDefault();
790
851
  close();
791
852
  return;
@@ -797,19 +858,23 @@
797
858
  vue.watch(
798
859
  () => props.modelValue,
799
860
  (isOpen) => {
861
+ if (!isBrowser()) {
862
+ return;
863
+ }
800
864
  if (isOpen) {
801
865
  previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
802
- lockBodyScroll();
866
+ holdScroll();
803
867
  void focusPanel();
804
868
  return;
805
869
  }
806
- unlockBodyScroll();
870
+ releaseScroll();
807
871
  restoreFocus();
808
872
  },
809
873
  { immediate: true }
810
874
  );
811
875
  vue.onBeforeUnmount(() => {
812
- unlockBodyScroll();
876
+ releaseScroll();
877
+ restoreFocus();
813
878
  });
814
879
  return (_ctx, _cache) => {
815
880
  return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
@@ -830,29 +895,35 @@
830
895
  "aria-labelledby": __props.title ? vue.unref(titleId) : void 0,
831
896
  tabindex: "-1"
832
897
  }, [
833
- __props.title || _ctx.$slots.header || __props.closable ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$z, [
898
+ __props.title || _ctx.$slots.header || __props.closable ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$A, [
834
899
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
835
900
  __props.title ? (vue.openBlock(), vue.createElementBlock("h2", {
836
901
  key: 0,
837
902
  id: vue.unref(titleId),
838
903
  class: "tao-modal__title"
839
- }, vue.toDisplayString(__props.title), 9, _hoisted_3$s)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$n))
904
+ }, vue.toDisplayString(__props.title), 9, _hoisted_3$u)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$p))
840
905
  ], true),
841
906
  __props.closable ? (vue.openBlock(), vue.createElementBlock("button", {
842
907
  key: 0,
843
908
  type: "button",
844
909
  class: "tao-modal__close",
845
- "aria-label": "Закрыть",
910
+ "aria-label": __props.closeLabel,
846
911
  onClick: close
847
- }, " × ")) : vue.createCommentVNode("", true)
912
+ }, [
913
+ vue.createElementVNode("span", _hoisted_6$d, [
914
+ vue.renderSlot(_ctx.$slots, "close-icon", {}, () => [
915
+ _cache[0] || (_cache[0] = vue.createTextVNode("×", -1))
916
+ ], true)
917
+ ])
918
+ ], 8, _hoisted_5$h)) : vue.createCommentVNode("", true)
848
919
  ])) : vue.createCommentVNode("", true),
849
- vue.createElementVNode("div", _hoisted_5$g, [
920
+ vue.createElementVNode("div", _hoisted_7$b, [
850
921
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
851
922
  ]),
852
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$c, [
923
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$a, [
853
924
  vue.renderSlot(_ctx.$slots, "footer", {}, void 0, true)
854
925
  ])) : vue.createCommentVNode("", true)
855
- ], 8, _hoisted_1$G)
926
+ ], 8, _hoisted_1$H)
856
927
  ], 32)) : vue.createCommentVNode("", true)
857
928
  ]),
858
929
  _: 3
@@ -861,11 +932,11 @@
861
932
  };
862
933
  }
863
934
  });
864
- const TaoModal = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-0cffe849"]]);
865
- const _hoisted_1$F = { class: "tao-tabs" };
866
- const _hoisted_2$y = ["id", "aria-selected", "aria-controls", "tabindex", "disabled", "onClick"];
867
- const _hoisted_3$r = ["id", "aria-labelledby"];
868
- const _sfc_main$M = /* @__PURE__ */ vue.defineComponent({
935
+ const TaoModal = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["__scopeId", "data-v-102cfd66"]]);
936
+ const _hoisted_1$G = { class: "tao-tabs" };
937
+ const _hoisted_2$z = ["id", "aria-selected", "aria-controls", "tabindex", "disabled", "onClick"];
938
+ const _hoisted_3$t = ["id", "aria-labelledby"];
939
+ const _sfc_main$N = /* @__PURE__ */ vue.defineComponent({
869
940
  ...{ name: "TaoTabs" },
870
941
  __name: "TaoTabs",
871
942
  props: {
@@ -929,7 +1000,7 @@
929
1000
  }
930
1001
  }
931
1002
  return (_ctx, _cache) => {
932
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$F, [
1003
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$G, [
933
1004
  vue.createElementVNode("div", {
934
1005
  class: "tao-tabs__list",
935
1006
  role: "tablist",
@@ -954,7 +1025,7 @@
954
1025
  }, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
955
1026
  vue.createTextVNode(vue.toDisplayString(tab.label), 1)
956
1027
  ], 64))
957
- ], 8, _hoisted_2$y);
1028
+ ], 8, _hoisted_2$z);
958
1029
  }), 128))
959
1030
  ], 32),
960
1031
  vue.createElementVNode("div", {
@@ -964,12 +1035,12 @@
964
1035
  "aria-labelledby": tabId(__props.modelValue)
965
1036
  }, [
966
1037
  vue.renderSlot(_ctx.$slots, "default", { activeTab: __props.modelValue }, void 0, true)
967
- ], 8, _hoisted_3$r)
1038
+ ], 8, _hoisted_3$t)
968
1039
  ]);
969
1040
  };
970
1041
  }
971
1042
  });
972
- const TaoTabs = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-bf16735e"]]);
1043
+ const TaoTabs = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-bf16735e"]]);
973
1044
  function listenFocusLoss(onLoss) {
974
1045
  function onVisibilityChange() {
975
1046
  if (document.hidden) {
@@ -985,7 +1056,7 @@
985
1056
  window.removeEventListener("pagehide", onLoss);
986
1057
  };
987
1058
  }
988
- const _sfc_main$L = /* @__PURE__ */ vue.defineComponent({
1059
+ const _sfc_main$M = /* @__PURE__ */ vue.defineComponent({
989
1060
  ...{ name: "TaoTooltip" },
990
1061
  __name: "TaoTooltip",
991
1062
  props: {
@@ -1147,9 +1218,9 @@
1147
1218
  };
1148
1219
  }
1149
1220
  });
1150
- const TaoTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["__scopeId", "data-v-926dfa73"]]);
1151
- const _hoisted_1$E = { class: "tao-popover" };
1152
- const _sfc_main$K = /* @__PURE__ */ vue.defineComponent({
1221
+ const TaoTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-926dfa73"]]);
1222
+ const _hoisted_1$F = { class: "tao-popover" };
1223
+ const _sfc_main$L = /* @__PURE__ */ vue.defineComponent({
1153
1224
  ...{ name: "TaoPopover" },
1154
1225
  __name: "TaoPopover",
1155
1226
  props: {
@@ -1183,15 +1254,26 @@
1183
1254
  function close() {
1184
1255
  void applyOpen(false);
1185
1256
  }
1186
- async function applyOpen(next) {
1187
- var _a;
1188
- setOpen(next);
1189
- if (!next) {
1257
+ function bindDismiss() {
1258
+ if (typeof document === "undefined") {
1190
1259
  return;
1191
1260
  }
1192
- await vue.nextTick();
1193
- updatePosition();
1194
- (_a = panelRef.value) == null ? void 0 : _a.focus();
1261
+ document.addEventListener("pointerdown", onDocumentPointer);
1262
+ document.addEventListener("keydown", onDocumentKey);
1263
+ window.addEventListener("resize", onViewportChange);
1264
+ window.addEventListener("scroll", onViewportChange, true);
1265
+ }
1266
+ function unbindDismiss() {
1267
+ if (typeof document === "undefined") {
1268
+ return;
1269
+ }
1270
+ document.removeEventListener("pointerdown", onDocumentPointer);
1271
+ document.removeEventListener("keydown", onDocumentKey);
1272
+ window.removeEventListener("resize", onViewportChange);
1273
+ window.removeEventListener("scroll", onViewportChange, true);
1274
+ }
1275
+ function applyOpen(next) {
1276
+ setOpen(next);
1195
1277
  }
1196
1278
  function focusTrigger() {
1197
1279
  var _a, _b;
@@ -1204,7 +1286,7 @@
1204
1286
  function updatePosition() {
1205
1287
  const trigger = triggerRef.value;
1206
1288
  const panel = panelRef.value;
1207
- if (!trigger || !panel) {
1289
+ if (typeof window === "undefined" || !trigger || !panel) {
1208
1290
  return;
1209
1291
  }
1210
1292
  const rect = trigger.getBoundingClientRect();
@@ -1287,27 +1369,27 @@
1287
1369
  updatePosition();
1288
1370
  }
1289
1371
  }
1290
- vue.watch(open, (isOpen) => {
1291
- if (isOpen) {
1292
- document.addEventListener("pointerdown", onDocumentPointer);
1293
- document.addEventListener("keydown", onDocumentKey);
1294
- window.addEventListener("resize", onViewportChange);
1295
- window.addEventListener("scroll", onViewportChange, true);
1296
- return;
1297
- }
1298
- document.removeEventListener("pointerdown", onDocumentPointer);
1299
- document.removeEventListener("keydown", onDocumentKey);
1300
- window.removeEventListener("resize", onViewportChange);
1301
- window.removeEventListener("scroll", onViewportChange, true);
1302
- });
1372
+ vue.watch(
1373
+ open,
1374
+ (isOpen) => {
1375
+ if (isOpen) {
1376
+ bindDismiss();
1377
+ void vue.nextTick(() => {
1378
+ var _a;
1379
+ updatePosition();
1380
+ (_a = panelRef.value) == null ? void 0 : _a.focus();
1381
+ });
1382
+ return;
1383
+ }
1384
+ unbindDismiss();
1385
+ },
1386
+ { immediate: true }
1387
+ );
1303
1388
  vue.onBeforeUnmount(() => {
1304
- document.removeEventListener("pointerdown", onDocumentPointer);
1305
- document.removeEventListener("keydown", onDocumentKey);
1306
- window.removeEventListener("resize", onViewportChange);
1307
- window.removeEventListener("scroll", onViewportChange, true);
1389
+ unbindDismiss();
1308
1390
  });
1309
1391
  return (_ctx, _cache) => {
1310
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$E, [
1392
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$F, [
1311
1393
  vue.createElementVNode("div", {
1312
1394
  ref_key: "triggerRef",
1313
1395
  ref: triggerRef,
@@ -1336,17 +1418,17 @@
1336
1418
  };
1337
1419
  }
1338
1420
  });
1339
- const TaoPopover = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["__scopeId", "data-v-e4ead301"]]);
1421
+ const TaoPopover = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["__scopeId", "data-v-afd791a7"]]);
1340
1422
  const spoilerGroupKey = Symbol("taoSpoilerGroup");
1341
- const _hoisted_1$D = { class: "tao-spoiler" };
1342
- const _hoisted_2$x = ["aria-expanded", "aria-controls"];
1343
- const _hoisted_3$q = {
1423
+ const _hoisted_1$E = { class: "tao-spoiler" };
1424
+ const _hoisted_2$y = ["aria-expanded", "aria-controls"];
1425
+ const _hoisted_3$s = {
1344
1426
  key: 0,
1345
1427
  class: "tao-spoiler__title"
1346
1428
  };
1347
- const _hoisted_4$m = ["id"];
1348
- const _hoisted_5$f = { class: "tao-spoiler__content-inner" };
1349
- const _sfc_main$J = /* @__PURE__ */ vue.defineComponent({
1429
+ const _hoisted_4$o = ["id"];
1430
+ const _hoisted_5$g = { class: "tao-spoiler__content-inner" };
1431
+ const _sfc_main$K = /* @__PURE__ */ vue.defineComponent({
1350
1432
  ...{ name: "TaoSpoiler" },
1351
1433
  __name: "TaoSpoiler",
1352
1434
  props: {
@@ -1401,7 +1483,7 @@
1401
1483
  });
1402
1484
  }
1403
1485
  return (_ctx, _cache) => {
1404
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$D, [
1486
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$E, [
1405
1487
  vue.createElementVNode("button", {
1406
1488
  type: "button",
1407
1489
  class: "tao-spoiler__header",
@@ -1412,12 +1494,12 @@
1412
1494
  vue.createElementVNode("span", {
1413
1495
  class: vue.normalizeClass(["tao-spoiler__icon", { "tao-spoiler__icon--open": isOpen.value }])
1414
1496
  }, "▶", 2),
1415
- __props.title || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$q, [
1497
+ __props.title || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$s, [
1416
1498
  vue.renderSlot(_ctx.$slots, "title", {}, () => [
1417
1499
  vue.createTextVNode(vue.toDisplayString(__props.title), 1)
1418
1500
  ], true)
1419
1501
  ])) : vue.createCommentVNode("", true)
1420
- ], 8, _hoisted_2$x),
1502
+ ], 8, _hoisted_2$y),
1421
1503
  vue.createVNode(vue.Transition, {
1422
1504
  name: "tao-spoiler-slide",
1423
1505
  onBeforeEnter,
@@ -1431,10 +1513,10 @@
1431
1513
  id: vue.unref(panelId),
1432
1514
  class: "tao-spoiler__content"
1433
1515
  }, [
1434
- vue.createElementVNode("div", _hoisted_5$f, [
1516
+ vue.createElementVNode("div", _hoisted_5$g, [
1435
1517
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1436
1518
  ])
1437
- ], 8, _hoisted_4$m)) : vue.createCommentVNode("", true)
1519
+ ], 8, _hoisted_4$o)) : vue.createCommentVNode("", true)
1438
1520
  ]),
1439
1521
  _: 3
1440
1522
  })
@@ -1442,20 +1524,25 @@
1442
1524
  };
1443
1525
  }
1444
1526
  });
1445
- const TaoSpoiler = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["__scopeId", "data-v-ccb052cf"]]);
1446
- const _hoisted_1$C = { class: "tao-spoiler-group" };
1447
- const _sfc_main$I = /* @__PURE__ */ vue.defineComponent({
1527
+ const TaoSpoiler = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["__scopeId", "data-v-ccb052cf"]]);
1528
+ const _hoisted_1$D = { class: "tao-spoiler-group" };
1529
+ const _sfc_main$J = /* @__PURE__ */ vue.defineComponent({
1448
1530
  ...{ name: "TaoSpoilerGroup" },
1449
1531
  __name: "TaoSpoilerGroup",
1450
1532
  props: {
1451
- modelValue: { default: null }
1533
+ modelValue: {}
1452
1534
  },
1453
1535
  emits: ["update:modelValue", "change"],
1454
1536
  setup(__props, { emit: __emit }) {
1455
1537
  const props = __props;
1456
1538
  const emit = __emit;
1457
- const model = vue.computed(() => props.modelValue);
1539
+ const isControlled = vue.computed(() => props.modelValue !== void 0);
1540
+ const internal = vue.ref(null);
1541
+ const model = vue.computed(() => isControlled.value ? props.modelValue : internal.value);
1458
1542
  function setOpen(name) {
1543
+ if (!isControlled.value) {
1544
+ internal.value = name;
1545
+ }
1459
1546
  emit("update:modelValue", name);
1460
1547
  emit("change", name);
1461
1548
  }
@@ -1464,20 +1551,21 @@
1464
1551
  setOpen
1465
1552
  });
1466
1553
  return (_ctx, _cache) => {
1467
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$C, [
1554
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$D, [
1468
1555
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1469
1556
  ]);
1470
1557
  };
1471
1558
  }
1472
1559
  });
1473
- const TaoSpoilerGroup = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-6b172e89"]]);
1474
- const _hoisted_1$B = ["aria-label"];
1475
- const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
1560
+ const TaoSpoilerGroup = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["__scopeId", "data-v-118970dd"]]);
1561
+ const _hoisted_1$C = ["aria-label"];
1562
+ const _sfc_main$I = /* @__PURE__ */ vue.defineComponent({
1476
1563
  ...{ name: "TaoCopy" },
1477
1564
  __name: "TaoCopy",
1478
1565
  props: {
1479
1566
  text: {},
1480
1567
  successMessage: { default: "Скопировано!" },
1568
+ copyLabel: { default: "Копировать" },
1481
1569
  tip: { type: Boolean, default: true }
1482
1570
  },
1483
1571
  setup(__props) {
@@ -1579,7 +1667,7 @@
1579
1667
  vue.createElementVNode("button", {
1580
1668
  type: "button",
1581
1669
  class: vue.normalizeClass(["tao-copy__button", { "tao-copy__button--copied": copied.value }]),
1582
- "aria-label": copied.value ? __props.successMessage : "Копировать",
1670
+ "aria-label": copied.value ? __props.successMessage : __props.copyLabel,
1583
1671
  onClick: copy
1584
1672
  }, [..._cache[0] || (_cache[0] = [
1585
1673
  vue.createElementVNode("svg", {
@@ -1606,7 +1694,7 @@
1606
1694
  "stroke-width": "2"
1607
1695
  })
1608
1696
  ], -1)
1609
- ])], 10, _hoisted_1$B)
1697
+ ])], 10, _hoisted_1$C)
1610
1698
  ], true),
1611
1699
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
1612
1700
  copied.value && __props.tip && __props.successMessage ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -1622,8 +1710,8 @@
1622
1710
  };
1623
1711
  }
1624
1712
  });
1625
- const TaoCopy = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["__scopeId", "data-v-1953c07e"]]);
1626
- const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
1713
+ const TaoCopy = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-38d3381d"]]);
1714
+ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
1627
1715
  ...{ name: "TaoContainer" },
1628
1716
  __name: "TaoContainer",
1629
1717
  props: {
@@ -1640,8 +1728,8 @@
1640
1728
  };
1641
1729
  }
1642
1730
  });
1643
- const TaoContainer = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["__scopeId", "data-v-4c0deb90"]]);
1644
- const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
1731
+ const TaoContainer = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["__scopeId", "data-v-4c0deb90"]]);
1732
+ const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
1645
1733
  ...{ name: "TaoFlex" },
1646
1734
  __name: "TaoFlex",
1647
1735
  props: {
@@ -1672,7 +1760,7 @@
1672
1760
  };
1673
1761
  }
1674
1762
  });
1675
- const _sfc_main$E = /* @__PURE__ */ vue.defineComponent({
1763
+ const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
1676
1764
  ...{ name: "TaoSpace" },
1677
1765
  __name: "TaoSpace",
1678
1766
  props: {
@@ -1692,7 +1780,332 @@
1692
1780
  };
1693
1781
  }
1694
1782
  });
1695
- const TaoSpace = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-698ca712"]]);
1783
+ const TaoSpace = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-698ca712"]]);
1784
+ const _hoisted_1$B = { class: "tao-split__pane tao-split__pane--start" };
1785
+ const _hoisted_2$x = ["aria-orientation", "aria-valuemin", "aria-valuemax", "aria-valuenow", "aria-valuetext", "aria-disabled", "tabindex"];
1786
+ const _hoisted_3$r = { class: "tao-split__pane tao-split__pane--end" };
1787
+ const _hoisted_4$n = {
1788
+ key: 0,
1789
+ class: "tao-split__shield"
1790
+ };
1791
+ const _sfc_main$E = /* @__PURE__ */ vue.defineComponent({
1792
+ ...{ name: "TaoSplit" },
1793
+ __name: "TaoSplit",
1794
+ props: {
1795
+ modelValue: { default: 50 },
1796
+ direction: { default: "row" },
1797
+ unit: { default: "%" },
1798
+ min: { default: 0 },
1799
+ max: {},
1800
+ minEnd: { default: 0 },
1801
+ resizable: { type: Boolean, default: true },
1802
+ step: {}
1803
+ },
1804
+ emits: ["update:modelValue"],
1805
+ setup(__props, { emit: __emit }) {
1806
+ const props = __props;
1807
+ const emit = __emit;
1808
+ const rootRef = vue.ref(null);
1809
+ const handleRef = vue.ref(null);
1810
+ const startPx = vue.ref(0);
1811
+ const available = vue.ref(0);
1812
+ const isDragging = vue.ref(false);
1813
+ const size = vue.ref(props.modelValue);
1814
+ const isRow = vue.computed(() => props.direction === "row");
1815
+ const stepValue = vue.computed(() => props.step ?? (props.unit === "%" ? 1 : 8));
1816
+ const ariaOrientation = vue.computed(() => isRow.value ? "vertical" : "horizontal");
1817
+ let dragPointer = -1;
1818
+ let dragStartPx = 0;
1819
+ let dragStartCoord = 0;
1820
+ let savedBodyCursor = "";
1821
+ let savedHtmlCursor = "";
1822
+ let savedUserSelect = "";
1823
+ let resizeObserver = null;
1824
+ let stopFocusLoss;
1825
+ function axisSize(el) {
1826
+ const rect = el.getBoundingClientRect();
1827
+ return isRow.value ? rect.width : rect.height;
1828
+ }
1829
+ function measureAvailable() {
1830
+ if (!rootRef.value || !handleRef.value) {
1831
+ return 0;
1832
+ }
1833
+ return Math.max(0, axisSize(rootRef.value) - axisSize(handleRef.value));
1834
+ }
1835
+ function toPx(value, avail) {
1836
+ if (avail <= 0) {
1837
+ return 0;
1838
+ }
1839
+ return props.unit === "%" ? value / 100 * avail : value;
1840
+ }
1841
+ function fromPx(px, avail) {
1842
+ if (props.unit === "%") {
1843
+ if (avail <= 0) {
1844
+ return 0;
1845
+ }
1846
+ return Math.round(px / avail * 1e4) / 100;
1847
+ }
1848
+ return Math.round(px);
1849
+ }
1850
+ function valuesEqual(a, b) {
1851
+ if (props.unit === "%") {
1852
+ return Math.abs(a - b) < 5e-3;
1853
+ }
1854
+ return Math.round(a) === Math.round(b);
1855
+ }
1856
+ function clampStartPx(desiredPx, avail) {
1857
+ if (avail <= 0) {
1858
+ return 0;
1859
+ }
1860
+ const minStartPx = toPx(props.min, avail);
1861
+ const minEndPx = toPx(props.minEnd, avail);
1862
+ const maxStartPx = props.max != null ? toPx(props.max, avail) : Infinity;
1863
+ if (minStartPx + minEndPx > avail) {
1864
+ return Math.min(Math.max(desiredPx, 0), avail);
1865
+ }
1866
+ const lo = minStartPx;
1867
+ const hi = Math.min(maxStartPx, avail - minEndPx);
1868
+ return Math.min(Math.max(desiredPx, lo), Math.max(lo, hi));
1869
+ }
1870
+ function commit(next) {
1871
+ if (valuesEqual(next, size.value)) {
1872
+ size.value = next;
1873
+ return;
1874
+ }
1875
+ size.value = next;
1876
+ emit("update:modelValue", next);
1877
+ }
1878
+ function applyLayout(emitIfChanged) {
1879
+ const avail = measureAvailable();
1880
+ available.value = avail;
1881
+ const clamped = clampStartPx(toPx(size.value, avail), avail);
1882
+ startPx.value = clamped;
1883
+ const next = fromPx(clamped, avail);
1884
+ if (emitIfChanged) {
1885
+ commit(next);
1886
+ }
1887
+ }
1888
+ function isRtl() {
1889
+ return !!rootRef.value && getComputedStyle(rootRef.value).direction === "rtl";
1890
+ }
1891
+ function applyDragCursor() {
1892
+ savedBodyCursor = document.body.style.cursor;
1893
+ savedHtmlCursor = document.documentElement.style.cursor;
1894
+ savedUserSelect = document.body.style.userSelect;
1895
+ const cursor = isRow.value ? "col-resize" : "row-resize";
1896
+ document.body.style.cursor = cursor;
1897
+ document.documentElement.style.cursor = cursor;
1898
+ document.body.style.userSelect = "none";
1899
+ }
1900
+ function restoreDragCursor() {
1901
+ document.body.style.cursor = savedBodyCursor;
1902
+ document.documentElement.style.cursor = savedHtmlCursor;
1903
+ document.body.style.userSelect = savedUserSelect;
1904
+ }
1905
+ function releaseDragCapture() {
1906
+ const el = handleRef.value;
1907
+ const id = dragPointer;
1908
+ if (!el || id === -1) {
1909
+ return;
1910
+ }
1911
+ if (typeof el.hasPointerCapture === "function" && !el.hasPointerCapture(id)) {
1912
+ return;
1913
+ }
1914
+ try {
1915
+ el.releasePointerCapture(id);
1916
+ } catch {
1917
+ }
1918
+ }
1919
+ function endDrag() {
1920
+ if (!isDragging.value) {
1921
+ return;
1922
+ }
1923
+ isDragging.value = false;
1924
+ releaseDragCapture();
1925
+ dragPointer = -1;
1926
+ restoreDragCursor();
1927
+ applyLayout(true);
1928
+ }
1929
+ function setStartFromDelta(delta) {
1930
+ const avail = measureAvailable();
1931
+ available.value = avail;
1932
+ const nextPx = clampStartPx(dragStartPx + delta, avail);
1933
+ startPx.value = nextPx;
1934
+ commit(fromPx(nextPx, avail));
1935
+ }
1936
+ function onPointerDown(event) {
1937
+ if (!props.resizable || event.button !== 0 || !handleRef.value) {
1938
+ return;
1939
+ }
1940
+ dragPointer = event.pointerId;
1941
+ isDragging.value = true;
1942
+ dragStartPx = startPx.value;
1943
+ dragStartCoord = isRow.value ? event.clientX : event.clientY;
1944
+ applyDragCursor();
1945
+ event.preventDefault();
1946
+ try {
1947
+ handleRef.value.setPointerCapture(event.pointerId);
1948
+ } catch {
1949
+ }
1950
+ }
1951
+ function onPointerMove(event) {
1952
+ if (!isDragging.value || event.pointerId !== dragPointer) {
1953
+ return;
1954
+ }
1955
+ const coord = isRow.value ? event.clientX : event.clientY;
1956
+ let delta = coord - dragStartCoord;
1957
+ if (isRow.value && isRtl()) {
1958
+ delta = -delta;
1959
+ }
1960
+ setStartFromDelta(delta);
1961
+ }
1962
+ function onPointerEnd(event) {
1963
+ if (!isDragging.value) {
1964
+ return;
1965
+ }
1966
+ if (dragPointer !== -1 && event.pointerId !== dragPointer) {
1967
+ return;
1968
+ }
1969
+ endDrag();
1970
+ }
1971
+ function onLostPointerCapture() {
1972
+ endDrag();
1973
+ }
1974
+ function ariaMax() {
1975
+ const avail = available.value;
1976
+ if (avail <= 0) {
1977
+ return props.max ?? (props.unit === "%" ? 100 - props.minEnd : 0);
1978
+ }
1979
+ const maxByEnd = fromPx(Math.max(0, avail - toPx(props.minEnd, avail)), avail);
1980
+ if (props.max == null) {
1981
+ return maxByEnd;
1982
+ }
1983
+ return Math.min(props.max, maxByEnd);
1984
+ }
1985
+ const ariaValueMin = vue.computed(() => props.min);
1986
+ const ariaValueMax = vue.computed(() => ariaMax());
1987
+ const ariaValueNow = vue.computed(() => size.value);
1988
+ const ariaValueText = vue.computed(() => props.unit === "%" ? `${size.value}%` : `${Math.round(size.value)}px`);
1989
+ function onKeydown(event) {
1990
+ if (!props.resizable) {
1991
+ return;
1992
+ }
1993
+ const avail = measureAvailable();
1994
+ available.value = avail;
1995
+ if (event.key === "Home") {
1996
+ event.preventDefault();
1997
+ const nextPx2 = clampStartPx(toPx(props.min, avail), avail);
1998
+ startPx.value = nextPx2;
1999
+ commit(fromPx(nextPx2, avail));
2000
+ return;
2001
+ }
2002
+ if (event.key === "End") {
2003
+ event.preventDefault();
2004
+ const nextPx2 = clampStartPx(toPx(ariaMax(), avail), avail);
2005
+ startPx.value = nextPx2;
2006
+ commit(fromPx(nextPx2, avail));
2007
+ return;
2008
+ }
2009
+ const primary = isRow.value && (event.key === "ArrowLeft" || event.key === "ArrowRight") || !isRow.value && (event.key === "ArrowUp" || event.key === "ArrowDown");
2010
+ const secondary = isRow.value && (event.key === "ArrowUp" || event.key === "ArrowDown") || !isRow.value && (event.key === "ArrowLeft" || event.key === "ArrowRight");
2011
+ if (!primary && !secondary) {
2012
+ return;
2013
+ }
2014
+ event.preventDefault();
2015
+ let dir = event.key === "ArrowRight" || event.key === "ArrowDown" ? 1 : -1;
2016
+ if (isRow.value && isRtl() && (event.key === "ArrowLeft" || event.key === "ArrowRight")) {
2017
+ dir = -dir;
2018
+ }
2019
+ const nextModel = size.value + dir * stepValue.value;
2020
+ const nextPx = clampStartPx(toPx(nextModel, avail), avail);
2021
+ startPx.value = nextPx;
2022
+ commit(fromPx(nextPx, avail));
2023
+ }
2024
+ vue.watch(
2025
+ () => props.modelValue,
2026
+ (value) => {
2027
+ if (isDragging.value) {
2028
+ return;
2029
+ }
2030
+ if (!valuesEqual(value, size.value)) {
2031
+ size.value = value;
2032
+ applyLayout(false);
2033
+ }
2034
+ }
2035
+ );
2036
+ vue.watch(
2037
+ () => [props.unit, props.direction, props.min, props.max, props.minEnd, props.resizable],
2038
+ () => {
2039
+ if (!isDragging.value) {
2040
+ applyLayout(true);
2041
+ }
2042
+ }
2043
+ );
2044
+ vue.onMounted(() => {
2045
+ applyLayout(false);
2046
+ resizeObserver = new ResizeObserver(() => {
2047
+ if (isDragging.value) {
2048
+ return;
2049
+ }
2050
+ applyLayout(true);
2051
+ });
2052
+ if (rootRef.value) {
2053
+ resizeObserver.observe(rootRef.value);
2054
+ }
2055
+ stopFocusLoss = listenFocusLoss(endDrag);
2056
+ });
2057
+ vue.onBeforeUnmount(() => {
2058
+ endDrag();
2059
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
2060
+ resizeObserver = null;
2061
+ stopFocusLoss == null ? void 0 : stopFocusLoss();
2062
+ });
2063
+ return (_ctx, _cache) => {
2064
+ return vue.openBlock(), vue.createElementBlock("div", {
2065
+ ref_key: "rootRef",
2066
+ ref: rootRef,
2067
+ class: vue.normalizeClass(["tao-split", [
2068
+ `tao-split--${__props.direction}`,
2069
+ {
2070
+ "tao-split--fixed": !__props.resizable,
2071
+ "tao-split--dragging": isDragging.value
2072
+ }
2073
+ ]]),
2074
+ style: vue.normalizeStyle({ "--tao-split-start": `${startPx.value}px` })
2075
+ }, [
2076
+ vue.createElementVNode("div", _hoisted_1$B, [
2077
+ vue.renderSlot(_ctx.$slots, "start", {}, void 0, true)
2078
+ ]),
2079
+ vue.createElementVNode("div", {
2080
+ ref_key: "handleRef",
2081
+ ref: handleRef,
2082
+ class: "tao-split__handle",
2083
+ role: "separator",
2084
+ "aria-orientation": ariaOrientation.value,
2085
+ "aria-valuemin": ariaValueMin.value,
2086
+ "aria-valuemax": ariaValueMax.value,
2087
+ "aria-valuenow": ariaValueNow.value,
2088
+ "aria-valuetext": ariaValueText.value,
2089
+ "aria-disabled": __props.resizable ? void 0 : true,
2090
+ tabindex: __props.resizable ? 0 : -1,
2091
+ onPointerdown: onPointerDown,
2092
+ onPointermove: onPointerMove,
2093
+ onPointerup: onPointerEnd,
2094
+ onPointercancel: onPointerEnd,
2095
+ onLostpointercapture: onLostPointerCapture,
2096
+ onKeydown,
2097
+ onDragstart: _cache[0] || (_cache[0] = vue.withModifiers(() => {
2098
+ }, ["prevent"]))
2099
+ }, null, 40, _hoisted_2$x),
2100
+ vue.createElementVNode("div", _hoisted_3$r, [
2101
+ vue.renderSlot(_ctx.$slots, "end", {}, void 0, true)
2102
+ ]),
2103
+ isDragging.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$n)) : vue.createCommentVNode("", true)
2104
+ ], 6);
2105
+ };
2106
+ }
2107
+ });
2108
+ const TaoSplit = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-f44196dc"]]);
1696
2109
  const _hoisted_1$A = { class: "tao-icon" };
1697
2110
  const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
1698
2111
  ...{ name: "TaoIcon" },
@@ -1785,6 +2198,7 @@
1785
2198
  const TaoLoader = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-75a40018"]]);
1786
2199
  const _hoisted_1$z = { class: "tao-image" };
1787
2200
  const _hoisted_2$w = ["src", "alt", "loading"];
2201
+ const _hoisted_3$q = { class: "tao-image__placeholder" };
1788
2202
  const _sfc_main$B = /* @__PURE__ */ vue.defineComponent({
1789
2203
  ...{ name: "TaoImage" },
1790
2204
  __name: "TaoImage",
@@ -1792,27 +2206,32 @@
1792
2206
  src: { default: "" },
1793
2207
  alt: { default: "" },
1794
2208
  pixelated: { type: Boolean, default: false },
1795
- lazy: { type: Boolean, default: false }
2209
+ lazy: { type: Boolean, default: false },
2210
+ placeholderText: { default: "No image available" }
1796
2211
  },
1797
2212
  emits: ["load", "error"],
1798
2213
  setup(__props, { emit: __emit }) {
1799
2214
  const props = __props;
1800
2215
  const emit = __emit;
1801
2216
  const isLoaded = vue.ref(false);
2217
+ const hasError = vue.ref(false);
1802
2218
  function handleLoad() {
1803
2219
  isLoaded.value = true;
2220
+ hasError.value = false;
1804
2221
  emit("load");
1805
2222
  }
1806
2223
  function handleError() {
1807
2224
  isLoaded.value = false;
2225
+ hasError.value = true;
1808
2226
  emit("error");
1809
2227
  }
1810
2228
  vue.watch(() => props.src, () => {
1811
2229
  isLoaded.value = false;
2230
+ hasError.value = false;
1812
2231
  });
1813
2232
  return (_ctx, _cache) => {
1814
2233
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$z, [
1815
- __props.src ? (vue.openBlock(), vue.createElementBlock("img", {
2234
+ __props.src && !hasError.value ? (vue.openBlock(), vue.createElementBlock("img", {
1816
2235
  key: 0,
1817
2236
  class: vue.normalizeClass({ "tao-image__img--hidden": !isLoaded.value, "tao-image__img--pixelated": props.pixelated }),
1818
2237
  src: __props.src,
@@ -1822,21 +2241,22 @@
1822
2241
  draggable: "false",
1823
2242
  onLoad: handleLoad,
1824
2243
  onError: handleError
1825
- }, null, 42, _hoisted_2$w)) : vue.renderSlot(_ctx.$slots, "default", {}, () => [
1826
- _cache[0] || (_cache[0] = vue.createElementVNode("div", { class: "tao-image__placeholder" }, "No image available", -1))
1827
- ], true, 1)
2244
+ }, null, 42, _hoisted_2$w)) : vue.createCommentVNode("", true),
2245
+ !__props.src || hasError.value ? vue.renderSlot(_ctx.$slots, "default", {}, () => [
2246
+ vue.createElementVNode("div", _hoisted_3$q, vue.toDisplayString(__props.placeholderText), 1)
2247
+ ], true, 1) : vue.createCommentVNode("", true)
1828
2248
  ]);
1829
2249
  };
1830
2250
  }
1831
2251
  });
1832
- const TaoImage = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-522fe4da"]]);
2252
+ const TaoImage = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-aea39025"]]);
1833
2253
  const _hoisted_1$y = ["for"];
1834
2254
  const _hoisted_2$v = ["id", "checked", "disabled", "aria-checked", "aria-invalid", "aria-describedby"];
1835
2255
  const _hoisted_3$p = {
1836
2256
  key: 0,
1837
2257
  class: "tao-checkbox__label"
1838
2258
  };
1839
- const _hoisted_4$l = {
2259
+ const _hoisted_4$m = {
1840
2260
  key: 1,
1841
2261
  class: "tao-checkbox__label"
1842
2262
  };
@@ -1912,7 +2332,7 @@
1912
2332
  onChange: onInputChange
1913
2333
  }, null, 40, _hoisted_2$v),
1914
2334
  _cache[0] || (_cache[0] = vue.createElementVNode("span", { class: "tao-checkbox__box" }, null, -1)),
1915
- __props.label ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$p, vue.toDisplayString(__props.label), 1)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$l, [
2335
+ __props.label ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$p, vue.toDisplayString(__props.label), 1)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$m, [
1916
2336
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1917
2337
  ])),
1918
2338
  vue.renderSlot(_ctx.$slots, "post", { text: __props.label }, void 0, true)
@@ -1927,6 +2347,7 @@
1927
2347
  };
1928
2348
  const _hoisted_2$u = { class: "tao-tag__text" };
1929
2349
  const _hoisted_3$o = ["aria-label"];
2350
+ const _hoisted_4$l = { "aria-hidden": "true" };
1930
2351
  const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
1931
2352
  ...{ name: "TaoTag" },
1932
2353
  __name: "TaoTag",
@@ -1979,12 +2400,18 @@
1979
2400
  class: "tao-tag__close",
1980
2401
  "aria-label": __props.closeLabel,
1981
2402
  onClick: vue.withModifiers(onClose, ["stop"])
1982
- }, " ✕ ", 8, _hoisted_3$o)) : vue.createCommentVNode("", true)
2403
+ }, [
2404
+ vue.createElementVNode("span", _hoisted_4$l, [
2405
+ vue.renderSlot(_ctx.$slots, "close-icon", {}, () => [
2406
+ _cache[0] || (_cache[0] = vue.createTextVNode("✕", -1))
2407
+ ], true)
2408
+ ])
2409
+ ], 8, _hoisted_3$o)) : vue.createCommentVNode("", true)
1983
2410
  ], 6);
1984
2411
  };
1985
2412
  }
1986
2413
  });
1987
- const TaoTag = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-5bd7ca79"]]);
2414
+ const TaoTag = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-f353f529"]]);
1988
2415
  const _hoisted_1$w = {
1989
2416
  key: 1,
1990
2417
  class: "tao-divider-text"
@@ -2221,7 +2648,7 @@
2221
2648
  }
2222
2649
  });
2223
2650
  const TaoTextarea = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["__scopeId", "data-v-2534c0c4"]]);
2224
- const _hoisted_1$t = ["tabindex"];
2651
+ const _hoisted_1$t = ["tabindex", "aria-label"];
2225
2652
  const _hoisted_2$q = { class: "tao-scroll-top__content" };
2226
2653
  const RIPPLE_DURATION = 750;
2227
2654
  const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
@@ -2234,7 +2661,8 @@
2234
2661
  zIndex: { default: 1e3 },
2235
2662
  boundary: { default: 300 },
2236
2663
  hasOutline: { type: Boolean, default: true },
2237
- tabindex: { default: 0 }
2664
+ tabindex: { default: 0 },
2665
+ ariaLabel: { default: "Наверх" }
2238
2666
  },
2239
2667
  setup(__props) {
2240
2668
  const props = __props;
@@ -2321,7 +2749,7 @@
2321
2749
  style: vue.normalizeStyle(mainStyle),
2322
2750
  tabindex: props.tabindex,
2323
2751
  class: vue.normalizeClass(["tao-scroll-top", { "tao-scroll-top--no-outline": !props.hasOutline }]),
2324
- "aria-label": "Наверх",
2752
+ "aria-label": props.ariaLabel,
2325
2753
  onClick: vue.withModifiers(onClick, ["prevent"])
2326
2754
  }, [
2327
2755
  vue.createElementVNode("div", _hoisted_2$q, [
@@ -2348,7 +2776,7 @@
2348
2776
  };
2349
2777
  }
2350
2778
  });
2351
- const TaoScrollTop = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-ce902f42"]]);
2779
+ const TaoScrollTop = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-59678649"]]);
2352
2780
  const _hoisted_1$s = { class: "tao-progress" };
2353
2781
  const _hoisted_2$p = {
2354
2782
  key: 0,
@@ -2359,11 +2787,11 @@
2359
2787
  key: 0,
2360
2788
  class: "tao-progress__percentage"
2361
2789
  };
2362
- const _hoisted_5$e = {
2790
+ const _hoisted_5$f = {
2363
2791
  key: 1,
2364
2792
  class: "tao-progress__side"
2365
2793
  };
2366
- const _hoisted_6$b = {
2794
+ const _hoisted_6$c = {
2367
2795
  key: 0,
2368
2796
  class: "tao-progress__percentage"
2369
2797
  };
@@ -2418,9 +2846,9 @@
2418
2846
  }, null, 6)
2419
2847
  ], 4)
2420
2848
  ]),
2421
- _ctx.$slots.right || showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$e, [
2849
+ _ctx.$slots.right || showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$f, [
2422
2850
  vue.renderSlot(_ctx.$slots, "right", {}, void 0, true),
2423
- showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$b, vue.toDisplayString(endPercentLabel.value), 1)) : vue.createCommentVNode("", true)
2851
+ showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$c, vue.toDisplayString(endPercentLabel.value), 1)) : vue.createCommentVNode("", true)
2424
2852
  ])) : vue.createCommentVNode("", true)
2425
2853
  ], 6)
2426
2854
  ]);
@@ -2665,14 +3093,17 @@
2665
3093
  const TaoSlider = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["__scopeId", "data-v-24a38782"]]);
2666
3094
  const _hoisted_1$q = { class: "tao-file-drop" };
2667
3095
  const _hoisted_2$n = { class: "tao-file-drop__row" };
2668
- const _hoisted_3$j = ["accept", "multiple"];
2669
- const _hoisted_4$i = {
3096
+ const _hoisted_3$j = ["aria-label"];
3097
+ const _hoisted_4$i = { "aria-hidden": "true" };
3098
+ const _hoisted_5$e = ["accept", "multiple"];
3099
+ const _hoisted_6$b = {
2670
3100
  key: 0,
2671
3101
  class: "tao-file-drop__list"
2672
3102
  };
2673
- const _hoisted_5$d = { class: "tao-file-drop__name" };
2674
- const _hoisted_6$a = { class: "tao-file-drop__meta" };
2675
- const _hoisted_7$8 = ["aria-label", "onClick"];
3103
+ const _hoisted_7$a = { class: "tao-file-drop__name" };
3104
+ const _hoisted_8$9 = { class: "tao-file-drop__meta" };
3105
+ const _hoisted_9$4 = ["aria-label", "onClick"];
3106
+ const _hoisted_10$4 = { "aria-hidden": "true" };
2676
3107
  const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
2677
3108
  ...{ name: "TaoFileDrop" },
2678
3109
  __name: "TaoFileDrop",
@@ -2682,6 +3113,9 @@
2682
3113
  accept: { default: "*" },
2683
3114
  multiple: { type: Boolean, default: false },
2684
3115
  showClear: { type: Boolean, default: false },
3116
+ clearLabel: { default: "Очистить файлы" },
3117
+ removeLabel: { default: "Убрать «{name}»" },
3118
+ formatSize: {},
2685
3119
  list: { type: Boolean, default: true }
2686
3120
  },
2687
3121
  emits: ["update:modelValue", "files", "clear-request"],
@@ -2693,6 +3127,28 @@
2693
3127
  function sameFile(a, b) {
2694
3128
  return a.name === b.name && a.size === b.size && a.lastModified === b.lastModified;
2695
3129
  }
3130
+ function acceptTokens(accept) {
3131
+ return accept.split(",").map((token) => token.trim().toLowerCase()).filter(Boolean);
3132
+ }
3133
+ function fileMatchesAccept(file, accept) {
3134
+ const tokens = acceptTokens(accept);
3135
+ if (!tokens.length || tokens.includes("*") || tokens.includes("*/*")) {
3136
+ return true;
3137
+ }
3138
+ const name = file.name.toLowerCase();
3139
+ const mime = (file.type || "").toLowerCase();
3140
+ const dot = name.lastIndexOf(".");
3141
+ const ext = dot >= 0 ? name.slice(dot) : "";
3142
+ return tokens.some((token) => {
3143
+ if (token.startsWith(".")) {
3144
+ return ext === token;
3145
+ }
3146
+ if (token.endsWith("/*")) {
3147
+ return mime.startsWith(token.slice(0, -1));
3148
+ }
3149
+ return mime === token;
3150
+ });
3151
+ }
2696
3152
  function commit(files) {
2697
3153
  emit("update:modelValue", files);
2698
3154
  emit("files", files);
@@ -2725,9 +3181,17 @@
2725
3181
  function removeAt(index) {
2726
3182
  commit(props.modelValue.filter((_, item) => item !== index));
2727
3183
  }
3184
+ function resetInput() {
3185
+ const el = fileInput.value;
3186
+ if (el) {
3187
+ el.type = "text";
3188
+ el.type = "file";
3189
+ }
3190
+ }
2728
3191
  function processFiles(fileList) {
2729
- const incoming = Array.from(fileList);
3192
+ const incoming = Array.from(fileList).filter((file) => fileMatchesAccept(file, props.accept));
2730
3193
  if (!incoming.length) {
3194
+ resetInput();
2731
3195
  return;
2732
3196
  }
2733
3197
  let result;
@@ -2742,13 +3206,9 @@
2742
3206
  }
2743
3207
  }
2744
3208
  commit(result);
2745
- const el = fileInput.value;
2746
- if (el) {
2747
- el.type = "text";
2748
- el.type = "file";
2749
- }
3209
+ resetInput();
2750
3210
  }
2751
- function formatSize(bytes) {
3211
+ function defaultFormatSize(bytes) {
2752
3212
  if (bytes < 1024) {
2753
3213
  return `${bytes} Б`;
2754
3214
  }
@@ -2761,6 +3221,9 @@
2761
3221
  const value = mb < 10 ? mb.toFixed(1) : String(Math.round(mb));
2762
3222
  return `${value.replace(".", ",")} МБ`;
2763
3223
  }
3224
+ function sizeLabel(bytes) {
3225
+ return props.formatSize ? props.formatSize(bytes) : defaultFormatSize(bytes);
3226
+ }
2764
3227
  function fileKey(file, index) {
2765
3228
  return `${file.name}-${file.size}-${file.lastModified}-${index}`;
2766
3229
  }
@@ -2778,9 +3241,15 @@
2778
3241
  key: 0,
2779
3242
  type: "button",
2780
3243
  class: "tao-file-drop__clear",
2781
- "aria-label": "Очистить файлы",
3244
+ "aria-label": __props.clearLabel,
2782
3245
  onClick: requestClear
2783
- }, " ✕ ")) : vue.createCommentVNode("", true),
3246
+ }, [
3247
+ vue.createElementVNode("span", _hoisted_4$i, [
3248
+ vue.renderSlot(_ctx.$slots, "clear-icon", {}, () => [
3249
+ _cache[1] || (_cache[1] = vue.createTextVNode("✕", -1))
3250
+ ], true)
3251
+ ])
3252
+ ], 8, _hoisted_3$j)) : vue.createCommentVNode("", true),
2784
3253
  vue.createElementVNode("label", {
2785
3254
  class: vue.normalizeClass(["tao-file-drop__zone", [`tao-file-drop__zone--${__props.size}`, { "tao-file-drop__zone--dragging": isDragging.value }]]),
2786
3255
  onDragover: handleDragOver,
@@ -2788,7 +3257,7 @@
2788
3257
  onDrop: handleDrop
2789
3258
  }, [
2790
3259
  vue.renderSlot(_ctx.$slots, "default", {}, () => [
2791
- _cache[1] || (_cache[1] = vue.createTextVNode("Перетащите файл сюда или нажмите, чтобы выбрать", -1))
3260
+ _cache[2] || (_cache[2] = vue.createTextVNode("Перетащите файл сюда или нажмите, чтобы выбрать", -1))
2792
3261
  ], true),
2793
3262
  vue.createElementVNode("input", {
2794
3263
  ref_key: "fileInput",
@@ -2800,23 +3269,29 @@
2800
3269
  onChange: handleFileSelect,
2801
3270
  onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
2802
3271
  }, ["stop"]))
2803
- }, null, 40, _hoisted_3$j)
3272
+ }, null, 40, _hoisted_5$e)
2804
3273
  ], 34)
2805
3274
  ]),
2806
- __props.list && __props.modelValue.length ? (vue.openBlock(), vue.createElementBlock("ul", _hoisted_4$i, [
3275
+ __props.list && __props.modelValue.length ? (vue.openBlock(), vue.createElementBlock("ul", _hoisted_6$b, [
2807
3276
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.modelValue, (file, index) => {
2808
3277
  return vue.openBlock(), vue.createElementBlock("li", {
2809
3278
  key: fileKey(file, index),
2810
3279
  class: "tao-file-drop__file"
2811
3280
  }, [
2812
- vue.createElementVNode("span", _hoisted_5$d, vue.toDisplayString(file.name), 1),
2813
- vue.createElementVNode("span", _hoisted_6$a, vue.toDisplayString(formatSize(file.size)), 1),
3281
+ vue.createElementVNode("span", _hoisted_7$a, vue.toDisplayString(file.name), 1),
3282
+ vue.createElementVNode("span", _hoisted_8$9, vue.toDisplayString(sizeLabel(file.size)), 1),
2814
3283
  vue.createElementVNode("button", {
2815
3284
  type: "button",
2816
3285
  class: "tao-file-drop__remove",
2817
- "aria-label": `Убрать «${file.name}»`,
3286
+ "aria-label": __props.removeLabel.replace("{name}", file.name),
2818
3287
  onClick: ($event) => removeAt(index)
2819
- }, " ✕ ", 8, _hoisted_7$8)
3288
+ }, [
3289
+ vue.createElementVNode("span", _hoisted_10$4, [
3290
+ vue.renderSlot(_ctx.$slots, "remove-icon", {}, () => [
3291
+ _cache[3] || (_cache[3] = vue.createTextVNode("✕", -1))
3292
+ ], true)
3293
+ ])
3294
+ ], 8, _hoisted_9$4)
2820
3295
  ]);
2821
3296
  }), 128))
2822
3297
  ])) : vue.createCommentVNode("", true)
@@ -2824,11 +3299,11 @@
2824
3299
  };
2825
3300
  }
2826
3301
  });
2827
- const TaoFileDrop = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-f97c4e91"]]);
2828
- const _hoisted_1$p = ["aria-expanded"];
3302
+ const TaoFileDrop = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-4b36e2a3"]]);
3303
+ const _hoisted_1$p = ["aria-expanded", "aria-label"];
2829
3304
  const _hoisted_2$m = {
2830
3305
  key: 1,
2831
- "aria-label": "Меню"
3306
+ "aria-hidden": "true"
2832
3307
  };
2833
3308
  const _hoisted_3$i = ["onClick", "onMouseenter"];
2834
3309
  const _hoisted_4$h = { key: 1 };
@@ -2836,7 +3311,8 @@
2836
3311
  ...{ name: "TaoDropdownMenu" },
2837
3312
  __name: "TaoDropdownMenu",
2838
3313
  props: {
2839
- actions: { default: () => [] }
3314
+ actions: { default: () => [] },
3315
+ menuLabel: { default: "Меню" }
2840
3316
  },
2841
3317
  emits: ["selected"],
2842
3318
  setup(__props, { emit: __emit }) {
@@ -2965,9 +3441,14 @@
2965
3441
  class: "tao-dropdown-menu__button",
2966
3442
  "aria-haspopup": "menu",
2967
3443
  "aria-expanded": isOpen.value,
3444
+ "aria-label": _ctx.$slots.button ? void 0 : __props.menuLabel,
2968
3445
  onClick: toggleMenu
2969
3446
  }, [
2970
- _ctx.$slots.button ? vue.renderSlot(_ctx.$slots, "button", {}, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$m, "⋮"))
3447
+ _ctx.$slots.button ? vue.renderSlot(_ctx.$slots, "button", {}, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$m, [
3448
+ vue.renderSlot(_ctx.$slots, "icon", {}, () => [
3449
+ _cache[0] || (_cache[0] = vue.createTextVNode("⋮", -1))
3450
+ ], true)
3451
+ ]))
2971
3452
  ], 8, _hoisted_1$p),
2972
3453
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
2973
3454
  isOpen.value ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -3002,9 +3483,9 @@
3002
3483
  };
3003
3484
  }
3004
3485
  });
3005
- const TaoDropdownMenu = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-420a7e63"]]);
3486
+ const TaoDropdownMenu = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-4750fe54"]]);
3006
3487
  const _hoisted_1$o = ["aria-invalid", "aria-describedby"];
3007
- const _hoisted_2$l = ["id", "value", "placeholder", "type", "inputmode", "pattern", "onInput", "onKeydown", "onFocus"];
3488
+ const _hoisted_2$l = ["id", "value", "placeholder", "type", "inputmode", "pattern", "maxlength", "onInput", "onPaste", "onKeydown", "onFocus"];
3008
3489
  const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
3009
3490
  ...{ name: "TaoPinCode" },
3010
3491
  __name: "TaoPinCode",
@@ -3062,11 +3543,43 @@
3062
3543
  function isFilled() {
3063
3544
  return numbers.value.length === props.length && numbers.value.every((cell) => cell !== "");
3064
3545
  }
3546
+ function applyChars(index, raw) {
3547
+ var _a;
3548
+ const chars = [...raw].map((ch) => acceptChar(ch)).filter(Boolean);
3549
+ if (!chars.length) {
3550
+ return;
3551
+ }
3552
+ numbers.value = [...numbers.value];
3553
+ let cursor = index;
3554
+ for (const ch of chars) {
3555
+ if (cursor >= props.length) {
3556
+ break;
3557
+ }
3558
+ numbers.value[cursor] = ch;
3559
+ cursor += 1;
3560
+ }
3561
+ emitChange();
3562
+ if (isFilled()) {
3563
+ (_a = inputRefs.value[index]) == null ? void 0 : _a.blur();
3564
+ emit("complete", serialize());
3565
+ return;
3566
+ }
3567
+ if (cursor < props.length) {
3568
+ focusCell(cursor);
3569
+ }
3570
+ }
3065
3571
  function mutation(v, index) {
3066
3572
  var _a;
3067
- const char = v.length > 1 ? v[v.length - 1] ?? "" : v;
3068
- const next = acceptChar(char);
3069
- if (props.numbersOnly && char && !next) {
3573
+ if (v.length > 1) {
3574
+ applyChars(index, v);
3575
+ return;
3576
+ }
3577
+ const next = acceptChar(v);
3578
+ if (props.numbersOnly && v && !next) {
3579
+ const el = inputRefs.value[index];
3580
+ if (el) {
3581
+ el.value = numbers.value[index] ?? "";
3582
+ }
3070
3583
  return;
3071
3584
  }
3072
3585
  numbers.value = [...numbers.value];
@@ -3086,6 +3599,15 @@
3086
3599
  focusCell(target);
3087
3600
  }
3088
3601
  }
3602
+ function onPaste(event, index) {
3603
+ var _a;
3604
+ const text = ((_a = event.clipboardData) == null ? void 0 : _a.getData("text")) ?? "";
3605
+ if (!text) {
3606
+ return;
3607
+ }
3608
+ event.preventDefault();
3609
+ applyChars(index, text);
3610
+ }
3089
3611
  function onFocus(index) {
3090
3612
  if (props.clearOn === "input") {
3091
3613
  const firstEmpty = firstEmptyIndex();
@@ -3167,8 +3689,9 @@
3167
3689
  inputmode: __props.numbersOnly ? "numeric" : "text",
3168
3690
  pattern: __props.numbersOnly ? "[0-9]" : void 0,
3169
3691
  autocomplete: "one-time-code",
3170
- maxlength: "1",
3692
+ maxlength: index === 0 ? __props.length : 1,
3171
3693
  onInput: ($event) => onChange($event, index),
3694
+ onPaste: ($event) => onPaste($event, index),
3172
3695
  onKeydown: ($event) => onKeydown($event, index),
3173
3696
  onFocus: ($event) => onFocus(index),
3174
3697
  onBlur
@@ -3178,7 +3701,7 @@
3178
3701
  };
3179
3702
  }
3180
3703
  });
3181
- const TaoPinCode = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-c3182673"]]);
3704
+ const TaoPinCode = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-44474500"]]);
3182
3705
  const _sfc_main$o = /* @__PURE__ */ vue.defineComponent({
3183
3706
  ...{ name: "TaoLink" },
3184
3707
  __name: "TaoLink",
@@ -3235,6 +3758,7 @@
3235
3758
  const id = vue.useId();
3236
3759
  const hintId = `${id}-hint`;
3237
3760
  const errorId = `${id}-error`;
3761
+ const labelId = `${id}-label`;
3238
3762
  const invalid = vue.computed(() => Boolean(props.error));
3239
3763
  const describedBy = vue.computed(() => {
3240
3764
  if (props.error) {
@@ -3250,14 +3774,27 @@
3250
3774
  invalid,
3251
3775
  describedBy
3252
3776
  });
3777
+ function onLabelClick() {
3778
+ var _a, _b;
3779
+ const target = document.getElementById(id);
3780
+ if (target instanceof HTMLInputElement || target instanceof HTMLButtonElement || target instanceof HTMLSelectElement || target instanceof HTMLTextAreaElement) {
3781
+ return;
3782
+ }
3783
+ const scope = target ?? ((_a = document.getElementById(labelId)) == null ? void 0 : _a.parentElement);
3784
+ (_b = scope == null ? void 0 : scope.querySelector(
3785
+ "input:not([disabled]), button:not([disabled]), textarea:not([disabled]), select:not([disabled])"
3786
+ )) == null ? void 0 : _b.focus();
3787
+ }
3253
3788
  return (_ctx, _cache) => {
3254
3789
  return vue.openBlock(), vue.createElementBlock("div", {
3255
3790
  class: vue.normalizeClass(["tao-form-field", { "tao-form-field--invalid": invalid.value }])
3256
3791
  }, [
3257
3792
  __props.label ? (vue.openBlock(), vue.createElementBlock("label", {
3258
3793
  key: 0,
3794
+ id: labelId,
3259
3795
  class: "tao-form-field__label",
3260
- for: vue.unref(id)
3796
+ for: vue.unref(id),
3797
+ onClick: onLabelClick
3261
3798
  }, vue.toDisplayString(__props.label), 9, _hoisted_1$n)) : vue.createCommentVNode("", true),
3262
3799
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true),
3263
3800
  __props.error ? (vue.openBlock(), vue.createElementBlock("p", {
@@ -3273,7 +3810,7 @@
3273
3810
  };
3274
3811
  }
3275
3812
  });
3276
- const TaoFormField = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-11324f0c"]]);
3813
+ const TaoFormField = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-edd0be31"]]);
3277
3814
  const _hoisted_1$m = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
3278
3815
  const _hoisted_2$k = { class: "tao-select__value" };
3279
3816
  const _hoisted_3$h = ["aria-activedescendant"];
@@ -3286,7 +3823,8 @@
3286
3823
  options: { default: () => [] },
3287
3824
  placeholder: { default: "Выберите" },
3288
3825
  disabled: { type: Boolean, default: false },
3289
- error: { type: Boolean, default: false }
3826
+ error: { type: Boolean, default: false },
3827
+ clearText: { default: "Очистить" }
3290
3828
  },
3291
3829
  emits: ["update:modelValue", "change"],
3292
3830
  setup(__props, { emit: __emit }) {
@@ -3316,12 +3854,16 @@
3316
3854
  }
3317
3855
  const rect = trigger.getBoundingClientRect();
3318
3856
  const panelHeight = panel.offsetHeight;
3857
+ const panelWidth = panel.offsetWidth || rect.width;
3319
3858
  const gap = 4;
3859
+ const pad = 8;
3320
3860
  const spaceBelow = window.innerHeight - rect.bottom - gap;
3321
3861
  const openUp = spaceBelow < panelHeight && rect.top > spaceBelow;
3862
+ const maxLeft = Math.max(pad, window.innerWidth - panelWidth - pad);
3863
+ const left = Math.min(Math.max(rect.left, pad), maxLeft);
3322
3864
  listStyle.value = {
3323
3865
  top: `${openUp ? rect.top - panelHeight - gap : rect.bottom + gap}px`,
3324
- left: `${rect.left}px`,
3866
+ left: `${left}px`,
3325
3867
  width: `${rect.width}px`
3326
3868
  };
3327
3869
  }
@@ -3335,7 +3877,7 @@
3335
3877
  return;
3336
3878
  }
3337
3879
  const selectedIndex = props.options.findIndex((option) => option.value === props.modelValue);
3338
- activeIndex.value = selectedIndex >= 0 ? selectedIndex : enabledIndexes.value[0] ?? -1;
3880
+ activeIndex.value = selectedIndex >= 0 && enabledIndexes.value.includes(selectedIndex) ? selectedIndex : enabledIndexes.value[0] ?? -1;
3339
3881
  await vue.nextTick();
3340
3882
  updatePosition();
3341
3883
  (_a = listRef.value) == null ? void 0 : _a.focus();
@@ -3492,10 +4034,12 @@
3492
4034
  onKeydown: onTriggerKeydown
3493
4035
  }, [
3494
4036
  vue.createElementVNode("span", _hoisted_2$k, vue.toDisplayString(((_a = selected.value) == null ? void 0 : _a.label) ?? __props.placeholder), 1),
3495
- _cache[2] || (_cache[2] = vue.createElementVNode("span", {
3496
- class: "tao-select__chevron",
4037
+ vue.createElementVNode("span", {
4038
+ class: vue.normalizeClass(["tao-select__chevron", { "tao-select__chevron--custom": _ctx.$slots.chevron }]),
3497
4039
  "aria-hidden": "true"
3498
- }, null, -1))
4040
+ }, [
4041
+ vue.renderSlot(_ctx.$slots, "chevron", {}, void 0, true)
4042
+ ], 2)
3499
4043
  ], 42, _hoisted_1$m),
3500
4044
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3501
4045
  open.value ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -3542,14 +4086,18 @@
3542
4086
  onMousedown: _cache[1] || (_cache[1] = vue.withModifiers(() => {
3543
4087
  }, ["prevent"])),
3544
4088
  onClick: clear
3545
- }, " Очистить ", 32)) : vue.createCommentVNode("", true)
4089
+ }, [
4090
+ vue.renderSlot(_ctx.$slots, "clear", {}, () => [
4091
+ vue.createTextVNode(vue.toDisplayString(__props.clearText), 1)
4092
+ ], true)
4093
+ ], 32)) : vue.createCommentVNode("", true)
3546
4094
  ], 4)) : vue.createCommentVNode("", true)
3547
4095
  ]))
3548
4096
  ], 2);
3549
4097
  };
3550
4098
  }
3551
4099
  });
3552
- const TaoSelect = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["__scopeId", "data-v-42551757"]]);
4100
+ const TaoSelect = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["__scopeId", "data-v-d9b336d8"]]);
3553
4101
  const _hoisted_1$l = ["id", "aria-expanded", "aria-activedescendant", "aria-invalid", "aria-describedby", "disabled", "placeholder", "value"];
3554
4102
  const _hoisted_2$j = {
3555
4103
  key: 0,
@@ -3565,6 +4113,8 @@
3565
4113
  placeholder: { default: "Начните вводить" },
3566
4114
  disabled: { type: Boolean, default: false },
3567
4115
  error: { type: Boolean, default: false },
4116
+ emptyText: { default: "Ничего не найдено" },
4117
+ clearText: { default: "Очистить" },
3568
4118
  allowCreate: { type: Boolean, default: false }
3569
4119
  },
3570
4120
  emits: ["update:modelValue", "change", "create"],
@@ -3635,12 +4185,16 @@
3635
4185
  }
3636
4186
  const rect = trigger.getBoundingClientRect();
3637
4187
  const panelHeight = panel.offsetHeight;
4188
+ const panelWidth = panel.offsetWidth || rect.width;
3638
4189
  const gap = 4;
4190
+ const pad = 8;
3639
4191
  const spaceBelow = window.innerHeight - rect.bottom - gap;
3640
4192
  const openUp = spaceBelow < panelHeight && rect.top > spaceBelow;
4193
+ const maxLeft = Math.max(pad, window.innerWidth - panelWidth - pad);
4194
+ const left = Math.min(Math.max(rect.left, pad), maxLeft);
3641
4195
  listStyle.value = {
3642
4196
  top: `${openUp ? rect.top - panelHeight - gap : rect.bottom + gap}px`,
3643
- left: `${rect.left}px`,
4197
+ left: `${left}px`,
3644
4198
  width: `${rect.width}px`
3645
4199
  };
3646
4200
  }
@@ -3707,6 +4261,13 @@
3707
4261
  }
3708
4262
  commitCreated(value);
3709
4263
  }
4264
+ function clear() {
4265
+ var _a;
4266
+ emitValue(null);
4267
+ query.value = "";
4268
+ open.value = false;
4269
+ (_a = inputRef.value) == null ? void 0 : _a.focus();
4270
+ }
3710
4271
  function revertQuery() {
3711
4272
  syncQueryFromModel();
3712
4273
  }
@@ -3965,10 +4526,12 @@
3965
4526
  onBlur,
3966
4527
  onKeydown: onInputKeydown
3967
4528
  }, null, 40, _hoisted_1$l),
3968
- _cache[1] || (_cache[1] = vue.createElementVNode("span", {
3969
- class: "tao-combobox__chevron",
4529
+ vue.createElementVNode("span", {
4530
+ class: vue.normalizeClass(["tao-combobox__chevron", { "tao-combobox__chevron--custom": _ctx.$slots.chevron }]),
3970
4531
  "aria-hidden": "true"
3971
- }, null, -1))
4532
+ }, [
4533
+ vue.renderSlot(_ctx.$slots, "chevron", {}, void 0, true)
4534
+ ], 2)
3972
4535
  ], 544),
3973
4536
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3974
4537
  open.value ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -3985,7 +4548,11 @@
3985
4548
  class: "tao-combobox__list",
3986
4549
  role: "listbox"
3987
4550
  }, [
3988
- !rows.value.length ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_2$j, "Ничего не найдено")) : vue.createCommentVNode("", true),
4551
+ !rows.value.length ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_2$j, [
4552
+ vue.renderSlot(_ctx.$slots, "empty", {}, () => [
4553
+ vue.createTextVNode(vue.toDisplayString(__props.emptyText), 1)
4554
+ ], true)
4555
+ ])) : vue.createCommentVNode("", true),
3989
4556
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(rows.value, (row, index) => {
3990
4557
  return vue.openBlock(), vue.createElementBlock("li", {
3991
4558
  id: `${listId}-row-${index}`,
@@ -4004,9 +4571,11 @@
4004
4571
  onClick: ($event) => activateRow(row),
4005
4572
  onMouseenter: ($event) => !(row.kind === "option" && row.option.disabled) && (activeIndex.value = index)
4006
4573
  }, [
4007
- row.kind === "create" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
4574
+ row.kind === "create" ? vue.renderSlot(_ctx.$slots, "create", {
4575
+ text: row.text
4576
+ }, () => [
4008
4577
  vue.createTextVNode("Добавить «" + vue.toDisplayString(row.text) + "»", 1)
4009
- ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
4578
+ ], true, 0) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
4010
4579
  vue.createTextVNode(vue.toDisplayString(row.option.label), 1)
4011
4580
  ], 64))
4012
4581
  ], 42, _hoisted_3$g);
@@ -4016,15 +4585,20 @@
4016
4585
  key: 0,
4017
4586
  type: "button",
4018
4587
  class: "tao-combobox__clear",
4019
- onMousedown: vue.withModifiers(markPicking, ["prevent"])
4020
- }, " Очистить ", 32)) : vue.createCommentVNode("", true)
4588
+ onMousedown: vue.withModifiers(markPicking, ["prevent"]),
4589
+ onClick: clear
4590
+ }, [
4591
+ vue.renderSlot(_ctx.$slots, "clear", {}, () => [
4592
+ vue.createTextVNode(vue.toDisplayString(__props.clearText), 1)
4593
+ ], true)
4594
+ ], 32)) : vue.createCommentVNode("", true)
4021
4595
  ], 4)) : vue.createCommentVNode("", true)
4022
4596
  ]))
4023
4597
  ], 2);
4024
4598
  };
4025
4599
  }
4026
4600
  });
4027
- const TaoCombobox = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["__scopeId", "data-v-60be67d0"]]);
4601
+ const TaoCombobox = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["__scopeId", "data-v-131d254d"]]);
4028
4602
  const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
4029
4603
  function formatTaoDateIso(parts) {
4030
4604
  return `${String(parts.y).padStart(4, "0")}-${String(parts.m).padStart(2, "0")}-${String(parts.d).padStart(2, "0")}`;
@@ -4063,8 +4637,23 @@
4063
4637
  if (!parts) {
4064
4638
  return iso;
4065
4639
  }
4066
- const date = new Date(parts.y, parts.m - 1 + months, parts.d);
4067
- return formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() });
4640
+ const monthStart = new Date(parts.y, parts.m - 1 + months, 1);
4641
+ const y = monthStart.getFullYear();
4642
+ const m = monthStart.getMonth() + 1;
4643
+ const lastDay = new Date(y, m, 0).getDate();
4644
+ return formatTaoDateIso({ y, m, d: Math.min(parts.d, lastDay) });
4645
+ }
4646
+ function clampTaoDateCursor(iso, min, max) {
4647
+ if (isTaoDateInRange(iso, min, max)) {
4648
+ return iso;
4649
+ }
4650
+ if (min && parseTaoDate(min) && iso < min) {
4651
+ return min;
4652
+ }
4653
+ if (max && parseTaoDate(max) && iso > max) {
4654
+ return max;
4655
+ }
4656
+ return iso;
4068
4657
  }
4069
4658
  function isTaoDateInRange(iso, min, max) {
4070
4659
  if (!parseTaoDate(iso)) {
@@ -4154,20 +4743,28 @@
4154
4743
  }
4155
4744
  const _hoisted_1$k = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
4156
4745
  const _hoisted_2$i = { class: "tao-date__value" };
4157
- const _hoisted_3$f = ["aria-label"];
4158
- const _hoisted_4$f = { class: "tao-date__header" };
4159
- const _hoisted_5$c = { class: "tao-date__month" };
4160
- const _hoisted_6$9 = {
4746
+ const _hoisted_3$f = {
4747
+ class: "tao-date__icon",
4748
+ "aria-hidden": "true"
4749
+ };
4750
+ const _hoisted_4$f = ["aria-label"];
4751
+ const _hoisted_5$d = { class: "tao-date__header" };
4752
+ const _hoisted_6$a = ["aria-label"];
4753
+ const _hoisted_7$9 = { "aria-hidden": "true" };
4754
+ const _hoisted_8$8 = { class: "tao-date__month" };
4755
+ const _hoisted_9$3 = ["aria-label"];
4756
+ const _hoisted_10$3 = { "aria-hidden": "true" };
4757
+ const _hoisted_11$2 = {
4161
4758
  class: "tao-date__weekdays",
4162
4759
  "aria-hidden": "true"
4163
4760
  };
4164
- const _hoisted_7$7 = {
4761
+ const _hoisted_12$1 = {
4165
4762
  class: "tao-date__grid",
4166
4763
  role: "grid"
4167
4764
  };
4168
- const _hoisted_8$6 = ["aria-label", "aria-selected", "disabled", "onClick"];
4169
- const _hoisted_9$2 = { class: "tao-date__footer" };
4170
- const _hoisted_10$1 = ["disabled"];
4765
+ const _hoisted_13$1 = ["aria-label", "aria-selected", "disabled", "onClick"];
4766
+ const _hoisted_14$1 = { class: "tao-date__footer" };
4767
+ const _hoisted_15 = ["disabled"];
4171
4768
  const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
4172
4769
  ...{ name: "TaoDate" },
4173
4770
  __name: "TaoDate",
@@ -4178,7 +4775,11 @@
4178
4775
  error: { type: Boolean, default: false },
4179
4776
  min: { default: void 0 },
4180
4777
  max: { default: void 0 },
4181
- locale: { default: "ru-RU" }
4778
+ locale: { default: "ru-RU" },
4779
+ todayText: { default: "Сегодня" },
4780
+ clearText: { default: "Очистить" },
4781
+ prevMonthLabel: { default: "Предыдущий месяц" },
4782
+ nextMonthLabel: { default: "Следующий месяц" }
4182
4783
  },
4183
4784
  emits: ["update:modelValue", "change"],
4184
4785
  setup(__props, { emit: __emit }) {
@@ -4243,7 +4844,7 @@
4243
4844
  if (!next) {
4244
4845
  return;
4245
4846
  }
4246
- syncViewFrom(valueIso.value ?? todayIso.value);
4847
+ syncViewFrom(clampTaoDateCursor(valueIso.value ?? todayIso.value, props.min, props.max));
4247
4848
  await vue.nextTick();
4248
4849
  updatePosition();
4249
4850
  (_a = panelRef.value) == null ? void 0 : _a.focus();
@@ -4272,18 +4873,13 @@
4272
4873
  (_a = triggerRef.value) == null ? void 0 : _a.focus();
4273
4874
  }
4274
4875
  function goMonth(delta) {
4275
- const next = shiftTaoMonth(`${viewYear.value}-${String(viewMonth.value).padStart(2, "0")}-01`, delta);
4276
- const parts = parseTaoDate(next);
4277
- if (!parts) {
4278
- return;
4279
- }
4280
- viewYear.value = parts.y;
4281
- viewMonth.value = parts.m;
4282
- cursorIso.value = shiftTaoMonth(cursorIso.value, delta);
4876
+ cursorIso.value = clampTaoDateCursor(shiftTaoMonth(cursorIso.value, delta), props.min, props.max);
4877
+ syncViewFrom(cursorIso.value);
4283
4878
  void vue.nextTick(updatePosition);
4284
4879
  }
4285
4880
  function moveCursor(days) {
4286
- cursorIso.value = shiftTaoDate(cursorIso.value, days);
4881
+ const next = shiftTaoDate(cursorIso.value, days);
4882
+ cursorIso.value = isTaoDateInRange(next, props.min, props.max) ? next : clampTaoDateCursor(next, props.min, props.max);
4287
4883
  syncViewFrom(cursorIso.value);
4288
4884
  void vue.nextTick(updatePosition);
4289
4885
  }
@@ -4399,32 +4995,34 @@
4399
4995
  onKeydown: onTriggerKeydown
4400
4996
  }, [
4401
4997
  vue.createElementVNode("span", _hoisted_2$i, vue.toDisplayString(displayLabel.value || __props.placeholder), 1),
4402
- _cache[4] || (_cache[4] = vue.createElementVNode("svg", {
4403
- class: "tao-date__icon",
4404
- viewBox: "0 0 16 16",
4405
- width: "16",
4406
- height: "16",
4407
- "aria-hidden": "true",
4408
- focusable: "false"
4409
- }, [
4410
- vue.createElementVNode("rect", {
4411
- x: "2",
4412
- y: "3",
4413
- width: "12",
4414
- height: "11",
4415
- rx: "1.5",
4416
- fill: "none",
4417
- stroke: "currentColor",
4418
- "stroke-width": "1.4"
4419
- }),
4420
- vue.createElementVNode("path", {
4421
- d: "M5 1.5v3M11 1.5v3M2 6.5h12",
4422
- fill: "none",
4423
- stroke: "currentColor",
4424
- "stroke-width": "1.4",
4425
- "stroke-linecap": "round"
4426
- })
4427
- ], -1))
4998
+ vue.createElementVNode("span", _hoisted_3$f, [
4999
+ vue.renderSlot(_ctx.$slots, "icon", {}, () => [
5000
+ _cache[4] || (_cache[4] = vue.createElementVNode("svg", {
5001
+ viewBox: "0 0 16 16",
5002
+ width: "16",
5003
+ height: "16",
5004
+ focusable: "false"
5005
+ }, [
5006
+ vue.createElementVNode("rect", {
5007
+ x: "2",
5008
+ y: "3",
5009
+ width: "12",
5010
+ height: "11",
5011
+ rx: "1.5",
5012
+ fill: "none",
5013
+ stroke: "currentColor",
5014
+ "stroke-width": "1.4"
5015
+ }),
5016
+ vue.createElementVNode("path", {
5017
+ d: "M5 1.5v3M11 1.5v3M2 6.5h12",
5018
+ fill: "none",
5019
+ stroke: "currentColor",
5020
+ "stroke-width": "1.4",
5021
+ "stroke-linecap": "round"
5022
+ })
5023
+ ], -1))
5024
+ ], true)
5025
+ ])
4428
5026
  ], 42, _hoisted_1$k),
4429
5027
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4430
5028
  open.value ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -4439,61 +5037,67 @@
4439
5037
  style: vue.normalizeStyle(panelStyle.value),
4440
5038
  onKeydown: onPanelKeydown
4441
5039
  }, [
4442
- vue.createElementVNode("div", _hoisted_4$f, [
5040
+ vue.createElementVNode("div", _hoisted_5$d, [
4443
5041
  vue.createElementVNode("button", {
4444
5042
  type: "button",
4445
5043
  class: "tao-date__nav",
4446
- "aria-label": "Предыдущий месяц",
5044
+ "aria-label": __props.prevMonthLabel,
4447
5045
  onClick: _cache[0] || (_cache[0] = ($event) => goMonth(-1))
4448
- }, [..._cache[5] || (_cache[5] = [
4449
- vue.createElementVNode("svg", {
4450
- viewBox: "0 0 24 24",
4451
- width: "14",
4452
- height: "14",
4453
- "aria-hidden": "true",
4454
- focusable: "false"
4455
- }, [
4456
- vue.createElementVNode("path", {
4457
- fill: "none",
4458
- stroke: "currentColor",
4459
- "stroke-width": "2.2",
4460
- "stroke-linecap": "round",
4461
- "stroke-linejoin": "round",
4462
- d: "M14.5 5 8 12l6.5 7"
4463
- })
4464
- ], -1)
4465
- ])]),
4466
- vue.createElementVNode("p", _hoisted_5$c, vue.toDisplayString(monthLabel.value), 1),
5046
+ }, [
5047
+ vue.createElementVNode("span", _hoisted_7$9, [
5048
+ vue.renderSlot(_ctx.$slots, "prev-icon", {}, () => [
5049
+ _cache[5] || (_cache[5] = vue.createElementVNode("svg", {
5050
+ viewBox: "0 0 24 24",
5051
+ width: "14",
5052
+ height: "14",
5053
+ focusable: "false"
5054
+ }, [
5055
+ vue.createElementVNode("path", {
5056
+ fill: "none",
5057
+ stroke: "currentColor",
5058
+ "stroke-width": "2.2",
5059
+ "stroke-linecap": "round",
5060
+ "stroke-linejoin": "round",
5061
+ d: "M14.5 5 8 12l6.5 7"
5062
+ })
5063
+ ], -1))
5064
+ ], true)
5065
+ ])
5066
+ ], 8, _hoisted_6$a),
5067
+ vue.createElementVNode("p", _hoisted_8$8, vue.toDisplayString(monthLabel.value), 1),
4467
5068
  vue.createElementVNode("button", {
4468
5069
  type: "button",
4469
5070
  class: "tao-date__nav",
4470
- "aria-label": "Следующий месяц",
5071
+ "aria-label": __props.nextMonthLabel,
4471
5072
  onClick: _cache[1] || (_cache[1] = ($event) => goMonth(1))
4472
- }, [..._cache[6] || (_cache[6] = [
4473
- vue.createElementVNode("svg", {
4474
- viewBox: "0 0 24 24",
4475
- width: "14",
4476
- height: "14",
4477
- "aria-hidden": "true",
4478
- focusable: "false"
4479
- }, [
4480
- vue.createElementVNode("path", {
4481
- fill: "none",
4482
- stroke: "currentColor",
4483
- "stroke-width": "2.2",
4484
- "stroke-linecap": "round",
4485
- "stroke-linejoin": "round",
4486
- d: "M9.5 5 16 12l-6.5 7"
4487
- })
4488
- ], -1)
4489
- ])])
5073
+ }, [
5074
+ vue.createElementVNode("span", _hoisted_10$3, [
5075
+ vue.renderSlot(_ctx.$slots, "next-icon", {}, () => [
5076
+ _cache[6] || (_cache[6] = vue.createElementVNode("svg", {
5077
+ viewBox: "0 0 24 24",
5078
+ width: "14",
5079
+ height: "14",
5080
+ focusable: "false"
5081
+ }, [
5082
+ vue.createElementVNode("path", {
5083
+ fill: "none",
5084
+ stroke: "currentColor",
5085
+ "stroke-width": "2.2",
5086
+ "stroke-linecap": "round",
5087
+ "stroke-linejoin": "round",
5088
+ d: "M9.5 5 16 12l-6.5 7"
5089
+ })
5090
+ ], -1))
5091
+ ], true)
5092
+ ])
5093
+ ], 8, _hoisted_9$3)
4490
5094
  ]),
4491
- vue.createElementVNode("div", _hoisted_6$9, [
5095
+ vue.createElementVNode("div", _hoisted_11$2, [
4492
5096
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(weekdays.value, (day) => {
4493
5097
  return vue.openBlock(), vue.createElementBlock("span", { key: day }, vue.toDisplayString(day), 1);
4494
5098
  }), 128))
4495
5099
  ]),
4496
- vue.createElementVNode("div", _hoisted_7$7, [
5100
+ vue.createElementVNode("div", _hoisted_12$1, [
4497
5101
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(cells.value, (cell) => {
4498
5102
  return vue.openBlock(), vue.createElementBlock("button", {
4499
5103
  key: cell.iso,
@@ -4512,42 +5116,58 @@
4512
5116
  onMousedown: _cache[2] || (_cache[2] = vue.withModifiers(() => {
4513
5117
  }, ["prevent"])),
4514
5118
  onClick: ($event) => selectDay(cell.iso)
4515
- }, vue.toDisplayString(cell.day), 43, _hoisted_8$6);
5119
+ }, vue.toDisplayString(cell.day), 43, _hoisted_13$1);
4516
5120
  }), 128))
4517
5121
  ]),
4518
- vue.createElementVNode("div", _hoisted_9$2, [
5122
+ vue.createElementVNode("div", _hoisted_14$1, [
4519
5123
  vue.createElementVNode("button", {
4520
5124
  type: "button",
4521
5125
  class: "tao-date__link",
4522
5126
  disabled: !todayEnabled.value,
4523
5127
  onClick: _cache[3] || (_cache[3] = ($event) => selectDay(todayIso.value))
4524
- }, " Сегодня ", 8, _hoisted_10$1),
5128
+ }, [
5129
+ vue.renderSlot(_ctx.$slots, "today", {}, () => [
5130
+ vue.createTextVNode(vue.toDisplayString(__props.todayText), 1)
5131
+ ], true)
5132
+ ], 8, _hoisted_15),
4525
5133
  valueIso.value ? (vue.openBlock(), vue.createElementBlock("button", {
4526
5134
  key: 0,
4527
5135
  type: "button",
4528
5136
  class: "tao-date__link",
4529
5137
  onClick: clear
4530
- }, "Очистить")) : vue.createCommentVNode("", true)
5138
+ }, [
5139
+ vue.renderSlot(_ctx.$slots, "clear", {}, () => [
5140
+ vue.createTextVNode(vue.toDisplayString(__props.clearText), 1)
5141
+ ], true)
5142
+ ])) : vue.createCommentVNode("", true)
4531
5143
  ])
4532
- ], 44, _hoisted_3$f)) : vue.createCommentVNode("", true)
5144
+ ], 44, _hoisted_4$f)) : vue.createCommentVNode("", true)
4533
5145
  ]))
4534
5146
  ], 2);
4535
5147
  };
4536
5148
  }
4537
5149
  });
4538
- const TaoDate = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-f4a9cddd"]]);
5150
+ const TaoDate = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-ebd437a8"]]);
4539
5151
  const _hoisted_1$j = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
4540
5152
  const _hoisted_2$h = { class: "tao-date-range__value" };
4541
- const _hoisted_3$e = ["aria-label"];
4542
- const _hoisted_4$e = { class: "tao-date__header" };
4543
- const _hoisted_5$b = { class: "tao-date__month" };
4544
- const _hoisted_6$8 = {
5153
+ const _hoisted_3$e = {
5154
+ class: "tao-date-range__icon",
5155
+ "aria-hidden": "true"
5156
+ };
5157
+ const _hoisted_4$e = ["aria-label"];
5158
+ const _hoisted_5$c = { class: "tao-date__header" };
5159
+ const _hoisted_6$9 = ["aria-label"];
5160
+ const _hoisted_7$8 = { "aria-hidden": "true" };
5161
+ const _hoisted_8$7 = { class: "tao-date__month" };
5162
+ const _hoisted_9$2 = ["aria-label"];
5163
+ const _hoisted_10$2 = { "aria-hidden": "true" };
5164
+ const _hoisted_11$1 = {
4545
5165
  class: "tao-date__weekdays",
4546
5166
  "aria-hidden": "true"
4547
5167
  };
4548
- const _hoisted_7$6 = ["aria-label", "aria-selected", "disabled", "onMouseenter", "onClick"];
4549
- const _hoisted_8$5 = { class: "tao-date__footer" };
4550
- const _hoisted_9$1 = ["disabled"];
5168
+ const _hoisted_12 = ["aria-label", "aria-selected", "disabled", "onMouseenter", "onClick"];
5169
+ const _hoisted_13 = { class: "tao-date__footer" };
5170
+ const _hoisted_14 = ["disabled"];
4551
5171
  const _sfc_main$j = /* @__PURE__ */ vue.defineComponent({
4552
5172
  ...{ name: "TaoDateRange" },
4553
5173
  __name: "TaoDateRange",
@@ -4558,7 +5178,11 @@
4558
5178
  error: { type: Boolean, default: false },
4559
5179
  min: { default: void 0 },
4560
5180
  max: { default: void 0 },
4561
- locale: { default: "ru-RU" }
5181
+ locale: { default: "ru-RU" },
5182
+ todayText: { default: "Сегодня" },
5183
+ clearText: { default: "Очистить" },
5184
+ prevMonthLabel: { default: "Предыдущий месяц" },
5185
+ nextMonthLabel: { default: "Следующий месяц" }
4562
5186
  },
4563
5187
  emits: ["update:modelValue", "change"],
4564
5188
  setup(__props, { emit: __emit }) {
@@ -4638,7 +5262,7 @@
4638
5262
  }
4639
5263
  draftStart.value = null;
4640
5264
  hoverIso.value = null;
4641
- syncViewFrom(((_a = committed.value) == null ? void 0 : _a.start) ?? todayIso.value);
5265
+ syncViewFrom(clampTaoDateCursor(((_a = committed.value) == null ? void 0 : _a.start) ?? todayIso.value, props.min, props.max));
4642
5266
  await vue.nextTick();
4643
5267
  updatePosition();
4644
5268
  (_b = panelRef.value) == null ? void 0 : _b.focus();
@@ -4687,19 +5311,14 @@
4687
5311
  }
4688
5312
  function goMonth(delta) {
4689
5313
  hoverIso.value = null;
4690
- const next = shiftTaoMonth(`${viewYear.value}-${String(viewMonth.value).padStart(2, "0")}-01`, delta);
4691
- const parts = parseTaoDate(next);
4692
- if (!parts) {
4693
- return;
4694
- }
4695
- viewYear.value = parts.y;
4696
- viewMonth.value = parts.m;
4697
- cursorIso.value = shiftTaoMonth(cursorIso.value, delta);
5314
+ cursorIso.value = clampTaoDateCursor(shiftTaoMonth(cursorIso.value, delta), props.min, props.max);
5315
+ syncViewFrom(cursorIso.value);
4698
5316
  void vue.nextTick(updatePosition);
4699
5317
  }
4700
5318
  function moveCursor(days) {
4701
5319
  hoverIso.value = null;
4702
- cursorIso.value = shiftTaoDate(cursorIso.value, days);
5320
+ const next = shiftTaoDate(cursorIso.value, days);
5321
+ cursorIso.value = isTaoDateInRange(next, props.min, props.max) ? next : clampTaoDateCursor(next, props.min, props.max);
4703
5322
  syncViewFrom(cursorIso.value);
4704
5323
  void vue.nextTick(updatePosition);
4705
5324
  }
@@ -4833,32 +5452,34 @@
4833
5452
  onKeydown: onTriggerKeydown
4834
5453
  }, [
4835
5454
  vue.createElementVNode("span", _hoisted_2$h, vue.toDisplayString(displayLabel.value || __props.placeholder), 1),
4836
- _cache[3] || (_cache[3] = vue.createElementVNode("svg", {
4837
- class: "tao-date-range__icon",
4838
- viewBox: "0 0 16 16",
4839
- width: "16",
4840
- height: "16",
4841
- "aria-hidden": "true",
4842
- focusable: "false"
4843
- }, [
4844
- vue.createElementVNode("rect", {
4845
- x: "2",
4846
- y: "3",
4847
- width: "12",
4848
- height: "11",
4849
- rx: "1.5",
4850
- fill: "none",
4851
- stroke: "currentColor",
4852
- "stroke-width": "1.4"
4853
- }),
4854
- vue.createElementVNode("path", {
4855
- d: "M5 1.5v3M11 1.5v3M2 6.5h12",
4856
- fill: "none",
4857
- stroke: "currentColor",
4858
- "stroke-width": "1.4",
4859
- "stroke-linecap": "round"
4860
- })
4861
- ], -1))
5455
+ vue.createElementVNode("span", _hoisted_3$e, [
5456
+ vue.renderSlot(_ctx.$slots, "icon", {}, () => [
5457
+ _cache[3] || (_cache[3] = vue.createElementVNode("svg", {
5458
+ viewBox: "0 0 16 16",
5459
+ width: "16",
5460
+ height: "16",
5461
+ focusable: "false"
5462
+ }, [
5463
+ vue.createElementVNode("rect", {
5464
+ x: "2",
5465
+ y: "3",
5466
+ width: "12",
5467
+ height: "11",
5468
+ rx: "1.5",
5469
+ fill: "none",
5470
+ stroke: "currentColor",
5471
+ "stroke-width": "1.4"
5472
+ }),
5473
+ vue.createElementVNode("path", {
5474
+ d: "M5 1.5v3M11 1.5v3M2 6.5h12",
5475
+ fill: "none",
5476
+ stroke: "currentColor",
5477
+ "stroke-width": "1.4",
5478
+ "stroke-linecap": "round"
5479
+ })
5480
+ ], -1))
5481
+ ], true)
5482
+ ])
4862
5483
  ], 42, _hoisted_1$j),
4863
5484
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4864
5485
  open.value ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -4873,56 +5494,62 @@
4873
5494
  style: vue.normalizeStyle(panelStyle.value),
4874
5495
  onKeydown: onPanelKeydown
4875
5496
  }, [
4876
- vue.createElementVNode("div", _hoisted_4$e, [
5497
+ vue.createElementVNode("div", _hoisted_5$c, [
4877
5498
  vue.createElementVNode("button", {
4878
5499
  type: "button",
4879
5500
  class: "tao-date__nav",
4880
- "aria-label": "Предыдущий месяц",
5501
+ "aria-label": __props.prevMonthLabel,
4881
5502
  onClick: _cache[0] || (_cache[0] = ($event) => goMonth(-1))
4882
- }, [..._cache[4] || (_cache[4] = [
4883
- vue.createElementVNode("svg", {
4884
- viewBox: "0 0 24 24",
4885
- width: "14",
4886
- height: "14",
4887
- "aria-hidden": "true",
4888
- focusable: "false"
4889
- }, [
4890
- vue.createElementVNode("path", {
4891
- fill: "none",
4892
- stroke: "currentColor",
4893
- "stroke-width": "2.2",
4894
- "stroke-linecap": "round",
4895
- "stroke-linejoin": "round",
4896
- d: "M14.5 5 8 12l6.5 7"
4897
- })
4898
- ], -1)
4899
- ])]),
4900
- vue.createElementVNode("p", _hoisted_5$b, vue.toDisplayString(monthLabel.value), 1),
5503
+ }, [
5504
+ vue.createElementVNode("span", _hoisted_7$8, [
5505
+ vue.renderSlot(_ctx.$slots, "prev-icon", {}, () => [
5506
+ _cache[4] || (_cache[4] = vue.createElementVNode("svg", {
5507
+ viewBox: "0 0 24 24",
5508
+ width: "14",
5509
+ height: "14",
5510
+ focusable: "false"
5511
+ }, [
5512
+ vue.createElementVNode("path", {
5513
+ fill: "none",
5514
+ stroke: "currentColor",
5515
+ "stroke-width": "2.2",
5516
+ "stroke-linecap": "round",
5517
+ "stroke-linejoin": "round",
5518
+ d: "M14.5 5 8 12l6.5 7"
5519
+ })
5520
+ ], -1))
5521
+ ], true)
5522
+ ])
5523
+ ], 8, _hoisted_6$9),
5524
+ vue.createElementVNode("p", _hoisted_8$7, vue.toDisplayString(monthLabel.value), 1),
4901
5525
  vue.createElementVNode("button", {
4902
5526
  type: "button",
4903
5527
  class: "tao-date__nav",
4904
- "aria-label": "Следующий месяц",
5528
+ "aria-label": __props.nextMonthLabel,
4905
5529
  onClick: _cache[1] || (_cache[1] = ($event) => goMonth(1))
4906
- }, [..._cache[5] || (_cache[5] = [
4907
- vue.createElementVNode("svg", {
4908
- viewBox: "0 0 24 24",
4909
- width: "14",
4910
- height: "14",
4911
- "aria-hidden": "true",
4912
- focusable: "false"
4913
- }, [
4914
- vue.createElementVNode("path", {
4915
- fill: "none",
4916
- stroke: "currentColor",
4917
- "stroke-width": "2.2",
4918
- "stroke-linecap": "round",
4919
- "stroke-linejoin": "round",
4920
- d: "M9.5 5 16 12l-6.5 7"
4921
- })
4922
- ], -1)
4923
- ])])
5530
+ }, [
5531
+ vue.createElementVNode("span", _hoisted_10$2, [
5532
+ vue.renderSlot(_ctx.$slots, "next-icon", {}, () => [
5533
+ _cache[5] || (_cache[5] = vue.createElementVNode("svg", {
5534
+ viewBox: "0 0 24 24",
5535
+ width: "14",
5536
+ height: "14",
5537
+ focusable: "false"
5538
+ }, [
5539
+ vue.createElementVNode("path", {
5540
+ fill: "none",
5541
+ stroke: "currentColor",
5542
+ "stroke-width": "2.2",
5543
+ "stroke-linecap": "round",
5544
+ "stroke-linejoin": "round",
5545
+ d: "M9.5 5 16 12l-6.5 7"
5546
+ })
5547
+ ], -1))
5548
+ ], true)
5549
+ ])
5550
+ ], 8, _hoisted_9$2)
4924
5551
  ]),
4925
- vue.createElementVNode("div", _hoisted_6$8, [
5552
+ vue.createElementVNode("div", _hoisted_11$1, [
4926
5553
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(weekdays.value, (day) => {
4927
5554
  return vue.openBlock(), vue.createElementBlock("span", { key: day }, vue.toDisplayString(day), 1);
4928
5555
  }), 128))
@@ -4955,32 +5582,40 @@
4955
5582
  }, ["prevent"])),
4956
5583
  onMouseenter: ($event) => onDayEnter(cell.iso),
4957
5584
  onClick: ($event) => selectDay(cell.iso)
4958
- }, vue.toDisplayString(cell.day), 43, _hoisted_7$6);
5585
+ }, vue.toDisplayString(cell.day), 43, _hoisted_12);
4959
5586
  }), 128))
4960
5587
  ], 32),
4961
- vue.createElementVNode("div", _hoisted_8$5, [
5588
+ vue.createElementVNode("div", _hoisted_13, [
4962
5589
  vue.createElementVNode("button", {
4963
5590
  type: "button",
4964
5591
  class: "tao-date__link",
4965
5592
  disabled: !todayEnabled.value,
4966
5593
  onClick: selectToday
4967
- }, " Сегодня ", 8, _hoisted_9$1),
5594
+ }, [
5595
+ vue.renderSlot(_ctx.$slots, "today", {}, () => [
5596
+ vue.createTextVNode(vue.toDisplayString(__props.todayText), 1)
5597
+ ], true)
5598
+ ], 8, _hoisted_14),
4968
5599
  committed.value ? (vue.openBlock(), vue.createElementBlock("button", {
4969
5600
  key: 0,
4970
5601
  type: "button",
4971
5602
  class: "tao-date__link",
4972
5603
  onClick: clear
4973
- }, "Очистить")) : vue.createCommentVNode("", true)
5604
+ }, [
5605
+ vue.renderSlot(_ctx.$slots, "clear", {}, () => [
5606
+ vue.createTextVNode(vue.toDisplayString(__props.clearText), 1)
5607
+ ], true)
5608
+ ])) : vue.createCommentVNode("", true)
4974
5609
  ])
4975
- ], 44, _hoisted_3$e)) : vue.createCommentVNode("", true)
5610
+ ], 44, _hoisted_4$e)) : vue.createCommentVNode("", true)
4976
5611
  ]))
4977
5612
  ], 2);
4978
5613
  };
4979
5614
  }
4980
5615
  });
4981
- const TaoDateRange = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-3d067081"]]);
5616
+ const TaoDateRange = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-aa589793"]]);
4982
5617
  const _hoisted_1$i = ["for"];
4983
- const _hoisted_2$g = ["id", "checked", "disabled", "aria-checked"];
5618
+ const _hoisted_2$g = ["id", "checked", "disabled", "aria-checked", "aria-invalid", "aria-describedby"];
4984
5619
  const _hoisted_3$d = {
4985
5620
  key: 0,
4986
5621
  class: "tao-switch__label"
@@ -5004,6 +5639,8 @@
5004
5639
  const field = vue.inject(formFieldKey, null);
5005
5640
  const localId = vue.useId();
5006
5641
  const controlId = vue.computed(() => (field == null ? void 0 : field.id) ?? localId);
5642
+ const invalid = vue.computed(() => Boolean(field == null ? void 0 : field.invalid.value));
5643
+ const describedBy = vue.computed(() => field == null ? void 0 : field.describedBy.value);
5007
5644
  function toggle() {
5008
5645
  if (props.disabled) {
5009
5646
  return;
@@ -5014,7 +5651,7 @@
5014
5651
  }
5015
5652
  return (_ctx, _cache) => {
5016
5653
  return vue.openBlock(), vue.createElementBlock("label", {
5017
- class: vue.normalizeClass(["tao-switch", { "tao-switch--disabled": __props.disabled, "tao-switch--on": __props.modelValue }]),
5654
+ class: vue.normalizeClass(["tao-switch", { "tao-switch--disabled": __props.disabled, "tao-switch--on": __props.modelValue, "tao-switch--invalid": invalid.value }]),
5018
5655
  for: controlId.value
5019
5656
  }, [
5020
5657
  vue.createElementVNode("input", {
@@ -5025,6 +5662,8 @@
5025
5662
  checked: __props.modelValue,
5026
5663
  disabled: __props.disabled,
5027
5664
  "aria-checked": __props.modelValue,
5665
+ "aria-invalid": invalid.value || void 0,
5666
+ "aria-describedby": describedBy.value,
5028
5667
  onChange: toggle
5029
5668
  }, null, 40, _hoisted_2$g),
5030
5669
  _cache[0] || (_cache[0] = vue.createElementVNode("span", {
@@ -5040,10 +5679,10 @@
5040
5679
  };
5041
5680
  }
5042
5681
  });
5043
- const TaoSwitch = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-db2bca61"]]);
5682
+ const TaoSwitch = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-17ce5000"]]);
5044
5683
  const radioGroupKey = Symbol("taoRadioGroup");
5045
5684
  const _hoisted_1$h = ["for"];
5046
- const _hoisted_2$f = ["id", "name", "value", "checked", "disabled"];
5685
+ const _hoisted_2$f = ["id", "name", "value", "checked", "disabled", "aria-invalid", "aria-describedby"];
5047
5686
  const _hoisted_3$c = {
5048
5687
  key: 0,
5049
5688
  class: "tao-radio__label"
@@ -5067,7 +5706,11 @@
5067
5706
  const props = __props;
5068
5707
  const emit = __emit;
5069
5708
  const group = vue.inject(radioGroupKey, null);
5709
+ const field = vue.inject(formFieldKey, null);
5070
5710
  const localId = vue.useId();
5711
+ const controlId = vue.computed(() => group ? localId : (field == null ? void 0 : field.id) ?? localId);
5712
+ const invalid = vue.computed(() => Boolean(field == null ? void 0 : field.invalid.value));
5713
+ const describedBy = vue.computed(() => group ? void 0 : field == null ? void 0 : field.describedBy.value);
5071
5714
  const isDisabled = vue.computed(() => props.disabled || Boolean(group == null ? void 0 : group.disabled.value));
5072
5715
  const inputName = vue.computed(() => (group == null ? void 0 : group.name.value) ?? props.name);
5073
5716
  const isChecked = vue.computed(() => {
@@ -5087,17 +5730,19 @@
5087
5730
  }
5088
5731
  return (_ctx, _cache) => {
5089
5732
  return vue.openBlock(), vue.createElementBlock("label", {
5090
- class: vue.normalizeClass(["tao-radio", { "tao-radio--disabled": isDisabled.value }]),
5091
- for: vue.unref(localId)
5733
+ class: vue.normalizeClass(["tao-radio", { "tao-radio--disabled": isDisabled.value, "tao-radio--invalid": invalid.value && !vue.unref(group) }]),
5734
+ for: controlId.value
5092
5735
  }, [
5093
5736
  vue.createElementVNode("input", {
5094
- id: vue.unref(localId),
5737
+ id: controlId.value,
5095
5738
  class: "tao-radio__input",
5096
5739
  type: "radio",
5097
5740
  name: inputName.value,
5098
5741
  value: String(__props.value),
5099
5742
  checked: isChecked.value,
5100
5743
  disabled: isDisabled.value,
5744
+ "aria-invalid": !vue.unref(group) && invalid.value || void 0,
5745
+ "aria-describedby": describedBy.value,
5101
5746
  onChange
5102
5747
  }, null, 40, _hoisted_2$f),
5103
5748
  _cache[0] || (_cache[0] = vue.createElementVNode("span", {
@@ -5111,8 +5756,8 @@
5111
5756
  };
5112
5757
  }
5113
5758
  });
5114
- const TaoRadio = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-c9c84481"]]);
5115
- const _hoisted_1$g = ["disabled"];
5759
+ const TaoRadio = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-e79d1fb6"]]);
5760
+ const _hoisted_1$g = ["id", "disabled", "aria-describedby", "aria-invalid", "aria-labelledby"];
5116
5761
  const _hoisted_2$e = {
5117
5762
  key: 0,
5118
5763
  class: "tao-radio-group__legend"
@@ -5131,10 +5776,14 @@
5131
5776
  setup(__props, { emit: __emit }) {
5132
5777
  const props = __props;
5133
5778
  const emit = __emit;
5779
+ const field = vue.inject(formFieldKey, null);
5134
5780
  const autoName = vue.useId();
5135
5781
  const groupName = vue.computed(() => props.name || autoName);
5136
5782
  const model = vue.computed(() => props.modelValue);
5137
5783
  const groupDisabled = vue.computed(() => props.disabled);
5784
+ const invalid = vue.computed(() => Boolean(field == null ? void 0 : field.invalid.value));
5785
+ const describedBy = vue.computed(() => field == null ? void 0 : field.describedBy.value);
5786
+ const labelledBy = vue.computed(() => props.legend || !field ? void 0 : `${field.id}-label`);
5138
5787
  function setValue(value) {
5139
5788
  emit("update:modelValue", value);
5140
5789
  emit("change", value);
@@ -5146,9 +5795,14 @@
5146
5795
  setValue
5147
5796
  });
5148
5797
  return (_ctx, _cache) => {
5798
+ var _a;
5149
5799
  return vue.openBlock(), vue.createElementBlock("fieldset", {
5150
- class: vue.normalizeClass(["tao-radio-group", `tao-radio-group--${__props.direction}`]),
5151
- disabled: __props.disabled
5800
+ id: (_a = vue.unref(field)) == null ? void 0 : _a.id,
5801
+ class: vue.normalizeClass(["tao-radio-group", [`tao-radio-group--${__props.direction}`, { "tao-radio-group--invalid": invalid.value }]]),
5802
+ disabled: __props.disabled,
5803
+ "aria-describedby": describedBy.value,
5804
+ "aria-invalid": invalid.value || void 0,
5805
+ "aria-labelledby": labelledBy.value
5152
5806
  }, [
5153
5807
  __props.legend ? (vue.openBlock(), vue.createElementBlock("legend", _hoisted_2$e, vue.toDisplayString(__props.legend), 1)) : vue.createCommentVNode("", true),
5154
5808
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
@@ -5156,9 +5810,9 @@
5156
5810
  };
5157
5811
  }
5158
5812
  });
5159
- const TaoRadioGroup = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-a0b1cb1f"]]);
5813
+ const TaoRadioGroup = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-6f6fa977"]]);
5160
5814
  const segmentedKey = Symbol("taoSegmented");
5161
- const _hoisted_1$f = ["disabled", "aria-describedby", "aria-invalid"];
5815
+ const _hoisted_1$f = ["disabled", "aria-describedby", "aria-invalid", "aria-labelledby", "id"];
5162
5816
  const _hoisted_2$d = {
5163
5817
  key: 0,
5164
5818
  class: "tao-segmented__legend"
@@ -5258,6 +5912,7 @@
5258
5912
  mutationObserver = null;
5259
5913
  });
5260
5914
  return (_ctx, _cache) => {
5915
+ var _a;
5261
5916
  return vue.openBlock(), vue.createElementBlock("fieldset", {
5262
5917
  class: vue.normalizeClass(["tao-segmented", [
5263
5918
  `tao-segmented--${__props.size}`,
@@ -5269,7 +5924,9 @@
5269
5924
  ]]),
5270
5925
  disabled: __props.disabled,
5271
5926
  "aria-describedby": describedBy.value,
5272
- "aria-invalid": invalid.value || void 0
5927
+ "aria-invalid": invalid.value || void 0,
5928
+ "aria-labelledby": __props.legend ? void 0 : vue.unref(field) ? `${vue.unref(field).id}-label` : void 0,
5929
+ id: (_a = vue.unref(field)) == null ? void 0 : _a.id
5273
5930
  }, [
5274
5931
  __props.legend ? (vue.openBlock(), vue.createElementBlock("legend", _hoisted_2$d, vue.toDisplayString(__props.legend), 1)) : vue.createCommentVNode("", true),
5275
5932
  vue.createElementVNode("div", {
@@ -5288,7 +5945,7 @@
5288
5945
  };
5289
5946
  }
5290
5947
  });
5291
- const TaoSegmented = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-cb3c591b"]]);
5948
+ const TaoSegmented = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-af757a32"]]);
5292
5949
  const _hoisted_1$e = ["for"];
5293
5950
  const _hoisted_2$c = ["id", "name", "value", "checked", "disabled", "aria-label"];
5294
5951
  const _hoisted_3$b = { class: "tao-segmented-option__face" };
@@ -5297,15 +5954,15 @@
5297
5954
  class: "tao-segmented-option__icon",
5298
5955
  "aria-hidden": "true"
5299
5956
  };
5300
- const _hoisted_5$a = {
5957
+ const _hoisted_5$b = {
5301
5958
  key: 1,
5302
5959
  class: "tao-segmented-option__label"
5303
5960
  };
5304
- const _hoisted_6$7 = {
5961
+ const _hoisted_6$8 = {
5305
5962
  key: 2,
5306
5963
  class: "tao-segmented-option__sr"
5307
5964
  };
5308
- const _hoisted_7$5 = {
5965
+ const _hoisted_7$7 = {
5309
5966
  key: 3,
5310
5967
  class: "tao-segmented-option__count"
5311
5968
  };
@@ -5390,12 +6047,12 @@
5390
6047
  vue.createTextVNode(vue.toDisplayString(__props.icon), 1)
5391
6048
  ], true)
5392
6049
  ])) : vue.createCommentVNode("", true),
5393
- hasLabel.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$a, [
6050
+ hasLabel.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$b, [
5394
6051
  vue.renderSlot(_ctx.$slots, "default", {}, () => [
5395
6052
  vue.createTextVNode(vue.toDisplayString(__props.label), 1)
5396
6053
  ], true)
5397
- ])) : __props.ariaLabel ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$7, vue.toDisplayString(__props.ariaLabel), 1)) : vue.createCommentVNode("", true),
5398
- countLabel.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_7$5, vue.toDisplayString(countLabel.value), 1)) : vue.createCommentVNode("", true)
6054
+ ])) : __props.ariaLabel ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$8, vue.toDisplayString(__props.ariaLabel), 1)) : vue.createCommentVNode("", true),
6055
+ countLabel.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_7$7, vue.toDisplayString(countLabel.value), 1)) : vue.createCommentVNode("", true)
5399
6056
  ])
5400
6057
  ], 10, _hoisted_1$e);
5401
6058
  };
@@ -5412,13 +6069,16 @@
5412
6069
  key: 1,
5413
6070
  class: "tao-alert__message"
5414
6071
  };
6072
+ const _hoisted_5$a = ["aria-label"];
6073
+ const _hoisted_6$7 = { "aria-hidden": "true" };
5415
6074
  const _sfc_main$d = /* @__PURE__ */ vue.defineComponent({
5416
6075
  ...{ name: "TaoAlert" },
5417
6076
  __name: "TaoAlert",
5418
6077
  props: {
5419
6078
  type: { default: "info" },
5420
6079
  title: { default: "" },
5421
- closable: { type: Boolean, default: false }
6080
+ closable: { type: Boolean, default: false },
6081
+ closeLabel: { default: "Закрыть" }
5422
6082
  },
5423
6083
  emits: ["close"],
5424
6084
  setup(__props, { emit: __emit }) {
@@ -5442,22 +6102,28 @@
5442
6102
  key: 0,
5443
6103
  type: "button",
5444
6104
  class: "tao-alert__close",
5445
- "aria-label": "Закрыть",
6105
+ "aria-label": __props.closeLabel,
5446
6106
  onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
5447
- }, " × ")) : vue.createCommentVNode("", true)
6107
+ }, [
6108
+ vue.createElementVNode("span", _hoisted_6$7, [
6109
+ vue.renderSlot(_ctx.$slots, "close-icon", {}, () => [
6110
+ _cache[1] || (_cache[1] = vue.createTextVNode("×", -1))
6111
+ ], true)
6112
+ ])
6113
+ ], 8, _hoisted_5$a)) : vue.createCommentVNode("", true)
5448
6114
  ], 10, _hoisted_1$d);
5449
6115
  };
5450
6116
  }
5451
6117
  });
5452
- const TaoAlert = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-4c89fa1f"]]);
6118
+ const TaoAlert = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-1a1dbef3"]]);
5453
6119
  const _hoisted_1$c = { key: 0 };
5454
6120
  const _hoisted_2$a = ["aria-sort"];
5455
6121
  const _hoisted_3$9 = ["onClick"];
5456
6122
  const _hoisted_4$9 = { key: 1 };
5457
6123
  const _hoisted_5$9 = { key: 0 };
5458
6124
  const _hoisted_6$6 = ["colspan"];
5459
- const _hoisted_7$4 = ["onClick"];
5460
- const _hoisted_8$4 = {
6125
+ const _hoisted_7$6 = ["onClick"];
6126
+ const _hoisted_8$6 = {
5461
6127
  key: 0,
5462
6128
  class: "tao-table__loading",
5463
6129
  "aria-busy": "true"
@@ -5610,11 +6276,11 @@
5610
6276
  ], true)
5611
6277
  ], 4);
5612
6278
  }), 128))
5613
- ], 8, _hoisted_7$4);
6279
+ ], 8, _hoisted_7$6);
5614
6280
  }), 128))
5615
6281
  ])
5616
6282
  ], 2),
5617
- __props.loading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$4, [
6283
+ __props.loading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$6, [
5618
6284
  vue.renderSlot(_ctx.$slots, "loading", {}, () => [
5619
6285
  vue.createVNode(TaoLoader, { size: 36 })
5620
6286
  ], true)
@@ -5654,15 +6320,17 @@
5654
6320
  class: "tao-pagination__total"
5655
6321
  };
5656
6322
  const _hoisted_3$8 = { class: "tao-pagination__pages" };
5657
- const _hoisted_4$8 = ["disabled"];
5658
- const _hoisted_5$8 = ["aria-label", "disabled", "onClick"];
5659
- const _hoisted_6$5 = {
6323
+ const _hoisted_4$8 = ["aria-label", "disabled"];
6324
+ const _hoisted_5$8 = { "aria-hidden": "true" };
6325
+ const _hoisted_6$5 = ["aria-label", "disabled", "onClick"];
6326
+ const _hoisted_7$5 = {
5660
6327
  key: 1,
5661
6328
  class: "tao-pagination__ellipsis",
5662
6329
  "aria-hidden": "true"
5663
6330
  };
5664
- const _hoisted_7$3 = ["aria-current", "aria-label", "disabled", "onClick"];
5665
- const _hoisted_8$3 = ["disabled"];
6331
+ const _hoisted_8$5 = ["aria-current", "aria-label", "disabled", "onClick"];
6332
+ const _hoisted_9$1 = ["aria-label", "disabled"];
6333
+ const _hoisted_10$1 = { "aria-hidden": "true" };
5666
6334
  const _sfc_main$b = /* @__PURE__ */ vue.defineComponent({
5667
6335
  ...{ name: "TaoPagination" },
5668
6336
  __name: "TaoPagination",
@@ -5675,7 +6343,12 @@
5675
6343
  showTotal: { type: Boolean, default: true },
5676
6344
  size: { default: "medium" },
5677
6345
  jump: { default: 5 },
5678
- ariaLabel: { default: "Пагинация" }
6346
+ ariaLabel: { default: "Пагинация" },
6347
+ prevLabel: { default: "Назад" },
6348
+ nextLabel: { default: "Вперёд" },
6349
+ pageLabel: { default: "Страница {page}" },
6350
+ jumpPrevLabel: { default: "Назад на {n} страниц" },
6351
+ jumpNextLabel: { default: "Вперёд на {n} страниц" }
5679
6352
  },
5680
6353
  emits: ["update:page", "change"],
5681
6354
  setup(__props, { emit: __emit }) {
@@ -5686,11 +6359,15 @@
5686
6359
  const items = vue.computed(() => buildPaginationItems(current.value, pageCount.value, props.siblingCount));
5687
6360
  const from = vue.computed(() => props.total === 0 ? 0 : (current.value - 1) * props.pageSize + 1);
5688
6361
  const to = vue.computed(() => Math.min(current.value * props.pageSize, props.total));
5689
- vue.watch(pageCount, (count) => {
5690
- if (props.page > count) {
5691
- goTo(count);
5692
- }
5693
- });
6362
+ vue.watch(
6363
+ () => [props.page, pageCount.value],
6364
+ ([page, count]) => {
6365
+ if (page > count || page < 1) {
6366
+ goTo(page);
6367
+ }
6368
+ },
6369
+ { immediate: true }
6370
+ );
5694
6371
  function goTo(next) {
5695
6372
  if (props.disabled) {
5696
6373
  return;
@@ -5708,20 +6385,32 @@
5708
6385
  "aria-label": __props.ariaLabel
5709
6386
  }, [
5710
6387
  __props.showTotal ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_2$9, [
5711
- __props.total === 0 ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
5712
- vue.createTextVNode("0 из 0")
5713
- ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
5714
- vue.createTextVNode(vue.toDisplayString(from.value) + "–" + vue.toDisplayString(to.value) + " из " + vue.toDisplayString(__props.total), 1)
5715
- ], 64))
6388
+ vue.renderSlot(_ctx.$slots, "total", {
6389
+ from: from.value,
6390
+ to: to.value,
6391
+ total: __props.total
6392
+ }, () => [
6393
+ __props.total === 0 ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
6394
+ vue.createTextVNode("0 из 0")
6395
+ ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
6396
+ vue.createTextVNode(vue.toDisplayString(from.value) + "–" + vue.toDisplayString(to.value) + " из " + vue.toDisplayString(__props.total), 1)
6397
+ ], 64))
6398
+ ], true)
5716
6399
  ])) : vue.createCommentVNode("", true),
5717
6400
  vue.createElementVNode("div", _hoisted_3$8, [
5718
6401
  vue.createElementVNode("button", {
5719
6402
  type: "button",
5720
6403
  class: "tao-pagination__btn",
5721
- "aria-label": "Назад",
6404
+ "aria-label": __props.prevLabel,
5722
6405
  disabled: __props.disabled || current.value <= 1,
5723
6406
  onClick: _cache[0] || (_cache[0] = ($event) => goTo(current.value - 1))
5724
- }, " ‹ ", 8, _hoisted_4$8),
6407
+ }, [
6408
+ vue.createElementVNode("span", _hoisted_5$8, [
6409
+ vue.renderSlot(_ctx.$slots, "prev-icon", {}, () => [
6410
+ _cache[2] || (_cache[2] = vue.createTextVNode("‹", -1))
6411
+ ], true)
6412
+ ])
6413
+ ], 8, _hoisted_4$8),
5725
6414
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(items.value, (item) => {
5726
6415
  return vue.openBlock(), vue.createElementBlock(vue.Fragment, {
5727
6416
  key: item.type === "page" ? item.page : item.id
@@ -5730,33 +6419,39 @@
5730
6419
  key: 0,
5731
6420
  type: "button",
5732
6421
  class: "tao-pagination__btn tao-pagination__btn--jump",
5733
- "aria-label": item.id === "left" ? `Назад на ${__props.jump} страниц` : `Вперёд на ${__props.jump} страниц`,
6422
+ "aria-label": item.id === "left" ? __props.jumpPrevLabel.replace("{n}", String(__props.jump)) : __props.jumpNextLabel.replace("{n}", String(__props.jump)),
5734
6423
  disabled: __props.disabled,
5735
6424
  onClick: ($event) => goTo(item.id === "left" ? current.value - __props.jump : current.value + __props.jump)
5736
- }, " … ", 8, _hoisted_5$8)) : item.type === "ellipsis" ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$5, "…")) : (vue.openBlock(), vue.createElementBlock("button", {
6425
+ }, " … ", 8, _hoisted_6$5)) : item.type === "ellipsis" ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_7$5, "…")) : (vue.openBlock(), vue.createElementBlock("button", {
5737
6426
  key: 2,
5738
6427
  type: "button",
5739
6428
  class: vue.normalizeClass(["tao-pagination__btn", { "tao-pagination__btn--current": item.page === current.value }]),
5740
6429
  "aria-current": item.page === current.value ? "page" : void 0,
5741
- "aria-label": `Страница ${item.page}`,
6430
+ "aria-label": __props.pageLabel.replace("{page}", String(item.page)),
5742
6431
  disabled: __props.disabled,
5743
6432
  onClick: ($event) => goTo(item.page)
5744
- }, vue.toDisplayString(item.page), 11, _hoisted_7$3))
6433
+ }, vue.toDisplayString(item.page), 11, _hoisted_8$5))
5745
6434
  ], 64);
5746
6435
  }), 128)),
5747
6436
  vue.createElementVNode("button", {
5748
6437
  type: "button",
5749
6438
  class: "tao-pagination__btn",
5750
- "aria-label": "Вперёд",
6439
+ "aria-label": __props.nextLabel,
5751
6440
  disabled: __props.disabled || current.value >= pageCount.value,
5752
6441
  onClick: _cache[1] || (_cache[1] = ($event) => goTo(current.value + 1))
5753
- }, " › ", 8, _hoisted_8$3)
6442
+ }, [
6443
+ vue.createElementVNode("span", _hoisted_10$1, [
6444
+ vue.renderSlot(_ctx.$slots, "next-icon", {}, () => [
6445
+ _cache[3] || (_cache[3] = vue.createTextVNode("›", -1))
6446
+ ], true)
6447
+ ])
6448
+ ], 8, _hoisted_9$1)
5754
6449
  ])
5755
6450
  ], 10, _hoisted_1$b);
5756
6451
  };
5757
6452
  }
5758
6453
  });
5759
- const TaoPagination = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-fd69be36"]]);
6454
+ const TaoPagination = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-37f3d381"]]);
5760
6455
  const _hoisted_1$a = { class: "tao-empty" };
5761
6456
  const _hoisted_2$8 = {
5762
6457
  key: 0,
@@ -5835,8 +6530,10 @@
5835
6530
  };
5836
6531
  const _hoisted_3$6 = ["id"];
5837
6532
  const _hoisted_4$6 = { key: 1 };
5838
- const _hoisted_5$6 = { class: "tao-drawer__content" };
5839
- const _hoisted_6$4 = {
6533
+ const _hoisted_5$6 = ["aria-label"];
6534
+ const _hoisted_6$4 = { "aria-hidden": "true" };
6535
+ const _hoisted_7$4 = { class: "tao-drawer__content" };
6536
+ const _hoisted_8$4 = {
5840
6537
  key: 1,
5841
6538
  class: "tao-drawer__footer"
5842
6539
  };
@@ -5847,7 +6544,8 @@
5847
6544
  modelValue: { type: Boolean },
5848
6545
  title: { default: "" },
5849
6546
  side: { default: "right" },
5850
- closable: { type: Boolean, default: true }
6547
+ closable: { type: Boolean, default: true },
6548
+ closeLabel: { default: "Закрыть" }
5851
6549
  },
5852
6550
  emits: ["update:modelValue", "close"],
5853
6551
  setup(__props, { emit: __emit }) {
@@ -5855,9 +6553,8 @@
5855
6553
  const emit = __emit;
5856
6554
  const panelRef = vue.ref(null);
5857
6555
  const titleId = vue.useId();
5858
- let previousOverflow = "";
5859
6556
  let previousFocus = null;
5860
- let scrollLocked = false;
6557
+ let scrollHeld = false;
5861
6558
  function close() {
5862
6559
  if (!props.closable) {
5863
6560
  return;
@@ -5865,21 +6562,19 @@
5865
6562
  emit("update:modelValue", false);
5866
6563
  emit("close");
5867
6564
  }
5868
- function lockBodyScroll() {
5869
- if (scrollLocked) {
6565
+ function holdScroll() {
6566
+ if (scrollHeld || !isBrowser()) {
5870
6567
  return;
5871
6568
  }
5872
- previousOverflow = document.body.style.overflow;
5873
- document.body.style.overflow = "hidden";
5874
- scrollLocked = true;
6569
+ lockBodyScroll();
6570
+ scrollHeld = true;
5875
6571
  }
5876
- function unlockBodyScroll() {
5877
- if (!scrollLocked) {
6572
+ function releaseScroll() {
6573
+ if (!scrollHeld) {
5878
6574
  return;
5879
6575
  }
5880
- document.body.style.overflow = previousOverflow;
5881
- previousOverflow = "";
5882
- scrollLocked = false;
6576
+ unlockBodyScroll();
6577
+ scrollHeld = false;
5883
6578
  }
5884
6579
  function restoreFocus() {
5885
6580
  var _a;
@@ -5897,6 +6592,9 @@
5897
6592
  }
5898
6593
  function onKeydown(event) {
5899
6594
  if (event.key === "Escape") {
6595
+ if (!props.closable) {
6596
+ return;
6597
+ }
5900
6598
  event.preventDefault();
5901
6599
  close();
5902
6600
  return;
@@ -5908,19 +6606,23 @@
5908
6606
  vue.watch(
5909
6607
  () => props.modelValue,
5910
6608
  (isOpen) => {
6609
+ if (!isBrowser()) {
6610
+ return;
6611
+ }
5911
6612
  if (isOpen) {
5912
6613
  previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
5913
- lockBodyScroll();
6614
+ holdScroll();
5914
6615
  void focusPanel();
5915
6616
  return;
5916
6617
  }
5917
- unlockBodyScroll();
6618
+ releaseScroll();
5918
6619
  restoreFocus();
5919
6620
  },
5920
6621
  { immediate: true }
5921
6622
  );
5922
6623
  vue.onBeforeUnmount(() => {
5923
- unlockBodyScroll();
6624
+ releaseScroll();
6625
+ restoreFocus();
5924
6626
  });
5925
6627
  return (_ctx, _cache) => {
5926
6628
  return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
@@ -5956,14 +6658,20 @@
5956
6658
  key: 2,
5957
6659
  type: "button",
5958
6660
  class: "tao-drawer__close",
5959
- "aria-label": "Закрыть",
6661
+ "aria-label": __props.closeLabel,
5960
6662
  onClick: close
5961
- }, " × ")) : vue.createCommentVNode("", true)
6663
+ }, [
6664
+ vue.createElementVNode("span", _hoisted_6$4, [
6665
+ vue.renderSlot(_ctx.$slots, "close-icon", {}, () => [
6666
+ _cache[0] || (_cache[0] = vue.createTextVNode("×", -1))
6667
+ ], true)
6668
+ ])
6669
+ ], 8, _hoisted_5$6)) : vue.createCommentVNode("", true)
5962
6670
  ])) : vue.createCommentVNode("", true),
5963
- vue.createElementVNode("div", _hoisted_5$6, [
6671
+ vue.createElementVNode("div", _hoisted_7$4, [
5964
6672
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
5965
6673
  ]),
5966
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$4, [
6674
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$4, [
5967
6675
  vue.renderSlot(_ctx.$slots, "footer", {}, void 0, true)
5968
6676
  ])) : vue.createCommentVNode("", true)
5969
6677
  ], 8, _hoisted_1$8)
@@ -5975,7 +6683,7 @@
5975
6683
  };
5976
6684
  }
5977
6685
  });
5978
- const TaoDrawer = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-6a0c0e98"]]);
6686
+ const TaoDrawer = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-10fb02f2"]]);
5979
6687
  const _hoisted_1$7 = ["title"];
5980
6688
  const _hoisted_2$6 = { class: "tao-avatar__face" };
5981
6689
  const _hoisted_3$5 = ["src", "alt"];
@@ -5994,7 +6702,10 @@
5994
6702
  alt: { default: "" },
5995
6703
  size: { default: "medium" },
5996
6704
  dot: { type: [Boolean, String], default: false },
5997
- count: { default: void 0 }
6705
+ count: { default: void 0 },
6706
+ fallbackLabel: { default: "Аватар" },
6707
+ notificationsLabel: { default: "{count} уведомлений" },
6708
+ dotLabels: { default: () => ({}) }
5998
6709
  },
5999
6710
  setup(__props) {
6000
6711
  const props = __props;
@@ -6039,7 +6750,7 @@
6039
6750
  }
6040
6751
  return String(props.count);
6041
6752
  });
6042
- const dotLabel = {
6753
+ const defaultDotLabel = {
6043
6754
  success: "в сети",
6044
6755
  danger: "занят",
6045
6756
  warning: "отошёл",
@@ -6047,28 +6758,40 @@
6047
6758
  neutral: "не в сети"
6048
6759
  };
6049
6760
  const label = vue.computed(() => {
6050
- const base = props.alt || props.name || "Аватар";
6761
+ const base = props.alt || props.name || props.fallbackLabel;
6051
6762
  const extra = [];
6052
6763
  if (dotTone.value) {
6053
- extra.push(dotLabel[dotTone.value]);
6764
+ extra.push(props.dotLabels[dotTone.value] ?? defaultDotLabel[dotTone.value]);
6054
6765
  }
6055
6766
  if (badge.value) {
6056
- extra.push(`${badge.value} уведомлений`);
6767
+ extra.push(props.notificationsLabel.replace("{count}", badge.value));
6057
6768
  }
6058
6769
  return extra.length ? `${base}, ${extra.join(", ")}` : base;
6059
6770
  });
6771
+ const imgFailed = vue.ref(false);
6772
+ const showImage = vue.computed(() => Boolean(props.src) && !imgFailed.value);
6773
+ vue.watch(
6774
+ () => props.src,
6775
+ () => {
6776
+ imgFailed.value = false;
6777
+ }
6778
+ );
6779
+ function onImgError() {
6780
+ imgFailed.value = true;
6781
+ }
6060
6782
  return (_ctx, _cache) => {
6061
6783
  return vue.openBlock(), vue.createElementBlock("span", {
6062
6784
  class: vue.normalizeClass(["tao-avatar", `tao-avatar--${sizeClass.value}`]),
6063
6785
  title: label.value
6064
6786
  }, [
6065
6787
  vue.createElementVNode("span", _hoisted_2$6, [
6066
- __props.src ? (vue.openBlock(), vue.createElementBlock("img", {
6788
+ showImage.value ? (vue.openBlock(), vue.createElementBlock("img", {
6067
6789
  key: 0,
6068
6790
  class: "tao-avatar__img",
6069
6791
  src: __props.src,
6070
- alt: label.value
6071
- }, null, 8, _hoisted_3$5)) : (vue.openBlock(), vue.createElementBlock("span", {
6792
+ alt: label.value,
6793
+ onError: onImgError
6794
+ }, null, 40, _hoisted_3$5)) : (vue.openBlock(), vue.createElementBlock("span", {
6072
6795
  key: 1,
6073
6796
  class: "tao-avatar__fallback",
6074
6797
  "aria-label": label.value
@@ -6084,11 +6807,8 @@
6084
6807
  };
6085
6808
  }
6086
6809
  });
6087
- const TaoAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-cb4ec893"]]);
6088
- const _hoisted_1$6 = {
6089
- class: "tao-breadcrumb",
6090
- "aria-label": "Хлебные крошки"
6091
- };
6810
+ const TaoAvatar = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-65ed2d7a"]]);
6811
+ const _hoisted_1$6 = ["aria-label"];
6092
6812
  const _hoisted_2$5 = { class: "tao-breadcrumb__list" };
6093
6813
  const _hoisted_3$4 = {
6094
6814
  key: 0,
@@ -6108,11 +6828,15 @@
6108
6828
  ...{ name: "TaoBreadcrumb" },
6109
6829
  __name: "TaoBreadcrumb",
6110
6830
  props: {
6111
- items: {}
6831
+ items: {},
6832
+ ariaLabel: { default: "Хлебные крошки" }
6112
6833
  },
6113
6834
  setup(__props) {
6114
6835
  return (_ctx, _cache) => {
6115
- return vue.openBlock(), vue.createElementBlock("nav", _hoisted_1$6, [
6836
+ return vue.openBlock(), vue.createElementBlock("nav", {
6837
+ class: "tao-breadcrumb",
6838
+ "aria-label": __props.ariaLabel
6839
+ }, [
6116
6840
  vue.createElementVNode("ol", _hoisted_2$5, [
6117
6841
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.items, (item, index) => {
6118
6842
  return vue.openBlock(), vue.createElementBlock("li", {
@@ -6133,11 +6857,11 @@
6133
6857
  ]);
6134
6858
  }), 128))
6135
6859
  ])
6136
- ]);
6860
+ ], 8, _hoisted_1$6);
6137
6861
  };
6138
6862
  }
6139
6863
  });
6140
- const TaoBreadcrumb = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-48cf9bb5"]]);
6864
+ const TaoBreadcrumb = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-94ab1f67"]]);
6141
6865
  const _hoisted_1$5 = ["aria-label"];
6142
6866
  const _hoisted_2$4 = {
6143
6867
  class: "tao-counter__row",
@@ -6221,16 +6945,13 @@
6221
6945
  });
6222
6946
  const TaoCounter = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-6b746f2f"]]);
6223
6947
  const _hoisted_1$4 = { class: "tao-carousel__row" };
6224
- const _hoisted_2$3 = ["disabled"];
6225
- const _hoisted_3$3 = ["aria-label"];
6226
- const _hoisted_4$3 = ["disabled"];
6227
- const _hoisted_5$3 = {
6228
- key: 0,
6229
- class: "tao-carousel__dots",
6230
- role: "group",
6231
- "aria-label": "Слайды"
6232
- };
6233
- const _hoisted_6$3 = ["aria-label", "aria-current", "onClick"];
6948
+ const _hoisted_2$3 = ["aria-label", "disabled"];
6949
+ const _hoisted_3$3 = { "aria-hidden": "true" };
6950
+ const _hoisted_4$3 = ["aria-label"];
6951
+ const _hoisted_5$3 = ["aria-label", "disabled"];
6952
+ const _hoisted_6$3 = { "aria-hidden": "true" };
6953
+ const _hoisted_7$3 = ["aria-label"];
6954
+ const _hoisted_8$3 = ["aria-label", "aria-current", "onClick"];
6234
6955
  const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
6235
6956
  ...{ name: "TaoCarousel" },
6236
6957
  __name: "TaoCarousel",
@@ -6242,7 +6963,11 @@
6242
6963
  autoplay: { default: 0 },
6243
6964
  loop: { type: Boolean, default: false },
6244
6965
  dots: { type: Boolean, default: false },
6245
- ariaLabel: { default: "Лента" }
6966
+ ariaLabel: { default: "Лента" },
6967
+ prevLabel: { default: "Назад" },
6968
+ nextLabel: { default: "Вперёд" },
6969
+ dotsLabel: { default: "Слайды" },
6970
+ slideLabel: { default: "Слайд {n} из {count}" }
6246
6971
  },
6247
6972
  emits: ["update:modelValue", "change"],
6248
6973
  setup(__props, { emit: __emit }) {
@@ -6291,7 +7016,8 @@
6291
7016
  return 0;
6292
7017
  }
6293
7018
  const left = ((_a = track.value) == null ? void 0 : _a.scrollLeft) ?? 0;
6294
- return Math.min(Math.max(Math.round(left / (width + gap)), 0), total - 1);
7019
+ const last = Math.max(total - step.value, 0);
7020
+ return Math.min(Math.max(Math.round(left / (width + gap)), 0), last);
6295
7021
  }
6296
7022
  function setIndex(next) {
6297
7023
  if (next === index.value) {
@@ -6342,13 +7068,10 @@
6342
7068
  autoplayTimer = 0;
6343
7069
  }
6344
7070
  function canAutoplay() {
6345
- return props.autoplay > 0 && count.value > step.value && !hoverPaused.value && !focusPaused.value && !dragging.value && typeof document !== "undefined" && !document.hidden && !prefersReducedMotion();
7071
+ return props.autoplay > 0 && count.value > step.value && !hoverPaused.value && !focusPaused.value && !dragging.value && typeof document !== "undefined" && !document.hidden && !prefersReducedMotion() && (props.loop || index.value < lastIndex.value);
6346
7072
  }
6347
7073
  function tickAutoplay() {
6348
7074
  if (!canAutoplay()) {
6349
- return;
6350
- }
6351
- if (!props.loop && index.value >= lastIndex.value) {
6352
7075
  stopAutoplay();
6353
7076
  return;
6354
7077
  }
@@ -6388,7 +7111,14 @@
6388
7111
  }
6389
7112
  cancelAnimationFrame(scrollFrame);
6390
7113
  scrollFrame = requestAnimationFrame(() => {
6391
- setIndex(nearestIndex());
7114
+ const next = nearestIndex();
7115
+ const { width, gap } = metrics();
7116
+ const el = track.value;
7117
+ if (el && width > 0 && el.scrollLeft - next * (width + gap) > (width + gap) / 2) {
7118
+ goTo(next, true);
7119
+ return;
7120
+ }
7121
+ setIndex(next);
6392
7122
  });
6393
7123
  }
6394
7124
  function releaseDragCapture() {
@@ -6493,7 +7223,7 @@
6493
7223
  }
6494
7224
  );
6495
7225
  vue.watch(
6496
- () => [props.autoplay, props.loop, count.value, dragging.value],
7226
+ () => [props.autoplay, props.loop, count.value, dragging.value, index.value],
6497
7227
  () => syncAutoplay()
6498
7228
  );
6499
7229
  vue.onMounted(() => {
@@ -6533,27 +7263,30 @@
6533
7263
  key: 0,
6534
7264
  type: "button",
6535
7265
  class: "tao-carousel__nav",
6536
- "aria-label": "Назад",
7266
+ "aria-label": __props.prevLabel,
6537
7267
  disabled: atStart.value,
6538
7268
  onClick: goPrev
6539
- }, [..._cache[0] || (_cache[0] = [
6540
- vue.createElementVNode("svg", {
6541
- viewBox: "0 0 24 24",
6542
- width: "16",
6543
- height: "16",
6544
- "aria-hidden": "true",
6545
- focusable: "false"
6546
- }, [
6547
- vue.createElementVNode("path", {
6548
- fill: "none",
6549
- stroke: "currentColor",
6550
- "stroke-width": "2.2",
6551
- "stroke-linecap": "round",
6552
- "stroke-linejoin": "round",
6553
- d: "M14.5 5 8 12l6.5 7"
6554
- })
6555
- ], -1)
6556
- ])], 8, _hoisted_2$3)) : vue.createCommentVNode("", true)
7269
+ }, [
7270
+ vue.createElementVNode("span", _hoisted_3$3, [
7271
+ vue.renderSlot(_ctx.$slots, "prev-icon", {}, () => [
7272
+ _cache[0] || (_cache[0] = vue.createElementVNode("svg", {
7273
+ viewBox: "0 0 24 24",
7274
+ width: "16",
7275
+ height: "16",
7276
+ focusable: "false"
7277
+ }, [
7278
+ vue.createElementVNode("path", {
7279
+ fill: "none",
7280
+ stroke: "currentColor",
7281
+ "stroke-width": "2.2",
7282
+ "stroke-linecap": "round",
7283
+ "stroke-linejoin": "round",
7284
+ d: "M14.5 5 8 12l6.5 7"
7285
+ })
7286
+ ], -1))
7287
+ ], true)
7288
+ ])
7289
+ ], 8, _hoisted_2$3)) : vue.createCommentVNode("", true)
6557
7290
  ], true),
6558
7291
  vue.createElementVNode("div", {
6559
7292
  ref_key: "track",
@@ -6572,7 +7305,7 @@
6572
7305
  onClickCapture
6573
7306
  }, [
6574
7307
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
6575
- ], 42, _hoisted_3$3),
7308
+ ], 42, _hoisted_4$3),
6576
7309
  vue.renderSlot(_ctx.$slots, "next", {
6577
7310
  disabled: atEnd.value,
6578
7311
  go: goNext
@@ -6581,27 +7314,30 @@
6581
7314
  key: 0,
6582
7315
  type: "button",
6583
7316
  class: "tao-carousel__nav",
6584
- "aria-label": "Вперёд",
7317
+ "aria-label": __props.nextLabel,
6585
7318
  disabled: atEnd.value,
6586
7319
  onClick: goNext
6587
- }, [..._cache[1] || (_cache[1] = [
6588
- vue.createElementVNode("svg", {
6589
- viewBox: "0 0 24 24",
6590
- width: "16",
6591
- height: "16",
6592
- "aria-hidden": "true",
6593
- focusable: "false"
6594
- }, [
6595
- vue.createElementVNode("path", {
6596
- fill: "none",
6597
- stroke: "currentColor",
6598
- "stroke-width": "2.2",
6599
- "stroke-linecap": "round",
6600
- "stroke-linejoin": "round",
6601
- d: "M9.5 5 16 12l-6.5 7"
6602
- })
6603
- ], -1)
6604
- ])], 8, _hoisted_4$3)) : vue.createCommentVNode("", true)
7320
+ }, [
7321
+ vue.createElementVNode("span", _hoisted_6$3, [
7322
+ vue.renderSlot(_ctx.$slots, "next-icon", {}, () => [
7323
+ _cache[1] || (_cache[1] = vue.createElementVNode("svg", {
7324
+ viewBox: "0 0 24 24",
7325
+ width: "16",
7326
+ height: "16",
7327
+ focusable: "false"
7328
+ }, [
7329
+ vue.createElementVNode("path", {
7330
+ fill: "none",
7331
+ stroke: "currentColor",
7332
+ "stroke-width": "2.2",
7333
+ "stroke-linecap": "round",
7334
+ "stroke-linejoin": "round",
7335
+ d: "M9.5 5 16 12l-6.5 7"
7336
+ })
7337
+ ], -1))
7338
+ ], true)
7339
+ ])
7340
+ ], 8, _hoisted_5$3)) : vue.createCommentVNode("", true)
6605
7341
  ], true)
6606
7342
  ]),
6607
7343
  vue.renderSlot(_ctx.$slots, "dots", {
@@ -6609,13 +7345,18 @@
6609
7345
  count: snapCount.value,
6610
7346
  go: goTo
6611
7347
  }, () => [
6612
- showDots.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$3, [
7348
+ showDots.value ? (vue.openBlock(), vue.createElementBlock("div", {
7349
+ key: 0,
7350
+ class: "tao-carousel__dots",
7351
+ role: "group",
7352
+ "aria-label": __props.dotsLabel
7353
+ }, [
6613
7354
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(snapCount.value, (n) => {
6614
7355
  return vue.openBlock(), vue.createElementBlock("button", {
6615
7356
  key: n,
6616
7357
  type: "button",
6617
7358
  class: vue.normalizeClass(["tao-carousel__dot", { "tao-carousel__dot--active": n - 1 === index.value }]),
6618
- "aria-label": `Слайд ${n} из ${snapCount.value}`,
7359
+ "aria-label": __props.slideLabel.replace("{n}", String(n)).replace("{count}", String(snapCount.value)),
6619
7360
  "aria-current": n - 1 === index.value ? "true" : void 0,
6620
7361
  onClick: ($event) => goTo(n - 1)
6621
7362
  }, [
@@ -6626,15 +7367,15 @@
6626
7367
  }, () => [
6627
7368
  _cache[2] || (_cache[2] = vue.createElementVNode("span", { class: "tao-carousel__pip" }, null, -1))
6628
7369
  ], true)
6629
- ], 10, _hoisted_6$3);
7370
+ ], 10, _hoisted_8$3);
6630
7371
  }), 128))
6631
- ])) : vue.createCommentVNode("", true)
7372
+ ], 8, _hoisted_7$3)) : vue.createCommentVNode("", true)
6632
7373
  ], true)
6633
7374
  ], 36);
6634
7375
  };
6635
7376
  }
6636
7377
  });
6637
- const TaoCarousel = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-4f6de725"]]);
7378
+ const TaoCarousel = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-bc396e5d"]]);
6638
7379
  const _hoisted_1$3 = ["aria-label"];
6639
7380
  const _hoisted_2$2 = ["aria-label"];
6640
7381
  const _hoisted_3$2 = {
@@ -6676,11 +7417,12 @@
6676
7417
  props: {
6677
7418
  items: { default: () => [] },
6678
7419
  vertical: { type: Boolean, default: true },
6679
- ariaLabel: { default: "Стадии" }
7420
+ ariaLabel: { default: "Стадии" },
7421
+ statusLabels: { default: () => ({}) }
6680
7422
  },
6681
7423
  setup(__props) {
6682
7424
  const props = __props;
6683
- const statusText = {
7425
+ const fallbackStatusText = {
6684
7426
  wait: "ожидание",
6685
7427
  work: "в работе",
6686
7428
  ok: "готово",
@@ -6693,7 +7435,8 @@
6693
7435
  return item.status ?? "wait";
6694
7436
  }
6695
7437
  function itemLabel(item) {
6696
- return `${item.label ?? item.key}, ${statusText[statusOf(item)]}`;
7438
+ const status = statusOf(item);
7439
+ return `${item.label ?? item.key}, ${props.statusLabels[status] ?? fallbackStatusText[status]}`;
6697
7440
  }
6698
7441
  return (_ctx, _cache) => {
6699
7442
  return vue.openBlock(), vue.createElementBlock("ul", {
@@ -6767,7 +7510,7 @@
6767
7510
  };
6768
7511
  }
6769
7512
  });
6770
- const TaoStages = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-fefa5c65"]]);
7513
+ const TaoStages = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-b62db56d"]]);
6771
7514
  const TOAST_POSITIONS = [
6772
7515
  "topRight",
6773
7516
  "topLeft",
@@ -6781,7 +7524,8 @@
6781
7524
  position: "topCenter",
6782
7525
  timeout: 3e3,
6783
7526
  closable: true,
6784
- progress: true
7527
+ progress: true,
7528
+ closeLabel: "Закрыть уведомление"
6785
7529
  };
6786
7530
  const toasts = vue.ref([]);
6787
7531
  const toastsByPosition = vue.computed(() => {
@@ -6892,6 +7636,7 @@
6892
7636
  key: 2,
6893
7637
  class: "tao-toast__actions"
6894
7638
  };
7639
+ const _hoisted_11 = ["aria-label"];
6895
7640
  const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
6896
7641
  ...{ name: "TaoToastItem" },
6897
7642
  __name: "TaoToastItem",
@@ -7060,9 +7805,9 @@
7060
7805
  key: 0,
7061
7806
  type: "button",
7062
7807
  class: "tao-toast__close",
7063
- "aria-label": "Закрыть уведомление",
7808
+ "aria-label": vue.unref(toastDefaults).closeLabel,
7064
7809
  onClick: close
7065
- }, " × ")) : vue.createCommentVNode("", true),
7810
+ }, " × ", 8, _hoisted_11)) : vue.createCommentVNode("", true),
7066
7811
  __props.toast.progress && __props.toast.timeout ? (vue.openBlock(), vue.createElementBlock("span", {
7067
7812
  key: 1,
7068
7813
  class: "tao-toast__progress",
@@ -7072,7 +7817,7 @@
7072
7817
  };
7073
7818
  }
7074
7819
  });
7075
- const TaoToastItem = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-7c4692c0"]]);
7820
+ const TaoToastItem = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-3909ff09"]]);
7076
7821
  const _hoisted_1$1 = { class: "tao-toast-slot__inner" };
7077
7822
  const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
7078
7823
  ...{ name: "TaoToastViewport" },
@@ -7207,14 +7952,13 @@
7207
7952
  __name: "TaoConfirmHost",
7208
7953
  setup(__props) {
7209
7954
  const panelRef = vue.ref(null);
7210
- let previousOverflow = "";
7211
7955
  let previousFocus = null;
7212
- let scrollLocked = false;
7956
+ let scrollHeld = false;
7213
7957
  vue.onMounted(() => {
7214
7958
  registerConfirmHost();
7215
7959
  });
7216
7960
  vue.onBeforeUnmount(() => {
7217
- unlockBodyScroll();
7961
+ releaseScroll();
7218
7962
  unregisterConfirmHost();
7219
7963
  });
7220
7964
  vue.watch(
@@ -7225,12 +7969,15 @@
7225
7969
  async (id) => {
7226
7970
  var _a, _b;
7227
7971
  if (!id) {
7228
- unlockBodyScroll();
7972
+ releaseScroll();
7229
7973
  restoreFocus();
7230
7974
  return;
7231
7975
  }
7976
+ if (!isBrowser()) {
7977
+ return;
7978
+ }
7232
7979
  previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
7233
- lockBodyScroll();
7980
+ holdScroll();
7234
7981
  await vue.nextTick();
7235
7982
  (_b = queryButton(((_a = currentConfirm.value) == null ? void 0 : _a.danger) ? "cancel" : "ok")) == null ? void 0 : _b.focus();
7236
7983
  }
@@ -7239,21 +7986,19 @@
7239
7986
  var _a;
7240
7987
  return ((_a = panelRef.value) == null ? void 0 : _a.querySelector(`[data-tao-confirm-${which}]`)) ?? null;
7241
7988
  }
7242
- function lockBodyScroll() {
7243
- if (scrollLocked) {
7989
+ function holdScroll() {
7990
+ if (scrollHeld || !isBrowser()) {
7244
7991
  return;
7245
7992
  }
7246
- previousOverflow = document.body.style.overflow;
7247
- document.body.style.overflow = "hidden";
7248
- scrollLocked = true;
7993
+ lockBodyScroll();
7994
+ scrollHeld = true;
7249
7995
  }
7250
- function unlockBodyScroll() {
7251
- if (!scrollLocked) {
7996
+ function releaseScroll() {
7997
+ if (!scrollHeld) {
7252
7998
  return;
7253
7999
  }
7254
- document.body.style.overflow = previousOverflow;
7255
- previousOverflow = "";
7256
- scrollLocked = false;
8000
+ unlockBodyScroll();
8001
+ scrollHeld = false;
7257
8002
  }
7258
8003
  function restoreFocus() {
7259
8004
  var _a;
@@ -7267,26 +8012,13 @@
7267
8012
  answer(false);
7268
8013
  }
7269
8014
  function onKeydown(event) {
7270
- var _a, _b;
7271
8015
  if (event.key === "Escape") {
7272
8016
  event.preventDefault();
7273
8017
  answer(false);
7274
8018
  return;
7275
8019
  }
7276
- if (event.key !== "Tab") {
7277
- return;
7278
- }
7279
- const first = queryButton(((_a = currentConfirm.value) == null ? void 0 : _a.danger) ? "cancel" : "ok");
7280
- const last = queryButton(((_b = currentConfirm.value) == null ? void 0 : _b.danger) ? "ok" : "cancel");
7281
- if (!first || !last) {
7282
- return;
7283
- }
7284
- if (event.shiftKey && document.activeElement === first) {
7285
- event.preventDefault();
7286
- last.focus();
7287
- } else if (!event.shiftKey && document.activeElement === last) {
7288
- event.preventDefault();
7289
- first.focus();
8020
+ if (panelRef.value) {
8021
+ trapTab(event, panelRef.value);
7290
8022
  }
7291
8023
  }
7292
8024
  return (_ctx, _cache) => {
@@ -7389,7 +8121,7 @@
7389
8121
  };
7390
8122
  }
7391
8123
  });
7392
- const TaoConfirmHost = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-503301db"]]);
8124
+ const TaoConfirmHost = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d54ae27e"]]);
7393
8125
  const TYPE_TIMEOUT = {
7394
8126
  success: 3e3,
7395
8127
  error: 5e3,
@@ -7781,8 +8513,9 @@
7781
8513
  TaoSpoilerGroup,
7782
8514
  TaoCopy,
7783
8515
  TaoContainer,
7784
- _sfc_main$F,
8516
+ _sfc_main$G,
7785
8517
  TaoSpace,
8518
+ TaoSplit,
7786
8519
  TaoIcon,
7787
8520
  TaoLoader,
7788
8521
  TaoImage,
@@ -7852,7 +8585,7 @@
7852
8585
  exports2.TaoEmpty = TaoEmpty;
7853
8586
  exports2.TaoFieldset = TaoFieldset;
7854
8587
  exports2.TaoFileDrop = TaoFileDrop;
7855
- exports2.TaoFlex = _sfc_main$F;
8588
+ exports2.TaoFlex = _sfc_main$G;
7856
8589
  exports2.TaoFormField = TaoFormField;
7857
8590
  exports2.TaoIcon = TaoIcon;
7858
8591
  exports2.TaoImage = TaoImage;
@@ -7876,6 +8609,7 @@
7876
8609
  exports2.TaoSkeleton = TaoSkeleton;
7877
8610
  exports2.TaoSlider = TaoSlider;
7878
8611
  exports2.TaoSpace = TaoSpace;
8612
+ exports2.TaoSplit = TaoSplit;
7879
8613
  exports2.TaoSpoiler = TaoSpoiler;
7880
8614
  exports2.TaoSpoilerGroup = TaoSpoilerGroup;
7881
8615
  exports2.TaoStages = TaoStages;