@1337exp/taoui 1.1.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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$E = ["type", "disabled"];
6
- const _hoisted_2$z = {
5
+ const _hoisted_1$J = ["type", "disabled"];
6
+ const _hoisted_2$C = {
7
7
  key: 0,
8
8
  class: "tao-button__loader"
9
9
  };
10
- const _hoisted_3$t = {
10
+ const _hoisted_3$w = {
11
11
  key: 1,
12
12
  class: "tao-button__icon"
13
13
  };
14
- const _hoisted_4$o = { class: "tao-button__content" };
15
- const _sfc_main$N = /* @__PURE__ */ vue.defineComponent({
14
+ const _hoisted_4$q = { class: "tao-button__content" };
15
+ const _sfc_main$S = /* @__PURE__ */ vue.defineComponent({
16
16
  ...{ name: "TaoButton" },
17
17
  __name: "TaoButton",
18
18
  props: {
@@ -49,12 +49,12 @@
49
49
  disabled: __props.disabled || __props.loading,
50
50
  onClick: handleClick
51
51
  }, [
52
- __props.loading ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$z)) : vue.createCommentVNode("", true),
53
- __props.icon ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$t, vue.toDisplayString(__props.icon), 1)) : vue.createCommentVNode("", true),
54
- vue.createElementVNode("span", _hoisted_4$o, [
52
+ __props.loading ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$C)) : vue.createCommentVNode("", true),
53
+ __props.icon ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$w, vue.toDisplayString(__props.icon), 1)) : vue.createCommentVNode("", true),
54
+ vue.createElementVNode("span", _hoisted_4$q, [
55
55
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
56
56
  ])
57
- ], 10, _hoisted_1$E);
57
+ ], 10, _hoisted_1$J);
58
58
  };
59
59
  }
60
60
  });
@@ -65,8 +65,8 @@
65
65
  }
66
66
  return target;
67
67
  };
68
- const TaoButton = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-5a0fd489"]]);
69
- const _sfc_main$M = /* @__PURE__ */ vue.defineComponent({
68
+ const TaoButton = /* @__PURE__ */ _export_sfc(_sfc_main$S, [["__scopeId", "data-v-5a0fd489"]]);
69
+ const _sfc_main$R = /* @__PURE__ */ vue.defineComponent({
70
70
  ...{ name: "TaoBlock" },
71
71
  __name: "TaoBlock",
72
72
  props: {
@@ -98,24 +98,24 @@
98
98
  };
99
99
  }
100
100
  });
101
- const TaoBlock = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-feb87e36"]]);
101
+ const TaoBlock = /* @__PURE__ */ _export_sfc(_sfc_main$R, [["__scopeId", "data-v-feb87e36"]]);
102
102
  const formFieldKey = Symbol("taoFormField");
103
- const _hoisted_1$D = { class: "tao-input-wrapper" };
104
- const _hoisted_2$y = ["for"];
105
- const _hoisted_3$s = {
103
+ const _hoisted_1$I = { class: "tao-input-wrapper" };
104
+ const _hoisted_2$B = ["for"];
105
+ const _hoisted_3$v = {
106
106
  key: 0,
107
107
  class: "tao-input__affix tao-input__affix--prefix"
108
108
  };
109
- const _hoisted_4$n = ["id", "type", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby"];
110
- const _hoisted_5$f = {
109
+ const _hoisted_4$p = ["id", "type", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby"];
110
+ const _hoisted_5$h = {
111
111
  key: 1,
112
112
  class: "tao-input__affix tao-input__affix--suffix"
113
113
  };
114
- const _hoisted_6$b = {
114
+ const _hoisted_6$d = {
115
115
  key: 1,
116
116
  class: "tao-input__error"
117
117
  };
118
- const _sfc_main$L = /* @__PURE__ */ vue.defineComponent({
118
+ const _sfc_main$Q = /* @__PURE__ */ vue.defineComponent({
119
119
  ...{ name: "TaoInput" },
120
120
  __name: "TaoInput",
121
121
  props: {
@@ -151,12 +151,12 @@
151
151
  emit("focus", event);
152
152
  }
153
153
  return (_ctx, _cache) => {
154
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$D, [
154
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$I, [
155
155
  __props.label && !vue.unref(field) ? (vue.openBlock(), vue.createElementBlock("label", {
156
156
  key: 0,
157
157
  class: "tao-input__label",
158
158
  for: controlId.value
159
- }, vue.toDisplayString(__props.label), 9, _hoisted_2$y)) : vue.createCommentVNode("", true),
159
+ }, vue.toDisplayString(__props.label), 9, _hoisted_2$B)) : vue.createCommentVNode("", true),
160
160
  vue.createElementVNode("div", {
161
161
  class: vue.normalizeClass(["tao-input-shell", {
162
162
  "tao-input-shell--focused": focused.value,
@@ -166,7 +166,7 @@
166
166
  "tao-input-shell--suffix": _ctx.$slots.suffix
167
167
  }])
168
168
  }, [
169
- _ctx.$slots.prefix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$s, [
169
+ _ctx.$slots.prefix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$v, [
170
170
  vue.renderSlot(_ctx.$slots, "prefix", {}, void 0, true)
171
171
  ])) : vue.createCommentVNode("", true),
172
172
  vue.createElementVNode("input", {
@@ -181,27 +181,27 @@
181
181
  onInput: handleInput,
182
182
  onBlur: handleBlur,
183
183
  onFocus: handleFocus
184
- }, null, 42, _hoisted_4$n),
185
- _ctx.$slots.suffix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$f, [
184
+ }, null, 42, _hoisted_4$p),
185
+ _ctx.$slots.suffix ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_5$h, [
186
186
  vue.renderSlot(_ctx.$slots, "suffix", {}, void 0, true)
187
187
  ])) : vue.createCommentVNode("", true)
188
188
  ], 2),
189
- __props.error && __props.errorMessage ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$b, vue.toDisplayString(__props.errorMessage), 1)) : vue.createCommentVNode("", true)
189
+ __props.error && __props.errorMessage ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$d, vue.toDisplayString(__props.errorMessage), 1)) : vue.createCommentVNode("", true)
190
190
  ]);
191
191
  };
192
192
  }
193
193
  });
194
- const TaoInput = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["__scopeId", "data-v-b522e041"]]);
195
- const _hoisted_1$C = {
194
+ const TaoInput = /* @__PURE__ */ _export_sfc(_sfc_main$Q, [["__scopeId", "data-v-b522e041"]]);
195
+ const _hoisted_1$H = {
196
196
  key: 0,
197
197
  class: "tao-input-group__addon tao-input-group__addon--before"
198
198
  };
199
- const _hoisted_2$x = { class: "tao-input-group__field" };
200
- const _hoisted_3$r = {
199
+ const _hoisted_2$A = { class: "tao-input-group__field" };
200
+ const _hoisted_3$u = {
201
201
  key: 1,
202
202
  class: "tao-input-group__addon tao-input-group__addon--after"
203
203
  };
204
- const _sfc_main$K = /* @__PURE__ */ vue.defineComponent({
204
+ const _sfc_main$P = /* @__PURE__ */ vue.defineComponent({
205
205
  ...{ name: "TaoInputGroup" },
206
206
  __name: "TaoInputGroup",
207
207
  setup(__props) {
@@ -223,28 +223,28 @@
223
223
  onFocusin: onFocusIn,
224
224
  onFocusout: onFocusOut
225
225
  }, [
226
- _ctx.$slots.before ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$C, [
226
+ _ctx.$slots.before ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$H, [
227
227
  vue.renderSlot(_ctx.$slots, "before", {}, void 0, true)
228
228
  ])) : vue.createCommentVNode("", true),
229
- vue.createElementVNode("div", _hoisted_2$x, [
229
+ vue.createElementVNode("div", _hoisted_2$A, [
230
230
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
231
231
  ]),
232
- _ctx.$slots.after ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$r, [
232
+ _ctx.$slots.after ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$u, [
233
233
  vue.renderSlot(_ctx.$slots, "after", {}, void 0, true)
234
234
  ])) : vue.createCommentVNode("", true)
235
235
  ], 34);
236
236
  };
237
237
  }
238
238
  });
239
- const TaoInputGroup = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["__scopeId", "data-v-f06bb3b1"]]);
240
- const _hoisted_1$B = ["id", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
241
- const _hoisted_2$w = {
239
+ const TaoInputGroup = /* @__PURE__ */ _export_sfc(_sfc_main$P, [["__scopeId", "data-v-f06bb3b1"]]);
240
+ const _hoisted_1$G = ["id", "value", "placeholder", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
241
+ const _hoisted_2$z = {
242
242
  key: 0,
243
243
  class: "tao-input-number__steppers"
244
244
  };
245
- const _hoisted_3$q = ["disabled"];
246
- const _hoisted_4$m = ["disabled"];
247
- const _sfc_main$J = /* @__PURE__ */ vue.defineComponent({
245
+ const _hoisted_3$t = ["disabled"];
246
+ const _hoisted_4$o = ["disabled"];
247
+ const _sfc_main$O = /* @__PURE__ */ vue.defineComponent({
248
248
  ...{ name: "TaoInputNumber" },
249
249
  __name: "TaoInputNumber",
250
250
  props: {
@@ -393,8 +393,8 @@
393
393
  onFocus,
394
394
  onBlur,
395
395
  onKeydown
396
- }, null, 40, _hoisted_1$B),
397
- __props.controls ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$w, [
396
+ }, null, 40, _hoisted_1$G),
397
+ __props.controls ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$z, [
398
398
  vue.createElementVNode("button", {
399
399
  type: "button",
400
400
  class: "tao-input-number__step",
@@ -402,7 +402,7 @@
402
402
  tabindex: "-1",
403
403
  disabled: __props.disabled || atMax.value,
404
404
  onClick: _cache[0] || (_cache[0] = ($event) => bump(1))
405
- }, " + ", 8, _hoisted_3$q),
405
+ }, " + ", 8, _hoisted_3$t),
406
406
  vue.createElementVNode("button", {
407
407
  type: "button",
408
408
  class: "tao-input-number__step",
@@ -410,17 +410,17 @@
410
410
  tabindex: "-1",
411
411
  disabled: __props.disabled || atMin.value,
412
412
  onClick: _cache[1] || (_cache[1] = ($event) => bump(-1))
413
- }, " − ", 8, _hoisted_4$m)
413
+ }, " − ", 8, _hoisted_4$o)
414
414
  ])) : vue.createCommentVNode("", true)
415
415
  ], 2);
416
416
  };
417
417
  }
418
418
  });
419
- const TaoInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["__scopeId", "data-v-55b65a4d"]]);
420
- const _hoisted_1$A = ["aria-label", "disabled"];
421
- const _hoisted_2$v = ["id", "value", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
422
- const _hoisted_3$p = ["disabled"];
423
- const _sfc_main$I = /* @__PURE__ */ vue.defineComponent({
419
+ const TaoInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$O, [["__scopeId", "data-v-55b65a4d"]]);
420
+ const _hoisted_1$F = ["aria-label", "disabled"];
421
+ const _hoisted_2$y = ["id", "value", "disabled", "aria-invalid", "aria-describedby", "aria-valuenow", "aria-valuemin", "aria-valuemax"];
422
+ const _hoisted_3$s = ["disabled"];
423
+ const _sfc_main$N = /* @__PURE__ */ vue.defineComponent({
424
424
  ...{ name: "TaoQuantity" },
425
425
  __name: "TaoQuantity",
426
426
  props: {
@@ -553,7 +553,7 @@
553
553
  "aria-label": minusLabel.value,
554
554
  disabled: minusDisabled.value,
555
555
  onClick: onDec
556
- }, " − ", 8, _hoisted_1$A),
556
+ }, " − ", 8, _hoisted_1$F),
557
557
  vue.createElementVNode("input", {
558
558
  id: controlId.value,
559
559
  class: "tao-quantity__input",
@@ -573,49 +573,49 @@
573
573
  onFocus,
574
574
  onBlur,
575
575
  onKeydown
576
- }, null, 40, _hoisted_2$v),
576
+ }, null, 40, _hoisted_2$y),
577
577
  vue.createElementVNode("button", {
578
578
  type: "button",
579
579
  class: "tao-quantity__btn tao-quantity__btn--inc",
580
580
  "aria-label": "Увеличить",
581
581
  disabled: plusDisabled.value,
582
582
  onClick: onInc
583
- }, " + ", 8, _hoisted_3$p)
583
+ }, " + ", 8, _hoisted_3$s)
584
584
  ], 2);
585
585
  };
586
586
  }
587
587
  });
588
- const TaoQuantity = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-df6baf04"]]);
589
- const _hoisted_1$z = {
588
+ const TaoQuantity = /* @__PURE__ */ _export_sfc(_sfc_main$N, [["__scopeId", "data-v-df6baf04"]]);
589
+ const _hoisted_1$E = {
590
590
  key: 0,
591
591
  class: "tao-card__cover"
592
592
  };
593
- const _hoisted_2$u = {
593
+ const _hoisted_2$x = {
594
594
  key: 0,
595
595
  class: "tao-card__header-title"
596
596
  };
597
- const _hoisted_3$o = { key: 0 };
598
- const _hoisted_4$l = {
597
+ const _hoisted_3$r = { key: 0 };
598
+ const _hoisted_4$n = {
599
599
  key: 2,
600
600
  class: "tao-card__title-block"
601
601
  };
602
- const _hoisted_5$e = {
602
+ const _hoisted_5$g = {
603
603
  key: 0,
604
604
  class: "tao-card__title"
605
605
  };
606
- const _hoisted_6$a = {
606
+ const _hoisted_6$c = {
607
607
  key: 1,
608
608
  class: "tao-card__sub"
609
609
  };
610
- const _hoisted_7$6 = {
610
+ const _hoisted_7$8 = {
611
611
  key: 3,
612
612
  class: "tao-card__body"
613
613
  };
614
- const _hoisted_8$6 = {
614
+ const _hoisted_8$7 = {
615
615
  key: 4,
616
616
  class: "tao-card__footer"
617
617
  };
618
- const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
618
+ const _sfc_main$M = /* @__PURE__ */ vue.defineComponent({
619
619
  ...{ name: "TaoCard" },
620
620
  __name: "TaoCard",
621
621
  props: {
@@ -647,14 +647,14 @@
647
647
  }]),
648
648
  style: vue.normalizeStyle(radiusStyle.value)
649
649
  }, [
650
- _ctx.$slots.cover ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$z, [
650
+ _ctx.$slots.cover ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$E, [
651
651
  vue.renderSlot(_ctx.$slots, "cover", {}, void 0, true)
652
652
  ])) : vue.createCommentVNode("", true),
653
653
  vue.createElementVNode("div", {
654
654
  class: "tao-card__content",
655
655
  style: vue.normalizeStyle(paddingStyle.value)
656
656
  }, [
657
- _ctx.$slots.headerTitle ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_2$u, [
657
+ _ctx.$slots.headerTitle ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_2$x, [
658
658
  vue.renderSlot(_ctx.$slots, "headerTitle", {}, void 0, true)
659
659
  ])) : vue.createCommentVNode("", true),
660
660
  _ctx.$slots.header || _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -664,22 +664,22 @@
664
664
  vue.createElementVNode("span", null, [
665
665
  vue.renderSlot(_ctx.$slots, "header", {}, void 0, true)
666
666
  ]),
667
- _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$o, [
667
+ _ctx.$slots.headerSecondary ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$r, [
668
668
  vue.renderSlot(_ctx.$slots, "headerSecondary", {}, void 0, true)
669
669
  ])) : vue.createCommentVNode("", true)
670
670
  ], 2)) : vue.createCommentVNode("", true),
671
- _ctx.$slots.title || _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$l, [
672
- _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_5$e, [
671
+ _ctx.$slots.title || _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$n, [
672
+ _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("h2", _hoisted_5$g, [
673
673
  vue.renderSlot(_ctx.$slots, "title", {}, void 0, true)
674
674
  ])) : vue.createCommentVNode("", true),
675
- _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$a, [
675
+ _ctx.$slots.sub ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$c, [
676
676
  vue.renderSlot(_ctx.$slots, "sub", {}, void 0, true)
677
677
  ])) : vue.createCommentVNode("", true)
678
678
  ])) : vue.createCommentVNode("", true),
679
- _ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$6, [
679
+ _ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$8, [
680
680
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
681
681
  ])) : vue.createCommentVNode("", true),
682
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$6, [
682
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$7, [
683
683
  vue.renderSlot(_ctx.$slots, "footer", {}, void 0, true)
684
684
  ])) : vue.createCommentVNode("", true)
685
685
  ], 4)
@@ -687,7 +687,7 @@
687
687
  };
688
688
  }
689
689
  });
690
- const TaoCard = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["__scopeId", "data-v-2ff3d055"]]);
690
+ const TaoCard = /* @__PURE__ */ _export_sfc(_sfc_main$M, [["__scopeId", "data-v-2ff3d055"]]);
691
691
  const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
692
692
  function getFocusable(root) {
693
693
  return [...root.querySelectorAll(FOCUSABLE)].filter(
@@ -716,19 +716,19 @@
716
716
  first.focus();
717
717
  }
718
718
  }
719
- const _hoisted_1$y = ["aria-labelledby"];
720
- const _hoisted_2$t = {
719
+ const _hoisted_1$D = ["aria-labelledby"];
720
+ const _hoisted_2$w = {
721
721
  key: 0,
722
722
  class: "tao-modal__header"
723
723
  };
724
- const _hoisted_3$n = ["id"];
725
- const _hoisted_4$k = { key: 1 };
726
- const _hoisted_5$d = { class: "tao-modal__content" };
727
- const _hoisted_6$9 = {
724
+ const _hoisted_3$q = ["id"];
725
+ const _hoisted_4$m = { key: 1 };
726
+ const _hoisted_5$f = { class: "tao-modal__content" };
727
+ const _hoisted_6$b = {
728
728
  key: 1,
729
729
  class: "tao-modal__footer"
730
730
  };
731
- const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
731
+ const _sfc_main$L = /* @__PURE__ */ vue.defineComponent({
732
732
  ...{ name: "TaoModal" },
733
733
  __name: "TaoModal",
734
734
  props: {
@@ -828,13 +828,13 @@
828
828
  "aria-labelledby": __props.title ? vue.unref(titleId) : void 0,
829
829
  tabindex: "-1"
830
830
  }, [
831
- __props.title || _ctx.$slots.header || __props.closable ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$t, [
831
+ __props.title || _ctx.$slots.header || __props.closable ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$w, [
832
832
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
833
833
  __props.title ? (vue.openBlock(), vue.createElementBlock("h2", {
834
834
  key: 0,
835
835
  id: vue.unref(titleId),
836
836
  class: "tao-modal__title"
837
- }, vue.toDisplayString(__props.title), 9, _hoisted_3$n)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$k))
837
+ }, vue.toDisplayString(__props.title), 9, _hoisted_3$q)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$m))
838
838
  ], true),
839
839
  __props.closable ? (vue.openBlock(), vue.createElementBlock("button", {
840
840
  key: 0,
@@ -844,13 +844,13 @@
844
844
  onClick: close
845
845
  }, " × ")) : vue.createCommentVNode("", true)
846
846
  ])) : vue.createCommentVNode("", true),
