rei-kit 2.14.0 → 2.15.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/styles.css CHANGED
@@ -632,6 +632,79 @@
632
632
  color: var(--color-ink-soft);
633
633
  }
634
634
 
635
+ /* The buttons are out of the Tab order: the keyboard already has the arrows,
636
+ and three stops for one number is two too many. They stay reachable by
637
+ pointer and by touch, which is who they are for. */
638
+ .rk-number[data-v-082bd3d7] {
639
+ display: flex;
640
+ align-items: center;
641
+ height: 2.75rem;
642
+ border-radius: var(--radius-card);
643
+ padding: 0 0.25rem;
644
+ }
645
+ .rk-number[data-v-082bd3d7]:focus-within {
646
+ outline: 2px solid var(--color-primary);
647
+ outline-offset: 1px;
648
+ }
649
+ .rk-number.is-invalid[data-v-082bd3d7] {
650
+ --surface-border-color: var(--color-negative);
651
+ }
652
+ .rk-number.is-disabled[data-v-082bd3d7] {
653
+ opacity: 0.5;
654
+ }
655
+ .rk-number-field[data-v-082bd3d7] {
656
+ min-width: 0;
657
+ flex: 1;
658
+ background: transparent;
659
+ text-align: center;
660
+ font-size: 1rem;
661
+ font-variant-numeric: tabular-nums;
662
+ color: var(--color-ink);
663
+ outline: none;
664
+ }
665
+ .rk-number-step[data-v-082bd3d7] {
666
+ display: grid;
667
+ width: 2.25rem;
668
+ height: 2.25rem;
669
+ flex-shrink: 0;
670
+ place-items: center;
671
+ border-radius: calc(var(--radius-card) - 4px);
672
+ color: var(--color-ink);
673
+ transition: background-color var(--duration-fast) var(--ease-standard);
674
+ }
675
+ .rk-number-step[data-v-082bd3d7]:hover:not(:disabled) {
676
+ background: var(--color-muted);
677
+ }
678
+ .rk-number-step[data-v-082bd3d7]:disabled {
679
+ opacity: 0.35;
680
+ }
681
+
682
+ /* The slider takes the room; the field is as wide as its digits need and no
683
+ wider, so the pair does not read as two fields of equal weight. */
684
+ .rk-slider-field[data-v-6ec3163a] {
685
+ display: flex;
686
+ flex-wrap: wrap;
687
+ /* Centred rather than bottom-aligned: the slider's block grows when its
688
+ hint wraps to a second line, and aligning to the bottom edge sank the
689
+ field down with it. */
690
+ align-items: center;
691
+ gap: 0.75rem;
692
+ }
693
+
694
+ /* It wraps rather than squeezing: a slider shorter than this is one nobody
695
+ can aim with, and then the field belongs under it instead of beside it.
696
+ Wrapping does that by itself, so it needs no container query -- which
697
+ would have been a rule that silently never matched unless the app had
698
+ declared a container above it. */
699
+ .rk-slider-field[data-v-6ec3163a] > :first-child {
700
+ min-width: 12rem;
701
+ flex: 1 1 12rem;
702
+ }
703
+ .rk-slider-field-number[data-v-6ec3163a] {
704
+ width: 7.5rem;
705
+ flex: 0 1 7.5rem;
706
+ }
707
+
635
708
  .rk-spin-wrap[data-v-842da62c] {
636
709
  display: inline-flex;
637
710
  align-items: center;
@@ -1827,53 +1900,6 @@ to {
1827
1900
  height: 1rem;
1828
1901
  }
1829
1902
 
1830
- /* The buttons are out of the Tab order: the keyboard already has the arrows,
1831
- and three stops for one number is two too many. They stay reachable by
1832
- pointer and by touch, which is who they are for. */
1833
- .rk-number[data-v-082bd3d7] {
1834
- display: flex;
1835
- align-items: center;
1836
- height: 2.75rem;
1837
- border-radius: var(--radius-card);
1838
- padding: 0 0.25rem;
1839
- }
1840
- .rk-number[data-v-082bd3d7]:focus-within {
1841
- outline: 2px solid var(--color-primary);
1842
- outline-offset: 1px;
1843
- }
1844
- .rk-number.is-invalid[data-v-082bd3d7] {
1845
- --surface-border-color: var(--color-negative);
1846
- }
1847
- .rk-number.is-disabled[data-v-082bd3d7] {
1848
- opacity: 0.5;
1849
- }
1850
- .rk-number-field[data-v-082bd3d7] {
1851
- min-width: 0;
1852
- flex: 1;
1853
- background: transparent;
1854
- text-align: center;
1855
- font-size: 1rem;
1856
- font-variant-numeric: tabular-nums;
1857
- color: var(--color-ink);
1858
- outline: none;
1859
- }
1860
- .rk-number-step[data-v-082bd3d7] {
1861
- display: grid;
1862
- width: 2.25rem;
1863
- height: 2.25rem;
1864
- flex-shrink: 0;
1865
- place-items: center;
1866
- border-radius: calc(var(--radius-card) - 4px);
1867
- color: var(--color-ink);
1868
- transition: background-color var(--duration-fast) var(--ease-standard);
1869
- }
1870
- .rk-number-step[data-v-082bd3d7]:hover:not(:disabled) {
1871
- background: var(--color-muted);
1872
- }
1873
- .rk-number-step[data-v-082bd3d7]:disabled {
1874
- opacity: 0.35;
1875
- }
1876
-
1877
1903
  .rk-pin-cells[data-v-ba322d9c] {
1878
1904
  display: flex;
1879
1905
  gap: 0.5rem;
@@ -3068,11 +3094,11 @@ to {
3068
3094
  outline-offset: 2px;
3069
3095
  }
3070
3096
 
3071
- .rk-tip[data-v-3a572640] {
3097
+ .rk-tip[data-v-c31426f8] {
3072
3098
  position: relative;
3073
3099
  display: inline-flex;
3074
3100
  }
3075
- .rk-tip-bubble[data-v-3a572640] {
3101
+ .rk-tip-bubble[data-v-c31426f8] {
3076
3102
  position: absolute;
3077
3103
  left: 50%;
3078
3104
  z-index: 60;
@@ -3091,18 +3117,30 @@ to {
3091
3117
  pointer-events: none;
3092
3118
  transition: opacity var(--duration-fast) ease;
3093
3119
  }
3094
- .rk-tip-bubble.is-top[data-v-3a572640] {
3120
+ .rk-tip-bubble.is-top[data-v-c31426f8] {
3095
3121
  bottom: calc(100% + 0.375rem);
3096
3122
  }
3097
- .rk-tip-bubble.is-bottom[data-v-3a572640] {
3123
+ .rk-tip-bubble.is-bottom[data-v-c31426f8] {
3098
3124
  top: calc(100% + 0.375rem);
3099
3125
  }
3100
- .rk-tip:hover .rk-tip-bubble[data-v-3a572640],
3101
- .rk-tip:focus-within .rk-tip-bubble[data-v-3a572640] {
3126
+
3127
+ /* Following: placed from the pointer rather than from the trigger's edges,
3128
+ so `top` and `bottom` both have to give way to the inline style. */
3129
+ .rk-tip-bubble.is-following[data-v-c31426f8] {
3130
+ bottom: auto;
3131
+ /* No transition on the position, or the bubble lags the pointer it is
3132
+ supposed to be under. */
3133
+ transition: opacity var(--duration-fast) ease;
3134
+ }
3135
+ .rk-tip-bubble.is-following.is-top[data-v-c31426f8] {
3136
+ transform: translate(-50%, -100%);
3137
+ }
3138
+ .rk-tip:hover .rk-tip-bubble[data-v-c31426f8],
3139
+ .rk-tip:focus-within .rk-tip-bubble[data-v-c31426f8] {
3102
3140
  opacity: 1;
3103
3141
  }
3104
3142
  @media (prefers-reduced-motion: reduce) {
3105
- .rk-tip-bubble[data-v-3a572640] {
3143
+ .rk-tip-bubble[data-v-c31426f8] {
3106
3144
  transition: none;
3107
3145
  }
3108
3146
  }
@@ -18,6 +18,19 @@
18
18
  * description of the control rather than as loose text nearby. That is why the
19
19
  * trigger goes in a slot: the component has to own the id on both ends.
20
20
  *
21
+ * ## `follow`, and what it costs
22
+ *
23
+ * With `follow` the bubble tracks the pointer across the trigger, which is
24
+ * what a large target wants — a chart, a map, a calendar cell — where a
25
+ * bubble pinned to the middle can be nowhere near what is under the cursor.
26
+ *
27
+ * It is opt-in because it is the one thing here that needs JavaScript: a
28
+ * `follow` tooltip does nothing until the bundle arrives, while the default
29
+ * works in a prerendered page with scripting switched off. It also stops
30
+ * following for a reader who asked their system for less motion, and for a
31
+ * keyboard, which has no cursor to follow — both fall back to the anchored
32
+ * position, so the tooltip is never lost, only still.
33
+ *
21
34
  * ## When not to use it
22
35
  *
23
36
  * For anything the reader must have. A tooltip is unreachable on a touch screen
@@ -27,6 +40,10 @@ type __VLS_Props = {
27
40
  /** The description. Already translated. */
28
41
  label: string;
29
42
  placement?: 'top' | 'bottom' | undefined;
43
+ /** Track the pointer across the trigger instead of pinning to its middle. */
44
+ follow?: boolean | undefined;
45
+ /** How far the bubble sits from the pointer, in pixels. */
46
+ offset?: number | undefined;
30
47
  };
31
48
  type __VLS_Slots = {
32
49
  /** The control being described. */
package/dist/web.js CHANGED
@@ -7,7 +7,7 @@ import { ArrowDown, ArrowUp, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpD
7
7
  import { RouterLink } from "vue-router";
8
8
  //#region src/web/BaseAccordion.vue?vue&type=script&setup=true&lang.ts
9
9
  var _hoisted_1$15 = { class: "rk-accordion" };
10
- var _hoisted_2$13 = [
10
+ var _hoisted_2$12 = [
11
11
  "aria-expanded",
12
12
  "aria-controls",
13
13
  "onClick"
@@ -54,7 +54,7 @@ var BaseAccordion_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
54
54
  }, [createElementVNode("span", _hoisted_3$11, [renderSlot(_ctx.$slots, "title", {
55
55
  item,
56
56
  open: isOpen(item.key)
57
- }, () => [createTextVNode(toDisplayString(item.title), 1)], true)]), createElementVNode("span", _hoisted_4$9, [_cache[0] || (_cache[0] = createElementVNode("span", { class: "rk-accordion-bar" }, null, -1)), createElementVNode("span", { class: normalizeClass(["rk-accordion-bar rk-accordion-bar-turn", { "is-open": isOpen(item.key) }]) }, null, 2)])], 8, _hoisted_2$13)]),
57
+ }, () => [createTextVNode(toDisplayString(item.title), 1)], true)]), createElementVNode("span", _hoisted_4$9, [_cache[0] || (_cache[0] = createElementVNode("span", { class: "rk-accordion-bar" }, null, -1)), createElementVNode("span", { class: normalizeClass(["rk-accordion-bar rk-accordion-bar-turn", { "is-open": isOpen(item.key) }]) }, null, 2)])], 8, _hoisted_2$12)]),
58
58
  _: 2
59
59
  }, 1024)), createElementVNode("div", {
60
60
  id: `${unref(uid)}-${item.key}`,
@@ -70,7 +70,7 @@ var BaseAccordion_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @
70
70
  //#endregion
71
71
  //#region src/web/BaseBreadcrumb.vue?vue&type=script&setup=true&lang.ts
72
72
  var _hoisted_1$14 = ["aria-label"];
73
- var _hoisted_2$12 = { class: "rk-crumbs" };
73
+ var _hoisted_2$11 = { class: "rk-crumbs" };
74
74
  var _hoisted_3$10 = {
75
75
  key: 1,
76
76
  class: "rk-crumb-current",
@@ -91,7 +91,7 @@ var BaseBreadcrumb_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
91
91
  },
92
92
  setup(__props) {
93
93
  return (_ctx, _cache) => {
94
- return openBlock(), createElementBlock("nav", { "aria-label": __props.label || void 0 }, [createElementVNode("ol", _hoisted_2$12, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
94
+ return openBlock(), createElementBlock("nav", { "aria-label": __props.label || void 0 }, [createElementVNode("ol", _hoisted_2$11, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
95
95
  return openBlock(), createElementBlock("li", {
96
96
  key: item.label,
97
97
  class: "rk-crumb"
@@ -110,7 +110,7 @@ var BaseBreadcrumb_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
110
110
  //#endregion
111
111
  //#region src/web/BaseDisclosure.vue?vue&type=script&setup=true&lang.ts
112
112
  var _hoisted_1$13 = { class: "rk-disclosure" };
113
- var _hoisted_2$11 = ["aria-expanded", "aria-controls"];
113
+ var _hoisted_2$10 = ["aria-expanded", "aria-controls"];
114
114
  var _hoisted_3$9 = { class: "rk-disclosure-title" };
115
115
  var _hoisted_4$7 = {
116
116
  class: "rk-disclosure-mark",
@@ -144,7 +144,7 @@ var BaseDisclosure_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
144
144
  "aria-expanded": open.value,
145
145
  "aria-controls": unref(id),
146
146
  onClick: _cache[0] || (_cache[0] = ($event) => open.value = !open.value)
147
- }, [createElementVNode("span", _hoisted_3$9, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)], true)]), createElementVNode("span", _hoisted_4$7, [_cache[1] || (_cache[1] = createElementVNode("span", { class: "rk-disclosure-bar" }, null, -1)), createElementVNode("span", { class: normalizeClass(["rk-disclosure-bar rk-disclosure-turn", { "is-open": open.value }]) }, null, 2)])], 8, _hoisted_2$11)]),
147
+ }, [createElementVNode("span", _hoisted_3$9, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)], true)]), createElementVNode("span", _hoisted_4$7, [_cache[1] || (_cache[1] = createElementVNode("span", { class: "rk-disclosure-bar" }, null, -1)), createElementVNode("span", { class: normalizeClass(["rk-disclosure-bar rk-disclosure-turn", { "is-open": open.value }]) }, null, 2)])], 8, _hoisted_2$10)]),
148
148
  _: 3
