rei-kit 2.19.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -348,17 +348,17 @@ function useDragScroll(target) {
348
348
  }
349
349
  //#endregion
350
350
  //#region src/components/BaseAvatar.vue?vue&type=script&setup=true&lang.ts
351
- var _hoisted_1$44 = [
351
+ var _hoisted_1$47 = [
352
352
  "role",
353
353
  "aria-label",
354
354
  "aria-hidden"
355
355
  ];
356
- var _hoisted_2$38 = ["src"];
357
- var _hoisted_3$25 = {
356
+ var _hoisted_2$41 = ["src"];
357
+ var _hoisted_3$27 = {
358
358
  key: 1,
359
359
  class: "rk-avatar-initials"
360
360
  };
361
- var _hoisted_4$19 = {
361
+ var _hoisted_4$21 = {
362
362
  key: 2,
363
363
  viewBox: "0 0 20 20",
364
364
  class: "rk-avatar-figure",
@@ -404,7 +404,7 @@ var BaseAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
404
404
  alt: "",
405
405
  class: "rk-avatar-img",
406
406
  onError: _cache[0] || (_cache[0] = ($event) => broken.value = true)
407
- }, null, 40, _hoisted_2$38)) : __props.fallback === "initials" && initials.value ? (openBlock(), createElementBlock("span", _hoisted_3$25, toDisplayString(initials.value), 1)) : (openBlock(), createElementBlock("svg", _hoisted_4$19, [..._cache[1] || (_cache[1] = [createElementVNode("circle", {
407
+ }, null, 40, _hoisted_2$41)) : __props.fallback === "initials" && initials.value ? (openBlock(), createElementBlock("span", _hoisted_3$27, toDisplayString(initials.value), 1)) : (openBlock(), createElementBlock("svg", _hoisted_4$21, [..._cache[1] || (_cache[1] = [createElementVNode("circle", {
408
408
  cx: "10",
409
409
  cy: "6.75",
410
410
  r: "3.25",
@@ -413,7 +413,7 @@ var BaseAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
413
413
  d: "M3.75 17c0-3.05 2.8-5.25 6.25-5.25S16.25 13.95 16.25 17",
414
414
  "stroke-width": "1.5",
415
415
  "stroke-linecap": "round"
416
- }, null, -1)])]))], 10, _hoisted_1$44);
416
+ }, null, -1)])]))], 10, _hoisted_1$47);
417
417
  };
418
418
  }
419
419
  }), [["__scopeId", "data-v-47586bec"]]);
@@ -438,12 +438,12 @@ var BaseBadge_default = /* @__PURE__ */ defineComponent({
438
438
  });
439
439
  //#endregion
440
440
  //#region src/components/BaseMenu.vue?vue&type=script&setup=true&lang.ts
441
- var _hoisted_1$43 = [
441
+ var _hoisted_1$46 = [
442
442
  "aria-label",
443
443
  "aria-expanded",
444
444
  "aria-controls"
445
445
  ];
446
- var _hoisted_2$37 = ["id"];
446
+ var _hoisted_2$40 = ["id"];
447
447
  //#endregion
448
448
  //#region src/components/BaseMenu.vue
449
449
  var BaseMenu_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -512,14 +512,14 @@ var BaseMenu_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
512
512
  "aria-haspopup": true,
513
513
  "aria-controls": open.value ? unref(id) : void 0,
514
514
  onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
515
- }, [renderSlot(_ctx.$slots, "trigger", { open: open.value }, void 0, true)], 8, _hoisted_1$43), open.value ? (openBlock(), createElementBlock("div", {
515
+ }, [renderSlot(_ctx.$slots, "trigger", { open: open.value }, void 0, true)], 8, _hoisted_1$46), open.value ? (openBlock(), createElementBlock("div", {
516
516
  key: 0,
517
517
  id: unref(id),
518
518
  ref_key: "panel",
519
519
  ref: panel,
520
520
  class: normalizeClass(["rk-menu-panel surface-overlay", `is-${__props.align}`]),
521
521
  role: "menu"
522
- }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 10, _hoisted_2$37)) : createCommentVNode("", true)], 544);
522
+ }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 10, _hoisted_2$40)) : createCommentVNode("", true)], 544);
523
523
  };
524
524
  }
525
525
  }), [["__scopeId", "data-v-ee62de72"]]);
@@ -589,14 +589,68 @@ var BaseCard_default = /* @__PURE__ */ defineComponent({
589
589
  }
590
590
  });
591
591
  //#endregion
592
+ //#region src/composables/use-virtual-window.ts
593
+ /** Rows of slack each way, so a fast scroll does not show a gap before the
594
+ * next frame fills it. */
595
+ var OVERSCAN_ROWS = 3;
596
+ /**
597
+ * The arithmetic behind a windowed list: which rows are near the viewport,
598
+ * and how much empty space stands in for the rest.
599
+ *
600
+ * This is the part `BaseCombobox` and `VirtualList` share. It was written
601
+ * inside the combobox first, and pulling it out here is the reason there is
602
+ * one copy of it rather than two — the second would have drifted, and the
603
+ * half that drifts silently is the padding, which is what keeps the
604
+ * scrollbar honest about how long the list is.
605
+ *
606
+ * There is no clock and no observer in here: it is a function of the scroll
607
+ * position, and the component that owns the element is what tells it where
608
+ * that is. That is also what makes it testable without a layout.
609
+ */
610
+ function useVirtualWindow({ count, rowHeight, threshold }) {
611
+ /** How far down the list is scrolled. Set by the owner from a scroll event. */
612
+ const scrollTop = ref(0);
613
+ /** How tall the viewport is. Measured by the owner, never guessed here. */
614
+ const viewportHeight = ref(0);
615
+ const active = computed(() => count.value > threshold.value);
616
+ const window_ = computed(() => {
617
+ if (!active.value) return {
618
+ start: 0,
619
+ end: count.value
620
+ };
621
+ const first = Math.max(0, Math.floor(scrollTop.value / rowHeight.value) - OVERSCAN_ROWS);
622
+ const rows = Math.ceil(viewportHeight.value / rowHeight.value) + 6;
623
+ return {
624
+ start: first,
625
+ end: Math.min(count.value, first + rows)
626
+ };
627
+ });
628
+ /** The empty space standing in for the rows above and below the window. */
629
+ const padTop = computed(() => active.value ? window_.value.start * rowHeight.value : 0);
630
+ const padBottom = computed(() => active.value ? (count.value - window_.value.end) * rowHeight.value : 0);
631
+ /** Takes the scroll position straight off the event the owner received. */
632
+ function onScroll(event) {
633
+ scrollTop.value = event.target.scrollTop;
634
+ }
635
+ return {
636
+ active,
637
+ window: window_,
638
+ padTop,
639
+ padBottom,
640
+ scrollTop,
641
+ viewportHeight,
642
+ onScroll
643
+ };
644
+ }
645
+ //#endregion
592
646
  //#region src/components/BaseCombobox.vue?vue&type=script&setup=true&lang.ts
593
- var _hoisted_1$42 = ["for"];
594
- var _hoisted_2$36 = [
647
+ var _hoisted_1$45 = ["for"];
648
+ var _hoisted_2$39 = [
595
649
  "aria-label",
596
650
  "disabled",
597
651
  "onClick"
598
652
  ];
599
- var _hoisted_3$24 = [
653
+ var _hoisted_3$26 = [
600
654
  "id",
601
655
  "placeholder",
602
656
  "disabled",
@@ -605,13 +659,13 @@ var _hoisted_3$24 = [
605
659
  "aria-invalid",
606
660
  "aria-describedby"
607
661
  ];
608
- var _hoisted_4$18 = ["disabled"];
609
- var _hoisted_5$11 = [
662
+ var _hoisted_4$20 = ["disabled"];
663
+ var _hoisted_5$13 = [
610
664
  "aria-label",
611
665
  "aria-multiselectable",
612
666
  "aria-busy"
613
667
  ];
614
- var _hoisted_6$6 = [
668
+ var _hoisted_6$8 = [
615
669
  "id",
616
670
  "aria-selected",
617
671
  "aria-setsize",
@@ -720,32 +774,18 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
720
774
  if (timer) clearTimeout(timer);
721
775
  timer = setTimeout(() => emit("search", value.trim()), __props.debounce);
722
776
  }
723
- const virtual = computed(() => matches.value.length > __props.virtualizeAfter);
724
- const scrollTop = ref(0);
725
- /** How tall the list box is; read once it is open, never guessed. */
726
- const viewport = ref(224);
727
- const window_ = computed(() => {
728
- if (!virtual.value) return {
729
- start: 0,
730
- end: matches.value.length
731
- };
732
- const first = Math.max(0, Math.floor(scrollTop.value / __props.rowHeight) - 3);
733
- const count = Math.ceil(viewport.value / __props.rowHeight) + 6;
734
- return {
735
- start: first,
736
- end: Math.min(matches.value.length, first + count)
737
- };
777
+ const { active: virtual, window: window_, padTop, padBottom, viewportHeight: viewport, onScroll } = useVirtualWindow({
778
+ count: computed(() => matches.value.length),
779
+ rowHeight: computed(() => __props.rowHeight),
780
+ threshold: computed(() => __props.virtualizeAfter)
738
781
  });
782
+ /** How tall the list box is; read once it is open, and this until then. */
783
+ viewport.value = 224;
739
784
  const rows = computed(() => matches.value.slice(window_.value.start, window_.value.end).map((option, index) => ({
740
785
  option,
741
786
  /** The row's place in the whole list, not in the window. */
742
787
  index: window_.value.start + index
743
788
  })));
744
- const padTop = computed(() => virtual.value ? window_.value.start * __props.rowHeight : 0);
745
- const padBottom = computed(() => virtual.value ? (matches.value.length - window_.value.end) * __props.rowHeight : 0);
746
- function onScroll(event) {
747
- scrollTop.value = event.target.scrollTop;
748
- }
749
789
  function choose(option) {
750
790
  if (!option) return;
751
791
  if (multiple.value) {
@@ -841,7 +881,7 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
841
881
  createElementVNode("label", {
842
882
  for: unref(id),
843
883
  class: "rk-combo-label"
844
- }, toDisplayString(__props.label), 9, _hoisted_1$42),
884
+ }, toDisplayString(__props.label), 9, _hoisted_1$45),
845
885
  createElementVNode("div", { class: normalizeClass(["rk-combo-field", multiple.value ? "is-multiple control" : ""]) }, [
846
886
  (openBlock(true), createElementBlock(Fragment, null, renderList(multiple.value ? chosenOptions.value : [], (option) => {
847
887
  return openBlock(), createElementBlock("span", {
@@ -854,7 +894,7 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
854
894
  "aria-label": __props.removeLabel(option.label),
855
895
  disabled: __props.disabled,
856
896
  onClick: ($event) => remove(option.value)
857
- }, " × ", 8, _hoisted_2$36)) : createCommentVNode("", true)]);
897
+ }, " × ", 8, _hoisted_2$39)) : createCommentVNode("", true)]);
858
898
  }), 128)),
859
899
  withDirectives(createElementVNode("input", {
860
900
  id: unref(id),
@@ -873,7 +913,7 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
873
913
  "aria-describedby": describedBy.value,
874
914
  onKeydown,
875
915
  onFocus: _cache[1] || (_cache[1] = ($event) => open.value = true)
876
- }, null, 42, _hoisted_3$24), [[vModelText, text.value]]),
916
+ }, null, 42, _hoisted_3$26), [[vModelText, text.value]]),
877
917
  createElementVNode("button", {
878
918
  type: "button",
879
919
  class: "rk-combo-toggle",
@@ -881,7 +921,7 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
881
921
  "aria-hidden": "true",
882
922
  disabled: __props.disabled,
883
923
  onClick: _cache[2] || (_cache[2] = ($event) => open.value = !open.value)
884
- }, " ▾ ", 8, _hoisted_4$18)
924
+ }, " ▾ ", 8, _hoisted_4$20)
885
925
  ], 2),