847
- vue.createElementVNode("div", _hoisted_5$d, [
847
+ vue.createElementVNode("div", _hoisted_5$f, [
848
848
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
849
849
  ]),
850
- _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$9, [
850
+ _ctx.$slots.footer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$b, [
851
851
  vue.renderSlot(_ctx.$slots, "footer", {}, void 0, true)
852
852
  ])) : vue.createCommentVNode("", true)
853
- ], 8, _hoisted_1$y)
853
+ ], 8, _hoisted_1$D)
854
854
  ], 32)) : vue.createCommentVNode("", true)
855
855
  ]),
856
856
  _: 3
@@ -859,11 +859,11 @@
859
859
  };
860
860
  }
861
861
  });
862
- const TaoModal = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["__scopeId", "data-v-0cffe849"]]);
863
- const _hoisted_1$x = { class: "tao-tabs" };
864
- const _hoisted_2$s = ["id", "aria-selected", "aria-controls", "tabindex", "disabled", "onClick"];
865
- const _hoisted_3$m = ["id", "aria-labelledby"];
866
- const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
862
+ const TaoModal = /* @__PURE__ */ _export_sfc(_sfc_main$L, [["__scopeId", "data-v-0cffe849"]]);
863
+ const _hoisted_1$C = { class: "tao-tabs" };
864
+ const _hoisted_2$v = ["id", "aria-selected", "aria-controls", "tabindex", "disabled", "onClick"];
865
+ const _hoisted_3$p = ["id", "aria-labelledby"];
866
+ const _sfc_main$K = /* @__PURE__ */ vue.defineComponent({
867
867
  ...{ name: "TaoTabs" },
868
868
  __name: "TaoTabs",
869
869
  props: {
@@ -927,7 +927,7 @@
927
927
  }
928
928
  }
929
929
  return (_ctx, _cache) => {
930
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$x, [
930
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$C, [
931
931
  vue.createElementVNode("div", {
932
932
  class: "tao-tabs__list",
933
933
  role: "tablist",
@@ -952,7 +952,7 @@
952
952
  }, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
953
953
  vue.createTextVNode(vue.toDisplayString(tab.label), 1)
954
954
  ], 64))
955
- ], 8, _hoisted_2$s);
955
+ ], 8, _hoisted_2$v);
956
956
  }), 128))
957
957
  ], 32),
958
958
  vue.createElementVNode("div", {
@@ -962,13 +962,13 @@
962
962
  "aria-labelledby": tabId(__props.modelValue)
963
963
  }, [
964
964
  vue.renderSlot(_ctx.$slots, "default", { activeTab: __props.modelValue }, void 0, true)
965
- ], 8, _hoisted_3$m)
965
+ ], 8, _hoisted_3$p)
966
966
  ]);
967
967
  };
968
968
  }
969
969
  });
970
- const TaoTabs = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-bf16735e"]]);
971
- const _sfc_main$E = /* @__PURE__ */ vue.defineComponent({
970
+ const TaoTabs = /* @__PURE__ */ _export_sfc(_sfc_main$K, [["__scopeId", "data-v-bf16735e"]]);
971
+ const _sfc_main$J = /* @__PURE__ */ vue.defineComponent({
972
972
  ...{ name: "TaoTooltip" },
973
973
  __name: "TaoTooltip",
974
974
  props: {
@@ -1000,22 +1000,213 @@
1000
1000
  };
1001
1001
  }
1002
1002
  });
1003
- const TaoTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-6f3b3c11"]]);
1004
- const _hoisted_1$w = { class: "tao-spoiler" };
1005
- const _hoisted_2$r = ["aria-expanded", "aria-controls"];
1006
- const _hoisted_3$l = {
1003
+ const TaoTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$J, [["__scopeId", "data-v-6f3b3c11"]]);
1004
+ const _hoisted_1$B = { class: "tao-popover" };
1005
+ const _sfc_main$I = /* @__PURE__ */ vue.defineComponent({
1006
+ ...{ name: "TaoPopover" },
1007
+ __name: "TaoPopover",
1008
+ props: {
1009
+ modelValue: { type: Boolean, default: void 0 },
1010
+ position: { default: "bottom" },
1011
+ disabled: { type: Boolean, default: false }
1012
+ },
1013
+ emits: ["update:modelValue", "change"],
1014
+ setup(__props, { emit: __emit }) {
1015
+ const props = __props;
1016
+ const emit = __emit;
1017
+ const triggerRef = vue.ref(null);
1018
+ const panelRef = vue.ref(null);
1019
+ const internal = vue.ref(false);
1020
+ const panelStyle = vue.ref({ top: "0px", left: "0px" });
1021
+ const isControlled = vue.computed(() => props.modelValue !== void 0);
1022
+ const open = vue.computed(() => isControlled.value ? Boolean(props.modelValue) : internal.value);
1023
+ function setOpen(next) {
1024
+ if (props.disabled && next) {
1025
+ return;
1026
+ }
1027
+ if (!isControlled.value) {
1028
+ internal.value = next;
1029
+ }
1030
+ emit("update:modelValue", next);
1031
+ emit("change", next);
1032
+ }
1033
+ function toggle() {
1034
+ void applyOpen(!open.value);
1035
+ }
1036
+ function close() {
1037
+ void applyOpen(false);
1038
+ }
1039
+ async function applyOpen(next) {
1040
+ var _a;
1041
+ setOpen(next);
1042
+ if (!next) {
1043
+ return;
1044
+ }
1045
+ await vue.nextTick();
1046
+ updatePosition();
1047
+ (_a = panelRef.value) == null ? void 0 : _a.focus();
1048
+ }
1049
+ function focusTrigger() {
1050
+ var _a, _b;
1051
+ const root = triggerRef.value;
1052
+ const focusable = root == null ? void 0 : root.querySelector(
1053
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1054
+ );
1055
+ (_b = (_a = focusable ?? root) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
1056
+ }
1057
+ function updatePosition() {
1058
+ const trigger = triggerRef.value;
1059
+ const panel = panelRef.value;
1060
+ if (!trigger || !panel) {
1061
+ return;
1062
+ }
1063
+ const rect = trigger.getBoundingClientRect();
1064
+ const width = panel.offsetWidth;
1065
+ const height = panel.offsetHeight;
1066
+ const gap = 4;
1067
+ const pad = 8;
1068
+ const viewW = window.innerWidth;
1069
+ const viewH = window.innerHeight;
1070
+ const space = {
1071
+ bottom: viewH - rect.bottom - gap - pad,
1072
+ top: rect.top - gap - pad,
1073
+ right: viewW - rect.right - gap - pad,
1074
+ left: rect.left - gap - pad
1075
+ };
1076
+ const opposite = {
1077
+ bottom: "top",
1078
+ top: "bottom",
1079
+ left: "right",
1080
+ right: "left"
1081
+ };
1082
+ let side = props.position;
1083
+ const need = side === "top" || side === "bottom" ? height : width;
1084
+ if (space[side] < need && space[opposite[side]] > space[side]) {
1085
+ side = opposite[side];
1086
+ }
1087
+ let top = 0;
1088
+ let left = 0;
1089
+ if (side === "bottom") {
1090
+ top = rect.bottom + gap;
1091
+ left = rect.left;
1092
+ } else if (side === "top") {
1093
+ top = rect.top - height - gap;
1094
+ left = rect.left;
1095
+ } else if (side === "right") {
1096
+ top = rect.top;
1097
+ left = rect.right + gap;
1098
+ } else {
1099
+ top = rect.top;
1100
+ left = rect.left - width - gap;
1101
+ }
1102
+ if (left + width > viewW - pad) {
1103
+ left = viewW - pad - width;
1104
+ }
1105
+ if (left < pad) {
1106
+ left = pad;
1107
+ }
1108
+ if (top + height > viewH - pad) {
1109
+ top = viewH - pad - height;
1110
+ }
1111
+ if (top < pad) {
1112
+ top = pad;
1113
+ }
1114
+ panelStyle.value = { top: `${top}px`, left: `${left}px` };
1115
+ }
1116
+ function onTriggerClick() {
1117
+ if (props.disabled) {
1118
+ return;
1119
+ }
1120
+ toggle();
1121
+ }
1122
+ function onDocumentPointer(event) {
1123
+ var _a, _b;
1124
+ const target = event.target;
1125
+ if (((_a = triggerRef.value) == null ? void 0 : _a.contains(target)) || ((_b = panelRef.value) == null ? void 0 : _b.contains(target))) {
1126
+ return;
1127
+ }
1128
+ close();
1129
+ }
1130
+ function onDocumentKey(event) {
1131
+ if (event.key !== "Escape") {
1132
+ return;
1133
+ }
1134
+ event.preventDefault();
1135
+ close();
1136
+ focusTrigger();
1137
+ }
1138
+ function onViewportChange() {
1139
+ if (open.value) {
1140
+ updatePosition();
1141
+ }
1142
+ }
1143
+ vue.watch(open, (isOpen) => {
1144
+ if (isOpen) {
1145
+ document.addEventListener("pointerdown", onDocumentPointer);
1146
+ document.addEventListener("keydown", onDocumentKey);
1147
+ window.addEventListener("resize", onViewportChange);
1148
+ window.addEventListener("scroll", onViewportChange, true);
1149
+ return;
1150
+ }
1151
+ document.removeEventListener("pointerdown", onDocumentPointer);
1152
+ document.removeEventListener("keydown", onDocumentKey);
1153
+ window.removeEventListener("resize", onViewportChange);
1154
+ window.removeEventListener("scroll", onViewportChange, true);
1155
+ });
1156
+ vue.onBeforeUnmount(() => {
1157
+ document.removeEventListener("pointerdown", onDocumentPointer);
1158
+ document.removeEventListener("keydown", onDocumentKey);
1159
+ window.removeEventListener("resize", onViewportChange);
1160
+ window.removeEventListener("scroll", onViewportChange, true);
1161
+ });
1162
+ return (_ctx, _cache) => {
1163
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$B, [
1164
+ vue.createElementVNode("div", {
1165
+ ref_key: "triggerRef",
1166
+ ref: triggerRef,
1167
+ class: "tao-popover__trigger",
1168
+ onClick: onTriggerClick
1169
+ }, [
1170
+ vue.renderSlot(_ctx.$slots, "trigger", {
1171
+ open: open.value,
1172
+ toggle
1173
+ }, void 0, true)
1174
+ ], 512),
1175
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
1176
+ open.value ? (vue.openBlock(), vue.createElementBlock("div", {
1177
+ key: 0,
1178
+ ref_key: "panelRef",
1179
+ ref: panelRef,
1180
+ class: "tao-popover__panel",
1181
+ role: "dialog",
1182
+ tabindex: "-1",
1183
+ style: vue.normalizeStyle(panelStyle.value)
1184
+ }, [
1185
+ vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1186
+ ], 4)) : vue.createCommentVNode("", true)
1187
+ ]))
1188
+ ]);
1189
+ };
1190
+ }
1191
+ });
1192
+ const TaoPopover = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-e4ead301"]]);
1193
+ const spoilerGroupKey = Symbol("taoSpoilerGroup");
1194
+ const _hoisted_1$A = { class: "tao-spoiler" };
1195
+ const _hoisted_2$u = ["aria-expanded", "aria-controls"];
1196
+ const _hoisted_3$o = {
1007
1197
  key: 0,
1008
1198
  class: "tao-spoiler__title"
1009
1199
  };
1010
- const _hoisted_4$j = ["id"];
1011
- const _hoisted_5$c = { class: "tao-spoiler__content-inner" };
1012
- const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
1200
+ const _hoisted_4$l = ["id"];
1201
+ const _hoisted_5$e = { class: "tao-spoiler__content-inner" };
1202
+ const _sfc_main$H = /* @__PURE__ */ vue.defineComponent({
1013
1203
  ...{ name: "TaoSpoiler" },
1014
1204
  __name: "TaoSpoiler",
1015
1205
  props: {
1016
1206
  title: { default: "" },
1017
1207
  defaultOpen: { type: Boolean, default: false },
1018
- modelValue: { type: Boolean, default: void 0 }
1208
+ modelValue: { type: Boolean, default: void 0 },
1209
+ name: { default: void 0 }
1019
1210
  },
1020
1211
  emits: ["update:modelValue"],
1021
1212
  setup(__props, { emit: __emit }) {
@@ -1023,9 +1214,20 @@
1023
1214
  const emit = __emit;
1024
1215
  const panelId = vue.useId();
1025
1216
  const internal = vue.ref(props.defaultOpen);
1217
+ const group = vue.inject(spoilerGroupKey, null);
1218
+ const inGroup = vue.computed(() => group !== null && props.name !== void 0 && props.name !== "");
1026
1219
  const isControlled = vue.computed(() => props.modelValue !== void 0);
1027
- const isOpen = vue.computed(() => isControlled.value ? Boolean(props.modelValue) : internal.value);
1220
+ const isOpen = vue.computed(() => {
1221
+ if (inGroup.value) {
1222
+ return group.model.value === props.name;
1223
+ }
1224
+ return isControlled.value ? Boolean(props.modelValue) : internal.value;
1225
+ });
1028
1226
  function toggle() {
1227
+ if (inGroup.value) {
1228
+ group.setOpen(isOpen.value ? null : props.name);
1229
+ return;
1230
+ }
1029
1231
  const next = !isOpen.value;
1030
1232
  if (!isControlled.value) {
1031
1233
  internal.value = next;
@@ -1052,7 +1254,7 @@
1052
1254
  });
1053
1255
  }
1054
1256
  return (_ctx, _cache) => {
1055
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$w, [
1257
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$A, [
1056
1258
  vue.createElementVNode("button", {
1057
1259
  type: "button",
1058
1260
  class: "tao-spoiler__header",
@@ -1063,12 +1265,12 @@
1063
1265
  vue.createElementVNode("span", {
1064
1266
  class: vue.normalizeClass(["tao-spoiler__icon", { "tao-spoiler__icon--open": isOpen.value }])
1065
1267
  }, "▶", 2),
1066
- __props.title || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$l, [
1268
+ __props.title || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$o, [
1067
1269
  vue.renderSlot(_ctx.$slots, "title", {}, () => [
1068
1270
  vue.createTextVNode(vue.toDisplayString(__props.title), 1)
1069
1271
  ], true)
1070
1272
  ])) : vue.createCommentVNode("", true)
1071
- ], 8, _hoisted_2$r),
1273
+ ], 8, _hoisted_2$u),
1072
1274
  vue.createVNode(vue.Transition, {
1073
1275
  name: "tao-spoiler-slide",
1074
1276
  onBeforeEnter,
@@ -1082,10 +1284,10 @@
1082
1284
  id: vue.unref(panelId),
1083
1285
  class: "tao-spoiler__content"
1084
1286
  }, [
1085
- vue.createElementVNode("div", _hoisted_5$c, [
1287
+ vue.createElementVNode("div", _hoisted_5$e, [
1086
1288
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1087
1289
  ])
1088
- ], 8, _hoisted_4$j)) : vue.createCommentVNode("", true)
1290
+ ], 8, _hoisted_4$l)) : vue.createCommentVNode("", true)
1089
1291
  ]),
1090
1292
  _: 3
1091
1293
  })
@@ -1093,33 +1295,136 @@
1093
1295
  };
1094
1296
  }
1095
1297
  });
1096
- const TaoSpoiler = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-c9f4d962"]]);
1097
- const _hoisted_1$v = { class: "tao-copy" };
1098
- const _sfc_main$C = /* @__PURE__ */ vue.defineComponent({
1298
+ const TaoSpoiler = /* @__PURE__ */ _export_sfc(_sfc_main$H, [["__scopeId", "data-v-ccb052cf"]]);
1299
+ const _hoisted_1$z = { class: "tao-spoiler-group" };
1300
+ const _sfc_main$G = /* @__PURE__ */ vue.defineComponent({
1301
+ ...{ name: "TaoSpoilerGroup" },
1302
+ __name: "TaoSpoilerGroup",
1303
+ props: {
1304
+ modelValue: { default: null }
1305
+ },
1306
+ emits: ["update:modelValue", "change"],
1307
+ setup(__props, { emit: __emit }) {
1308
+ const props = __props;
1309
+ const emit = __emit;
1310
+ const model = vue.computed(() => props.modelValue);
1311
+ function setOpen(name) {
1312
+ emit("update:modelValue", name);
1313
+ emit("change", name);
1314
+ }
1315
+ vue.provide(spoilerGroupKey, {
1316
+ model,
1317
+ setOpen
1318
+ });
1319
+ return (_ctx, _cache) => {
1320
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$z, [
1321
+ vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1322
+ ]);
1323
+ };
1324
+ }
1325
+ });
1326
+ const TaoSpoilerGroup = /* @__PURE__ */ _export_sfc(_sfc_main$G, [["__scopeId", "data-v-6b172e89"]]);
1327
+ const _hoisted_1$y = ["aria-label"];
1328
+ const _sfc_main$F = /* @__PURE__ */ vue.defineComponent({
1099
1329
  ...{ name: "TaoCopy" },
1100
1330
  __name: "TaoCopy",
1101
1331
  props: {
1102
1332
  text: {},
1103
- successMessage: { default: "Скопировано!" }
1333
+ successMessage: { default: "Скопировано!" },
1334
+ tip: { type: Boolean, default: true }
1104
1335
  },
1105
1336
  setup(__props) {
1106
1337
  const props = __props;
1107
1338
  const copied = vue.ref(false);
1108
- let timeoutId;
1339
+ const triggerRef = vue.ref(null);
1340
+ const tipRef = vue.ref(null);
1341
+ const tipStyle = vue.ref({ top: "0px", left: "0px" });
1342
+ let hideTimer = 0;
1343
+ let visibleObserver = null;
1344
+ function hideTip() {
1345
+ copied.value = false;
1346
+ window.clearTimeout(hideTimer);
1347
+ hideTimer = 0;
1348
+ }
1349
+ function updateTipPosition() {
1350
+ const trigger = triggerRef.value;
1351
+ const tip = tipRef.value;
1352
+ if (!trigger || !tip) {
1353
+ return;
1354
+ }
1355
+ const rect = trigger.getBoundingClientRect();
1356
+ if (rect.width === 0 && rect.height === 0) {
1357
+ hideTip();
1358
+ return;
1359
+ }
1360
+ const gap = 8;
1361
+ const pad = 8;
1362
+ const width = tip.offsetWidth;
1363
+ const height = tip.offsetHeight;
1364
+ let left = rect.left + rect.width / 2 - width / 2;
1365
+ let top = rect.top - height - gap;
1366
+ if (left < pad) {
1367
+ left = pad;
1368
+ }
1369
+ if (left + width > window.innerWidth - pad) {
1370
+ left = window.innerWidth - pad - width;
1371
+ }
1372
+ if (top < pad) {
1373
+ top = rect.bottom + gap;
1374
+ }
1375
+ tipStyle.value = { top: `${top}px`, left: `${left}px` };
1376
+ }
1377
+ function bindTipGuards() {
1378
+ window.addEventListener("scroll", updateTipPosition, true);
1379
+ window.addEventListener("resize", updateTipPosition);
1380
+ }
1381
+ function unbindTipGuards() {
1382
+ window.removeEventListener("scroll", updateTipPosition, true);
1383
+ window.removeEventListener("resize", updateTipPosition);
1384
+ }
1109
1385
  async function copy() {
1110
1386
  try {
1111
1387
  await navigator.clipboard.writeText(props.text);
1112
1388
  copied.value = true;
1113
- clearTimeout(timeoutId);
1114
- timeoutId = setTimeout(() => {
1115
- copied.value = false;
1116
- }, 2e3);
1389
+ window.clearTimeout(hideTimer);
1390
+ hideTimer = window.setTimeout(hideTip, 2e3);
1117
1391
  } catch (err) {
1118
1392
  console.error("Failed to copy:", err);
1393
+ hideTip();
1119
1394
  }
1120
1395
  }
1396
+ vue.watch(copied, async (isCopied) => {
1397
+ if (!isCopied || !props.tip) {
1398
+ unbindTipGuards();
1399
+ return;
1400
+ }
1401
+ await vue.nextTick();
1402
+ await vue.nextTick();
1403
+ updateTipPosition();
1404
+ bindTipGuards();
1405
+ });
1406
+ vue.onMounted(() => {
1407
+ visibleObserver = new IntersectionObserver((entries) => {
1408
+ if (entries.some((entry) => !entry.isIntersecting)) {
1409
+ hideTip();
1410
+ }
1411
+ });
1412
+ if (triggerRef.value) {
1413
+ visibleObserver.observe(triggerRef.value);
1414
+ }
1415
+ });
1416
+ vue.onBeforeUnmount(() => {
1417
+ hideTip();
1418
+ unbindTipGuards();
1419
+ visibleObserver == null ? void 0 : visibleObserver.disconnect();
1420
+ visibleObserver = null;
1421
+ });
1121
1422
  return (_ctx, _cache) => {
1122
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$v, [
1423
+ return vue.openBlock(), vue.createElementBlock("span", {
1424
+ ref_key: "triggerRef",
1425
+ ref: triggerRef,
1426
+ class: "tao-copy"
1427
+ }, [
1123
1428
  vue.renderSlot(_ctx.$slots, "default", {
1124
1429
  copy,
1125
1430
  copied: copied.value
@@ -1127,15 +1432,51 @@
1127
1432
  vue.createElementVNode("button", {
1128
1433
  type: "button",
1129
1434
  class: vue.normalizeClass(["tao-copy__button", { "tao-copy__button--copied": copied.value }]),
1435
+ "aria-label": copied.value ? __props.successMessage : "Копировать",
1130
1436
  onClick: copy
1131
- }, vue.toDisplayString(copied.value ? __props.successMessage : "Копировать"), 3)
1132
- ], true)
1133
- ]);
1437
+ }, [..._cache[0] || (_cache[0] = [
1438
+ vue.createElementVNode("svg", {
1439
+ viewBox: "0 0 24 24",
1440
+ width: "16",
1441
+ height: "16",
1442
+ "aria-hidden": "true",
1443
+ focusable: "false"
1444
+ }, [
1445
+ vue.createElementVNode("rect", {
1446
+ x: "8",
1447
+ y: "7",
1448
+ width: "12",
1449
+ height: "14",
1450
+ rx: "2",
1451
+ fill: "none",
1452
+ stroke: "currentColor",
1453
+ "stroke-width": "2"
1454
+ }),
1455
+ vue.createElementVNode("path", {
1456
+ d: "M16 7V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h2",
1457
+ fill: "none",
1458
+ stroke: "currentColor",
1459
+ "stroke-width": "2"
1460
+ })
1461
+ ], -1)
1462
+ ])], 10, _hoisted_1$y)
1463
+ ], true),
1464
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
1465
+ copied.value && __props.tip && __props.successMessage ? (vue.openBlock(), vue.createElementBlock("div", {
1466
+ key: 0,
1467
+ ref_key: "tipRef",
1468
+ ref: tipRef,
1469
+ class: "tao-copy__tip",
1470
+ role: "status",
1471
+ style: vue.normalizeStyle(tipStyle.value)
1472
+ }, vue.toDisplayString(__props.successMessage), 5)) : vue.createCommentVNode("", true)
1473
+ ]))
1474
+ ], 512);
1134
1475
  };