149
149
  })), createElementVNode("div", {
150
150
  id: unref(id),
@@ -156,7 +156,7 @@ var BaseDisclosure_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
156
156
  //#endregion
157
157
  //#region src/web/BaseModal.vue?vue&type=script&setup=true&lang.ts
158
158
  var _hoisted_1$12 = ["role", "aria-label"];
159
- var _hoisted_2$10 = { class: "rk-modal-head" };
159
+ var _hoisted_2$9 = { class: "rk-modal-head" };
160
160
  var _hoisted_3$8 = { class: "rk-modal-title" };
161
161
  var _hoisted_4$6 = ["aria-label"];
162
162
  var _hoisted_5$5 = { class: "rk-modal-body" };
@@ -279,7 +279,7 @@ var BaseModal_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
279
279
  "aria-label": __props.title,
280
280
  tabindex: "-1"
281
281
  }, [
282
- createElementVNode("div", _hoisted_2$10, [createElementVNode("h2", _hoisted_3$8, toDisplayString(__props.title), 1), __props.dismissible ? (openBlock(), createElementBlock("button", {
282
+ createElementVNode("div", _hoisted_2$9, [createElementVNode("h2", _hoisted_3$8, toDisplayString(__props.title), 1), __props.dismissible ? (openBlock(), createElementBlock("button", {
283
283
  key: 0,
284
284
  type: "button",
285
285
  class: "rk-modal-close",
@@ -305,7 +305,7 @@ var BaseModal_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
305
305
  //#endregion
306
306
  //#region src/web/BasePagination.vue?vue&type=script&setup=true&lang.ts
307
307
  var _hoisted_1$11 = ["aria-label"];
308
- var _hoisted_2$9 = ["disabled", "aria-label"];
308
+ var _hoisted_2$8 = ["disabled", "aria-label"];
309
309
  var _hoisted_3$7 = {
310
310
  key: 0,
311
311
  class: "rk-pager-gap",
@@ -375,7 +375,7 @@ var BasePagination_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
375
375
  disabled: __props.page <= 1,
376
376
  "aria-label": __props.previousLabel,
377
377
  onClick: _cache[0] || (_cache[0] = ($event) => go(__props.page - 1))
378
- }, " ‹ ", 8, _hoisted_2$9),
378
+ }, " ‹ ", 8, _hoisted_2$8),
379
379
  (openBlock(true), createElementBlock(Fragment, null, renderList(slots.value, (slot, index) => {
380
380
  return openBlock(), createElementBlock(Fragment, { key: `${slot}-${index}` }, [slot === "gap" ? (openBlock(), createElementBlock("span", _hoisted_3$7, "…")) : (openBlock(), createElementBlock("button", {
381
381
  key: 1,
@@ -399,7 +399,7 @@ var BasePagination_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
399
399
  //#endregion
400
400
  //#region src/web/CommandMenu.vue?vue&type=script&setup=true&lang.ts
401
401
  var _hoisted_1$10 = ["aria-label"];
402
- var _hoisted_2$8 = { class: "rk-command-field" };
402
+ var _hoisted_2$7 = { class: "rk-command-field" };
403
403
  var _hoisted_3$6 = [
404
404
  "placeholder",
405
405
  "aria-label",
@@ -540,7 +540,7 @@ var CommandMenu_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
540
540
  role: "dialog",
541
541
  "aria-modal": "true",
542
542
  "aria-label": __props.label
543
- }, [createElementVNode("div", _hoisted_2$8, [createVNode(unref(Search), {
543
+ }, [createElementVNode("div", _hoisted_2$7, [createVNode(unref(Search), {
544
544
  class: "text-ink-soft size-4 shrink-0",
545
545
  "aria-hidden": "true"
546
546
  }), withDirectives(createElementVNode("input", {
@@ -590,7 +590,7 @@ var CommandMenu_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
590
590
  //#endregion
591
591
  //#region src/web/DataTable.vue?vue&type=script&setup=true&lang.ts
592
592
  var _hoisted_1$9 = ["aria-label"];
593
- var _hoisted_2$7 = {
593
+ var _hoisted_2$6 = {
594
594
  key: 0,
595
595
  scope: "col",
596
596
  class: "rk-data-pick"
@@ -714,7 +714,7 @@ var DataTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
714
714
  "aria-label": __props.caption
715
715
  }, [createElementVNode("table", { class: normalizeClass(["rk-data", { "is-sticky": __props.stickyHeader }]) }, [
716
716
  createElementVNode("caption", { class: normalizeClass(__props.captionHidden ? "rk-data-caption-hidden" : "rk-data-caption") }, toDisplayString(__props.caption), 3),
717
- createElementVNode("thead", null, [createElementVNode("tr", null, [selectable.value ? (openBlock(), createElementBlock("th", _hoisted_2$7, [createElementVNode("input", {
717
+ createElementVNode("thead", null, [createElementVNode("tr", null, [selectable.value ? (openBlock(), createElementBlock("th", _hoisted_2$6, [createElementVNode("input", {
718
718
  type: "checkbox",
719
719
  class: "rk-data-box focus-ring",
720
720
  checked: allChosen.value,
@@ -784,7 +784,7 @@ var DataTable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
784
784
  //#endregion
785
785
  //#region src/web/BaseSplitter.vue?vue&type=script&setup=true&lang.ts
786
786
  var _hoisted_1$8 = { class: "rk-split-pane is-start" };
787
- var _hoisted_2$6 = [
787
+ var _hoisted_2$5 = [
788
788
  "aria-label",
789
789
  "aria-orientation",
790
790
  "aria-valuenow",
@@ -874,7 +874,7 @@ var BaseSplitter_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
874
874
  }, [..._cache[0] || (_cache[0] = [createElementVNode("span", {
875
875
  class: "rk-split-grip",
876
876
  "aria-hidden": "true"
877
- }, null, -1)])], 40, _hoisted_2$6),
877
+ }, null, -1)])], 40, _hoisted_2$5),
878
878
  createElementVNode("div", _hoisted_3$4, [renderSlot(_ctx.$slots, "end", {}, void 0, true)])
879
879
  ], 6);
880
880
  };
@@ -969,7 +969,7 @@ var BaseToolbar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
969
969
  //#endregion
970
970
  //#region src/web/BaseTree.vue?vue&type=script&setup=true&lang.ts
971
971
  var _hoisted_1$6 = ["aria-label", "aria-multiselectable"];
972
- var _hoisted_2$5 = [
972
+ var _hoisted_2$4 = [
973
973
  "aria-level",
974
974
  "aria-setsize",
975
975
  "aria-posinset",
@@ -1129,7 +1129,7 @@ var BaseTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
1129
1129
  "aria-hidden": "true"
1130
1130
  })) : createCommentVNode("", true),
1131
1131
  createElementVNode("span", _hoisted_4$2, toDisplayString(row.node.label), 1)
1132
- ], 14, _hoisted_2$5);
1132
+ ], 14, _hoisted_2$4);
1133
1133
  }), 128))], 40, _hoisted_1$6);
1134
1134
  };
1135
1135
  }
@@ -1137,7 +1137,7 @@ var BaseTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
1137
1137
  //#endregion
1138
1138
  //#region src/web/TransferList.vue?vue&type=script&setup=true&lang.ts
1139
1139
  var _hoisted_1$5 = { class: "rk-transfer" };
1140
- var _hoisted_2$4 = { class: "rk-transfer-side" };
1140
+ var _hoisted_2$3 = { class: "rk-transfer-side" };
1141
1141
  var _hoisted_3$2 = { class: "rk-transfer-title" };
1142
1142
  var _hoisted_4$1 = { class: "rk-transfer-middle" };
1143
1143
  var _hoisted_5$1 = { class: "rk-transfer-side" };
@@ -1175,7 +1175,7 @@ var TransferList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
1175
1175
  }
1176
1176
  return (_ctx, _cache) => {
1177
1177
  return openBlock(), createElementBlock("div", _hoisted_1$5, [
1178
- createElementVNode("div", _hoisted_2$4, [createElementVNode("p", _hoisted_3$2, toDisplayString(__props.availableLabel), 1), createVNode(BaseListbox_default, {
1178
+ createElementVNode("div", _hoisted_2$3, [createElementVNode("p", _hoisted_3$2, toDisplayString(__props.availableLabel), 1), createVNode(BaseListbox_default, {
1179
1179
  modelValue: markedAvailable.value,
1180
1180
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => markedAvailable.value = $event),
1181
1181
  mode: "multiple",
@@ -1301,7 +1301,7 @@ var ResponsiveDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/
1301
1301
  //#endregion
1302
1302
  //#region src/web/BaseTabs.vue?vue&type=script&setup=true&lang.ts
1303
1303
  var _hoisted_1$3 = ["aria-label"];
1304
- var _hoisted_2$3 = [
1304
+ var _hoisted_2$2 = [
1305
1305
  "id",
1306
1306
  "aria-selected",
1307
1307
  "aria-controls",
@@ -1367,7 +1367,7 @@ var BaseTabs_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
1367
1367
  "aria-controls": panelId(item.key),
1368
1368
  tabindex: item.key === active.value ? 0 : -1,
1369
1369
  onClick: ($event) => select(item.key)
1370
- }, toDisplayString(item.label), 11, _hoisted_2$3);
1370
+ }, toDisplayString(item.label), 11, _hoisted_2$2);
1371
1371
  }), 128))], 40, _hoisted_1$3), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
1372
1372
  return withDirectives((openBlock(), createElementBlock("div", {
1373
1373
  id: panelId(item.key),
@@ -1386,27 +1386,70 @@ var BaseTabs_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
1386
1386
  }), [["__scopeId", "data-v-8135ecab"]]);
1387
1387
  //#endregion
1388
1388
  //#region src/web/BaseTooltip.vue?vue&type=script&setup=true&lang.ts
1389
- var _hoisted_1$2 = { class: "rk-tip" };
1390
- var _hoisted_2$2 = ["id"];
1389
+ var _hoisted_1$2 = ["id"];
1391
1390
  //#endregion
1392
1391
  //#region src/web/BaseTooltip.vue
1393
1392
  var BaseTooltip_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
1394
1393
  __name: "BaseTooltip",
1395
1394
  props: {
1396
1395
  label: {},
1397
- placement: { default: "top" }
1396
+ placement: { default: "top" },
1397
+ follow: {
1398
+ type: Boolean,
1399
+ default: false
1400
+ },
1401
+ offset: { default: 14 }
1398
1402
  },
1399
1403
  setup(__props) {
1400
1404
  const id = useId();
1405
+ /** Where the pointer is inside the trigger, or null when it is not. */
1406
+ const at = ref(null);
1407
+ let frame = 0;
1408
+ /**
1409
+ * A box chasing the pointer is motion, so a reader who asked for less of it
1410
+ * gets the anchored bubble. Read per move rather than cached: the preference
1411
+ * can change while the page is open.
1412
+ */
1413
+ const wantsStill = () => typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
1414
+ function onPointerMove(event) {
1415
+ if (!__props.follow || wantsStill()) return;
1416
+ if (frame) return;
1417
+ const { clientX, clientY, currentTarget } = event;
1418
+ const box = currentTarget.getBoundingClientRect();
1419
+ frame = requestAnimationFrame(() => {
1420
+ frame = 0;
1421
+ at.value = {
1422
+ x: clientX - box.left,
1423
+ y: clientY - box.top
1424
+ };
1425
+ });
1426
+ }
1427
+ function onPointerLeave() {
1428
+ if (frame) cancelAnimationFrame(frame);
1429
+ frame = 0;
1430
+ at.value = null;
1431
+ }
1432
+ onBeforeUnmount(() => {
1433
+ if (frame) cancelAnimationFrame(frame);
1434
+ });
1401
1435
  return (_ctx, _cache) => {
1402
- return openBlock(), createElementBlock("span", _hoisted_1$2, [renderSlot(_ctx.$slots, "default", { describedBy: unref(id) }, void 0, true), createElementVNode("span", {
1436
+ return openBlock(), createElementBlock("span", {
1437
+ class: "rk-tip",
1438
+ onPointermove: onPointerMove,
1439
+ onPointerleave: onPointerLeave,
1440
+ onFocusout: onPointerLeave
1441
+ }, [renderSlot(_ctx.$slots, "default", { describedBy: unref(id) }, void 0, true), createElementVNode("span", {
1403
1442
  id: unref(id),
1404
1443
  role: "tooltip",
1405
- class: normalizeClass(["rk-tip-bubble", `is-${__props.placement}`])
1406
- }, toDisplayString(__props.label), 11, _hoisted_2$2)]);
1444
+ class: normalizeClass(["rk-tip-bubble", [`is-${__props.placement}`, { "is-following": at.value }]]),
1445
+ style: normalizeStyle(at.value ? {
1446
+ left: `${at.value.x}px`,
1447
+ top: __props.placement === "top" ? `${at.value.y - __props.offset}px` : `${at.value.y + __props.offset}px`
1448
+ } : void 0)
1449
+ }, toDisplayString(__props.label), 15, _hoisted_1$2)], 32);
1407
1450
  };
1408
1451
  }
1409
- }), [["__scopeId", "data-v-3a572640"]]);
1452
+ }), [["__scopeId", "data-v-c31426f8"]]);
1410
1453
  //#endregion
1411
1454
  //#region src/web/MegaMenu.vue?vue&type=script&setup=true&lang.ts
1412
1455
  var _hoisted_1$1 = ["aria-label"];