886
926
  withDirectives(createElementVNode("ul", {
887
927
  id: listId,
@@ -892,11 +932,11 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
892
932
  "aria-label": __props.label,
893
933
  "aria-multiselectable": multiple.value ? true : void 0,
894
934
  "aria-busy": __props.loading ? true : void 0,
895
- onScroll
935
+ onScroll: _cache[3] || (_cache[3] = (...args) => unref(onScroll) && unref(onScroll)(...args))
896
936
  }, [
897
- padTop.value > 0 ? (openBlock(), createElementBlock("li", {
937
+ unref(padTop) > 0 ? (openBlock(), createElementBlock("li", {
898
938
  key: 0,
899
- style: normalizeStyle({ height: `${padTop.value}px` }),
939
+ style: normalizeStyle({ height: `${unref(padTop)}px` }),
900
940
  "aria-hidden": "true"
901
941
  }, null, 4)) : createCommentVNode("", true),
902
942
  (openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (row) => {
@@ -908,17 +948,17 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
908
948
  "is-highlighted": row.index === highlighted.value,
909
949
  "is-selected": chosen.value.includes(row.option.value)
910
950
  }]),
911
- style: normalizeStyle(virtual.value ? { height: `${__props.rowHeight}px` } : void 0),
951
+ style: normalizeStyle(unref(virtual) ? { height: `${__props.rowHeight}px` } : void 0),
912
952
  "aria-selected": chosen.value.includes(row.option.value),
913
953
  "aria-setsize": matches.value.length,
914
954
  "aria-posinset": row.index + 1,
915
955
  onPointerdown: withModifiers(($event) => choose(row.option), ["prevent"]),
916
956
  onPointermove: ($event) => highlighted.value = row.index
917
- }, toDisplayString(row.option.label), 47, _hoisted_6$6);
957
+ }, toDisplayString(row.option.label), 47, _hoisted_6$8);
918
958
  }), 128)),
919
- padBottom.value > 0 ? (openBlock(), createElementBlock("li", {
959
+ unref(padBottom) > 0 ? (openBlock(), createElementBlock("li", {
920
960
  key: 1,
921
- style: normalizeStyle({ height: `${padBottom.value}px` }),
961
+ style: normalizeStyle({ height: `${unref(padBottom)}px` }),
922
962
  "aria-hidden": "true"
923
963
  }, null, 4)) : createCommentVNode("", true),
924
964
  __props.loading ? (openBlock(), createElementBlock("li", _hoisted_7$4, [__props.loadingLabel ? (openBlock(), createElementBlock("span", _hoisted_8$3, toDisplayString(__props.loadingLabel), 1)) : createCommentVNode("", true), createElementVNode("span", _hoisted_9$3, [(openBlock(), createElementBlock(Fragment, null, renderList(3, (n) => {
@@ -928,7 +968,7 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
928
968
  height: "0.75rem"
929
969
  });
930
970
  }), 64))])])) : matches.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_10$3, toDisplayString(__props.emptyLabel), 1)) : createCommentVNode("", true)
931
- ], 40, _hoisted_5$11), [[vShow, open.value]]),
971
+ ], 40, _hoisted_5$13), [[vShow, open.value]]),
932
972
  __props.error ? (openBlock(), createElementBlock("p", {
933
973
  key: 0,
934
974
  id: errorId,
@@ -941,16 +981,16 @@ var BaseCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
941
981
  ], 512);
942
982
  };
943
983
  }
944
- }), [["__scopeId", "data-v-aa2335fa"]]);
984
+ }), [["__scopeId", "data-v-006740dc"]]);
945
985
  //#endregion
946
986
  //#region src/components/BaseRadioGroup.vue?vue&type=script&setup=true&lang.ts
947
- var _hoisted_1$41 = ["aria-describedby"];
948
- var _hoisted_2$35 = [
987
+ var _hoisted_1$44 = ["aria-describedby"];
988
+ var _hoisted_2$38 = [
949
989
  "name",
950
990
  "value",
951
991
  "disabled"
952
992
  ];
953
- var _hoisted_3$23 = { class: "text-ink text-sm" };
993
+ var _hoisted_3$25 = { class: "text-ink text-sm" };
954
994
  //#endregion
955
995
  //#region src/components/BaseRadioGroup.vue
956
996
  var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
@@ -994,7 +1034,7 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
994
1034
  value: option.value,
995
1035
  disabled: option.disabled,
996
1036
  class: "accent-primary focus-visible:outline-primary size-4 shrink-0 focus-visible:outline-2 focus-visible:outline-offset-2"
997
- }, null, 8, _hoisted_2$35), [[vModelRadio, unref(model)]]), createElementVNode("span", _hoisted_3$23, toDisplayString(option.label), 1)], 2);
1037
+ }, null, 8, _hoisted_2$38), [[vModelRadio, unref(model)]]), createElementVNode("span", _hoisted_3$25, toDisplayString(option.label), 1)], 2);
998
1038
  }), 128)),
999
1039
  __props.error ? (openBlock(), createElementBlock("p", {
1000
1040
  key: 0,
@@ -1005,24 +1045,24 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1005
1045
  id: hintId,
1006
1046
  class: "text-ink-soft text-xs"
1007
1047
  }, toDisplayString(__props.hint), 1)) : createCommentVNode("", true)
1008
- ], 8, _hoisted_1$41);
1048
+ ], 8, _hoisted_1$44);
1009
1049
  };
1010
1050
  }
1011
1051
  });
1012
1052
  //#endregion
1013
1053
  //#region src/components/BaseSelect.vue?vue&type=script&setup=true&lang.ts
1014
- var _hoisted_1$40 = { class: "relative" };
1015
- var _hoisted_2$34 = [
1054
+ var _hoisted_1$43 = { class: "relative" };
1055
+ var _hoisted_2$37 = [
1016
1056
  "id",
1017
1057
  "aria-invalid",
1018
1058
  "aria-describedby"
1019
1059
  ];
1020
- var _hoisted_3$22 = {
1060
+ var _hoisted_3$24 = {
1021
1061
  key: 0,
1022
1062
  value: void 0,
1023
1063
  disabled: ""
1024
1064
  };
1025
- var _hoisted_4$17 = ["value", "disabled"];
1065
+ var _hoisted_4$19 = ["value", "disabled"];
1026
1066
  //#endregion
1027
1067
  //#region src/components/BaseSelect.vue
1028
1068
  var BaseSelect_default = /* @__PURE__ */ defineComponent({
@@ -1058,7 +1098,7 @@ var BaseSelect_default = /* @__PURE__ */ defineComponent({
1058
1098
  "label-hidden": __props.labelHidden,
1059
1099
  size: __props.size
1060
1100
  }, {
1061
- default: withCtx(({ id, describedBy, invalid }) => [createElementVNode("div", _hoisted_1$40, [withDirectives(createElementVNode("select", {
1101
+ default: withCtx(({ id, describedBy, invalid }) => [createElementVNode("div", _hoisted_1$43, [withDirectives(createElementVNode("select", {
1062
1102
  id,
1063
1103
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
1064
1104
  "aria-invalid": invalid,
@@ -1068,13 +1108,13 @@ var BaseSelect_default = /* @__PURE__ */ defineComponent({
1068
1108
  __props.variant === "unstyled" ? "" : SIZE_CLASS[__props.size],
1069
1109
  __props.variant !== "unstyled" && invalid ? "border-negative" : ""
1070
1110
  ]])
1071
- }, [__props.placeholder ? (openBlock(), createElementBlock("option", _hoisted_3$22, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
1111
+ }, [__props.placeholder ? (openBlock(), createElementBlock("option", _hoisted_3$24, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
1072
1112
  return openBlock(), createElementBlock("option", {
1073
1113
  key: option.value,
1074
1114
  value: option.value,
1075
1115
  disabled: option.disabled
1076
- }, toDisplayString(option.label), 9, _hoisted_4$17);
1077
- }), 128))], 10, _hoisted_2$34), [[vModelSelect, model.value]]), createVNode(unref(ChevronDown), {
1116
+ }, toDisplayString(option.label), 9, _hoisted_4$19);
1117
+ }), 128))], 10, _hoisted_2$37), [[vModelSelect, model.value]]), createVNode(unref(ChevronDown), {
1078
1118
  class: "text-ink-soft pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2",
1079
1119
  "aria-hidden": "true"
1080
1120
  })])]),
@@ -1091,11 +1131,11 @@ var BaseSelect_default = /* @__PURE__ */ defineComponent({
1091
1131
  });
1092
1132
  //#endregion
1093
1133
  //#region src/components/BaseSlider.vue?vue&type=script&setup=true&lang.ts
1094
- var _hoisted_1$39 = { class: "rk-slider" };
1095
- var _hoisted_2$33 = { class: "rk-slider-head" };
1096
- var _hoisted_3$21 = ["for"];
1097
- var _hoisted_4$16 = ["for"];
1098
- var _hoisted_5$10 = [
1134
+ var _hoisted_1$42 = { class: "rk-slider" };
1135
+ var _hoisted_2$36 = { class: "rk-slider-head" };
1136
+ var _hoisted_3$23 = ["for"];
1137
+ var _hoisted_4$18 = ["for"];
1138
+ var _hoisted_5$12 = [
1099
1139
  "id",
1100
1140
  "min",
1101
1141
  "max",
@@ -1139,15 +1179,15 @@ var BaseSlider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
1139
1179
  return span <= 0 ? 0 : (model.value - __props.min) / span * 100;
1140
1180
  });
1141
1181
  return (_ctx, _cache) => {
1142
- return openBlock(), createElementBlock("div", _hoisted_1$39, [
1143
- createElementVNode("div", _hoisted_2$33, [createElementVNode("label", {
1182
+ return openBlock(), createElementBlock("div", _hoisted_1$42, [
1183
+ createElementVNode("div", _hoisted_2$36, [createElementVNode("label", {
1144
1184
  for: unref(id),
1145
1185
  class: "rk-slider-label"
1146
- }, toDisplayString(__props.label), 9, _hoisted_3$21), __props.showValue ? (openBlock(), createElementBlock("output", {
1186
+ }, toDisplayString(__props.label), 9, _hoisted_3$23), __props.showValue ? (openBlock(), createElementBlock("output", {
1147
1187
  key: 0,
1148
1188
  for: unref(id),
1149
1189
  class: "rk-slider-value"
1150
- }, toDisplayString(text.value), 9, _hoisted_4$16)) : createCommentVNode("", true)]),
1190
+ }, toDisplayString(text.value), 9, _hoisted_4$18)) : createCommentVNode("", true)]),
1151
1191
  withDirectives(createElementVNode("input", {
1152
1192
  id: unref(id),
1153
1193
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
@@ -1160,7 +1200,7 @@ var BaseSlider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
1160
1200
  "aria-valuetext": text.value,
1161
1201
  "aria-describedby": __props.hint ? hintId : void 0,
1162
1202
  style: normalizeStyle({ "--rk-slider-filled": `${filled.value}%` })
1163
- }, null, 12, _hoisted_5$10), [[
1203
+ }, null, 12, _hoisted_5$12), [[
1164
1204
  vModelText,
1165
1205
  model.value,
1166
1206
  void 0,
@@ -1177,8 +1217,8 @@ var BaseSlider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
1177
1217
  }), [["__scopeId", "data-v-7fa2769b"]]);
1178
1218
  //#endregion
1179
1219
  //#region src/components/NumberInput.vue?vue&type=script&setup=true&lang.ts
1180
- var _hoisted_1$38 = ["aria-label", "disabled"];
1181
- var _hoisted_2$32 = [
1220
+ var _hoisted_1$41 = ["aria-label", "disabled"];
1221
+ var _hoisted_2$35 = [
1182
1222
  "id",
1183
1223
  "value",
1184
1224
  "aria-valuenow",
@@ -1188,7 +1228,7 @@ var _hoisted_2$32 = [
1188
1228
  "aria-describedby",
1189
1229
  "disabled"
1190
1230
  ];
1191
- var _hoisted_3$20 = ["aria-label", "disabled"];
1231
+ var _hoisted_3$22 = ["aria-label", "disabled"];
1192
1232
  //#endregion
1193
1233
  //#region src/components/NumberInput.vue
1194
1234
  var NumberInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -1291,7 +1331,7 @@ var NumberInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1291
1331
  }, [createVNode(unref(Minus), {
1292
1332
  class: "size-4",
1293
1333
  "aria-hidden": "true"
1294
- })], 8, _hoisted_1$38),
1334
+ })], 8, _hoisted_1$41),
1295
1335
  createElementVNode("input", {
1296
1336
  id,
1297
1337
  value: draft.value,
@@ -1309,7 +1349,7 @@ var NumberInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1309
1349
  onInput,
1310
1350
  onBlur: commit,
1311
1351
  onKeydown
1312
- }, null, 40, _hoisted_2$32),
1352
+ }, null, 40, _hoisted_2$35),
1313
1353
  createElementVNode("button", {
1314
1354
  type: "button",
1315
1355
  class: "rk-number-step focus-ring",
@@ -1320,7 +1360,7 @@ var NumberInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1320
1360
  }, [createVNode(unref(Plus), {
1321
1361
  class: "size-4",
1322
1362
  "aria-hidden": "true"
1323
- })], 8, _hoisted_3$20)
1363
+ })], 8, _hoisted_3$22)
1324
1364
  ], 2)]),