1135
1476
  }
1136
1477
  });
1137
- const TaoCopy = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-73a42ad9"]]);
1138
- const _sfc_main$B = /* @__PURE__ */ vue.defineComponent({
1478
+ const TaoCopy = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-1953c07e"]]);
1479
+ const _sfc_main$E = /* @__PURE__ */ vue.defineComponent({
1139
1480
  ...{ name: "TaoContainer" },
1140
1481
  __name: "TaoContainer",
1141
1482
  props: {
@@ -1152,8 +1493,8 @@
1152
1493
  };
1153
1494
  }
1154
1495
  });
1155
- const TaoContainer = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-4c0deb90"]]);
1156
- const _sfc_main$A = /* @__PURE__ */ vue.defineComponent({
1496
+ const TaoContainer = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-4c0deb90"]]);
1497
+ const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
1157
1498
  ...{ name: "TaoFlex" },
1158
1499
  __name: "TaoFlex",
1159
1500
  props: {
@@ -1184,7 +1525,7 @@
1184
1525
  };
1185
1526
  }
1186
1527
  });
1187
- const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
1528
+ const _sfc_main$C = /* @__PURE__ */ vue.defineComponent({
1188
1529
  ...{ name: "TaoSpace" },
1189
1530
  __name: "TaoSpace",
1190
1531
  props: {
@@ -1204,9 +1545,9 @@
1204
1545
  };
1205
1546
  }
1206
1547
  });
1207
- const TaoSpace = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-698ca712"]]);
1208
- const _hoisted_1$u = { class: "tao-icon" };
1209
- const _sfc_main$y = /* @__PURE__ */ vue.defineComponent({
1548
+ const TaoSpace = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["__scopeId", "data-v-698ca712"]]);
1549
+ const _hoisted_1$x = { class: "tao-icon" };
1550
+ const _sfc_main$B = /* @__PURE__ */ vue.defineComponent({
1210
1551
  ...{ name: "TaoIcon" },
1211
1552
  __name: "TaoIcon",
1212
1553
  props: {
@@ -1221,7 +1562,7 @@
1221
1562
  }));
1222
1563
  const props = __props;
1223
1564
  return (_ctx, _cache) => {
1224
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$u, [
1565
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$x, [
1225
1566
  vue.renderSlot(_ctx.$slots, "prefix", {}, void 0, true),
1226
1567
  vue.createElementVNode("i", {
1227
1568
  class: vue.normalizeClass(["tao-icon__value", [`icon-${props.name}`, { "tao-icon__value--invert": props.invert }]]),
@@ -1232,8 +1573,8 @@
1232
1573
  };
1233
1574
  }
1234
1575
  });
1235
- const TaoIcon = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["__scopeId", "data-v-145b2cfc"]]);
1236
- const _sfc_main$x = /* @__PURE__ */ vue.defineComponent({
1576
+ const TaoIcon = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["__scopeId", "data-v-145b2cfc"]]);
1577
+ const _sfc_main$A = /* @__PURE__ */ vue.defineComponent({
1237
1578
  ...{ name: "TaoLoader" },
1238
1579
  __name: "TaoLoader",
1239
1580
  props: {
@@ -1294,16 +1635,17 @@
1294
1635
  };
1295
1636
  }
1296
1637
  });
1297
- const TaoLoader = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["__scopeId", "data-v-75a40018"]]);
1298
- const _hoisted_1$t = { class: "tao-image" };
1299
- const _hoisted_2$q = ["src", "alt"];
1300
- const _sfc_main$w = /* @__PURE__ */ vue.defineComponent({
1638
+ const TaoLoader = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["__scopeId", "data-v-75a40018"]]);
1639
+ const _hoisted_1$w = { class: "tao-image" };
1640
+ const _hoisted_2$t = ["src", "alt", "loading"];
1641
+ const _sfc_main$z = /* @__PURE__ */ vue.defineComponent({
1301
1642
  ...{ name: "TaoImage" },
1302
1643
  __name: "TaoImage",
1303
1644
  props: {
1304
1645
  src: { default: "" },
1305
1646
  alt: { default: "" },
1306
- pixelated: { type: Boolean, default: false }
1647
+ pixelated: { type: Boolean, default: false },
1648
+ lazy: { type: Boolean, default: false }
1307
1649
  },
1308
1650
  emits: ["load", "error"],
1309
1651
  setup(__props, { emit: __emit }) {
@@ -1322,34 +1664,36 @@
1322
1664
  isLoaded.value = false;
1323
1665
  });
1324
1666
  return (_ctx, _cache) => {
1325
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$t, [
1667
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$w, [
1326
1668
  __props.src ? (vue.openBlock(), vue.createElementBlock("img", {
1327
1669
  key: 0,
1328
1670
  class: vue.normalizeClass({ "tao-image__img--hidden": !isLoaded.value, "tao-image__img--pixelated": props.pixelated }),
1329
1671
  src: __props.src,
1330
1672
  alt: __props.alt,
1673
+ loading: __props.lazy ? "lazy" : "eager",
1674
+ decoding: "async",
1331
1675
  draggable: "false",
1332
1676
  onLoad: handleLoad,
1333
1677
  onError: handleError
1334
- }, null, 42, _hoisted_2$q)) : vue.renderSlot(_ctx.$slots, "default", {}, () => [
1678
+ }, null, 42, _hoisted_2$t)) : vue.renderSlot(_ctx.$slots, "default", {}, () => [
1335
1679
  _cache[0] || (_cache[0] = vue.createElementVNode("div", { class: "tao-image__placeholder" }, "No image available", -1))
1336
1680
  ], true, 1)
1337
1681
  ]);
1338
1682
  };
1339
1683
  }
1340
1684
  });
1341
- const TaoImage = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["__scopeId", "data-v-9da4bb7d"]]);
1342
- const _hoisted_1$s = ["for"];
1343
- const _hoisted_2$p = ["id", "checked", "disabled", "aria-checked", "aria-invalid", "aria-describedby"];
1344
- const _hoisted_3$k = {
1685
+ const TaoImage = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["__scopeId", "data-v-522fe4da"]]);
1686
+ const _hoisted_1$v = ["for"];
1687
+ const _hoisted_2$s = ["id", "checked", "disabled", "aria-checked", "aria-invalid", "aria-describedby"];
1688
+ const _hoisted_3$n = {
1345
1689
  key: 0,
1346
1690
  class: "tao-checkbox__label"
1347
1691
  };
1348
- const _hoisted_4$i = {
1692
+ const _hoisted_4$k = {
1349
1693
  key: 1,
1350
1694
  class: "tao-checkbox__label"
1351
1695
  };
1352
- const _sfc_main$v = /* @__PURE__ */ vue.defineComponent({
1696
+ const _sfc_main$y = /* @__PURE__ */ vue.defineComponent({
1353
1697
  ...{ name: "TaoCheckbox" },
1354
1698
  __name: "TaoCheckbox",
1355
1699
  props: {
@@ -1419,18 +1763,18 @@
1419
1763
  "aria-invalid": invalid.value || void 0,
1420
1764
  "aria-describedby": describedBy.value,
1421
1765
  onChange: onInputChange
1422
- }, null, 40, _hoisted_2$p),
1766
+ }, null, 40, _hoisted_2$s),
1423
1767
  _cache[0] || (_cache[0] = vue.createElementVNode("span", { class: "tao-checkbox__box" }, null, -1)),
1424
- __props.label ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$k, vue.toDisplayString(__props.label), 1)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$i, [
1768
+ __props.label ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$n, vue.toDisplayString(__props.label), 1)) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$k, [
1425
1769
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1426
1770
  ])),
1427
1771
  vue.renderSlot(_ctx.$slots, "post", { text: __props.label }, void 0, true)
1428
- ], 10, _hoisted_1$s);
1772
+ ], 10, _hoisted_1$v);
1429
1773
  };
1430
1774
  }
1431
1775
  });
1432
- const TaoCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["__scopeId", "data-v-f6b0e565"]]);
1433
- const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
1776
+ const TaoCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["__scopeId", "data-v-f6b0e565"]]);
1777
+ const _sfc_main$x = /* @__PURE__ */ vue.defineComponent({
1434
1778
  ...{ name: "TaoTag" },
1435
1779
  __name: "TaoTag",
1436
1780
  props: {
@@ -1458,17 +1802,17 @@
1458
1802
  };
1459
1803
  }
1460
1804
  });
1461
- const TaoTag = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-290c0f6a"]]);
1462
- const _hoisted_1$r = {
1805
+ const TaoTag = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["__scopeId", "data-v-290c0f6a"]]);
1806
+ const _hoisted_1$u = {
1463
1807
  key: 1,
1464
1808
  class: "tao-divider-text"
1465
1809
  };
1466
- const _hoisted_2$o = { class: "tao-divider-text__value" };
1467
- const _hoisted_3$j = {
1810
+ const _hoisted_2$r = { class: "tao-divider-text__value" };
1811
+ const _hoisted_3$m = {
1468
1812
  key: 2,
1469
1813
  class: "tao-divider-line"
1470
1814
  };
1471
- const _sfc_main$t = /* @__PURE__ */ vue.defineComponent({
1815
+ const _sfc_main$w = /* @__PURE__ */ vue.defineComponent({
1472
1816
  ...{ name: "TaoDivider" },
1473
1817
  __name: "TaoDivider",
1474
1818
  props: {
@@ -1482,18 +1826,48 @@
1482
1826
  return __props.variant === "gap" ? (vue.openBlock(), vue.createElementBlock("div", {
1483
1827
  key: 0,
1484
1828
  class: vue.normalizeClass(["tao-divider-gap", `tao-divider-gap--${gapSize.value}`])
1485
- }, null, 2)) : __props.variant === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$r, [
1829
+ }, null, 2)) : __props.variant === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$u, [
1486
1830
  _cache[0] || (_cache[0] = vue.createElementVNode("span", { class: "tao-divider-text__line tao-divider-text__line--left" }, null, -1)),
1487
- vue.createElementVNode("span", _hoisted_2$o, [
1831
+ vue.createElementVNode("span", _hoisted_2$r, [
1488
1832
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1489
1833
  ]),
1490
1834
  _cache[1] || (_cache[1] = vue.createElementVNode("span", { class: "tao-divider-text__line tao-divider-text__line--right" }, null, -1))
1491
- ])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$j));
1835
+ ])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$m));
1492
1836
  };
1493
1837
  }
1494
1838
  });
1495
- const TaoDivider = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["__scopeId", "data-v-8187a15d"]]);
1496
- const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
1839
+ const TaoDivider = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["__scopeId", "data-v-8187a15d"]]);
1840
+ const _hoisted_1$t = {
1841
+ key: 0,
1842
+ class: "tao-fieldset__legend"
1843
+ };
1844
+ const _hoisted_2$q = { class: "tao-fieldset__body" };
1845
+ const _sfc_main$v = /* @__PURE__ */ vue.defineComponent({
1846
+ ...{ name: "TaoFieldset" },
1847
+ __name: "TaoFieldset",
1848
+ props: {
1849
+ legend: { default: "" },
1850
+ align: { default: "start" }
1851
+ },
1852
+ setup(__props) {
1853
+ return (_ctx, _cache) => {
1854
+ return vue.openBlock(), vue.createElementBlock("fieldset", {
1855
+ class: vue.normalizeClass(["tao-fieldset", `tao-fieldset--${__props.align}`])
1856
+ }, [
1857
+ __props.legend || _ctx.$slots.legend ? (vue.openBlock(), vue.createElementBlock("legend", _hoisted_1$t, [
1858
+ vue.renderSlot(_ctx.$slots, "legend", {}, () => [
1859
+ vue.createTextVNode(vue.toDisplayString(__props.legend), 1)
1860
+ ], true)
1861
+ ])) : vue.createCommentVNode("", true),
1862
+ vue.createElementVNode("div", _hoisted_2$q, [
1863
+ vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
1864
+ ])
1865
+ ], 2);
1866
+ };
1867
+ }
1868
+ });
1869
+ const TaoFieldset = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["__scopeId", "data-v-34440ba5"]]);
1870
+ const _sfc_main$u = /* @__PURE__ */ vue.defineComponent({
1497
1871
  ...{ name: "TaoAnimatedBorder" },
1498
1872
  __name: "TaoAnimatedBorder",
1499
1873
  props: {
@@ -1517,18 +1891,18 @@
1517
1891
  };
1518
1892
  }
1519
1893
  });
1520
- const TaoAnimatedBorder = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["__scopeId", "data-v-f1534571"]]);
1521
- const _hoisted_1$q = {
1894
+ const TaoAnimatedBorder = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-f1534571"]]);
1895
+ const _hoisted_1$s = {
1522
1896
  key: 0,
1523
1897
  class: "tao-textarea tao-textarea--dummy"
1524
1898
  };
1525
- const _hoisted_2$n = {
1899
+ const _hoisted_2$p = {
1526
1900
  key: 1,
1527
1901
  class: "tao-textarea-wrap"
1528
1902
  };
1529
- const _hoisted_3$i = ["id", "placeholder", "spellcheck", "autocomplete", "minlength", "maxlength", "disabled", "rows", "value", "aria-invalid", "aria-describedby"];
1530
- const _hoisted_4$h = ["id"];
1531
- const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
1903
+ const _hoisted_3$l = ["id", "placeholder", "spellcheck", "autocomplete", "minlength", "maxlength", "disabled", "rows", "value", "aria-invalid", "aria-describedby"];
1904
+ const _hoisted_4$j = ["id"];
1905
+ const _sfc_main$t = /* @__PURE__ */ vue.defineComponent({
1532
1906
  ...{ name: "TaoTextarea" },
1533
1907
  __name: "TaoTextarea",
1534
1908
  props: {
@@ -1625,7 +1999,7 @@
1625
1999
  vue.nextTick(autoResize);
1626
2000
  });
1627
2001
  return (_ctx, _cache) => {
1628
- return __props.dummy ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$q, vue.toDisplayString(__props.modelValue), 1)) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$n, [
2002
+ return __props.dummy ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$s, vue.toDisplayString(__props.modelValue), 1)) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$p, [
1629
2003
  vue.createElementVNode("textarea", {
1630
2004
  id: controlId.value,
1631
2005
  ref_key: "textareaRef",
@@ -1654,21 +2028,21 @@
1654
2028
  onFocus,
1655
2029
  onBlur,
1656
2030
  onKeydown
1657
- }, null, 42, _hoisted_3$i),
2031
+ }, null, 42, _hoisted_3$l),
1658
2032
  __props.count ? (vue.openBlock(), vue.createElementBlock("span", {
1659
2033
  key: 0,
1660
2034
  id: counterId.value,
1661
2035
  class: vue.normalizeClass(["tao-textarea__count", { "tao-textarea__count--limit": atLimit.value }])
1662
- }, vue.toDisplayString(countLabel.value), 11, _hoisted_4$h)) : vue.createCommentVNode("", true)
2036
+ }, vue.toDisplayString(countLabel.value), 11, _hoisted_4$j)) : vue.createCommentVNode("", true)
1663
2037
  ]));
1664
2038
  };
1665
2039
  }
1666
2040
  });
1667
- const TaoTextarea = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-2534c0c4"]]);
1668
- const _hoisted_1$p = ["tabindex"];
1669
- const _hoisted_2$m = { class: "tao-scroll-top__content" };
2041
+ const TaoTextarea = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["__scopeId", "data-v-2534c0c4"]]);
2042
+ const _hoisted_1$r = ["tabindex"];
2043
+ const _hoisted_2$o = { class: "tao-scroll-top__content" };
1670
2044
  const RIPPLE_DURATION = 750;
1671
- const _sfc_main$q = /* @__PURE__ */ vue.defineComponent({
2045
+ const _sfc_main$s = /* @__PURE__ */ vue.defineComponent({
1672
2046
  ...{ name: "TaoScrollTop" },
1673
2047
  __name: "TaoScrollTop",
1674
2048
  props: {
@@ -1768,7 +2142,7 @@
1768
2142
  "aria-label": "Наверх",
1769
2143
  onClick: vue.withModifiers(onClick, ["prevent"])
1770
2144
  }, [
1771
- vue.createElementVNode("div", _hoisted_2$m, [
2145
+ vue.createElementVNode("div", _hoisted_2$o, [
1772
2146
  vue.createElementVNode("div", {
1773
2147
  class: vue.normalizeClass([{ "tao-scroll-top__ripple--active": isRippleActive.value }, "tao-scroll-top__ripple"]),
1774
2148
  style: vue.normalizeStyle(rippleStyle)
@@ -1785,33 +2159,33 @@
1785
2159
  ], -1))
1786
2160
  ], true)
1787
2161
  ])
1788
- ], 14, _hoisted_1$p)) : vue.createCommentVNode("", true)
2162
+ ], 14, _hoisted_1$r)) : vue.createCommentVNode("", true)
1789
2163
  ]),
1790
2164
  _: 3
1791
2165
  });
1792
2166
  };
1793
2167
  }
1794
2168
  });
1795
- const TaoScrollTop = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-ce902f42"]]);
1796
- const _hoisted_1$o = { class: "tao-progress" };
1797
- const _hoisted_2$l = {
2169
+ const TaoScrollTop = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["__scopeId", "data-v-ce902f42"]]);
2170
+ const _hoisted_1$q = { class: "tao-progress" };
2171
+ const _hoisted_2$n = {
1798
2172
  key: 0,
1799
2173
  class: "tao-progress__side"
1800
2174
  };
1801
- const _hoisted_3$h = { class: "tao-progress__main" };
1802
- const _hoisted_4$g = {
2175
+ const _hoisted_3$k = { class: "tao-progress__main" };
2176
+ const _hoisted_4$i = {
1803
2177
  key: 0,
1804
2178
  class: "tao-progress__percentage"
1805
2179
  };
1806
- const _hoisted_5$b = {
2180
+ const _hoisted_5$d = {
1807
2181
  key: 1,
1808
2182
  class: "tao-progress__side"
1809
2183
  };
1810
- const _hoisted_6$8 = {
2184
+ const _hoisted_6$a = {
1811
2185
  key: 0,
1812
2186
  class: "tao-progress__percentage"
1813
2187
  };
1814
- const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
2188
+ const _sfc_main$r = /* @__PURE__ */ vue.defineComponent({
1815
2189
  ...{ name: "TaoProgress" },
1816
2190
  __name: "TaoProgress",
1817
2191
  props: {
@@ -1842,16 +2216,16 @@
1842
2216
  () => hasRight.value ? `(${props.progress}%)` : `${props.progress}%`
1843
2217
  );
1844
2218
  return (_ctx, _cache) => {
1845
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$o, [
2219
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$q, [
1846
2220
  vue.createElementVNode("div", {
1847
2221
  class: vue.normalizeClass(["tao-progress__container", { "tao-progress__container--over": showOverPercent.value }]),
1848
2222
  style: vue.normalizeStyle({ minWidth: `${minW.value}px`, maxWidth: `${maxW.value}px` })
1849
2223
  }, [
1850
- _ctx.$slots.left ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$l, [
2224
+ _ctx.$slots.left ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$n, [
1851
2225
  vue.renderSlot(_ctx.$slots, "left", {}, void 0, true)
1852
2226
  ])) : vue.createCommentVNode("", true),
1853
- vue.createElementVNode("div", _hoisted_3$h, [
1854
- showOverPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$g, vue.toDisplayString(__props.progress) + "%", 1)) : vue.createCommentVNode("", true),
2227
+ vue.createElementVNode("div", _hoisted_3$k, [
2228
+ showOverPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$i, vue.toDisplayString(__props.progress) + "%", 1)) : vue.createCommentVNode("", true),
1855
2229
  vue.createElementVNode("div", {
1856
2230
  class: "tao-progress__track",
1857
2231
  style: vue.normalizeStyle({ height: `${__props.height}px` })
@@ -1862,23 +2236,23 @@
1862
2236
  }, null, 6)
1863
2237
  ], 4)
1864
2238
  ]),
1865
- _ctx.$slots.right || showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$b, [
2239
+ _ctx.$slots.right || showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5$d, [
1866
2240
  vue.renderSlot(_ctx.$slots, "right", {}, void 0, true),
1867
- showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$8, vue.toDisplayString(endPercentLabel.value), 1)) : vue.createCommentVNode("", true)
2241
+ showEndPercent.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_6$a, vue.toDisplayString(endPercentLabel.value), 1)) : vue.createCommentVNode("", true)
1868
2242
  ])) : vue.createCommentVNode("", true)
1869
2243
  ], 6)
1870
2244
  ]);
1871
2245
  };
1872
2246
  }
1873
2247
  });
1874
- const TaoProgress = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-54c13718"]]);
1875
- const _hoisted_1$n = ["id", "tabindex", "aria-valuemin", "aria-valuemax", "aria-valuenow", "aria-disabled", "aria-describedby"];
1876
- const _hoisted_2$k = ["placeholder"];
1877
- const _hoisted_3$g = {
2248
+ const TaoProgress = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-54c13718"]]);
2249
+ const _hoisted_1$p = ["id", "tabindex", "aria-valuemin", "aria-valuemax", "aria-valuenow", "aria-disabled", "aria-describedby"];
2250
+ const _hoisted_2$m = ["placeholder"];
2251
+ const _hoisted_3$j = {
1878
2252
  key: 1,
1879
2253
  class: "tao-slider__value"
1880
2254
  };
1881
- const _sfc_main$o = /* @__PURE__ */ vue.defineComponent({
2255
+ const _sfc_main$q = /* @__PURE__ */ vue.defineComponent({
1882
2256
  ...{ name: "TaoSlider" },
1883
2257
  __name: "TaoSlider",
1884
2258
  props: {
@@ -2072,21 +2446,29 @@
2072
2446
  onKeydown: onShadowKeydown,
2073
2447
  onMousedown: _cache[1] || (_cache[1] = vue.withModifiers(() => {
2074
2448
  }, ["stop"]))
2075
- }, null, 40, _hoisted_2$k)), [
2449
+ }, null, 40, _hoisted_2$m)), [
2076
2450
  [vue.vModelText, shadowModel.value]
2077
- ]) : __props.showValue ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$g, [
2451
+ ]) : __props.showValue ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$j, [
2078
2452
  vue.renderSlot(_ctx.$slots, "pre-value", {}, void 0, true),
2079
2453
  vue.createTextVNode(vue.toDisplayString(__props.modelValue), 1),
2080
2454
  vue.renderSlot(_ctx.$slots, "post-value", {}, void 0, true)
2081
2455
  ])) : vue.createCommentVNode("", true)
2082
- ], 42, _hoisted_1$n);
2456
+ ], 42, _hoisted_1$p);
2083
2457
  };
2084
2458
  }
2085
2459
  });
2086
- const TaoSlider = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-241d1042"]]);
2087
- const _hoisted_1$m = { class: "tao-file-drop" };
2088
- const _hoisted_2$j = ["accept", "multiple"];
2089
- const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
2460
+ const TaoSlider = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["__scopeId", "data-v-241d1042"]]);
2461
+ const _hoisted_1$o = { class: "tao-file-drop" };
2462
+ const _hoisted_2$l = { class: "tao-file-drop__row" };
2463
+ const _hoisted_3$i = ["accept", "multiple"];
2464
+ const _hoisted_4$h = {
2465
+ key: 0,
2466
+ class: "tao-file-drop__list"
2467
+ };
2468
+ const _hoisted_5$c = { class: "tao-file-drop__name" };
2469
+ const _hoisted_6$9 = { class: "tao-file-drop__meta" };
2470
+ const _hoisted_7$7 = ["aria-label", "onClick"];
2471
+ const _sfc_main$p = /* @__PURE__ */ vue.defineComponent({
2090
2472
  ...{ name: "TaoFileDrop" },
2091
2473
  __name: "TaoFileDrop",
2092
2474
  props: {
@@ -2094,7 +2476,8 @@
2094
2476
  size: { default: "medium" },
2095
2477
  accept: { default: "*" },
2096
2478
  multiple: { type: Boolean, default: false },
2097
- showClear: { type: Boolean, default: false }
2479
+ showClear: { type: Boolean, default: false },
2480
+ list: { type: Boolean, default: true }
2098
2481
  },
2099
2482
  emits: ["update:modelValue", "files", "clear-request"],
2100
2483
  setup(__props, { emit: __emit }) {
@@ -2102,6 +2485,13 @@
2102
2485
  const emit = __emit;
2103
2486
  const isDragging = vue.ref(false);
2104
2487
  const fileInput = vue.ref(null);
2488
+ function sameFile(a, b) {
2489
+ return a.name === b.name && a.size === b.size && a.lastModified === b.lastModified;
2490
+ }
2491
+ function commit(files) {
2492
+ emit("update:modelValue", files);
2493
+ emit("files", files);
2494
+ }
2105
2495
  function handleDragOver(event) {
2106
2496
  event.preventDefault();
2107
2497
  isDragging.value = true;
@@ -2127,60 +2517,110 @@
2127
2517
  function requestClear() {
2128
2518
  emit("clear-request");
2129
2519
  }
2520
+ function removeAt(index) {
2521
+ commit(props.modelValue.filter((_, item) => item !== index));
2522
+ }
2130
2523
  function processFiles(fileList) {
2131
- const files = Array.from(fileList);
2132
- const result = !props.multiple && files.length > 1 ? [files[0]] : files;
2133
- emit("update:modelValue", result);
2134
- emit("files", result);
2524
+ const incoming = Array.from(fileList);
2525
+ if (!incoming.length) {
2526
+ return;
2527
+ }
2528
+ let result;
2529
+ if (!props.multiple) {
2530
+ result = [incoming[0]];
2531
+ } else {
2532
+ result = [...props.modelValue];
2533
+ for (const file of incoming) {
2534
+ if (!result.some((item) => sameFile(item, file))) {
2535
+ result.push(file);
2536
+ }
2537
+ }
2538
+ }
2539
+ commit(result);
2135
2540
  const el = fileInput.value;
2136
2541
  if (el) {
2137
2542
  el.type = "text";
2138
2543
  el.type = "file";
2139
2544
  }
2140
2545
  }
2546
+ function formatSize(bytes) {
2547
+ if (bytes < 1024) {
2548
+ return `${bytes} Б`;
2549
+ }
2550
+ const kb = bytes / 1024;
2551
+ if (kb < 1024) {
2552
+ const value2 = kb < 10 ? kb.toFixed(1) : String(Math.round(kb));
2553
+ return `${value2.replace(".", ",")} КБ`;
2554
+ }
2555
+ const mb = kb / 1024;
2556
+ const value = mb < 10 ? mb.toFixed(1) : String(Math.round(mb));
2557
+ return `${value.replace(".", ",")} МБ`;
2558
+ }
2559
+ function fileKey(file, index) {
2560
+ return `${file.name}-${file.size}-${file.lastModified}-${index}`;
2561
+ }
2141
2562
  return (_ctx, _cache) => {
2142
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$m, [
2143
- __props.showClear && __props.modelValue.length ? (vue.openBlock(), vue.createElementBlock("button", {
2144
- key: 0,
2145
- type: "button",
2146
- class: "tao-file-drop__clear",
2147
- "aria-label": "Очистить файлы",
2148
- onClick: requestClear
2149
- }, " ✕ ")) : vue.createCommentVNode("", true),
2150
- vue.createElementVNode("label", {
2151
- class: vue.normalizeClass(["tao-file-drop__zone", [`tao-file-drop__zone--${__props.size}`, { "tao-file-drop__zone--dragging": isDragging.value }]]),
2152
- onDragover: handleDragOver,
2153
- onDragleave: handleDragLeave,
2154
- onDrop: handleDrop
2155
- }, [
2156
- vue.renderSlot(_ctx.$slots, "default", {}, () => [
2157
- _cache[1] || (_cache[1] = vue.createTextVNode("Перетащите файл сюда или нажмите, чтобы выбрать", -1))
2158
- ], true),
2159
- vue.createElementVNode("input", {
2160
- ref_key: "fileInput",
2161
- ref: fileInput,
2162
- class: "tao-sr-only",
2163
- type: "file",
2164
- accept: __props.accept,
2165
- multiple: __props.multiple,
2166
- onChange: handleFileSelect,
2167
- onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
2168
- }, ["stop"]))
2169
- }, null, 40, _hoisted_2$j)
2170
- ], 34)
2563
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$o, [
2564
+ vue.createElementVNode("div", _hoisted_2$l, [
2565
+ __props.showClear && __props.modelValue.length ? (vue.openBlock(), vue.createElementBlock("button", {
2566
+ key: 0,
2567
+ type: "button",
2568
+ class: "tao-file-drop__clear",
2569
+ "aria-label": "Очистить файлы",
2570
+ onClick: requestClear
2571
+ }, " ✕ ")) : vue.createCommentVNode("", true),
2572
+ vue.createElementVNode("label", {
2573
+ class: vue.normalizeClass(["tao-file-drop__zone", [`tao-file-drop__zone--${__props.size}`, { "tao-file-drop__zone--dragging": isDragging.value }]]),
2574
+ onDragover: handleDragOver,
2575
+ onDragleave: handleDragLeave,
2576
+ onDrop: handleDrop
2577
+ }, [
2578
+ vue.renderSlot(_ctx.$slots, "default", {}, () => [
2579
+ _cache[1] || (_cache[1] = vue.createTextVNode("Перетащите файл сюда или нажмите, чтобы выбрать", -1))
2580
+ ], true),
2581
+ vue.createElementVNode("input", {
2582
+ ref_key: "fileInput",
2583
+ ref: fileInput,
2584
+ class: "tao-sr-only",
2585
+ type: "file",
2586
+ accept: __props.accept,
2587
+ multiple: __props.multiple,
2588
+ onChange: handleFileSelect,
2589
+ onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
2590
+ }, ["stop"]))
2591
+ }, null, 40, _hoisted_3$i)
2592
+ ], 34)
2593
+ ]),
2594
+ __props.list && __props.modelValue.length ? (vue.openBlock(), vue.createElementBlock("ul", _hoisted_4$h, [
2595
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.modelValue, (file, index) => {
2596
+ return vue.openBlock(), vue.createElementBlock("li", {
2597
+ key: fileKey(file, index),
2598
+ class: "tao-file-drop__file"
2599
+ }, [
2600
+ vue.createElementVNode("span", _hoisted_5$c, vue.toDisplayString(file.name), 1),
2601
+ vue.createElementVNode("span", _hoisted_6$9, vue.toDisplayString(formatSize(file.size)), 1),
2602
+ vue.createElementVNode("button", {
2603
+ type: "button",
2604
+ class: "tao-file-drop__remove",
2605
+ "aria-label": `Убрать «${file.name}»`,
2606
+ onClick: ($event) => removeAt(index)
2607
+ }, " ✕ ", 8, _hoisted_7$7)
2608
+ ]);
2609
+ }), 128))
2610
+ ])) : vue.createCommentVNode("", true)
2171
2611
  ]);
2172
2612
  };
2173
2613
  }
2174
2614
  });
2175
- const TaoFileDrop = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-3543419a"]]);
2176
- const _hoisted_1$l = ["aria-expanded"];
2177
- const _hoisted_2$i = {
2615
+ const TaoFileDrop = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["__scopeId", "data-v-fbd848b0"]]);
2616
+ const _hoisted_1$n = ["aria-expanded"];
2617
+ const _hoisted_2$k = {
2178
2618
  key: 1,
2179
2619
  "aria-label": "Меню"
2180
2620
  };
2181
- const _hoisted_3$f = ["onClick", "onMouseenter"];
2182
- const _hoisted_4$f = { key: 1 };
2183
- const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
2621
+ const _hoisted_3$h = ["onClick", "onMouseenter"];
2622
+ const _hoisted_4$g = { key: 1 };
2623
+ const _sfc_main$o = /* @__PURE__ */ vue.defineComponent({
2184
2624
  ...{ name: "TaoDropdownMenu" },
2185
2625
  __name: "TaoDropdownMenu",
2186
2626
  props: {
@@ -2315,8 +2755,8 @@
2315
2755
  "aria-expanded": isOpen.value,
2316
2756
  onClick: toggleMenu
2317
2757
  }, [
2318
- _ctx.$slots.button ? vue.renderSlot(_ctx.$slots, "button", {}, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$i, "⋮"))
2319
- ], 8, _hoisted_1$l),
2758
+ _ctx.$slots.button ? vue.renderSlot(_ctx.$slots, "button", {}, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$k, "⋮"))
2759
+ ], 8, _hoisted_1$n),
2320
2760
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
2321
2761
  isOpen.value ? (vue.openBlock(), vue.createElementBlock("div", {
2322
2762
  key: 0,
@@ -2341,8 +2781,8 @@
2341
2781
  id: action.id,
2342
2782
  ico: action.ico,
2343
2783
  text: action.name
2344
- }, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$f, vue.toDisplayString(action.name), 1))
2345
- ], 42, _hoisted_3$f);
2784
+ }, void 0, true, 0) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$g, vue.toDisplayString(action.name), 1))
2785
+ ], 42, _hoisted_3$h);
2346
2786
  }), 128))
2347
2787
  ], 36)) : vue.createCommentVNode("", true)
2348
2788
  ]))
@@ -2350,10 +2790,10 @@
2350
2790
  };
2351
2791
  }
2352
2792
  });
2353
- const TaoDropdownMenu = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["__scopeId", "data-v-420a7e63"]]);
2354
- const _hoisted_1$k = ["aria-invalid", "aria-describedby"];
2355
- const _hoisted_2$h = ["id", "value", "placeholder", "type", "inputmode", "pattern", "onInput", "onKeydown", "onFocus"];
2356
- const _sfc_main$l = /* @__PURE__ */ vue.defineComponent({
2793
+ const TaoDropdownMenu = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-420a7e63"]]);
2794
+ const _hoisted_1$m = ["aria-invalid", "aria-describedby"];
2795
+ const _hoisted_2$j = ["id", "value", "placeholder", "type", "inputmode", "pattern", "onInput", "onKeydown", "onFocus"];
2796
+ const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
2357
2797
  ...{ name: "TaoPinCode" },
2358
2798
  __name: "TaoPinCode",
2359
2799
  props: {
@@ -2520,14 +2960,14 @@
2520
2960
  onKeydown: ($event) => onKeydown($event, index),
2521
2961
  onFocus: ($event) => onFocus(index),
2522
2962
  onBlur
2523
- }, null, 42, _hoisted_2$h);
2963
+ }, null, 42, _hoisted_2$j);
2524
2964
  }), 128))
2525
- ], 8, _hoisted_1$k);
2965
+ ], 8, _hoisted_1$m);
2526
2966
  };
2527
2967
  }
2528
2968
  });
2529
- const TaoPinCode = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["__scopeId", "data-v-c3182673"]]);
2530
- const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
2969
+ const TaoPinCode = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["__scopeId", "data-v-c3182673"]]);
2970
+ const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
2531
2971
  ...{ name: "TaoLink" },
2532
2972
  __name: "TaoLink",
2533
2973
  props: {
@@ -2569,8 +3009,8 @@
2569
3009
  };
2570
3010
  }
2571
3011
  });