1325
1365
  _: 1
1326
1366
  }, 8, [
@@ -1335,7 +1375,7 @@ var NumberInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1335
1375
  }), [["__scopeId", "data-v-082bd3d7"]]);
1336
1376
  //#endregion
1337
1377
  //#region src/components/SliderField.vue?vue&type=script&setup=true&lang.ts
1338
- var _hoisted_1$37 = { class: "rk-slider-field" };
1378
+ var _hoisted_1$40 = { class: "rk-slider-field" };
1339
1379
  //#endregion
1340
1380
  //#region src/components/SliderField.vue
1341
1381
  var SliderField_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -1376,7 +1416,7 @@ var SliderField_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1376
1416
  }
1377
1417
  });
1378
1418
  return (_ctx, _cache) => {
1379
- return openBlock(), createElementBlock("div", _hoisted_1$37, [createVNode(BaseSlider_default, {
1419
+ return openBlock(), createElementBlock("div", _hoisted_1$40, [createVNode(BaseSlider_default, {
1380
1420
  modelValue: model.value,
1381
1421
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
1382
1422
  label: __props.label,
@@ -1424,11 +1464,11 @@ var SliderField_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1424
1464
  }), [["__scopeId", "data-v-6ec3163a"]]);
1425
1465
  //#endregion
1426
1466
  //#region src/components/BaseSpinner.vue?vue&type=script&setup=true&lang.ts
1427
- var _hoisted_1$36 = {
1467
+ var _hoisted_1$39 = {
1428
1468
  class: "rk-spin-wrap",
1429
1469
  role: "status"
1430
1470
  };
1431
- var _hoisted_2$31 = { class: "rk-spin-label" };
1471
+ var _hoisted_2$34 = { class: "rk-spin-label" };
1432
1472
  //#endregion
1433
1473
  //#region src/components/BaseSpinner.vue
1434
1474
  var BaseSpinner_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -1456,26 +1496,26 @@ var BaseSpinner_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
1456
1496
  lg: "2.5rem"
1457
1497
  };
1458
1498
  return (_ctx, _cache) => {
1459
- return openBlock(), createElementBlock("span", _hoisted_1$36, [createElementVNode("span", {
1499
+ return openBlock(), createElementBlock("span", _hoisted_1$39, [createElementVNode("span", {
1460
1500
  class: "rk-spin",
1461
1501
  style: normalizeStyle({
1462
1502
  width: SIZES[__props.size],
1463
1503
  height: SIZES[__props.size]
1464
1504
  }),
1465
1505
  "aria-hidden": "true"
1466
- }, null, 4), createElementVNode("span", _hoisted_2$31, toDisplayString(__props.label), 1)]);
1506
+ }, null, 4), createElementVNode("span", _hoisted_2$34, toDisplayString(__props.label), 1)]);
1467
1507
  };
1468
1508
  }
1469
1509
  }), [["__scopeId", "data-v-842da62c"]]);
1470
1510
  //#endregion
1471
1511
  //#region src/components/BaseSwitch.vue?vue&type=script&setup=true&lang.ts
1472
- var _hoisted_1$35 = { class: "flex items-center justify-between gap-4" };
1473
- var _hoisted_2$30 = {
1512
+ var _hoisted_1$38 = { class: "flex items-center justify-between gap-4" };
1513
+ var _hoisted_2$33 = {
1474
1514
  key: 0,
1475
1515
  class: "min-w-0"
1476
1516
  };
1477
- var _hoisted_3$19 = ["id"];
1478
- var _hoisted_4$15 = [
1517
+ var _hoisted_3$21 = ["id"];
1518
+ var _hoisted_4$17 = [
1479
1519
  "aria-checked",
1480
1520
  "aria-labelledby",
1481
1521
  "aria-label",
@@ -1514,10 +1554,10 @@ var BaseSwitch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
1514
1554
  if (!__props.disabled) model.value = !model.value;
1515
1555
  }
1516
1556
  return (_ctx, _cache) => {
1517
- return openBlock(), createElementBlock("div", _hoisted_1$35, [!__props.labelHidden ? (openBlock(), createElementBlock("span", _hoisted_2$30, [createElementVNode("span", {
1557
+ return openBlock(), createElementBlock("div", _hoisted_1$38, [!__props.labelHidden ? (openBlock(), createElementBlock("span", _hoisted_2$33, [createElementVNode("span", {
1518
1558
  id: unref(id),
1519
1559
  class: "text-ink block text-sm"
1520
- }, toDisplayString(__props.label), 9, _hoisted_3$19), __props.hint ? (openBlock(), createElementBlock("span", {
1560
+ }, toDisplayString(__props.label), 9, _hoisted_3$21), __props.hint ? (openBlock(), createElementBlock("span", {
1521
1561
  key: 0,
1522
1562
  id: hintId,
1523
1563
  class: "text-ink-soft mt-0.5 block text-xs"
@@ -1534,17 +1574,17 @@ var BaseSwitch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
1534
1574
  }, [..._cache[0] || (_cache[0] = [createElementVNode("span", {
1535
1575
  class: "rk-switch-knob",
1536
1576
  "aria-hidden": "true"
1537
- }, null, -1)])], 10, _hoisted_4$15)]);
1577
+ }, null, -1)])], 10, _hoisted_4$17)]);
1538
1578
  };
1539
1579
  }
1540
1580
  }), [["__scopeId", "data-v-3f4400a0"]]);
1541
1581
  //#endregion
1542
1582
  //#region src/components/BaseTable.vue?vue&type=script&setup=true&lang.ts
1543
- var _hoisted_1$34 = ["aria-label"];
1544
- var _hoisted_2$29 = { class: "rk-table" };
1545
- var _hoisted_3$18 = { key: 0 };
1546
- var _hoisted_4$14 = { key: 1 };
1547
- var _hoisted_5$9 = ["colspan"];
1583
+ var _hoisted_1$37 = ["aria-label"];
1584
+ var _hoisted_2$32 = { class: "rk-table" };
1585
+ var _hoisted_3$20 = { key: 0 };
1586
+ var _hoisted_4$16 = { key: 1 };
1587
+ var _hoisted_5$11 = ["colspan"];
1548
1588
  //#endregion
1549
1589
  //#region src/components/BaseTable.vue
1550
1590
  var BaseTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -1567,7 +1607,7 @@ var BaseTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
1567
1607
  tabindex: "0",
1568
1608
  role: "region",
1569
1609
  "aria-label": __props.caption
1570
- }, [createElementVNode("table", _hoisted_2$29, [
1610
+ }, [createElementVNode("table", _hoisted_2$32, [
1571
1611
  createElementVNode("caption", { class: normalizeClass(__props.captionHidden ? "rk-table-caption-hidden" : "rk-table-caption") }, toDisplayString(__props.caption), 3),
1572
1612
  createElementVNode("thead", null, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
1573
1613
  return openBlock(), createElementBlock("th", {
@@ -1576,7 +1616,7 @@ var BaseTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
1576
1616
  class: normalizeClass([column.align && `is-${column.align}`, column.nowrap && "is-nowrap"])
1577
1617
  }, toDisplayString(column.label), 3);
1578
1618
  }), 128))])]),
1579
- __props.rows.length > 0 ? (openBlock(), createElementBlock("tbody", _hoisted_3$18, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row, index) => {
1619
+ __props.rows.length > 0 ? (openBlock(), createElementBlock("tbody", _hoisted_3$20, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row, index) => {
1580
1620
  return openBlock(), createElementBlock("tr", { key: keyFor(row, index) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
1581
1621
  return openBlock(), createElementBlock("td", {
1582
1622
  key: column.key,
@@ -1586,17 +1626,17 @@ var BaseTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
1586
1626
  value: row[column.key]
1587
1627
  }, () => [createTextVNode(toDisplayString(row[column.key]), 1)], true)], 2);
1588
1628
  }), 128))]);