2572
- const _hoisted_1$j = ["for"];
2573
- const _sfc_main$j = /* @__PURE__ */ vue.defineComponent({
3012
+ const _hoisted_1$l = ["for"];
3013
+ const _sfc_main$l = /* @__PURE__ */ vue.defineComponent({
2574
3014
  ...{ name: "TaoFormField" },
2575
3015
  __name: "TaoFormField",
2576
3016
  props: {
@@ -2606,7 +3046,7 @@
2606
3046
  key: 0,
2607
3047
  class: "tao-form-field__label",
2608
3048
  for: vue.unref(id)
2609
- }, vue.toDisplayString(__props.label), 9, _hoisted_1$j)) : vue.createCommentVNode("", true),
3049
+ }, vue.toDisplayString(__props.label), 9, _hoisted_1$l)) : vue.createCommentVNode("", true),
2610
3050
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true),
2611
3051
  __props.error ? (vue.openBlock(), vue.createElementBlock("p", {
2612
3052
  key: 1,
@@ -2621,12 +3061,12 @@
2621
3061
  };
2622
3062
  }
2623
3063
  });
2624
- const TaoFormField = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-11324f0c"]]);
2625
- const _hoisted_1$i = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
2626
- const _hoisted_2$g = { class: "tao-select__value" };
2627
- const _hoisted_3$e = ["aria-activedescendant"];
2628
- const _hoisted_4$e = ["id", "aria-selected", "aria-disabled", "data-tao-select-index", "onClick", "onMouseenter"];
2629
- const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
3064
+ const TaoFormField = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["__scopeId", "data-v-11324f0c"]]);
3065
+ const _hoisted_1$k = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
3066
+ const _hoisted_2$i = { class: "tao-select__value" };
3067
+ const _hoisted_3$g = ["aria-activedescendant"];
3068
+ const _hoisted_4$f = ["id", "aria-selected", "aria-disabled", "data-tao-select-index", "onClick", "onMouseenter"];
3069
+ const _sfc_main$k = /* @__PURE__ */ vue.defineComponent({
2630
3070
  ...{ name: "TaoSelect" },
2631
3071
  __name: "TaoSelect",
2632
3072
  props: {
@@ -2839,12 +3279,12 @@
2839
3279
  onClick: toggle,
2840
3280
  onKeydown: onTriggerKeydown
2841
3281
  }, [
2842
- vue.createElementVNode("span", _hoisted_2$g, vue.toDisplayString(((_a = selected.value) == null ? void 0 : _a.label) ?? __props.placeholder), 1),
3282
+ vue.createElementVNode("span", _hoisted_2$i, vue.toDisplayString(((_a = selected.value) == null ? void 0 : _a.label) ?? __props.placeholder), 1),
2843
3283
  _cache[2] || (_cache[2] = vue.createElementVNode("span", {
2844
3284
  class: "tao-select__chevron",
2845
3285
  "aria-hidden": "true"
2846
3286
  }, null, -1))
2847
- ], 42, _hoisted_1$i),
3287
+ ], 42, _hoisted_1$k),
2848
3288
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
2849
3289
  open.value ? (vue.openBlock(), vue.createElementBlock("div", {
2850
3290
  key: 0,
@@ -2872,131 +3312,1013 @@
2872
3312
  "tao-select__option--selected": option.value === __props.modelValue,
2873
3313
  "tao-select__option--disabled": option.disabled
2874
3314
  }]),
2875
- role: "option",
2876
- "aria-selected": option.value === __props.modelValue,
2877
- "aria-disabled": option.disabled || void 0,
2878
- "data-tao-select-index": index,
2879
- onMousedown: _cache[0] || (_cache[0] = vue.withModifiers(() => {
3315
+ role: "option",
3316
+ "aria-selected": option.value === __props.modelValue,
3317
+ "aria-disabled": option.disabled || void 0,
3318
+ "data-tao-select-index": index,
3319
+ onMousedown: _cache[0] || (_cache[0] = vue.withModifiers(() => {
3320
+ }, ["prevent"])),
3321
+ onClick: ($event) => selectOption(option),
3322
+ onMouseenter: ($event) => !option.disabled && (activeIndex.value = index)
3323
+ }, vue.toDisplayString(option.label), 43, _hoisted_4$f);
3324
+ }), 128))
3325
+ ], 40, _hoisted_3$g),
3326
+ selected.value ? (vue.openBlock(), vue.createElementBlock("button", {
3327
+ key: 0,
3328
+ type: "button",
3329
+ class: "tao-select__clear",
3330
+ onMousedown: _cache[1] || (_cache[1] = vue.withModifiers(() => {
3331
+ }, ["prevent"])),
3332
+ onClick: clear
3333
+ }, " Очистить ", 32)) : vue.createCommentVNode("", true)
3334
+ ], 4)) : vue.createCommentVNode("", true)
3335
+ ]))
3336
+ ], 2);
3337
+ };
3338
+ }
3339
+ });
3340
+ const TaoSelect = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["__scopeId", "data-v-42551757"]]);
3341
+ const _hoisted_1$j = ["id", "aria-expanded", "aria-activedescendant", "aria-invalid", "aria-describedby", "disabled", "placeholder", "value"];
3342
+ const _hoisted_2$h = {
3343
+ key: 0,
3344
+ class: "tao-combobox__empty"
3345
+ };
3346
+ const _hoisted_3$f = ["id", "aria-selected", "aria-disabled", "data-tao-combobox-index", "onClick", "onMouseenter"];
3347
+ const _sfc_main$j = /* @__PURE__ */ vue.defineComponent({
3348
+ ...{ name: "TaoCombobox" },
3349
+ __name: "TaoCombobox",
3350
+ props: {
3351
+ modelValue: { default: null },
3352
+ options: { default: () => [] },
3353
+ placeholder: { default: "Начните вводить" },
3354
+ disabled: { type: Boolean, default: false },
3355
+ error: { type: Boolean, default: false },
3356
+ allowCreate: { type: Boolean, default: false }
3357
+ },
3358
+ emits: ["update:modelValue", "change", "create"],
3359
+ setup(__props, { emit: __emit }) {
3360
+ const props = __props;
3361
+ const emit = __emit;
3362
+ const field = vue.inject(formFieldKey, null);
3363
+ const localId = vue.useId();
3364
+ const listId = `${localId}-list`;
3365
+ const controlId = vue.computed(() => (field == null ? void 0 : field.id) ?? localId);
3366
+ const invalid = vue.computed(() => props.error || Boolean(field == null ? void 0 : field.invalid.value));
3367
+ const describedBy = vue.computed(() => field == null ? void 0 : field.describedBy.value);
3368
+ const open = vue.ref(false);
3369
+ const focused = vue.ref(false);
3370
+ const picking = vue.ref(false);
3371
+ const skipFocusOpen = vue.ref(false);
3372
+ const query = vue.ref("");
3373
+ const activeIndex = vue.ref(-1);
3374
+ const fieldRef = vue.ref(null);
3375
+ const inputRef = vue.ref(null);
3376
+ const panelRef = vue.ref(null);
3377
+ const listRef = vue.ref(null);
3378
+ const listStyle = vue.ref({ top: "0px", left: "0px", width: "0px" });
3379
+ const selected = vue.computed(() => {
3380
+ const found = props.options.find((option) => option.value === props.modelValue);
3381
+ if (found) {
3382
+ return found;
3383
+ }
3384
+ if (props.modelValue === null || props.modelValue === void 0 || props.modelValue === "") {
3385
+ return null;
3386
+ }
3387
+ return { value: props.modelValue, label: String(props.modelValue) };
3388
+ });
3389
+ const needle = vue.computed(() => query.value.trim().toLowerCase());
3390
+ const filtered = vue.computed(() => {
3391
+ if (!needle.value) {
3392
+ return props.options;
3393
+ }
3394
+ return props.options.filter((option) => option.label.toLowerCase().includes(needle.value));
3395
+ });
3396
+ const canCreate = vue.computed(() => {
3397
+ const text = query.value.trim();
3398
+ if (!props.allowCreate || !text) {
3399
+ return false;
3400
+ }
3401
+ return !props.options.some((option) => option.label.toLowerCase() === text.toLowerCase());
3402
+ });
3403
+ const rows = vue.computed(() => {
3404
+ const next = filtered.value.map((option) => ({ kind: "option", option }));
3405
+ if (canCreate.value) {
3406
+ next.push({ kind: "create", text: query.value.trim() });
3407
+ }
3408
+ return next;
3409
+ });
3410
+ const enabledIndexes = vue.computed(
3411
+ () => rows.value.map((row, index) => row.kind === "option" && row.option.disabled ? -1 : index).filter((index) => index >= 0)
3412
+ );
3413
+ const activeId = vue.computed(() => activeIndex.value >= 0 ? `${listId}-row-${activeIndex.value}` : void 0);
3414
+ function syncQueryFromModel() {
3415
+ var _a;
3416
+ query.value = ((_a = selected.value) == null ? void 0 : _a.label) ?? "";
3417
+ }
3418
+ function updatePosition() {
3419
+ const trigger = fieldRef.value;
3420
+ const panel = panelRef.value;
3421
+ if (!trigger || !panel) {
3422
+ return;
3423
+ }
3424
+ const rect = trigger.getBoundingClientRect();
3425
+ const panelHeight = panel.offsetHeight;
3426
+ const gap = 4;
3427
+ const spaceBelow = window.innerHeight - rect.bottom - gap;
3428
+ const openUp = spaceBelow < panelHeight && rect.top > spaceBelow;
3429
+ listStyle.value = {
3430
+ top: `${openUp ? rect.top - panelHeight - gap : rect.bottom + gap}px`,
3431
+ left: `${rect.left}px`,
3432
+ width: `${rect.width}px`
3433
+ };
3434
+ }
3435
+ function resetActive() {
3436
+ const selectedIndex = rows.value.findIndex(
3437
+ (row) => row.kind === "option" && row.option.value === props.modelValue
3438
+ );
3439
+ if (selectedIndex >= 0 && enabledIndexes.value.includes(selectedIndex)) {
3440
+ activeIndex.value = selectedIndex;
3441
+ return;
3442
+ }
3443
+ activeIndex.value = enabledIndexes.value[0] ?? -1;
3444
+ }
3445
+ async function setOpen(next) {
3446
+ if (props.disabled) {
3447
+ return;
3448
+ }
3449
+ open.value = next;
3450
+ resetActive();
3451
+ await vue.nextTick();
3452
+ updatePosition();
3453
+ scrollActiveIntoView();
3454
+ }
3455
+ function emitValue(value) {
3456
+ emit("update:modelValue", value);
3457
+ emit("change", value);
3458
+ }
3459
+ function keepFocusQuiet() {
3460
+ var _a;
3461
+ skipFocusOpen.value = true;
3462
+ picking.value = false;
3463
+ (_a = inputRef.value) == null ? void 0 : _a.focus();
3464
+ }
3465
+ function commitCreated(value) {
3466
+ emitValue(value);
3467
+ emit("create", value);
3468
+ query.value = value;
3469
+ open.value = false;
3470
+ keepFocusQuiet();
3471
+ }
3472
+ function selectOption(option) {
3473
+ if (option.disabled) {
3474
+ return;
3475
+ }
3476
+ emitValue(option.value);
3477
+ query.value = option.label;
3478
+ open.value = false;
3479
+ keepFocusQuiet();
3480
+ }
3481
+ function createFromQuery(text) {
3482
+ const value = text.trim();
3483
+ if (!value) {
3484
+ return;
3485
+ }
3486
+ const exact = props.options.find(
3487
+ (option) => !option.disabled && option.label.toLowerCase() === value.toLowerCase()
3488
+ );
3489
+ if (exact) {
3490
+ selectOption(exact);
3491
+ return;
3492
+ }
3493
+ if (!props.allowCreate) {
3494
+ return;
3495
+ }
3496
+ commitCreated(value);
3497
+ }
3498
+ function revertQuery() {
3499
+ syncQueryFromModel();
3500
+ }
3501
+ function closeAndRevert() {
3502
+ open.value = false;
3503
+ revertQuery();
3504
+ }
3505
+ function closeAndCommit() {
3506
+ open.value = false;
3507
+ const text = query.value.trim();
3508
+ if (!text) {
3509
+ revertQuery();
3510
+ return;
3511
+ }
3512
+ const exact = props.options.find(
3513
+ (option) => !option.disabled && option.label.toLowerCase() === text.toLowerCase()
3514
+ );
3515
+ if (exact) {
3516
+ emitValue(exact.value);
3517
+ query.value = exact.label;
3518
+ return;
3519
+ }
3520
+ if (props.allowCreate) {
3521
+ emitValue(text);
3522
+ emit("create", text);
3523
+ query.value = text;
3524
+ return;
3525
+ }
3526
+ revertQuery();
3527
+ }
3528
+ function moveActive(delta) {
3529
+ const enabled = enabledIndexes.value;
3530
+ if (!enabled.length) {
3531
+ return;
3532
+ }
3533
+ const currentPos = enabled.indexOf(activeIndex.value);
3534
+ const nextPos = currentPos < 0 ? 0 : (currentPos + delta + enabled.length) % enabled.length;
3535
+ activeIndex.value = enabled[nextPos];
3536
+ scrollActiveIntoView();
3537
+ }
3538
+ function scrollActiveIntoView() {
3539
+ const list = listRef.value;
3540
+ if (!list || activeIndex.value < 0) {
3541
+ return;
3542
+ }
3543
+ const option = list.querySelector(`[data-tao-combobox-index="${activeIndex.value}"]`);
3544
+ option == null ? void 0 : option.scrollIntoView({ block: "nearest" });
3545
+ }
3546
+ function onFieldMouseDown(event) {
3547
+ var _a;
3548
+ if (props.disabled || event.button !== 0) {
3549
+ return;
3550
+ }
3551
+ const onInput2 = event.target === inputRef.value;
3552
+ if (onInput2) {
3553
+ if (focused.value && !open.value) {
3554
+ void setOpen(true);
3555
+ }
3556
+ return;
3557
+ }
3558
+ event.preventDefault();
3559
+ if (open.value) {
3560
+ open.value = false;
3561
+ return;
3562
+ }
3563
+ (_a = inputRef.value) == null ? void 0 : _a.focus();
3564
+ void setOpen(true);
3565
+ }
3566
+ function onInput() {
3567
+ if (props.disabled) {
3568
+ return;
3569
+ }
3570
+ void setOpen(true);
3571
+ resetActive();
3572
+ }
3573
+ function onFocus() {
3574
+ if (props.disabled) {
3575
+ return;
3576
+ }
3577
+ focused.value = true;
3578
+ if (skipFocusOpen.value) {
3579
+ skipFocusOpen.value = false;
3580
+ return;
3581
+ }
3582
+ void setOpen(true);
3583
+ vue.nextTick(() => {
3584
+ var _a;
3585
+ return (_a = inputRef.value) == null ? void 0 : _a.select();
3586
+ });
3587
+ }
3588
+ function markPicking() {
3589
+ picking.value = true;
3590
+ }
3591
+ function onBlur() {
3592
+ focused.value = false;
3593
+ window.setTimeout(() => {
3594
+ var _a, _b;
3595
+ if (picking.value) {
3596
+ picking.value = false;
3597
+ return;
3598
+ }
3599
+ if (((_a = fieldRef.value) == null ? void 0 : _a.contains(document.activeElement)) || ((_b = panelRef.value) == null ? void 0 : _b.contains(document.activeElement))) {
3600
+ return;
3601
+ }
3602
+ if (props.allowCreate) {
3603
+ closeAndCommit();
3604
+ return;
3605
+ }
3606
+ closeAndRevert();
3607
+ }, 0);
3608
+ }
3609
+ function activateRow(row) {
3610
+ if (row.kind === "create") {
3611
+ createFromQuery(row.text);
3612
+ return;
3613
+ }
3614
+ selectOption(row.option);
3615
+ }
3616
+ function onInputKeydown(event) {
3617
+ if (props.disabled) {
3618
+ return;
3619
+ }
3620
+ if (event.key === "Escape") {
3621
+ event.preventDefault();
3622
+ closeAndRevert();
3623
+ return;
3624
+ }
3625
+ if (event.key === "ArrowDown") {
3626
+ event.preventDefault();
3627
+ if (!open.value) {
3628
+ void setOpen(true);
3629
+ return;
3630
+ }
3631
+ moveActive(1);
3632
+ return;
3633
+ }
3634
+ if (event.key === "ArrowUp") {
3635
+ event.preventDefault();
3636
+ if (!open.value) {
3637
+ void setOpen(true);
3638
+ return;
3639
+ }
3640
+ moveActive(-1);
3641
+ return;
3642
+ }
3643
+ if (event.key === "Enter") {
3644
+ event.preventDefault();
3645
+ if (!open.value) {
3646
+ void setOpen(true);
3647
+ return;
3648
+ }
3649
+ const row = rows.value[activeIndex.value];
3650
+ if (row) {
3651
+ activateRow(row);
3652
+ return;
3653
+ }
3654
+ if (props.allowCreate) {
3655
+ createFromQuery(query.value);
3656
+ }
3657
+ }
3658
+ }
3659
+ function onDocumentPointer(event) {
3660
+ var _a, _b;
3661
+ const target = event.target;
3662
+ if (((_a = fieldRef.value) == null ? void 0 : _a.contains(target)) || ((_b = panelRef.value) == null ? void 0 : _b.contains(target))) {
3663
+ return;
3664
+ }
3665
+ if (props.allowCreate) {
3666
+ closeAndCommit();
3667
+ return;
3668
+ }
3669
+ closeAndRevert();
3670
+ }
3671
+ function onViewportChange() {
3672
+ if (open.value) {
3673
+ updatePosition();
3674
+ }
3675
+ }
3676
+ vue.watch(
3677
+ () => props.modelValue,
3678
+ () => {
3679
+ if (!focused.value) {
3680
+ syncQueryFromModel();
3681
+ }
3682
+ },
3683
+ { immediate: true }
3684
+ );
3685
+ vue.watch(rows, () => {
3686
+ if (!open.value) {
3687
+ return;
3688
+ }
3689
+ if (!enabledIndexes.value.includes(activeIndex.value)) {
3690
+ activeIndex.value = enabledIndexes.value[0] ?? -1;
3691
+ }
3692
+ });
3693
+ vue.watch(open, (isOpen) => {
3694
+ if (isOpen) {
3695
+ document.addEventListener("pointerdown", onDocumentPointer);
3696
+ window.addEventListener("resize", onViewportChange);
3697
+ window.addEventListener("scroll", onViewportChange, true);
3698
+ return;
3699
+ }
3700
+ document.removeEventListener("pointerdown", onDocumentPointer);
3701
+ window.removeEventListener("resize", onViewportChange);
3702
+ window.removeEventListener("scroll", onViewportChange, true);
3703
+ });
3704
+ vue.onBeforeUnmount(() => {
3705
+ document.removeEventListener("pointerdown", onDocumentPointer);
3706
+ window.removeEventListener("resize", onViewportChange);
3707
+ window.removeEventListener("scroll", onViewportChange, true);
3708
+ });
3709
+ return (_ctx, _cache) => {
3710
+ return vue.openBlock(), vue.createElementBlock("div", {
3711
+ class: vue.normalizeClass(["tao-combobox", {
3712
+ "tao-combobox--open": open.value,
3713
+ "tao-combobox--invalid": invalid.value,
3714
+ "tao-combobox--disabled": __props.disabled
3715
+ }])
3716
+ }, [
3717
+ vue.createElementVNode("div", {
3718
+ ref_key: "fieldRef",
3719
+ ref: fieldRef,
3720
+ class: "tao-combobox__field",
3721
+ onMousedown: onFieldMouseDown
3722
+ }, [
3723
+ vue.createElementVNode("input", {
3724
+ id: controlId.value,
3725
+ ref_key: "inputRef",
3726
+ ref: inputRef,
3727
+ class: "tao-combobox__input",
3728
+ type: "text",
3729
+ role: "combobox",
3730
+ autocomplete: "off",
3731
+ "aria-autocomplete": "list",
3732
+ "aria-haspopup": "listbox",
3733
+ "aria-expanded": open.value,
3734
+ "aria-controls": listId,
3735
+ "aria-activedescendant": open.value ? activeId.value : void 0,
3736
+ "aria-invalid": invalid.value || void 0,
3737
+ "aria-describedby": describedBy.value,
3738
+ disabled: __props.disabled,
3739
+ placeholder: __props.placeholder,
3740
+ value: query.value,
3741
+ onInput: _cache[0] || (_cache[0] = ($event) => {
3742
+ query.value = $event.target.value;
3743
+ onInput();
3744
+ }),
3745
+ onFocus,
3746
+ onBlur,
3747
+ onKeydown: onInputKeydown
3748
+ }, null, 40, _hoisted_1$j),
3749
+ _cache[1] || (_cache[1] = vue.createElementVNode("span", {
3750
+ class: "tao-combobox__chevron",
3751
+ "aria-hidden": "true"
3752
+ }, null, -1))
3753
+ ], 544),
3754
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3755
+ open.value ? (vue.openBlock(), vue.createElementBlock("div", {
3756
+ key: 0,
3757
+ ref_key: "panelRef",
3758
+ ref: panelRef,
3759
+ class: "tao-combobox__panel",
3760
+ style: vue.normalizeStyle(listStyle.value)
3761
+ }, [
3762
+ vue.createElementVNode("ul", {
3763
+ id: listId,
3764
+ ref_key: "listRef",
3765
+ ref: listRef,
3766
+ class: "tao-combobox__list",
3767
+ role: "listbox"
3768
+ }, [
3769
+ !rows.value.length ? (vue.openBlock(), vue.createElementBlock("li", _hoisted_2$h, "Ничего не найдено")) : vue.createCommentVNode("", true),
3770
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(rows.value, (row, index) => {
3771
+ return vue.openBlock(), vue.createElementBlock("li", {
3772
+ id: `${listId}-row-${index}`,
3773
+ key: row.kind === "create" ? "create" : String(row.option.value),
3774
+ class: vue.normalizeClass(["tao-combobox__option", {
3775
+ "tao-combobox__option--active": index === activeIndex.value,
3776
+ "tao-combobox__option--selected": row.kind === "option" && row.option.value === __props.modelValue,
3777
+ "tao-combobox__option--disabled": row.kind === "option" && row.option.disabled,
3778
+ "tao-combobox__option--create": row.kind === "create"
3779
+ }]),
3780
+ role: "option",
3781
+ "aria-selected": row.kind === "option" && row.option.value === __props.modelValue,
3782
+ "aria-disabled": row.kind === "option" && row.option.disabled ? true : void 0,
3783
+ "data-tao-combobox-index": index,
3784
+ onMousedown: vue.withModifiers(markPicking, ["prevent"]),
3785
+ onClick: ($event) => activateRow(row),
3786
+ onMouseenter: ($event) => !(row.kind === "option" && row.option.disabled) && (activeIndex.value = index)
3787
+ }, [
3788
+ row.kind === "create" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
3789
+ vue.createTextVNode("Добавить «" + vue.toDisplayString(row.text) + "»", 1)
3790
+ ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
3791
+ vue.createTextVNode(vue.toDisplayString(row.option.label), 1)
3792
+ ], 64))
3793
+ ], 42, _hoisted_3$f);
3794
+ }), 128))
3795
+ ], 512),
3796
+ selected.value ? (vue.openBlock(), vue.createElementBlock("button", {
3797
+ key: 0,
3798
+ type: "button",
3799
+ class: "tao-combobox__clear",
3800
+ onMousedown: vue.withModifiers(markPicking, ["prevent"])
3801
+ }, " Очистить ", 32)) : vue.createCommentVNode("", true)
3802
+ ], 4)) : vue.createCommentVNode("", true)
3803
+ ]))
3804
+ ], 2);
3805
+ };
3806
+ }
3807
+ });
3808
+ const TaoCombobox = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["__scopeId", "data-v-adeb76a4"]]);
3809
+ const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
3810
+ function formatTaoDateIso(parts) {
3811
+ return `${String(parts.y).padStart(4, "0")}-${String(parts.m).padStart(2, "0")}-${String(parts.d).padStart(2, "0")}`;
3812
+ }
3813
+ function parseTaoDate(value) {
3814
+ if (!value) {
3815
+ return null;
3816
+ }
3817
+ const match = ISO_DATE.exec(value);
3818
+ if (!match) {
3819
+ return null;
3820
+ }
3821
+ const y = Number(match[1]);
3822
+ const m = Number(match[2]);
3823
+ const d = Number(match[3]);
3824
+ const date = new Date(y, m - 1, d);
3825
+ if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) {
3826
+ return null;
3827
+ }
3828
+ return { y, m, d };
3829
+ }
3830
+ function todayTaoDate() {
3831
+ const now = /* @__PURE__ */ new Date();
3832
+ return formatTaoDateIso({ y: now.getFullYear(), m: now.getMonth() + 1, d: now.getDate() });
3833
+ }
3834
+ function shiftTaoDate(iso, days) {
3835
+ const parts = parseTaoDate(iso);
3836
+ if (!parts) {
3837
+ return iso;
3838
+ }
3839
+ const date = new Date(parts.y, parts.m - 1, parts.d + days);
3840
+ return formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() });
3841
+ }
3842
+ function shiftTaoMonth(iso, months) {
3843
+ const parts = parseTaoDate(iso);
3844
+ if (!parts) {
3845
+ return iso;
3846
+ }
3847
+ const date = new Date(parts.y, parts.m - 1 + months, parts.d);
3848
+ return formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() });
3849
+ }
3850
+ function isTaoDateInRange(iso, min, max) {
3851
+ if (!parseTaoDate(iso)) {
3852
+ return false;
3853
+ }
3854
+ if (min && parseTaoDate(min) && iso < min) {
3855
+ return false;
3856
+ }
3857
+ if (max && parseTaoDate(max) && iso > max) {
3858
+ return false;
3859
+ }
3860
+ return true;
3861
+ }
3862
+ function formatTaoDateLabel(iso, locale = "ru-RU") {
3863
+ const parts = parseTaoDate(iso);
3864
+ if (!parts) {
3865
+ return "";
3866
+ }
3867
+ return new Date(parts.y, parts.m - 1, parts.d).toLocaleDateString(locale, {
3868
+ day: "numeric",
3869
+ month: "long",
3870
+ year: "numeric"
3871
+ });
3872
+ }
3873
+ function sortTaoDateRange(a, b) {
3874
+ return a <= b ? { start: a, end: b } : { start: b, end: a };
3875
+ }
3876
+ function parseTaoDateRange(value) {
3877
+ if (!value) {
3878
+ return null;
3879
+ }
3880
+ const start = parseTaoDate(value.start);
3881
+ const end = parseTaoDate(value.end);
3882
+ if (!start || !end) {
3883
+ return null;
3884
+ }
3885
+ return sortTaoDateRange(formatTaoDateIso(start), formatTaoDateIso(end));
3886
+ }
3887
+ function formatTaoDateRangeLabel(start, end, locale = "ru-RU") {
3888
+ const fromParts = parseTaoDate(start);
3889
+ const toParts = parseTaoDate(end);
3890
+ if (!fromParts || !toParts) {
3891
+ return "";
3892
+ }
3893
+ if (start === end) {
3894
+ return formatTaoDateLabel(start, locale);
3895
+ }
3896
+ const from = new Date(fromParts.y, fromParts.m - 1, fromParts.d).toLocaleDateString(locale, {
3897
+ day: "numeric",
3898
+ month: "long",
3899
+ ...fromParts.y === toParts.y ? {} : { year: "numeric" }
3900
+ });
3901
+ return `${from} — ${formatTaoDateLabel(end, locale)}`;
3902
+ }
3903
+ function formatTaoMonthLabel(year, month, locale = "ru-RU") {
3904
+ const label = new Date(year, month - 1, 1).toLocaleDateString(locale, {
3905
+ month: "long",
3906
+ year: "numeric"
3907
+ });
3908
+ return label.charAt(0).toUpperCase() + label.slice(1);
3909
+ }
3910
+ function taoDateWeekdayIndex(iso) {
3911
+ const parts = parseTaoDate(iso);
3912
+ if (!parts) {
3913
+ return 0;
3914
+ }
3915
+ return (new Date(parts.y, parts.m - 1, parts.d).getDay() + 6) % 7;
3916
+ }
3917
+ function taoWeekdayLabels(locale = "ru-RU") {
3918
+ return Array.from({ length: 7 }, (_, index) => {
3919
+ const label = new Date(2026, 0, 5 + index).toLocaleDateString(locale, { weekday: "short" });
3920
+ return label.replace(/\.$/, "");
3921
+ });
3922
+ }
3923
+ function buildTaoDateGrid(year, month) {
3924
+ const first = new Date(year, month - 1, 1);
3925
+ const mondayOffset = (first.getDay() + 6) % 7;
3926
+ const start = new Date(year, month - 1, 1 - mondayOffset);
3927
+ return Array.from({ length: 42 }, (_, index) => {
3928
+ const date = new Date(start.getFullYear(), start.getMonth(), start.getDate() + index);
3929
+ return {
3930
+ iso: formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() }),
3931
+ day: date.getDate(),
3932
+ currentMonth: date.getMonth() === month - 1
3933
+ };
3934
+ });
3935
+ }
3936
+ const _hoisted_1$i = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
3937
+ const _hoisted_2$g = { class: "tao-date__value" };
3938
+ const _hoisted_3$e = ["aria-label"];
3939
+ const _hoisted_4$e = { class: "tao-date__header" };
3940
+ const _hoisted_5$b = { class: "tao-date__month" };
3941
+ const _hoisted_6$8 = {
3942
+ class: "tao-date__weekdays",
3943
+ "aria-hidden": "true"
3944
+ };
3945
+ const _hoisted_7$6 = {
3946
+ class: "tao-date__grid",
3947
+ role: "grid"
3948
+ };
3949
+ const _hoisted_8$6 = ["aria-label", "aria-selected", "disabled", "onClick"];
3950
+ const _hoisted_9$2 = { class: "tao-date__footer" };
3951
+ const _hoisted_10$1 = ["disabled"];
3952
+ const _sfc_main$i = /* @__PURE__ */ vue.defineComponent({
3953
+ ...{ name: "TaoDate" },
3954
+ __name: "TaoDate",
3955
+ props: {
3956
+ modelValue: { default: null },
3957
+ placeholder: { default: "Дата" },
3958
+ disabled: { type: Boolean, default: false },
3959
+ error: { type: Boolean, default: false },
3960
+ min: { default: void 0 },
3961
+ max: { default: void 0 },
3962
+ locale: { default: "ru-RU" }
3963
+ },
3964
+ emits: ["update:modelValue", "change"],
3965
+ setup(__props, { emit: __emit }) {
3966
+ const props = __props;
3967
+ const emit = __emit;
3968
+ const field = vue.inject(formFieldKey, null);
3969
+ const localId = vue.useId();
3970
+ const gridId = `${localId}-grid`;
3971
+ const controlId = vue.computed(() => (field == null ? void 0 : field.id) ?? localId);
3972
+ const invalid = vue.computed(() => props.error || Boolean(field == null ? void 0 : field.invalid.value));
3973
+ const describedBy = vue.computed(() => field == null ? void 0 : field.describedBy.value);
3974
+ const open = vue.ref(false);
3975
+ const viewYear = vue.ref(2026);
3976
+ const viewMonth = vue.ref(1);
3977
+ const cursorIso = vue.ref(todayTaoDate());
3978
+ const triggerRef = vue.ref(null);
3979
+ const panelRef = vue.ref(null);
3980
+ const panelStyle = vue.ref({ top: "0px", left: "0px" });
3981
+ const valueIso = vue.computed(() => {
3982
+ const parsed = parseTaoDate(props.modelValue);
3983
+ return parsed ? formatTaoDateIso(parsed) : null;
3984
+ });
3985
+ const displayLabel = vue.computed(() => valueIso.value ? formatTaoDateLabel(valueIso.value, props.locale) : "");
3986
+ const weekdays = vue.computed(() => taoWeekdayLabels(props.locale));
3987
+ const monthLabel = vue.computed(() => formatTaoMonthLabel(viewYear.value, viewMonth.value, props.locale));
3988
+ const cells = vue.computed(() => buildTaoDateGrid(viewYear.value, viewMonth.value));
3989
+ const todayIso = vue.computed(() => todayTaoDate());
3990
+ const todayEnabled = vue.computed(() => isTaoDateInRange(todayIso.value, props.min, props.max));
3991
+ function syncViewFrom(iso) {
3992
+ const parts = parseTaoDate(iso);
3993
+ if (!parts) {
3994
+ return;
3995
+ }
3996
+ viewYear.value = parts.y;
3997
+ viewMonth.value = parts.m;
3998
+ cursorIso.value = iso;
3999
+ }
4000
+ function updatePosition() {
4001
+ const trigger = triggerRef.value;
4002
+ const panel = panelRef.value;
4003
+ if (!trigger || !panel) {
4004
+ return;
4005
+ }
4006
+ const rect = trigger.getBoundingClientRect();
4007
+ const height = panel.offsetHeight;
4008
+ const width = panel.offsetWidth;
4009
+ const gap = 4;
4010
+ const spaceBelow = window.innerHeight - rect.bottom - gap;
4011
+ const openUp = spaceBelow < height && rect.top > spaceBelow;
4012
+ const left = Math.min(rect.left, Math.max(8, window.innerWidth - width - 8));
4013
+ panelStyle.value = {
4014
+ top: `${openUp ? rect.top - height - gap : rect.bottom + gap}px`,
4015
+ left: `${Math.max(8, left)}px`
4016
+ };
4017
+ }
4018
+ async function setOpen(next) {
4019
+ var _a;
4020
+ if (props.disabled) {
4021
+ return;
4022
+ }
4023
+ open.value = next;
4024
+ if (!next) {
4025
+ return;
4026
+ }
4027
+ syncViewFrom(valueIso.value ?? todayIso.value);
4028
+ await vue.nextTick();
4029
+ updatePosition();
4030
+ (_a = panelRef.value) == null ? void 0 : _a.focus();
4031
+ }
4032
+ function toggle() {
4033
+ void setOpen(!open.value);
4034
+ }
4035
+ function close() {
4036
+ open.value = false;
4037
+ }
4038
+ function selectDay(iso) {
4039
+ var _a;
4040
+ if (!isTaoDateInRange(iso, props.min, props.max)) {
4041
+ return;
4042
+ }
4043
+ emit("update:modelValue", iso);
4044
+ emit("change", iso);
4045
+ close();
4046
+ (_a = triggerRef.value) == null ? void 0 : _a.focus();
4047
+ }
4048
+ function clear() {
4049
+ var _a;
4050
+ emit("update:modelValue", null);
4051
+ emit("change", null);
4052
+ close();
4053
+ (_a = triggerRef.value) == null ? void 0 : _a.focus();
4054
+ }
4055
+ function goMonth(delta) {
4056
+ const next = shiftTaoMonth(`${viewYear.value}-${String(viewMonth.value).padStart(2, "0")}-01`, delta);
4057
+ const parts = parseTaoDate(next);
4058
+ if (!parts) {
4059
+ return;
4060
+ }
4061
+ viewYear.value = parts.y;
4062
+ viewMonth.value = parts.m;
4063
+ cursorIso.value = shiftTaoMonth(cursorIso.value, delta);
4064
+ void vue.nextTick(updatePosition);
4065
+ }
4066
+ function moveCursor(days) {
4067
+ cursorIso.value = shiftTaoDate(cursorIso.value, days);
4068
+ syncViewFrom(cursorIso.value);
4069
+ void vue.nextTick(updatePosition);
4070
+ }
4071
+ function onTriggerKeydown(event) {
4072
+ if (props.disabled) {
4073
+ return;
4074
+ }
4075
+ if (event.key === "ArrowDown" || event.key === "ArrowUp" || event.key === "Enter" || event.key === " ") {
4076
+ event.preventDefault();
4077
+ void setOpen(true);
4078
+ }
4079
+ }
4080
+ function onPanelKeydown(event) {
4081
+ var _a;
4082
+ if (event.key === "Escape") {
4083
+ event.preventDefault();
4084
+ close();
4085
+ (_a = triggerRef.value) == null ? void 0 : _a.focus();
4086
+ return;
4087
+ }
4088
+ if (event.key === "ArrowLeft") {
4089
+ event.preventDefault();
4090
+ moveCursor(-1);
4091
+ return;
4092
+ }
4093
+ if (event.key === "ArrowRight") {
4094
+ event.preventDefault();
4095
+ moveCursor(1);
4096
+ return;
4097
+ }
4098
+ if (event.key === "ArrowUp") {
4099
+ event.preventDefault();
4100
+ moveCursor(-7);
4101
+ return;
4102
+ }
4103
+ if (event.key === "ArrowDown") {
4104
+ event.preventDefault();
4105
+ moveCursor(7);
4106
+ return;
4107
+ }
4108
+ if (event.key === "PageUp") {
4109
+ event.preventDefault();
4110
+ goMonth(-1);
4111
+ return;
4112
+ }
4113
+ if (event.key === "PageDown") {
4114
+ event.preventDefault();
4115
+ goMonth(1);
4116
+ return;
4117
+ }
4118
+ if (event.key === "Home") {
4119
+ event.preventDefault();
4120
+ moveCursor(-taoDateWeekdayIndex(cursorIso.value));
4121
+ return;
4122
+ }
4123
+ if (event.key === "End") {
4124
+ event.preventDefault();
4125
+ moveCursor(6 - taoDateWeekdayIndex(cursorIso.value));
4126
+ return;
4127
+ }
4128
+ if (event.key === "Enter" || event.key === " ") {
4129
+ event.preventDefault();
4130
+ selectDay(cursorIso.value);
4131
+ }
4132
+ }
4133
+ function onDocumentPointer(event) {
4134
+ var _a, _b;
4135
+ const target = event.target;
4136
+ if (((_a = triggerRef.value) == null ? void 0 : _a.contains(target)) || ((_b = panelRef.value) == null ? void 0 : _b.contains(target))) {
4137
+ return;
4138
+ }
4139
+ close();
4140
+ }
4141
+ function onViewportChange() {
4142
+ if (open.value) {
4143
+ updatePosition();
4144
+ }
4145
+ }
4146
+ vue.watch(open, (isOpen) => {
4147
+ if (isOpen) {
4148
+ document.addEventListener("pointerdown", onDocumentPointer);
4149
+ window.addEventListener("resize", onViewportChange);
4150
+ window.addEventListener("scroll", onViewportChange, true);
4151
+ return;
4152
+ }
4153
+ document.removeEventListener("pointerdown", onDocumentPointer);
4154
+ window.removeEventListener("resize", onViewportChange);
4155
+ window.removeEventListener("scroll", onViewportChange, true);
4156
+ });
4157
+ vue.onBeforeUnmount(() => {
4158
+ document.removeEventListener("pointerdown", onDocumentPointer);
4159
+ window.removeEventListener("resize", onViewportChange);
4160
+ window.removeEventListener("scroll", onViewportChange, true);
4161
+ });
4162
+ return (_ctx, _cache) => {
4163
+ return vue.openBlock(), vue.createElementBlock("div", {
4164
+ class: vue.normalizeClass(["tao-date", { "tao-date--open": open.value, "tao-date--invalid": invalid.value }])
4165
+ }, [
4166
+ vue.createElementVNode("button", {
4167
+ id: controlId.value,
4168
+ ref_key: "triggerRef",
4169
+ ref: triggerRef,
4170
+ type: "button",
4171
+ class: vue.normalizeClass(["tao-date__trigger", { "tao-date__trigger--placeholder": !valueIso.value }]),
4172
+ role: "combobox",
4173
+ "aria-expanded": open.value,
4174
+ "aria-haspopup": "dialog",
4175
+ "aria-controls": gridId,
4176
+ "aria-invalid": invalid.value || void 0,
4177
+ "aria-describedby": describedBy.value,
4178
+ disabled: __props.disabled,
4179
+ onClick: toggle,
4180
+ onKeydown: onTriggerKeydown
4181
+ }, [
4182
+ vue.createElementVNode("span", _hoisted_2$g, vue.toDisplayString(displayLabel.value || __props.placeholder), 1),
4183
+ _cache[4] || (_cache[4] = vue.createElementVNode("svg", {
4184
+ class: "tao-date__icon",
4185
+ viewBox: "0 0 16 16",
4186
+ width: "16",
4187
+ height: "16",
4188
+ "aria-hidden": "true",
4189
+ focusable: "false"
4190
+ }, [
4191
+ vue.createElementVNode("rect", {
4192
+ x: "2",
4193
+ y: "3",
4194
+ width: "12",
4195
+ height: "11",
4196
+ rx: "1.5",
4197
+ fill: "none",
4198
+ stroke: "currentColor",
4199
+ "stroke-width": "1.4"
4200
+ }),
4201
+ vue.createElementVNode("path", {
4202
+ d: "M5 1.5v3M11 1.5v3M2 6.5h12",
4203
+ fill: "none",
4204
+ stroke: "currentColor",
4205
+ "stroke-width": "1.4",
4206
+ "stroke-linecap": "round"
4207
+ })
4208
+ ], -1))
4209
+ ], 42, _hoisted_1$i),
4210
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4211
+ open.value ? (vue.openBlock(), vue.createElementBlock("div", {
4212
+ key: 0,
4213
+ id: gridId,
4214
+ ref_key: "panelRef",
4215
+ ref: panelRef,
4216
+ class: "tao-date__panel",
4217
+ role: "dialog",
4218
+ "aria-label": monthLabel.value,
4219
+ tabindex: "-1",
4220
+ style: vue.normalizeStyle(panelStyle.value),
4221
+ onKeydown: onPanelKeydown
4222
+ }, [
4223
+ vue.createElementVNode("div", _hoisted_4$e, [
4224
+ vue.createElementVNode("button", {
4225
+ type: "button",
4226
+ class: "tao-date__nav",
4227
+ "aria-label": "Предыдущий месяц",
4228
+ onClick: _cache[0] || (_cache[0] = ($event) => goMonth(-1))
4229
+ }, [..._cache[5] || (_cache[5] = [
4230
+ vue.createElementVNode("svg", {
4231
+ viewBox: "0 0 24 24",
4232
+ width: "14",
4233
+ height: "14",
4234
+ "aria-hidden": "true",
4235
+ focusable: "false"
4236
+ }, [
4237
+ vue.createElementVNode("path", {
4238
+ fill: "none",
4239
+ stroke: "currentColor",
4240
+ "stroke-width": "2.2",
4241
+ "stroke-linecap": "round",
4242
+ "stroke-linejoin": "round",
4243
+ d: "M14.5 5 8 12l6.5 7"
4244
+ })
4245
+ ], -1)
4246
+ ])]),
4247
+ vue.createElementVNode("p", _hoisted_5$b, vue.toDisplayString(monthLabel.value), 1),
4248
+ vue.createElementVNode("button", {
4249
+ type: "button",
4250
+ class: "tao-date__nav",
4251
+ "aria-label": "Следующий месяц",
4252
+ onClick: _cache[1] || (_cache[1] = ($event) => goMonth(1))
4253
+ }, [..._cache[6] || (_cache[6] = [
4254
+ vue.createElementVNode("svg", {
4255
+ viewBox: "0 0 24 24",
4256
+ width: "14",
4257
+ height: "14",
4258
+ "aria-hidden": "true",
4259
+ focusable: "false"
4260
+ }, [
4261
+ vue.createElementVNode("path", {
4262
+ fill: "none",
4263
+ stroke: "currentColor",
4264
+ "stroke-width": "2.2",
4265
+ "stroke-linecap": "round",
4266
+ "stroke-linejoin": "round",
4267
+ d: "M9.5 5 16 12l-6.5 7"
4268
+ })
4269
+ ], -1)
4270
+ ])])
4271
+ ]),
4272
+ vue.createElementVNode("div", _hoisted_6$8, [
4273
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(weekdays.value, (day) => {
4274
+ return vue.openBlock(), vue.createElementBlock("span", { key: day }, vue.toDisplayString(day), 1);
4275
+ }), 128))
4276
+ ]),
4277
+ vue.createElementVNode("div", _hoisted_7$6, [
4278
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(cells.value, (cell) => {
4279
+ return vue.openBlock(), vue.createElementBlock("button", {
4280
+ key: cell.iso,
4281
+ type: "button",
4282
+ class: vue.normalizeClass(["tao-date__day", {
4283
+ "tao-date__day--outside": !cell.currentMonth,
4284
+ "tao-date__day--today": cell.iso === todayIso.value,
4285
+ "tao-date__day--selected": cell.iso === valueIso.value,
4286
+ "tao-date__day--cursor": cell.iso === cursorIso.value,
4287
+ "tao-date__day--disabled": !vue.unref(isTaoDateInRange)(cell.iso, __props.min, __props.max)
4288
+ }]),
4289
+ role: "gridcell",
4290
+ "aria-label": vue.unref(formatTaoDateLabel)(cell.iso, __props.locale),
4291
+ "aria-selected": cell.iso === valueIso.value,
4292
+ disabled: !vue.unref(isTaoDateInRange)(cell.iso, __props.min, __props.max),
4293
+ onMousedown: _cache[2] || (_cache[2] = vue.withModifiers(() => {
2880
4294
  }, ["prevent"])),
2881
- onClick: ($event) => selectOption(option),
2882
- onMouseenter: ($event) => !option.disabled && (activeIndex.value = index)
2883
- }, vue.toDisplayString(option.label), 43, _hoisted_4$e);
4295
+ onClick: ($event) => selectDay(cell.iso)
4296
+ }, vue.toDisplayString(cell.day), 43, _hoisted_8$6);
2884
4297
  }), 128))
2885
- ], 40, _hoisted_3$e),
2886
- selected.value ? (vue.openBlock(), vue.createElementBlock("button", {
2887
- key: 0,
2888
- type: "button",
2889
- class: "tao-select__clear",
2890
- onMousedown: _cache[1] || (_cache[1] = vue.withModifiers(() => {
2891
- }, ["prevent"])),
2892
- onClick: clear
2893
- }, " Очистить ", 32)) : vue.createCommentVNode("", true)
2894
- ], 4)) : vue.createCommentVNode("", true)
4298
+ ]),
4299
+ vue.createElementVNode("div", _hoisted_9$2, [
4300
+ vue.createElementVNode("button", {
4301
+ type: "button",
4302
+ class: "tao-date__link",
4303
+ disabled: !todayEnabled.value,
4304
+ onClick: _cache[3] || (_cache[3] = ($event) => selectDay(todayIso.value))
4305
+ }, " Сегодня ", 8, _hoisted_10$1),
4306
+ valueIso.value ? (vue.openBlock(), vue.createElementBlock("button", {
4307
+ key: 0,
4308
+ type: "button",
4309
+ class: "tao-date__link",
4310
+ onClick: clear
4311
+ }, "Очистить")) : vue.createCommentVNode("", true)
4312
+ ])
4313
+ ], 44, _hoisted_3$e)) : vue.createCommentVNode("", true)
2895
4314
  ]))