1589
- }), 128))])) : (openBlock(), createElementBlock("tbody", _hoisted_4$14, [createElementVNode("tr", null, [createElementVNode("td", {
1629
+ }), 128))])) : (openBlock(), createElementBlock("tbody", _hoisted_4$16, [createElementVNode("tr", null, [createElementVNode("td", {
1590
1630
  colspan: __props.columns.length,
1591
1631
  class: "rk-table-empty"
1592
- }, [renderSlot(_ctx.$slots, "empty", {}, void 0, true)], 8, _hoisted_5$9)])]))
1593
- ])], 8, _hoisted_1$34);
1632
+ }, [renderSlot(_ctx.$slots, "empty", {}, void 0, true)], 8, _hoisted_5$11)])]))
1633
+ ])], 8, _hoisted_1$37);
1594
1634
  };
1595
1635
  }
1596
1636
  }), [["__scopeId", "data-v-ab10e9fa"]]);
1597
1637
  //#endregion
1598
1638
  //#region src/components/BaseTextarea.vue?vue&type=script&setup=true&lang.ts
1599
- var _hoisted_1$33 = [
1639
+ var _hoisted_1$36 = [
1600
1640
  "id",
1601
1641
  "rows",
1602
1642
  "aria-invalid",
@@ -1642,7 +1682,7 @@ var BaseTextarea_default = /* @__PURE__ */ defineComponent({
1642
1682
  __props.variant === "unstyled" ? "" : "control text-ink rounded-card focus-visible:outline-primary resize-y px-3 py-2 leading-relaxed focus-visible:outline-2 focus-visible:outline-offset-1",
1643
1683
  "text-base",
1644
1684
  __props.variant !== "unstyled" && invalid ? "border-negative" : ""
1645
- ] }), null, 16, _hoisted_1$33), [[vModelText, unref(model)]])]),
1685
+ ] }), null, 16, _hoisted_1$36), [[vModelText, unref(model)]])]),
1646
1686
  _: 1
1647
1687
  }, 8, [
1648
1688
  "label",
@@ -1656,17 +1696,17 @@ var BaseTextarea_default = /* @__PURE__ */ defineComponent({
1656
1696
  });
1657
1697
  //#endregion
1658
1698
  //#region src/components/EmptyState.vue?vue&type=script&setup=true&lang.ts
1659
- var _hoisted_1$32 = { class: "flex flex-col items-center gap-3 px-6 py-10 text-center" };
1660
- var _hoisted_2$28 = {
1699
+ var _hoisted_1$35 = { class: "flex flex-col items-center gap-3 px-6 py-10 text-center" };
1700
+ var _hoisted_2$31 = {
1661
1701
  key: 0,
1662
1702
  class: "bg-muted text-primary rounded-card flex size-12 items-center justify-center"
1663
1703
  };
1664
- var _hoisted_3$17 = { class: "text-ink text-base font-semibold" };
1665
- var _hoisted_4$13 = {
1704
+ var _hoisted_3$19 = { class: "text-ink text-base font-semibold" };
1705
+ var _hoisted_4$15 = {
1666
1706
  key: 1,
1667
1707
  class: "text-ink-soft max-w-[36ch] text-sm"
1668
1708
  };
1669
- var _hoisted_5$8 = {
1709
+ var _hoisted_5$10 = {
1670
1710
  key: 2,
1671
1711
  class: "mt-2 flex w-full flex-col gap-2"
1672
1712
  };
@@ -1688,11 +1728,11 @@ var EmptyState_default = /* @__PURE__ */ defineComponent({
1688
1728
  * goes — the button that creates the first one.
1689
1729
  */
1690
1730
  return (_ctx, _cache) => {
1691
- return openBlock(), createElementBlock("div", _hoisted_1$32, [
1692
- _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_2$28, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
1693
- createElementVNode("h3", _hoisted_3$17, toDisplayString(__props.title), 1),
1694
- __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$13, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
1695
- _ctx.$slots.action ? (openBlock(), createElementBlock("div", _hoisted_5$8, [renderSlot(_ctx.$slots, "action")])) : createCommentVNode("", true)
1731
+ return openBlock(), createElementBlock("div", _hoisted_1$35, [
1732
+ _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_2$31, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
1733
+ createElementVNode("h3", _hoisted_3$19, toDisplayString(__props.title), 1),
1734
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$15, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
1735
+ _ctx.$slots.action ? (openBlock(), createElementBlock("div", _hoisted_5$10, [renderSlot(_ctx.$slots, "action")])) : createCommentVNode("", true)
1696
1736
  ]);
1697
1737
  };
1698
1738
  }
@@ -1759,11 +1799,11 @@ var PageContainer_default = /* @__PURE__ */ defineComponent({
1759
1799
  });
1760
1800
  //#endregion
1761
1801
  //#region src/components/PageHeader.vue?vue&type=script&setup=true&lang.ts
1762
- var _hoisted_1$31 = { class: "grid h-12 shrink-0 grid-cols-[2.5rem_1fr_2.5rem] items-center" };
1763
- var _hoisted_2$27 = { class: "justify-self-start" };
1764
- var _hoisted_3$16 = { class: "text-ink flex min-w-0 justify-center text-base font-semibold tabular-nums" };
1765
- var _hoisted_4$12 = { class: "truncate" };
1766
- var _hoisted_5$7 = { class: "justify-self-end" };
1802
+ var _hoisted_1$34 = { class: "grid h-12 shrink-0 grid-cols-[2.5rem_1fr_2.5rem] items-center" };
1803
+ var _hoisted_2$30 = { class: "justify-self-start" };
1804
+ var _hoisted_3$18 = { class: "text-ink flex min-w-0 justify-center text-base font-semibold tabular-nums" };
1805
+ var _hoisted_4$14 = { class: "truncate" };
1806
+ var _hoisted_5$9 = { class: "justify-self-end" };
1767
1807
  //#endregion
1768
1808
  //#region src/components/PageHeader.vue
1769
1809
  var PageHeader_default = /* @__PURE__ */ defineComponent({
@@ -1780,17 +1820,17 @@ var PageHeader_default = /* @__PURE__ */ defineComponent({
1780
1820
  * each other.
1781
1821
  */
1782
1822
  return (_ctx, _cache) => {
1783
- return openBlock(), createElementBlock("header", _hoisted_1$31, [
1784
- createElementVNode("div", _hoisted_2$27, [renderSlot(_ctx.$slots, "left")]),
1785
- createElementVNode("h1", _hoisted_3$16, [renderSlot(_ctx.$slots, "title", {}, () => [createElementVNode("span", _hoisted_4$12, toDisplayString(__props.title), 1)])]),
1786
- createElementVNode("div", _hoisted_5$7, [renderSlot(_ctx.$slots, "right")])
1823
+ return openBlock(), createElementBlock("header", _hoisted_1$34, [
1824
+ createElementVNode("div", _hoisted_2$30, [renderSlot(_ctx.$slots, "left")]),
1825
+ createElementVNode("h1", _hoisted_3$18, [renderSlot(_ctx.$slots, "title", {}, () => [createElementVNode("span", _hoisted_4$14, toDisplayString(__props.title), 1)])]),
1826
+ createElementVNode("div", _hoisted_5$9, [renderSlot(_ctx.$slots, "right")])
1787
1827
  ]);
1788
1828
  };
1789
1829
  }
1790
1830
  });
1791
1831
  //#endregion
1792
1832
  //#region src/components/ProgressBar.vue?vue&type=script&setup=true&lang.ts
1793
- var _hoisted_1$30 = ["aria-valuenow", "aria-label"];
1833
+ var _hoisted_1$33 = ["aria-valuenow", "aria-label"];
1794
1834
  //#endregion
1795
1835
  //#region src/components/ProgressBar.vue
1796
1836
  var ProgressBar_default = /* @__PURE__ */ defineComponent({
@@ -1822,24 +1862,24 @@ var ProgressBar_default = /* @__PURE__ */ defineComponent({
1822
1862
  }, [createElementVNode("div", {
1823
1863
  class: "bg-primary h-full rounded-full transition-[width] duration-700 ease-out",
1824
1864
  style: normalizeStyle({ width: `${portion.value}%` })
1825
- }, null, 4)], 10, _hoisted_1$30);
1865
+ }, null, 4)], 10, _hoisted_1$33);
1826
1866
  };
1827
1867
  }
1828
1868
  });
1829
1869
  //#endregion
1830
1870
  //#region src/components/PriceCard.vue?vue&type=script&setup=true&lang.ts
1831
- var _hoisted_1$29 = {
1871
+ var _hoisted_1$32 = {
1832
1872
  key: 0,
1833
1873
  class: "bg-primary rounded-cell text-on-primary absolute -top-3 left-7 px-3 py-1 text-[0.7rem] font-semibold"
1834
1874
  };
1835
- var _hoisted_2$26 = { class: "flex items-start justify-between gap-4" };
1836
- var _hoisted_3$15 = { class: "text-ink mt-5 text-lg font-semibold" };
1837
- var _hoisted_4$11 = {
1875
+ var _hoisted_2$29 = { class: "flex items-start justify-between gap-4" };
1876
+ var _hoisted_3$17 = { class: "text-ink mt-5 text-lg font-semibold" };
1877
+ var _hoisted_4$13 = {
1838
1878
  key: 1,
1839
1879
  class: "text-ink-soft mt-1.5 text-sm leading-relaxed"
1840
1880
  };
1841
- var _hoisted_5$6 = { class: "mt-6 flex items-baseline gap-1.5" };
1842
- var _hoisted_6$5 = { class: "text-ink text-3xl font-semibold tracking-tight tabular-nums" };
1881
+ var _hoisted_5$8 = { class: "mt-6 flex items-baseline gap-1.5" };
1882
+ var _hoisted_6$7 = { class: "text-ink text-3xl font-semibold tracking-tight tabular-nums" };
1843
1883
  var _hoisted_7$3 = {
1844
1884
  key: 0,
1845
1885
  class: "text-ink-soft text-sm"
@@ -1903,17 +1943,17 @@ var PriceCard_default = /* @__PURE__ */ defineComponent({
1903
1943
  const palette = computed(() => TONE[__props.tone]);
1904
1944
  return (_ctx, _cache) => {
1905
1945
  return openBlock(), createElementBlock("article", { class: normalizeClass(["surface rounded-card ease-standard relative flex h-full flex-col p-7 transition-[border-color,box-shadow,transform] duration-(--duration-slower) hover:[--surface-border-color:color-mix(in_oklab,var(--color-primary)_60%,transparent)] hover:[--surface-shadow:var(--shadow-raised)] sm:p-8", [palette.value.ring, __props.recommended ? "[--surface-shadow:var(--shadow-raised)]" : "hover:-translate-y-0.5"]]) }, [
1906
- __props.badge && __props.recommended ? (openBlock(), createElementBlock("span", _hoisted_1$29, toDisplayString(__props.badge), 1)) : createCommentVNode("", true),
1907
- createElementVNode("div", _hoisted_2$26, [_ctx.$slots.icon ? (openBlock(), createElementBlock("span", {
1946
+ __props.badge && __props.recommended ? (openBlock(), createElementBlock("span", _hoisted_1$32, toDisplayString(__props.badge), 1)) : createCommentVNode("", true),
1947
+ createElementVNode("div", _hoisted_2$29, [_ctx.$slots.icon ? (openBlock(), createElementBlock("span", {
1908
1948
  key: 0,
1909
1949
  class: normalizeClass(["rounded-card grid size-11 place-items-center text-xl", palette.value.icon])
1910
1950
  }, [renderSlot(_ctx.$slots, "icon")], 2)) : createCommentVNode("", true), __props.chip ? (openBlock(), createElementBlock("span", {
1911
1951
  key: 1,
1912
1952
  class: normalizeClass(["rounded-cell ml-auto px-2.5 py-1 text-[0.7rem] font-medium", palette.value.soft])
1913
1953
  }, toDisplayString(__props.chip), 3)) : createCommentVNode("", true)]),
1914
- createElementVNode("h3", _hoisted_3$15, toDisplayString(__props.name), 1),
1915
- __props.lead ? (openBlock(), createElementBlock("p", _hoisted_4$11, toDisplayString(__props.lead), 1)) : createCommentVNode("", true),
1916
- createElementVNode("p", _hoisted_5$6, [createElementVNode("span", _hoisted_6$5, toDisplayString(__props.price), 1), __props.period ? (openBlock(), createElementBlock("span", _hoisted_7$3, toDisplayString(__props.period), 1)) : createCommentVNode("", true)]),
1954
+ createElementVNode("h3", _hoisted_3$17, toDisplayString(__props.name), 1),
1955
+ __props.lead ? (openBlock(), createElementBlock("p", _hoisted_4$13, toDisplayString(__props.lead), 1)) : createCommentVNode("", true),
1956
+ createElementVNode("p", _hoisted_5$8, [createElementVNode("span", _hoisted_6$7, toDisplayString(__props.price), 1), __props.period ? (openBlock(), createElementBlock("span", _hoisted_7$3, toDisplayString(__props.period), 1)) : createCommentVNode("", true)]),
1917
1957
  __props.note ? (openBlock(), createElementBlock("p", _hoisted_8$2, toDisplayString(__props.note), 1)) : createCommentVNode("", true),
1918
1958
  createElementVNode("ul", _hoisted_9$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.features, (feature) => {
1919
1959
  return openBlock(), createElementBlock("li", {
@@ -1928,8 +1968,8 @@ var PriceCard_default = /* @__PURE__ */ defineComponent({
1928
1968
  });
1929
1969
  //#endregion
1930
1970
  //#region src/components/ToneDot.vue?vue&type=script&setup=true&lang.ts
1931
- var _hoisted_1$28 = { class: "inline-flex items-center gap-1.5" };
1932
- var _hoisted_2$25 = {
1971
+ var _hoisted_1$31 = { class: "inline-flex items-center gap-1.5" };
1972
+ var _hoisted_2$28 = {
1933
1973
  key: 0,
1934
1974
  class: "text-ink-soft text-xs font-medium"
1935
1975
  };
@@ -1950,13 +1990,13 @@ var ToneDot_default = /* @__PURE__ */ defineComponent({
1950
1990
  * priorities — without this component knowing about any of them.
1951
1991
  */
1952
1992
  return (_ctx, _cache) => {
1953
- return openBlock(), createElementBlock("span", _hoisted_1$28, [createElementVNode("span", { class: normalizeClass(["size-2 rounded-full", __props.fill]) }, null, 2), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$25, toDisplayString(__props.label), 1)) : createCommentVNode("", true)]);
1993
+ return openBlock(), createElementBlock("span", _hoisted_1$31, [createElementVNode("span", { class: normalizeClass(["size-2 rounded-full", __props.fill]) }, null, 2), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$28, toDisplayString(__props.label), 1)) : createCommentVNode("", true)]);
1954
1994
  };
1955
1995
  }
1956
1996
  });
1957
1997
  //#endregion
1958
1998
  //#region src/components/SectionHeading.vue?vue&type=script&setup=true&lang.ts
1959
- var _hoisted_1$27 = {
1999
+ var _hoisted_1$30 = {
1960
2000
  key: 0,
1961
2001
  class: "text-ink-soft text-xs tabular-nums"
1962
2002
  };
@@ -1974,15 +2014,15 @@ var SectionHeading_default = /* @__PURE__ */ defineComponent({
1974
2014
  return openBlock(), createElementBlock("h2", { class: normalizeClass(["flex w-fit items-center gap-2 self-start rounded-full border px-3 py-1", __props.tone.card]) }, [
1975
2015
  createVNode(ToneDot_default, { fill: __props.tone.fill }, null, 8, ["fill"]),
1976
2016
  createElementVNode("span", { class: normalizeClass(["text-xs font-semibold tracking-wide uppercase", __props.tone.text]) }, toDisplayString(__props.label), 3),
1977
- __props.count > 0 ? (openBlock(), createElementBlock("span", _hoisted_1$27, toDisplayString(__props.count), 1)) : createCommentVNode("", true)
2017
+ __props.count > 0 ? (openBlock(), createElementBlock("span", _hoisted_1$30, toDisplayString(__props.count), 1)) : createCommentVNode("", true)
1978
2018
  ], 2);
1979
2019
  };
1980
2020
  }
1981
2021
  });
1982
2022
  //#endregion
1983
2023
  //#region src/components/SegmentedControl.vue?vue&type=script&setup=true&lang.ts
1984
- var _hoisted_1$26 = { class: "bg-muted rounded-card flex w-full gap-1 p-1" };
1985
- var _hoisted_2$24 = ["value", "name"];
2024
+ var _hoisted_1$29 = { class: "bg-muted rounded-card flex w-full gap-1 p-1" };
2025
+ var _hoisted_2$27 = ["value", "name"];
1986
2026
  //#endregion
1987
2027
  //#region src/components/SegmentedControl.vue
1988
2028
  var SegmentedControl_default = /* @__PURE__ */ defineComponent({
@@ -1996,7 +2036,7 @@ var SegmentedControl_default = /* @__PURE__ */ defineComponent({
1996
2036
  const model = useModel(__props, "modelValue");
1997
2037
  const name = useId();
1998
2038
  return (_ctx, _cache) => {
1999
- return openBlock(), createElementBlock("div", _hoisted_1$26, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
2039
+ return openBlock(), createElementBlock("div", _hoisted_1$29, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
2000
2040
  return openBlock(), createElementBlock("label", {
2001
2041
  key: String(option.value),
2002
2042
  class: "flex-1 cursor-pointer"
@@ -2006,18 +2046,18 @@ var SegmentedControl_default = /* @__PURE__ */ defineComponent({
2006
2046
  value: option.value,
2007
2047
  name: unref(name),
2008
2048
  class: "peer sr-only"
2009
- }, null, 8, _hoisted_2$24), [[vModelRadio, model.value]]), createElementVNode("span", { class: normalizeClass(["peer-focus-visible:outline-primary flex h-10 items-center justify-center rounded-xl px-2 text-sm font-medium transition-colors select-none peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2", model.value === option.value ? "bg-surface text-ink shadow-(--shadow-control)" : "text-ink-soft"]) }, toDisplayString(option.label), 3)]);
2049
+ }, null, 8, _hoisted_2$27), [[vModelRadio, model.value]]), createElementVNode("span", { class: normalizeClass(["peer-focus-visible:outline-primary flex h-10 items-center justify-center rounded-xl px-2 text-sm font-medium transition-colors select-none peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2", model.value === option.value ? "bg-surface text-ink shadow-(--shadow-control)" : "text-ink-soft"]) }, toDisplayString(option.label), 3)]);
2010
2050
  }), 128))]);
2011
2051
  };
2012
2052
  }
2013
2053
  });
2014
2054
  //#endregion
2015
2055
  //#region src/components/SkeletonList.vue?vue&type=script&setup=true&lang.ts
2016
- var _hoisted_1$25 = {
2056
+ var _hoisted_1$28 = {
2017
2057
  role: "status",
2018
2058
  class: "flex flex-col gap-1"
2019
2059
  };
2020
- var _hoisted_2$23 = { class: "sr-only" };
2060
+ var _hoisted_2$26 = { class: "sr-only" };
2021
2061
  //#endregion
2022
2062
  //#region src/components/SkeletonList.vue
2023
2063
  var SkeletonList_default = /* @__PURE__ */ defineComponent({
@@ -2031,7 +2071,7 @@ var SkeletonList_default = /* @__PURE__ */ defineComponent({
2031
2071
  /** A length starts with a digit, a dot, or opens a CSS function. */
2032
2072
  const isLength = computed(() => /^(?:[.\d]|calc\(|var\(|clamp\(|min\(|max\()/.test(__props.rowHeight));
2033
2073
  return (_ctx, _cache) => {
2034
- return openBlock(), createElementBlock("div", _hoisted_1$25, [createElementVNode("span", _hoisted_2$23, toDisplayString(__props.label), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row) => {
2074
+ return openBlock(), createElementBlock("div", _hoisted_1$28, [createElementVNode("span", _hoisted_2$26, toDisplayString(__props.label), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row) => {
2035
2075
  return openBlock(), createElementBlock("div", {
2036
2076
  key: row,
2037
2077
  class: normalizeClass(["bg-muted rounded-card animate-pulse", isLength.value ? void 0 : __props.rowHeight]),
@@ -2044,10 +2084,10 @@ var SkeletonList_default = /* @__PURE__ */ defineComponent({
2044
2084
  });
2045
2085
  //#endregion
2046
2086
  //#region src/components/StatCard.vue?vue&type=script&setup=true&lang.ts
2047
- var _hoisted_1$24 = { class: "surface rounded-card flex flex-1 flex-col gap-0.5 p-3" };
2048
- var _hoisted_2$22 = { class: "flex items-baseline gap-1" };
2049
- var _hoisted_3$14 = { class: "text-ink text-xl font-semibold tabular-nums" };
2050
- var _hoisted_4$10 = { class: "text-ink-soft text-xs" };
2087
+ var _hoisted_1$27 = { class: "surface rounded-card flex flex-1 flex-col gap-0.5 p-3" };
2088
+ var _hoisted_2$25 = { class: "flex items-baseline gap-1" };
2089
+ var _hoisted_3$16 = { class: "text-ink text-xl font-semibold tabular-nums" };
2090
+ var _hoisted_4$12 = { class: "text-ink-soft text-xs" };
2051
2091
  //#endregion
2052
2092
  //#region src/components/StatCard.vue
2053
2093
  var StatCard_default = /* @__PURE__ */ defineComponent({
@@ -2064,22 +2104,22 @@ var StatCard_default = /* @__PURE__ */ defineComponent({
2064
2104
  flat: ArrowRight
2065
2105
  };
2066
2106
  return (_ctx, _cache) => {
2067
- return openBlock(), createElementBlock("div", _hoisted_1$24, [createElementVNode("div", _hoisted_2$22, [createElementVNode("span", _hoisted_3$14, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createBlock(resolveDynamicComponent(TREND_ICON[__props.trend]), {
2107
+ return openBlock(), createElementBlock("div", _hoisted_1$27, [createElementVNode("div", _hoisted_2$25, [createElementVNode("span", _hoisted_3$16, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createBlock(resolveDynamicComponent(TREND_ICON[__props.trend]), {
2068
2108
  key: 0,
2069
2109
  class: "text-ink-soft size-3"
2070
- })) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_4$10, toDisplayString(__props.label), 1)]);
2110
+ })) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_4$12, toDisplayString(__props.label), 1)]);
2071
2111
  };
2072
2112
  }
2073
2113
  });
2074
2114
  //#endregion
2075
2115
  //#region src/components/ToastHost.vue?vue&type=script&setup=true&lang.ts
2076
- var _hoisted_1$23 = [
2116
+ var _hoisted_1$26 = [
2077
2117
  "onMouseenter",
2078
2118
  "onMouseleave",
2079
2119
  "onFocusin",
2080
2120
  "onFocusout"
2081
2121
  ];
2082
- var _hoisted_2$21 = { class: "flex-1 text-sm leading-snug" };
2122
+ var _hoisted_2$24 = { class: "flex-1 text-sm leading-snug" };
2083
2123
  //#endregion
2084
2124
  //#region src/components/ToastHost.vue
2085
2125
  var ToastHost_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -2140,7 +2180,7 @@ var ToastHost_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
2140
2180
  class: normalizeClass(["mt-0.5 size-5 shrink-0", TONE_CLASS[toast.tone]]),
2141
2181
  "aria-hidden": "true"
2142
2182
  }, null, 8, ["class"])),
2143
- createElementVNode("p", _hoisted_2$21, toDisplayString(toast.message), 1),
2183
+ createElementVNode("p", _hoisted_2$24, toDisplayString(toast.message), 1),
2144
2184
  toast.action ? (openBlock(), createBlock(BaseButton_default, {
2145
2185
  key: 0,
2146
2186
  variant: "link",
@@ -2163,7 +2203,7 @@ var ToastHost_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
2163
2203
  default: withCtx(() => [createVNode(unref(X), { class: "size-4" })]),
2164
2204
  _: 1
2165
2205
  }, 8, ["aria-label", "onClick"])
2166
- ], 40, _hoisted_1$23);
2206
+ ], 40, _hoisted_1$26);
2167
2207
  }), 128))]),
2168
2208
  _: 1
2169
2209
  })], 2)])) : createCommentVNode("", true);
@@ -2172,8 +2212,8 @@ var ToastHost_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
2172
2212
  }), [["__scopeId", "data-v-737eb240"]]);
2173
2213
  //#endregion
2174
2214
  //#region src/components/LocaleLinks.vue?vue&type=script&setup=true&lang.ts
2175
- var _hoisted_1$22 = ["aria-label"];
2176
- var _hoisted_2$20 = [
2215
+ var _hoisted_1$25 = ["aria-label"];
2216
+ var _hoisted_2$23 = [
2177
2217
  "lang",
2178
2218
  "aria-pressed",
2179
2219
  "onClick"
@@ -2217,17 +2257,17 @@ var LocaleLinks_default = /* @__PURE__ */ defineComponent({
2217
2257
  class: normalizeClass(["focus-ring rounded-full px-2.5 py-1.5 text-xs transition-colors", preference.value === locale ? "bg-muted text-ink font-semibold" : "text-ink-soft hover:text-ink"]),
2218
2258
  "aria-pressed": preference.value === locale,
2219
2259
  onClick: ($event) => preference.value = locale
2220
- }, toDisplayString(__props.labels[locale]), 11, _hoisted_2$20);
2221
- }), 128))], 8, _hoisted_1$22);
2260
+ }, toDisplayString(__props.labels[locale]), 11, _hoisted_2$23);
2261
+ }), 128))], 8, _hoisted_1$25);
2222
2262
  };
2223
2263
  }
2224
2264
  });
2225
2265
  //#endregion
2226
2266
  //#region src/components/TabBar.vue?vue&type=script&setup=true&lang.ts
2227
- var _hoisted_1$21 = { class: "tab-bar" };
2228
- var _hoisted_2$19 = ["aria-label"];
2229
- var _hoisted_3$13 = { class: "tab-icon-slot" };
2230
- var _hoisted_4$9 = { class: "tab-label" };
2267
+ var _hoisted_1$24 = { class: "tab-bar" };
2268
+ var _hoisted_2$22 = ["aria-label"];
2269
+ var _hoisted_3$15 = { class: "tab-icon-slot" };
2270
+ var _hoisted_4$11 = { class: "tab-label" };
2231
2271
  //#endregion
2232
2272
  //#region src/components/TabBar.vue
2233
2273
  var TabBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -2239,7 +2279,7 @@ var TabBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
2239
2279
  },
2240
2280
  setup(__props) {
2241
2281
  return (_ctx, _cache) => {
2242
- return openBlock(), createElementBlock("header", _hoisted_1$21, [createElementVNode("nav", {
2282
+ return openBlock(), createElementBlock("header", _hoisted_1$24, [createElementVNode("nav", {
2243
2283
  class: "tab-bar-inner",
2244
2284
  "aria-label": __props.label || void 0
2245
2285
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
@@ -2250,18 +2290,441 @@ var TabBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
2250
2290
  "aria-current": item.key === __props.active ? "page" : void 0,
2251
2291
  onClick: _cache[0] || (_cache[0] = ($event) => unref(tapFeedback)())
2252
2292
  }, {
2253
- default: withCtx(() => [createElementVNode("span", _hoisted_3$13, [(openBlock(), createBlock(resolveDynamicComponent(item.icon), { class: "tab-icon" }))]), createElementVNode("span", _hoisted_4$9, toDisplayString(item.label), 1)]),
2293
+ default: withCtx(() => [createElementVNode("span", _hoisted_3$15, [(openBlock(), createBlock(resolveDynamicComponent(item.icon), { class: "tab-icon" }))]), createElementVNode("span", _hoisted_4$11, toDisplayString(item.label), 1)]),
2254
2294
  _: 2
2255
2295
  }, 1032, [
2256
2296
  "to",
2257
2297
  "class",
2258
2298
  "aria-current"
2259
2299
  ]);
2260
- }), 128))], 8, _hoisted_2$19)]);
2300
+ }), 128))], 8, _hoisted_2$22)]);
2261
2301
  };
2262
2302
  }
2263
2303
  }), [["__scopeId", "data-v-a76891c4"]]);
2264
2304
  //#endregion
2305
+ //#region src/components/ActivityGrid.vue?vue&type=script&setup=true&lang.ts
2306
+ var _hoisted_1$23 = ["aria-label"];
2307
+ var _hoisted_2$21 = ["colspan"];
2308
+ var _hoisted_3$14 = {
2309
+ scope: "row",
2310
+ class: "rk-activity-weekday"
2311
+ };
2312
+ var _hoisted_4$10 = { class: "sr-only" };
2313
+ var _hoisted_5$7 = ["tabindex", "aria-label"];
2314
+ var _hoisted_6$6 = {
2315
+ key: 1,
2316
+ class: "rk-activity-cell is-blank",
2317
+ "aria-hidden": "true"
2318
+ };
2319
+ //#endregion
2320
+ //#region src/components/ActivityGrid.vue
2321
+ var ActivityGrid_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
2322
+ __name: "ActivityGrid",
2323
+ props: {
2324
+ days: {},
2325
+ label: {},
2326
+ levelFor: { type: Function },
2327
+ dayLabel: { type: Function },
2328
+ isSelectable: {
2329
+ type: Function,
2330
+ default: void 0
2331
+ },
2332
+ weekStartsOn: { default: 1 },
2333
+ startAtEnd: {
2334
+ type: Boolean,
2335
+ default: true
2336
+ }
2337
+ },
2338
+ emits: ["select"],
2339
+ setup(__props, { emit: __emit }) {
2340
+ const emit = __emit;
2341
+ const scroller = useTemplateRef("scroller");
2342
+ const grid = useTemplateRef("grid");
2343
+ /** Where the keyboard is: an index into `cells`, not a date. */
2344
+ const focused = ref(0);
2345
+ const weeks = computed(() => {
2346
+ if (__props.days.length === 0) return [];
2347
+ const first = __props.days[0];
2348
+ const lead = (fromDateKey(first).getDay() - __props.weekStartsOn + 7) % 7;
2349
+ const slots = [...Array.from({ length: lead }, () => null), ...__props.days];
2350
+ while (slots.length % 7 !== 0) slots.push(null);
2351
+ return Array.from({ length: slots.length / 7 }, (_, week) => slots.slice(week * 7, week * 7 + 7));
2352
+ });
2353
+ /** The weekday names, in the app's locale, starting on the chosen day. */
2354
+ const weekdays = computed(() => Array.from({ length: 7 }, (_, row) => {
2355
+ const date = new Date(2024, 0, 7);
2356
+ date.setDate(date.getDate() + (row + __props.weekStartsOn) % 7);
2357
+ return formatDate(date, { weekday: "long" });
2358
+ }));
2359
+ /**
2360
+ * A month heading per run of weeks.
2361
+ *
2362
+ * A week is counted under the month its first real day falls in, so a week
2363
+ * split across two months does not give the later one a heading of its own
2364
+ * one column wide.
2365
+ */
2366
+ const months = computed(() => {
2367
+ const runs = [];
2368
+ for (const week of weeks.value) {
2369
+ const day = week.find((one) => one !== null);
2370
+ if (!day) continue;
2371
+ const key = day.slice(0, 7);
2372
+ const last = runs.at(-1);
2373
+ if (last?.key === key) last.span += 1;
2374
+ else runs.push({
2375
+ key,
2376
+ label: formatDate(fromDateKey(day), { month: "short" }),
2377
+ span: 1
2378
+ });
2379
+ }
2380
+ return runs;
2381
+ });
2382
+ /** Every real day, in reading order, which is what the arrows walk. */
2383
+ const cells = computed(() => weeks.value.flatMap((week, column) => week.flatMap((day, row) => day === null ? [] : [{
2384
+ day,
2385
+ column,
2386
+ row
2387
+ }])));
2388
+ const dayAttrs = (day) => ({ "data-day": day });
2389
+ const indexOf = (day) => cells.value.findIndex((cell) => cell.day === day);
2390
+ function moveTo(index) {
2391
+ const next = Math.max(0, Math.min(cells.value.length - 1, index));
2392
+ focused.value = next;
2393
+ nextTick(() => {
2394
+ grid.value?.querySelector("[tabindex=\"0\"]")?.focus();
2395
+ });
2396
+ }
2397
+ /** Steps a whole column, which is a week, in reading order. */
2398
+ function step(by) {
2399
+ const here = cells.value[focused.value];
2400
+ if (!here) return;
2401
+ const wanted = {
2402
+ column: here.column + by,
2403
+ row: here.row
2404
+ };
2405
+ const found = cells.value.findIndex((cell) => cell.column === wanted.column && cell.row === wanted.row);
2406
+ if (found !== -1) moveTo(found);
2407
+ }
2408
+ function choose(day) {
2409
+ if (__props.isSelectable?.(day)) emit("select", day);
2410
+ }
2411
+ function onKeydown(event) {
2412
+ const here = cells.value[focused.value];
2413
+ if (!here) return;
2414
+ switch (event.key) {
2415
+ case "ArrowUp":
2416
+ event.preventDefault();
2417
+ moveTo(focused.value - 1);
2418
+ break;
2419
+ case "ArrowDown":
2420
+ event.preventDefault();
2421
+ moveTo(focused.value + 1);
2422
+ break;
2423
+ case "ArrowLeft":
2424
+ event.preventDefault();
2425
+ step(-1);
2426
+ break;
2427
+ case "ArrowRight":
2428
+ event.preventDefault();
2429
+ step(1);
2430
+ break;
2431
+ case "Home":
2432
+ event.preventDefault();
2433
+ moveTo(0);
2434
+ break;
2435
+ case "End":
2436
+ event.preventDefault();
2437
+ moveTo(cells.value.length - 1);
2438
+ break;
2439
+ case "Enter":
2440
+ case " ":
2441
+ event.preventDefault();
2442
+ choose(here.day);
2443
+ }
2444
+ }
2445
+ function onClick(event) {
2446
+ const day = event.target.closest("[data-day]")?.dataset.day;
2447
+ if (!day) return;
2448
+ focused.value = indexOf(day);
2449
+ choose(day);
2450
+ }
2451
+ onMounted(() => {
2452
+ if (__props.startAtEnd && scroller.value) scroller.value.scrollLeft = scroller.value.scrollWidth;
2453
+ });
2454
+ return (_ctx, _cache) => {
2455
+ return openBlock(), createElementBlock("div", {
2456
+ ref_key: "scroller",
2457
+ ref: scroller,
2458
+ class: "rk-activity no-scrollbar"
2459
+ }, [createElementVNode("table", {
2460
+ ref_key: "grid",
2461
+ ref: grid,
2462
+ class: "rk-activity-table",
2463
+ "aria-label": __props.label,
2464
+ onKeydown,
2465
+ onClick
2466
+ }, [createElementVNode("thead", null, [createElementVNode("tr", null, [_cache[0] || (_cache[0] = createElementVNode("td", { class: "rk-activity-corner" }, null, -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(months.value, (month) => {
2467
+ return openBlock(), createElementBlock("th", {
2468
+ key: month.key,
2469
+ colspan: month.span,
2470
+ scope: "colgroup"
2471
+ }, toDisplayString(month.label), 9, _hoisted_2$21);
2472
+ }), 128))])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(weekdays.value, (weekday, row) => {
2473
+ return openBlock(), createElementBlock("tr", { key: weekday }, [createElementVNode("th", _hoisted_3$14, [createElementVNode("span", _hoisted_4$10, toDisplayString(weekday), 1)]), (openBlock(true), createElementBlock(Fragment, null, renderList(weeks.value, (week, column) => {
2474
+ return openBlock(), createElementBlock(Fragment, { key: column }, [week[row] ? (openBlock(), createElementBlock("td", mergeProps({
2475
+ key: 0,
2476
+ class: "rk-activity-cell"
2477
+ }, { ref_for: true }, dayAttrs(week[row]), {
2478
+ tabindex: cells.value[focused.value]?.day === week[row] ? 0 : -1,
2479
+ "aria-label": __props.dayLabel(week[row]),
2480
+ class: [__props.levelFor(week[row]), { "is-pickable": __props.isSelectable?.(week[row]) }]
2481
+ }), null, 16, _hoisted_5$7)) : (openBlock(), createElementBlock("td", _hoisted_6$6))], 64);
2482
+ }), 128))]);
2483
+ }), 128))])], 40, _hoisted_1$23)], 512);
2484
+ };
2485
+ }
2486
+ }), [["__scopeId", "data-v-9f622328"]]);
2487
+ //#endregion
2488
+ //#region src/components/ScrollArea.vue?vue&type=script&setup=true&lang.ts
2489
+ var _hoisted_1$22 = { class: "rk-scroll" };
2490
+ var _hoisted_2$20 = [
2491
+ "tabindex",
2492
+ "role",
2493
+ "aria-label"
2494
+ ];
2495
+ var _hoisted_3$13 = {
2496
+ key: 0,
2497
+ class: "rk-scroll-fade is-start-x",
2498
+ "aria-hidden": "true"
2499
+ };
2500
+ var _hoisted_4$9 = {
2501
+ key: 1,
2502
+ class: "rk-scroll-fade is-end-x",
2503
+ "aria-hidden": "true"
2504
+ };
2505
+ var _hoisted_5$6 = {
2506
+ key: 2,
2507
+ class: "rk-scroll-fade is-start-y",
2508
+ "aria-hidden": "true"
2509
+ };
2510
+ var _hoisted_6$5 = {
2511
+ key: 3,
2512
+ class: "rk-scroll-fade is-end-y",
2513
+ "aria-hidden": "true"
2514
+ };
2515
+ /**
2516
+ * A box that scrolls, with the two things a hand-written one leaves out.
2517
+ *
2518
+ * ## The edge fade is the affordance `no-scrollbar` takes away
2519
+ *
2520
+ * Every app here hides the scrollbar on a horizontal row — a strip of
2521
+ * months, a row of filter chips — because a native bar under a 40px row is
2522
+ * louder than the row. What goes with it is the only sign on screen that
2523
+ * there is anything further along. So the fades are driven by the actual
2524
+ * scroll position: one appears at an edge exactly when there is content
2525
+ * past it, and both are gone when everything fits.
2526
+ *
2527
+ * ## A focus stop, but only when there is no other way in
2528
+ *
2529
+ * A box that scrolls and cannot take focus cannot be scrolled by a
2530
+ * keyboard, so the far end is simply unreachable. That is the fault
2531
+ * `CodeBlock` was written for, and it is not about code: it is true of any
2532
+ * scrolling box whose contents are not focusable.
2533
+ *
2534
+ * But it is *only* true of those. A row of buttons already moves under the
2535
+ * keyboard — Tab scrolls the next one into view — and giving that row a
2536
+ * stop of its own costs a press for nothing, on every row. So this checks:
2537
+ * it becomes a named region when it overflows **and** holds nothing
2538
+ * focusable, and stays out of the tab order otherwise.
2539
+ *
2540
+ * The check runs when the box or its contents resize, which covers a list
2541
+ * that arrives from a server. A swap that changes neither size — the same
2542
+ * number of rows, buttons turned into plain text — will not be noticed;
2543
+ * that is a trade against watching every mutation of a scroll container,
2544
+ * and the shape it misses is a rare one.
2545
+ */
2546
+ var FOCUSABLE$1 = "a[href], button, input, select, textarea, summary, [tabindex]:not([tabindex=\"-1\"])";
2547
+ //#endregion
2548
+ //#region src/components/ScrollArea.vue
2549
+ var ScrollArea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
2550
+ __name: "ScrollArea",
2551
+ props: {
2552
+ label: {},
2553
+ axis: { default: "y" },
2554
+ scrollbar: { default: "auto" },
2555
+ fade: {
2556
+ type: Boolean,
2557
+ default: true
2558
+ },
2559
+ drag: {
2560
+ type: Boolean,
2561
+ default: false
2562
+ }
2563
+ },
2564
+ emits: ["scroll"],
2565
+ setup(__props, { expose: __expose, emit: __emit }) {
2566
+ const emit = __emit;
2567
+ const viewport = useTemplateRef("viewport");
2568
+ /** Anything that takes focus on its own, so the box does not need to. */
2569
+ const horizontal = computed(() => __props.axis === "x" || __props.axis === "both");
2570
+ const vertical = computed(() => __props.axis === "y" || __props.axis === "both");
2571
+ const start = ref({
2572
+ x: false,
2573
+ y: false
2574
+ });
2575
+ const end = ref({
2576
+ x: false,
2577
+ y: false
2578
+ });
2579
+ const overflows = ref(false);
2580
+ const hasFocusable = ref(true);
2581
+ function measure() {
2582
+ const element = viewport.value;
2583
+ if (!element) return;
2584
+ const overX = element.scrollWidth - element.clientWidth;
2585
+ const overY = element.scrollHeight - element.clientHeight;
2586
+ const slack = 1;
2587
+ const alongX = Math.abs(element.scrollLeft);
2588
+ start.value = {
2589
+ x: alongX > slack,
2590
+ y: element.scrollTop > slack
2591
+ };
2592
+ end.value = {
2593
+ x: overX - alongX > slack,
2594
+ y: overY - element.scrollTop > slack
2595
+ };
2596
+ overflows.value = horizontal.value && overX > slack || vertical.value && overY > slack;
2597
+ hasFocusable.value = element.querySelector(FOCUSABLE$1) !== null;
2598
+ }
2599
+ function onScroll(event) {
2600
+ measure();
2601
+ emit("scroll", event);
2602
+ }
2603
+ /** The box itself is the way in only when nothing inside it is. */
2604
+ const isStop = computed(() => overflows.value && !hasFocusable.value);
2605
+ let observer = null;
2606
+ watchEffect(() => {
2607
+ observer?.disconnect();
2608
+ observer = null;
2609
+ const element = viewport.value;
2610
+ if (!element || typeof ResizeObserver === "undefined") return;
2611
+ observer = new ResizeObserver(measure);
2612
+ observer.observe(element);
2613
+ for (const child of element.children) observer.observe(child);
2614
+ measure();
2615
+ });
2616
+ onScopeDispose(() => observer?.disconnect());
2617
+ useDragScroll(computed(() => __props.drag ? viewport.value : null));
2618
+ __expose({
2619
+ /** The element that actually scrolls, for a parent that has to measure it. */
2620
+ viewport });
2621
+ return (_ctx, _cache) => {
2622
+ return openBlock(), createElementBlock("div", _hoisted_1$22, [createElementVNode("div", {
2623
+ ref_key: "viewport",
2624
+ ref: viewport,
2625
+ class: normalizeClass(["rk-scroll-viewport", [`is-${__props.axis}`, { "no-scrollbar": __props.scrollbar === "hidden" }]]),
2626
+ tabindex: isStop.value ? 0 : void 0,
2627
+ role: isStop.value ? "region" : void 0,
2628
+ "aria-label": isStop.value ? __props.label : void 0,
2629
+ onScroll
2630
+ }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 42, _hoisted_2$20), __props.fade ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
2631
+ horizontal.value && start.value.x ? (openBlock(), createElementBlock("span", _hoisted_3$13)) : createCommentVNode("", true),
2632
+ horizontal.value && end.value.x ? (openBlock(), createElementBlock("span", _hoisted_4$9)) : createCommentVNode("", true),
2633
+ vertical.value && start.value.y ? (openBlock(), createElementBlock("span", _hoisted_5$6)) : createCommentVNode("", true),
2634
+ vertical.value && end.value.y ? (openBlock(), createElementBlock("span", _hoisted_6$5)) : createCommentVNode("", true)
2635
+ ], 64)) : createCommentVNode("", true)]);
2636
+ };
2637
+ }
2638
+ }), [["__scopeId", "data-v-4c21cdc9"]]);
2639
+ //#endregion
2640
+ //#region src/components/VirtualList.vue?vue&type=script&setup=true&lang.ts
2641
+ var _hoisted_1$21 = ["aria-label"];
2642
+ var _hoisted_2$19 = ["aria-setsize", "aria-posinset"];
2643
+ //#endregion
2644
+ //#region src/components/VirtualList.vue
2645
+ var VirtualList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
2646
+ __name: "VirtualList",
2647
+ props: {
2648
+ items: {},
2649
+ rowHeight: {},
2650
+ label: {},
2651
+ virtualizeAfter: { default: 50 },
2652
+ scrollbar: { default: "auto" }
2653
+ },
2654
+ setup(__props, { expose: __expose }) {
2655
+ const area = useTemplateRef("area");
2656
+ const { window: shown, padTop, padBottom, viewportHeight, onScroll } = useVirtualWindow({
2657
+ count: computed(() => __props.items.length),
2658
+ rowHeight: computed(() => __props.rowHeight),
2659
+ threshold: computed(() => __props.virtualizeAfter)
2660
+ });
2661
+ const rows = computed(() => __props.items.slice(shown.value.start, shown.value.end).map((item, offset) => ({
2662
+ item,
2663
+ /** The row's place in the whole list, which is what a reader is told. */
2664
+ index: shown.value.start + offset
2665
+ })));
2666
+ function measure() {
2667
+ const element = area.value?.viewport;
2668
+ if (element) viewportHeight.value = element.clientHeight;
2669
+ }
2670
+ onMounted(measure);
2671
+ watch(() => __props.items.length, measure);
2672
+ /** Scrolls a row into view by its index, for an app driving the list itself. */
2673
+ function scrollToIndex(index) {
2674
+ const element = area.value?.viewport;
2675
+ if (!element) return;
2676
+ const top = Math.max(0, Math.min(__props.items.length - 1, index)) * __props.rowHeight;
2677
+ if (top < element.scrollTop) element.scrollTop = top;
2678
+ else if (top + __props.rowHeight > element.scrollTop + element.clientHeight) element.scrollTop = top + __props.rowHeight - element.clientHeight;
2679
+ }
2680
+ __expose({ scrollToIndex });
2681
+ return (_ctx, _cache) => {
2682
+ return openBlock(), createBlock(ScrollArea_default, {
2683
+ ref_key: "area",
2684
+ ref: area,
2685
+ axis: "y",
2686
+ label: __props.label,
2687
+ scrollbar: __props.scrollbar,
2688
+ class: "rk-vlist",
2689
+ onScroll: unref(onScroll)
2690
+ }, {
2691
+ default: withCtx(() => [createElementVNode("ul", {
2692
+ class: "rk-vlist-rows",
2693
+ "aria-label": __props.label
2694
+ }, [
2695
+ unref(padTop) > 0 ? (openBlock(), createElementBlock("li", {
2696
+ key: 0,
2697
+ style: normalizeStyle({ height: `${unref(padTop)}px` }),
2698
+ "aria-hidden": "true"
2699
+ }, null, 4)) : createCommentVNode("", true),
2700
+ (openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (row) => {
2701
+ return openBlock(), createElementBlock("li", {
2702
+ key: row.index,
2703
+ class: "rk-vlist-row",
2704
+ style: normalizeStyle({ height: `${__props.rowHeight}px` }),
2705
+ "aria-setsize": __props.items.length,
2706
+ "aria-posinset": row.index + 1
2707
+ }, [renderSlot(_ctx.$slots, "default", {
2708
+ item: row.item,
2709
+ index: row.index
2710
+ }, void 0, true)], 12, _hoisted_2$19);
2711
+ }), 128)),
2712
+ unref(padBottom) > 0 ? (openBlock(), createElementBlock("li", {
2713
+ key: 1,
2714
+ style: normalizeStyle({ height: `${unref(padBottom)}px` }),
2715
+ "aria-hidden": "true"
2716
+ }, null, 4)) : createCommentVNode("", true)
2717
+ ], 8, _hoisted_1$21)]),
2718
+ _: 3
2719
+ }, 8, [
2720
+ "label",
2721
+ "scrollbar",
2722
+ "onScroll"
2723
+ ]);
2724
+ };
2725
+ }
2726
+ }), [["__scopeId", "data-v-936ed40c"]]);
2727
+ //#endregion
2265
2728
  //#region src/components/AvatarStack.vue?vue&type=script&setup=true&lang.ts
2266
2729
  var _hoisted_1$20 = ["aria-label"];
2267
2730
  var _hoisted_2$18 = {
@@ -4471,8 +4934,8 @@ function createI18nRuntime(options) {
4471
4934
  *
4472
4935
  * The fallback keeps `vitest` and `vite dev` honest, where no define runs.
4473
4936
  */
4474
- var VERSION = "2.19.0";
4937
+ var VERSION = "2.21.0";
4475
4938
  //#endregion
4476
- export { AppError, AvatarStack_default as AvatarStack, BaseAlert_default as BaseAlert, BaseAvatar_default as BaseAvatar, BaseBadge_default as BaseBadge, BaseButton_default as BaseButton, BaseCalendar_default as BaseCalendar, BaseCard_default as BaseCard, BaseCheckbox_default as BaseCheckbox, BaseChip_default as BaseChip, BaseCombobox_default as BaseCombobox, BaseDatePicker_default as BaseDatePicker, BaseInput_default as BaseInput, BaseKbd_default as BaseKbd, BaseLink_default as BaseLink, BaseListbox_default as BaseListbox, BaseMenu_default as BaseMenu, BasePopconfirm_default as BasePopconfirm, BasePopover_default as BasePopover, BaseRadioGroup_default as BaseRadioGroup, BaseRating_default as BaseRating, BaseSelect_default as BaseSelect, BaseSeparator_default as BaseSeparator, BaseSheet_default as BaseSheet, BaseSkeleton_default as BaseSkeleton, BaseSlider_default as BaseSlider, BaseSpinner_default as BaseSpinner, BaseStepper_default as BaseStepper, BaseSwitch_default as BaseSwitch, BaseTable_default as BaseTable, BaseTextarea_default as BaseTextarea, BaseTimeline_default as BaseTimeline, CircularProgress_default as CircularProgress, CodeBlock_default as CodeBlock, ColorPicker_default as ColorPicker, CopyButton_default as CopyButton, DescriptionList_default as DescriptionList, EmptyState_default as EmptyState, ErrorBoundary_default as ErrorBoundary, FileDrop_default as FileDrop, FormField_default as FormField, GoogleButton_default as GoogleButton, LocaleLinks_default as LocaleLinks, MATERIALS, NumberInput_default as NumberInput, PALETTES, PageContainer_default as PageContainer, PageHeader_default as PageHeader, PinInput_default as PinInput, PriceCard_default as PriceCard, ProgressBar_default as ProgressBar, SHEET_ROOT_ID, SectionHeading_default as SectionHeading, SegmentedControl_default as SegmentedControl, SettingsGroup_default as SettingsGroup, SettingsRow_default as SettingsRow, SkeletonList_default as SkeletonList, SliderField_default as SliderField, StatCard_default as StatCard, TabBar_default as TabBar, TagsInput_default as TagsInput, TimePicker_default as TimePicker, ToastHost_default as ToastHost, ToggleGroup_default as ToggleGroup, ToneDot_default as ToneDot, VERSION, addDays, applyMaterial, applyPalette, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, ensureSheetRoot, formatDate, formatNumber, fromDateKey, isApplePortable, isInstalled, isMaterial, isPaletteName, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setMaterialStorageKey, setPaletteStorageKey, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, toRedirectPath, todayKey, useDebouncedCallback, useDragScroll, useMaterial, useMediaQuery, useOnline, usePalette, useTheme, useToast, useToday, useVisualViewport };
4939
+ export { ActivityGrid_default as ActivityGrid, AppError, AvatarStack_default as AvatarStack, BaseAlert_default as BaseAlert, BaseAvatar_default as BaseAvatar, BaseBadge_default as BaseBadge, BaseButton_default as BaseButton, BaseCalendar_default as BaseCalendar, BaseCard_default as BaseCard, BaseCheckbox_default as BaseCheckbox, BaseChip_default as BaseChip, BaseCombobox_default as BaseCombobox, BaseDatePicker_default as BaseDatePicker, BaseInput_default as BaseInput, BaseKbd_default as BaseKbd, BaseLink_default as BaseLink, BaseListbox_default as BaseListbox, BaseMenu_default as BaseMenu, BasePopconfirm_default as BasePopconfirm, BasePopover_default as BasePopover, BaseRadioGroup_default as BaseRadioGroup, BaseRating_default as BaseRating, BaseSelect_default as BaseSelect, BaseSeparator_default as BaseSeparator, BaseSheet_default as BaseSheet, BaseSkeleton_default as BaseSkeleton, BaseSlider_default as BaseSlider, BaseSpinner_default as BaseSpinner, BaseStepper_default as BaseStepper, BaseSwitch_default as BaseSwitch, BaseTable_default as BaseTable, BaseTextarea_default as BaseTextarea, BaseTimeline_default as BaseTimeline, CircularProgress_default as CircularProgress, CodeBlock_default as CodeBlock, ColorPicker_default as ColorPicker, CopyButton_default as CopyButton, DescriptionList_default as DescriptionList, EmptyState_default as EmptyState, ErrorBoundary_default as ErrorBoundary, FileDrop_default as FileDrop, FormField_default as FormField, GoogleButton_default as GoogleButton, LocaleLinks_default as LocaleLinks, MATERIALS, NumberInput_default as NumberInput, PALETTES, PageContainer_default as PageContainer, PageHeader_default as PageHeader, PinInput_default as PinInput, PriceCard_default as PriceCard, ProgressBar_default as ProgressBar, SHEET_ROOT_ID, ScrollArea_default as ScrollArea, SectionHeading_default as SectionHeading, SegmentedControl_default as SegmentedControl, SettingsGroup_default as SettingsGroup, SettingsRow_default as SettingsRow, SkeletonList_default as SkeletonList, SliderField_default as SliderField, StatCard_default as StatCard, TabBar_default as TabBar, TagsInput_default as TagsInput, TimePicker_default as TimePicker, ToastHost_default as ToastHost, ToggleGroup_default as ToggleGroup, ToneDot_default as ToneDot, VERSION, VirtualList_default as VirtualList, addDays, applyMaterial, applyPalette, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, ensureSheetRoot, formatDate, formatNumber, fromDateKey, isApplePortable, isInstalled, isMaterial, isPaletteName, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setMaterialStorageKey, setPaletteStorageKey, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, toRedirectPath, todayKey, useDebouncedCallback, useDragScroll, useMaterial, useMediaQuery, useOnline, usePalette, useTheme, useToast, useToday, useVisualViewport };
4477
4940
 
4478
4941
  //# sourceMappingURL=index.js.map