2896
4315
  ], 2);
2897
4316
  };
2898
4317
  }
2899
4318
  });
2900
- const TaoSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-42551757"]]);
2901
- const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
2902
- function formatTaoDateIso(parts) {
2903
- return `${String(parts.y).padStart(4, "0")}-${String(parts.m).padStart(2, "0")}-${String(parts.d).padStart(2, "0")}`;
2904
- }
2905
- function parseTaoDate(value) {
2906
- if (!value) {
2907
- return null;
2908
- }
2909
- const match = ISO_DATE.exec(value);
2910
- if (!match) {
2911
- return null;
2912
- }
2913
- const y = Number(match[1]);
2914
- const m = Number(match[2]);
2915
- const d = Number(match[3]);
2916
- const date = new Date(y, m - 1, d);
2917
- if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) {
2918
- return null;
2919
- }
2920
- return { y, m, d };
2921
- }
2922
- function todayTaoDate() {
2923
- const now = /* @__PURE__ */ new Date();
2924
- return formatTaoDateIso({ y: now.getFullYear(), m: now.getMonth() + 1, d: now.getDate() });
2925
- }
2926
- function shiftTaoDate(iso, days) {
2927
- const parts = parseTaoDate(iso);
2928
- if (!parts) {
2929
- return iso;
2930
- }
2931
- const date = new Date(parts.y, parts.m - 1, parts.d + days);
2932
- return formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() });
2933
- }
2934
- function shiftTaoMonth(iso, months) {
2935
- const parts = parseTaoDate(iso);
2936
- if (!parts) {
2937
- return iso;
2938
- }
2939
- const date = new Date(parts.y, parts.m - 1 + months, parts.d);
2940
- return formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() });
2941
- }
2942
- function isTaoDateInRange(iso, min, max) {
2943
- if (!parseTaoDate(iso)) {
2944
- return false;
2945
- }
2946
- if (min && parseTaoDate(min) && iso < min) {
2947
- return false;
2948
- }
2949
- if (max && parseTaoDate(max) && iso > max) {
2950
- return false;
2951
- }
2952
- return true;
2953
- }
2954
- function formatTaoDateLabel(iso, locale = "ru-RU") {
2955
- const parts = parseTaoDate(iso);
2956
- if (!parts) {
2957
- return "";
2958
- }
2959
- return new Date(parts.y, parts.m - 1, parts.d).toLocaleDateString(locale, {
2960
- day: "numeric",
2961
- month: "long",
2962
- year: "numeric"
2963
- });
2964
- }
2965
- function formatTaoMonthLabel(year, month, locale = "ru-RU") {
2966
- const label = new Date(year, month - 1, 1).toLocaleDateString(locale, {
2967
- month: "long",
2968
- year: "numeric"
2969
- });
2970
- return label.charAt(0).toUpperCase() + label.slice(1);
2971
- }
2972
- function taoDateWeekdayIndex(iso) {
2973
- const parts = parseTaoDate(iso);
2974
- if (!parts) {
2975
- return 0;
2976
- }
2977
- return (new Date(parts.y, parts.m - 1, parts.d).getDay() + 6) % 7;
2978
- }
2979
- function taoWeekdayLabels(locale = "ru-RU") {
2980
- return Array.from({ length: 7 }, (_, index) => {
2981
- const label = new Date(2026, 0, 5 + index).toLocaleDateString(locale, { weekday: "short" });
2982
- return label.replace(/\.$/, "");
2983
- });
2984
- }
2985
- function buildTaoDateGrid(year, month) {
2986
- const first = new Date(year, month - 1, 1);
2987
- const mondayOffset = (first.getDay() + 6) % 7;
2988
- const start = new Date(year, month - 1, 1 - mondayOffset);
2989
- return Array.from({ length: 42 }, (_, index) => {
2990
- const date = new Date(start.getFullYear(), start.getMonth(), start.getDate() + index);
2991
- return {
2992
- iso: formatTaoDateIso({ y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate() }),
2993
- day: date.getDate(),
2994
- currentMonth: date.getMonth() === month - 1
2995
- };
2996
- });
2997
- }
4319
+ const TaoDate = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-f4a9cddd"]]);
2998
4320
  const _hoisted_1$h = ["id", "aria-expanded", "aria-invalid", "aria-describedby", "disabled"];
2999
- const _hoisted_2$f = { class: "tao-date__value" };
4321
+ const _hoisted_2$f = { class: "tao-date-range__value" };
3000
4322
  const _hoisted_3$d = ["aria-label"];
3001
4323
  const _hoisted_4$d = { class: "tao-date__header" };
3002
4324
  const _hoisted_5$a = { class: "tao-date__month" };
@@ -3004,19 +4326,15 @@
3004
4326
  class: "tao-date__weekdays",
3005
4327
  "aria-hidden": "true"
3006
4328
  };
3007
- const _hoisted_7$5 = {
3008
- class: "tao-date__grid",
3009
- role: "grid"
3010
- };
3011
- const _hoisted_8$5 = ["aria-selected", "disabled", "onClick"];
3012
- const _hoisted_9$1 = { class: "tao-date__footer" };
3013
- const _hoisted_10$1 = ["disabled"];
4329
+ const _hoisted_7$5 = ["aria-label", "aria-selected", "disabled", "onMouseenter", "onClick"];
4330
+ const _hoisted_8$5 = { class: "tao-date__footer" };
4331
+ const _hoisted_9$1 = ["disabled"];
3014
4332
  const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
3015
- ...{ name: "TaoDate" },
3016
- __name: "TaoDate",
4333
+ ...{ name: "TaoDateRange" },
4334
+ __name: "TaoDateRange",
3017
4335
  props: {
3018
4336
  modelValue: { default: null },
3019
- placeholder: { default: "Дата" },
4337
+ placeholder: { default: "Период" },
3020
4338
  disabled: { type: Boolean, default: false },
3021
4339
  error: { type: Boolean, default: false },
3022
4340
  min: { default: void 0 },
@@ -3037,19 +4355,32 @@
3037
4355
  const viewYear = vue.ref(2026);
3038
4356
  const viewMonth = vue.ref(1);
3039
4357
  const cursorIso = vue.ref(todayTaoDate());
4358
+ const draftStart = vue.ref(null);
4359
+ const hoverIso = vue.ref(null);
3040
4360
  const triggerRef = vue.ref(null);
3041
4361
  const panelRef = vue.ref(null);
3042
4362
  const panelStyle = vue.ref({ top: "0px", left: "0px" });
3043
- const valueIso = vue.computed(() => {
3044
- const parsed = parseTaoDate(props.modelValue);
3045
- return parsed ? formatTaoDateIso(parsed) : null;
4363
+ const committed = vue.computed(() => parseTaoDateRange(props.modelValue));
4364
+ const highlight = vue.computed(() => {
4365
+ if (draftStart.value) {
4366
+ return sortTaoDateRange(draftStart.value, hoverIso.value ?? cursorIso.value ?? draftStart.value);
4367
+ }
4368
+ return committed.value;
3046
4369
  });
3047
- const displayLabel = vue.computed(() => valueIso.value ? formatTaoDateLabel(valueIso.value, props.locale) : "");
4370
+ const displayLabel = vue.computed(
4371
+ () => committed.value ? formatTaoDateRangeLabel(committed.value.start, committed.value.end, props.locale) : ""
4372
+ );
3048
4373
  const weekdays = vue.computed(() => taoWeekdayLabels(props.locale));
3049
4374
  const monthLabel = vue.computed(() => formatTaoMonthLabel(viewYear.value, viewMonth.value, props.locale));
3050
4375
  const cells = vue.computed(() => buildTaoDateGrid(viewYear.value, viewMonth.value));
3051
4376
  const todayIso = vue.computed(() => todayTaoDate());
3052
4377
  const todayEnabled = vue.computed(() => isTaoDateInRange(todayIso.value, props.min, props.max));
4378
+ function daySelected(iso) {
4379
+ return Boolean(highlight.value && (iso === highlight.value.start || iso === highlight.value.end));
4380
+ }
4381
+ function dayInRange(iso) {
4382
+ return Boolean(highlight.value && iso > highlight.value.start && iso < highlight.value.end);
4383
+ }
3053
4384
  function syncViewFrom(iso) {
3054
4385
  const parts = parseTaoDate(iso);
3055
4386
  if (!parts) {
@@ -3078,7 +4409,7 @@
3078
4409
  };
3079
4410
  }
3080
4411
  async function setOpen(next) {
3081
- var _a;
4412
+ var _a, _b;
3082
4413
  if (props.disabled) {
3083
4414
  return;
3084
4415
  }
@@ -3086,10 +4417,12 @@
3086
4417
  if (!next) {
3087
4418
  return;
3088
4419
  }
3089
- syncViewFrom(valueIso.value ?? todayIso.value);
4420
+ draftStart.value = null;
4421
+ hoverIso.value = null;
4422
+ syncViewFrom(((_a = committed.value) == null ? void 0 : _a.start) ?? todayIso.value);
3090
4423
  await vue.nextTick();
3091
4424
  updatePosition();
3092
- (_a = panelRef.value) == null ? void 0 : _a.focus();
4425
+ (_b = panelRef.value) == null ? void 0 : _b.focus();
3093
4426
  }
3094
4427
  function toggle() {
3095
4428
  void setOpen(!open.value);
@@ -3097,24 +4430,44 @@
3097
4430
  function close() {
3098
4431
  open.value = false;
3099
4432
  }
3100
- function selectDay(iso) {
4433
+ function commitRange(range) {
3101
4434
  var _a;
4435
+ emit("update:modelValue", range);
4436
+ emit("change", range);
4437
+ draftStart.value = null;
4438
+ hoverIso.value = null;
4439
+ close();
4440
+ (_a = triggerRef.value) == null ? void 0 : _a.focus();
4441
+ }
4442
+ function selectDay(iso) {
3102
4443
  if (!isTaoDateInRange(iso, props.min, props.max)) {
3103
4444
  return;
3104
4445
  }
3105
- emit("update:modelValue", iso);
3106
- emit("change", iso);
3107
- close();
3108
- (_a = triggerRef.value) == null ? void 0 : _a.focus();
4446
+ if (!draftStart.value) {
4447
+ draftStart.value = iso;
4448
+ hoverIso.value = iso;
4449
+ cursorIso.value = iso;
4450
+ return;
4451
+ }
4452
+ commitRange(sortTaoDateRange(draftStart.value, iso));
4453
+ }
4454
+ function selectToday() {
4455
+ if (!todayEnabled.value) {
4456
+ return;
4457
+ }
4458
+ commitRange({ start: todayIso.value, end: todayIso.value });
3109
4459
  }
3110
4460
  function clear() {
3111
4461
  var _a;
3112
4462
  emit("update:modelValue", null);
3113
4463
  emit("change", null);
4464
+ draftStart.value = null;
4465
+ hoverIso.value = null;
3114
4466
  close();
3115
4467
  (_a = triggerRef.value) == null ? void 0 : _a.focus();
3116
4468
  }
3117
4469
  function goMonth(delta) {
4470
+ hoverIso.value = null;
3118
4471
  const next = shiftTaoMonth(`${viewYear.value}-${String(viewMonth.value).padStart(2, "0")}-01`, delta);
3119
4472
  const parts = parseTaoDate(next);
3120
4473
  if (!parts) {
@@ -3126,10 +4479,20 @@
3126
4479
  void vue.nextTick(updatePosition);
3127
4480
  }
3128
4481
  function moveCursor(days) {
4482
+ hoverIso.value = null;
3129
4483
  cursorIso.value = shiftTaoDate(cursorIso.value, days);
3130
4484
  syncViewFrom(cursorIso.value);
3131
4485
  void vue.nextTick(updatePosition);
3132
4486
  }
4487
+ function onDayEnter(iso) {
4488
+ if (!isTaoDateInRange(iso, props.min, props.max)) {
4489
+ return;
4490
+ }
4491
+ hoverIso.value = iso;
4492
+ }
4493
+ function onGridLeave() {
4494
+ hoverIso.value = null;
4495
+ }
3133
4496
  function onTriggerKeydown(event) {
3134
4497
  if (props.disabled) {
3135
4498
  return;
@@ -3212,6 +4575,8 @@
3212
4575
  window.addEventListener("scroll", onViewportChange, true);
3213
4576
  return;
3214
4577
  }
4578
+ draftStart.value = null;
4579
+ hoverIso.value = null;
3215
4580
  document.removeEventListener("pointerdown", onDocumentPointer);
3216
4581
  window.removeEventListener("resize", onViewportChange);
3217
4582
  window.removeEventListener("scroll", onViewportChange, true);
@@ -3223,14 +4588,14 @@
3223
4588
  });
3224
4589
  return (_ctx, _cache) => {
3225
4590
  return vue.openBlock(), vue.createElementBlock("div", {
3226
- class: vue.normalizeClass(["tao-date", { "tao-date--open": open.value, "tao-date--invalid": invalid.value }])
4591
+ class: vue.normalizeClass(["tao-date-range", { "tao-date-range--open": open.value, "tao-date-range--invalid": invalid.value }])
3227
4592
  }, [
3228
4593
  vue.createElementVNode("button", {
3229
4594
  id: controlId.value,
3230
4595
  ref_key: "triggerRef",
3231
4596
  ref: triggerRef,
3232
4597
  type: "button",
3233
- class: vue.normalizeClass(["tao-date__trigger", { "tao-date__trigger--placeholder": !valueIso.value }]),
4598
+ class: vue.normalizeClass(["tao-date-range__trigger", { "tao-date-range__trigger--placeholder": !committed.value }]),
3234
4599
  role: "combobox",
3235
4600
  "aria-expanded": open.value,
3236
4601
  "aria-haspopup": "dialog",
@@ -3242,8 +4607,8 @@
3242
4607
  onKeydown: onTriggerKeydown
3243
4608
  }, [
3244
4609
  vue.createElementVNode("span", _hoisted_2$f, vue.toDisplayString(displayLabel.value || __props.placeholder), 1),
3245
- _cache[4] || (_cache[4] = vue.createElementVNode("svg", {
3246
- class: "tao-date__icon",
4610
+ _cache[3] || (_cache[3] = vue.createElementVNode("svg", {
4611
+ class: "tao-date-range__icon",
3247
4612
  viewBox: "0 0 16 16",
3248
4613
  width: "16",
3249
4614
  height: "16",
@@ -3288,7 +4653,7 @@
3288
4653
  class: "tao-date__nav",
3289
4654
  "aria-label": "Предыдущий месяц",
3290
4655
  onClick: _cache[0] || (_cache[0] = ($event) => goMonth(-1))
3291
- }, [..._cache[5] || (_cache[5] = [
4656
+ }, [..._cache[4] || (_cache[4] = [
3292
4657
  vue.createElementVNode("svg", {
3293
4658
  viewBox: "0 0 24 24",
3294
4659
  width: "14",
@@ -3312,7 +4677,7 @@
3312
4677
  class: "tao-date__nav",
3313
4678
  "aria-label": "Следующий месяц",
3314
4679
  onClick: _cache[1] || (_cache[1] = ($event) => goMonth(1))
3315
- }, [..._cache[6] || (_cache[6] = [
4680
+ }, [..._cache[5] || (_cache[5] = [
3316
4681
  vue.createElementVNode("svg", {
3317
4682
  viewBox: "0 0 24 24",
3318
4683
  width: "14",
@@ -3336,35 +4701,45 @@
3336
4701
  return vue.openBlock(), vue.createElementBlock("span", { key: day }, vue.toDisplayString(day), 1);
3337
4702
  }), 128))
3338
4703
  ]),
3339
- vue.createElementVNode("div", _hoisted_7$5, [
4704
+ vue.createElementVNode("div", {
4705
+ class: "tao-date__grid",
4706
+ role: "grid",
4707
+ onMouseleave: onGridLeave
4708
+ }, [
3340
4709
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(cells.value, (cell) => {
4710
+ var _a, _b;
3341
4711
  return vue.openBlock(), vue.createElementBlock("button", {
3342
4712
  key: cell.iso,
3343
4713
  type: "button",
3344
4714
  class: vue.normalizeClass(["tao-date__day", {
3345
4715
  "tao-date__day--outside": !cell.currentMonth,
3346
4716
  "tao-date__day--today": cell.iso === todayIso.value,
3347
- "tao-date__day--selected": cell.iso === valueIso.value,
4717
+ "tao-date__day--selected": daySelected(cell.iso),
4718
+ "tao-date__day--in-range": dayInRange(cell.iso),
4719
+ "tao-date__day--range-start": ((_a = highlight.value) == null ? void 0 : _a.start) === cell.iso,
4720
+ "tao-date__day--range-end": ((_b = highlight.value) == null ? void 0 : _b.end) === cell.iso,
3348
4721
  "tao-date__day--cursor": cell.iso === cursorIso.value,
3349
4722
  "tao-date__day--disabled": !vue.unref(isTaoDateInRange)(cell.iso, __props.min, __props.max)
3350
4723
  }]),
3351
4724
  role: "gridcell",
3352
- "aria-selected": cell.iso === valueIso.value,
4725
+ "aria-label": vue.unref(formatTaoDateLabel)(cell.iso, __props.locale),
4726
+ "aria-selected": daySelected(cell.iso),
3353
4727
  disabled: !vue.unref(isTaoDateInRange)(cell.iso, __props.min, __props.max),
3354
4728
  onMousedown: _cache[2] || (_cache[2] = vue.withModifiers(() => {
3355
4729
  }, ["prevent"])),
4730
+ onMouseenter: ($event) => onDayEnter(cell.iso),
3356
4731
  onClick: ($event) => selectDay(cell.iso)
3357
- }, vue.toDisplayString(cell.day), 43, _hoisted_8$5);
4732
+ }, vue.toDisplayString(cell.day), 43, _hoisted_7$5);
3358
4733
  }), 128))
3359
- ]),
3360
- vue.createElementVNode("div", _hoisted_9$1, [
4734
+ ], 32),
4735
+ vue.createElementVNode("div", _hoisted_8$5, [
3361
4736
  vue.createElementVNode("button", {
3362
4737
  type: "button",
3363
4738
  class: "tao-date__link",
3364
4739
  disabled: !todayEnabled.value,
3365
- onClick: _cache[3] || (_cache[3] = ($event) => selectDay(todayIso.value))
3366
- }, " Сегодня ", 8, _hoisted_10$1),
3367
- valueIso.value ? (vue.openBlock(), vue.createElementBlock("button", {
4740
+ onClick: selectToday
4741
+ }, " Сегодня ", 8, _hoisted_9$1),
4742
+ committed.value ? (vue.openBlock(), vue.createElementBlock("button", {
3368
4743
  key: 0,
3369
4744
  type: "button",
3370
4745
  class: "tao-date__link",
@@ -3377,7 +4752,7 @@
3377
4752
  };
3378
4753
  }
3379
4754
  });
3380
- const TaoDate = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-4227e5f8"]]);
4755
+ const TaoDateRange = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-4e222262"]]);
3381
4756
  const _hoisted_1$g = ["for"];
3382
4757
  const _hoisted_2$e = ["id", "checked", "disabled", "aria-checked"];
3383
4758
  const _hoisted_3$c = {
@@ -4274,7 +5649,7 @@
4274
5649
  class: "tao-breadcrumb__item"
4275
5650
  }, [
4276
5651
  index > 0 ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3$4, "/")) : vue.createCommentVNode("", true),
4277
- index === __props.items.length - 1 ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$4, vue.toDisplayString(item.label), 1)) : item.to ? (vue.openBlock(), vue.createBlock(_sfc_main$k, {
5652
+ index === __props.items.length - 1 ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_4$4, vue.toDisplayString(item.label), 1)) : item.to ? (vue.openBlock(), vue.createBlock(_sfc_main$m, {
4278
5653
  key: 2,
4279
5654
  class: "tao-breadcrumb__link",
4280
5655
  to: item.to
@@ -4465,7 +5840,7 @@
4465
5840
  function goNext() {
4466
5841
  goTo(index.value + step.value);
4467
5842
  }
4468
- function goTo(next) {
5843
+ function goTo(next, instant = false) {
4469
5844
  const el = track.value;
4470
5845
  const { width, gap, total } = metrics();
4471
5846
  if (!el || width <= 0 || total <= 0) {
@@ -4487,7 +5862,7 @@
4487
5862
  }
4488
5863
  el.scrollTo({
4489
5864
  left: page * (width + gap),
4490
- behavior: prefersReducedMotion() || dragging.value || wrapping ? "auto" : "smooth"
5865
+ behavior: prefersReducedMotion() || dragging.value || wrapping || instant ? "auto" : "smooth"
4491
5866
  });
4492
5867
  setIndex(page);
4493
5868
  }
@@ -4545,6 +5920,35 @@
4545
5920
  setIndex(nearestIndex());
4546
5921
  });
4547
5922
  }
5923
+ function releaseDragCapture() {
5924
+ const el = track.value;
5925
+ const id = dragPointer;
5926
+ if (!el || id === -1) {
5927
+ return;
5928
+ }
5929
+ if (typeof el.hasPointerCapture === "function" && !el.hasPointerCapture(id)) {
5930
+ return;
5931
+ }
5932
+ try {
5933
+ el.releasePointerCapture(id);
5934
+ } catch {
5935
+ }
5936
+ }
5937
+ function endDrag(keepClickGuard = false) {
5938
+ if (!dragging.value) {
5939
+ return;
5940
+ }
5941
+ dragging.value = false;
5942
+ releaseDragCapture();
5943
+ dragPointer = -1;
5944
+ if (!keepClickGuard) {
5945
+ dragMoved = 0;
5946
+ }
5947
+ if (track.value) {
5948
+ goTo(nearestIndex(), true);
5949
+ }
5950
+ syncAutoplay();
5951
+ }
4548
5952
  function onPointerDown(event) {
4549
5953
  if (event.pointerType !== "mouse" || event.button !== 0 || !track.value) {
4550
5954
  return;
@@ -4554,7 +5958,10 @@
4554
5958
  dragStartScroll = track.value.scrollLeft;
4555
5959
  dragMoved = 0;
4556
5960
  dragging.value = true;
4557
- track.value.setPointerCapture(event.pointerId);
5961
+ try {
5962
+ track.value.setPointerCapture(event.pointerId);
5963
+ } catch {
5964
+ }
4558
5965
  }
4559
5966
  function onPointerMove(event) {
4560
5967
  if (!dragging.value || event.pointerId !== dragPointer || !track.value) {
@@ -4564,13 +5971,25 @@
4564
5971
  dragMoved = Math.abs(dx);
4565
5972
  track.value.scrollLeft = dragStartScroll - dx;
4566
5973
  }
4567
- function onPointerUp(event) {
4568
- if (!dragging.value || event.pointerId !== dragPointer) {
5974
+ function onPointerEnd(event) {
5975
+ if (!dragging.value) {
4569
5976
  return;
4570
5977
  }
4571
- dragging.value = false;
4572
- dragPointer = -1;
4573
- goTo(nearestIndex());
5978
+ if (dragPointer !== -1 && event.pointerId !== dragPointer) {
5979
+ return;
5980
+ }
5981
+ endDrag(true);
5982
+ }
5983
+ function onLostPointerCapture() {
5984
+ endDrag();
5985
+ }
5986
+ function onWindowBlur() {
5987
+ endDrag();
5988
+ }
5989
+ function onVisibilityChange() {
5990
+ if (document.hidden) {
5991
+ endDrag();
5992
+ }
4574
5993
  syncAutoplay();
4575
5994
  }
4576
5995
  function onClickCapture(event) {
@@ -4609,13 +6028,18 @@
4609
6028
  goTo(props.modelValue);
4610
6029
  syncAutoplay();
4611
6030
  });
4612
- document.addEventListener("visibilitychange", syncAutoplay);
6031
+ document.addEventListener("visibilitychange", onVisibilityChange);
6032
+ window.addEventListener("blur", onWindowBlur);
6033
+ window.addEventListener("pagehide", onWindowBlur);
4613
6034
  });
4614
6035
  vue.onUpdated(refreshCount);
4615
6036
  vue.onBeforeUnmount(() => {
6037
+ endDrag();
4616
6038
  cancelAnimationFrame(scrollFrame);
4617
6039
  stopAutoplay();
4618
- document.removeEventListener("visibilitychange", syncAutoplay);
6040
+ document.removeEventListener("visibilitychange", onVisibilityChange);
6041
+ window.removeEventListener("blur", onWindowBlur);
6042
+ window.removeEventListener("pagehide", onWindowBlur);
4619
6043
  });
4620
6044
  return (_ctx, _cache) => {
4621
6045
  return vue.openBlock(), vue.createElementBlock("div", {
@@ -4668,8 +6092,9 @@
4668
6092
  onKeydown,
4669
6093
  onPointerdown: onPointerDown,
4670
6094
  onPointermove: onPointerMove,
4671
- onPointerup: onPointerUp,
4672
- onPointercancel: onPointerUp,
6095
+ onPointerup: onPointerEnd,
6096
+ onPointercancel: onPointerEnd,
6097
+ onLostpointercapture: onLostPointerCapture,
4673
6098
  onClickCapture
4674
6099
  }, [
4675
6100
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
@@ -4735,7 +6160,7 @@
4735
6160
  };
4736
6161
  }
4737
6162
  });
4738
- const TaoCarousel = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-173f4ce0"]]);
6163
+ const TaoCarousel = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-81afb8b0"]]);
4739
6164
  const _hoisted_1$3 = ["aria-label"];
4740
6165
  const _hoisted_2$2 = ["aria-label"];
4741
6166
  const _hoisted_3$2 = {
@@ -5872,10 +7297,12 @@
5872
7297
  TaoModal,
5873
7298
  TaoTabs,
5874
7299
  TaoTooltip,
7300
+ TaoPopover,
5875
7301
  TaoSpoiler,
7302
+ TaoSpoilerGroup,
5876
7303
  TaoCopy,
5877
7304
  TaoContainer,
5878
- _sfc_main$A,
7305
+ _sfc_main$D,
5879
7306
  TaoSpace,
5880
7307
  TaoIcon,
5881
7308
  TaoLoader,
@@ -5883,6 +7310,7 @@
5883
7310
  TaoCheckbox,
5884
7311
  TaoTag,
5885
7312
  TaoDivider,
7313
+ TaoFieldset,
5886
7314
  TaoAnimatedBorder,
5887
7315
  TaoTextarea,
5888
7316
  TaoScrollTop,
@@ -5891,10 +7319,12 @@
5891
7319
  TaoFileDrop,
5892
7320
  TaoDropdownMenu,
5893
7321
  TaoPinCode,
5894
- _sfc_main$k,
7322
+ _sfc_main$m,
5895
7323
  TaoFormField,
5896
7324
  TaoSelect,
7325
+ TaoCombobox,
5897
7326
  TaoDate,
7327
+ TaoDateRange,
5898
7328
  TaoSwitch,
5899
7329
  TaoRadio,
5900
7330
  TaoRadioGroup,
@@ -5928,28 +7358,32 @@
5928
7358
  exports2.TaoCard = TaoCard;
5929
7359
  exports2.TaoCarousel = TaoCarousel;
5930
7360
  exports2.TaoCheckbox = TaoCheckbox;
7361
+ exports2.TaoCombobox = TaoCombobox;
5931
7362
  exports2.TaoConfirmHost = TaoConfirmHost;
5932
7363
  exports2.TaoContainer = TaoContainer;
5933
7364
  exports2.TaoCopy = TaoCopy;
5934
7365
  exports2.TaoCounter = TaoCounter;
5935
7366
  exports2.TaoDate = TaoDate;
7367
+ exports2.TaoDateRange = TaoDateRange;
5936
7368
  exports2.TaoDivider = TaoDivider;
5937
7369
  exports2.TaoDrawer = TaoDrawer;
5938
7370
  exports2.TaoDropdownMenu = TaoDropdownMenu;
5939
7371
  exports2.TaoEmpty = TaoEmpty;
7372
+ exports2.TaoFieldset = TaoFieldset;
5940
7373
  exports2.TaoFileDrop = TaoFileDrop;
5941
- exports2.TaoFlex = _sfc_main$A;
7374
+ exports2.TaoFlex = _sfc_main$D;
5942
7375
  exports2.TaoFormField = TaoFormField;
5943
7376
  exports2.TaoIcon = TaoIcon;
5944
7377
  exports2.TaoImage = TaoImage;
5945
7378
  exports2.TaoInput = TaoInput;
5946
7379
  exports2.TaoInputGroup = TaoInputGroup;
5947
7380
  exports2.TaoInputNumber = TaoInputNumber;
5948
- exports2.TaoLink = _sfc_main$k;
7381
+ exports2.TaoLink = _sfc_main$m;
5949
7382
  exports2.TaoLoader = TaoLoader;
5950
7383
  exports2.TaoModal = TaoModal;
5951
7384
  exports2.TaoPagination = TaoPagination;
5952
7385
  exports2.TaoPinCode = TaoPinCode;
7386
+ exports2.TaoPopover = TaoPopover;
5953
7387
  exports2.TaoProgress = TaoProgress;
5954
7388
  exports2.TaoQuantity = TaoQuantity;
5955
7389
  exports2.TaoRadio = TaoRadio;
@@ -5960,6 +7394,7 @@
5960
7394
  exports2.TaoSlider = TaoSlider;
5961
7395
  exports2.TaoSpace = TaoSpace;
5962
7396
  exports2.TaoSpoiler = TaoSpoiler;
7397
+ exports2.TaoSpoilerGroup = TaoSpoilerGroup;
5963
7398
  exports2.TaoStages = TaoStages;
5964
7399
  exports2.TaoSwitch = TaoSwitch;
5965
7400
  exports2.TaoTable = TaoTable;
@@ -5973,7 +7408,9 @@
5973
7408
  exports2.default = TaoUI;
5974
7409
  exports2.formatTaoDateIso = formatTaoDateIso;
5975
7410
  exports2.formatTaoDateLabel = formatTaoDateLabel;
7411
+ exports2.formatTaoDateRangeLabel = formatTaoDateRangeLabel;
5976
7412
  exports2.parseTaoDate = parseTaoDate;
7413
+ exports2.parseTaoDateRange = parseTaoDateRange;
5977
7414
  exports2.toast = toast;
5978
7415
  exports2.todayTaoDate = todayTaoDate;
5979
7416
  Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });