@leavepulse/ui 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/chunks/{LpAddressInput-B411MOJa.js → LpAddressInput-Dah7asXy.js} +1 -1
  2. package/dist/chunks/{LpAppShell-CfM7fdr3.js → LpAppShell-DGZv907S.js} +2 -2
  3. package/dist/chunks/{LpConfirmDialog-D8pBGPOI.js → LpConfirmDialog-CkMzeKdp.js} +1 -1
  4. package/dist/chunks/{LpDrawer-B4cNj39a.js → LpDrawer-DAJN5rGK.js} +1 -1
  5. package/dist/chunks/{LpFileTree-d9nXtSVo.js → LpFileTree-DWx77B1F.js} +1 -1
  6. package/dist/chunks/{LpLogViewer-BXPBUV21.js → LpLogViewer-B1aLUVdz.js} +1 -1
  7. package/dist/chunks/{LpModal-DKFdzKwV.js → LpModal-CNAFRgCU.js} +36 -3
  8. package/dist/chunks/{LpNotificationBell-Nges4kJk.js → LpNotificationBell-HSGo1pcf.js} +1 -1
  9. package/dist/chunks/{LpScrollArea-Du8tW8c5.js → LpScrollArea-D8xyKXcF.js} +10 -2
  10. package/dist/chunks/{LpSidebar-Bd0148dd.js → LpSidebar-JvMaaYsy.js} +2 -2
  11. package/dist/chunks/{LpSidebarNav-BqGpNr4S.js → LpSidebarNav-BIYzk7e_.js} +1 -1
  12. package/dist/chunks/{LpTable-BBKlNR9j.js → LpTable-DTj52qlg.js} +45 -9
  13. package/dist/chunks/{LpTooltip-CIwoRCag.js → LpTooltip-D1hbjQWG.js} +23 -9
  14. package/dist/components/LpAddressInput.vue.js +1 -1
  15. package/dist/components/LpAppShell.vue.js +1 -1
  16. package/dist/components/LpCommandPalette.vue.js +1 -1
  17. package/dist/components/LpConfirmDialog.vue.js +1 -1
  18. package/dist/components/LpDrawer.vue.js +1 -1
  19. package/dist/components/LpFileTree.vue.js +1 -1
  20. package/dist/components/LpLogViewer.vue.js +1 -1
  21. package/dist/components/LpModal.vue.d.ts +16 -5
  22. package/dist/components/LpModal.vue.js +1 -1
  23. package/dist/components/LpNotificationBell.vue.js +1 -1
  24. package/dist/components/LpScrollArea.vue.js +1 -1
  25. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  26. package/dist/components/LpSidebar.vue.js +1 -1
  27. package/dist/components/LpSidebarNav.vue.js +1 -1
  28. package/dist/components/LpTable.vue.js +1 -1
  29. package/dist/components/LpTooltip.vue.d.ts +19 -1
  30. package/dist/components/LpTooltip.vue.js +1 -1
  31. package/dist/composables/useRovingFocus.d.ts +49 -0
  32. package/dist/composables/useRovingFocus.js +160 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +14 -12
  35. package/package.json +1 -1
  36. package/src/components/LpModal.vue +67 -1
  37. package/src/components/LpScrollArea.vue +26 -6
  38. package/src/components/LpTable.vue +57 -2
  39. package/src/components/LpTooltip.vue +57 -5
  40. package/src/composables/useRovingFocus.ts +275 -0
  41. package/src/index.ts +2 -0
  42. package/src/tokens/utilities.css +15 -0
@@ -6,7 +6,7 @@ import { _ as _sfc_main$3 } from "./LpButton-5VXXCjwF.js";
6
6
  import { _ as _sfc_main$1 } from "./LpFormField-Bn-ZwC6z.js";
7
7
  import { _ as _sfc_main$4 } from "./LpIcon-CCnX5_2j.js";
8
8
  import { _ as _sfc_main$5 } from "./LpInput-BauZRyzm.js";
9
- import { _ as _sfc_main$7 } from "./LpModal-DKFdzKwV.js";
9
+ import { _ as _sfc_main$7 } from "./LpModal-CNAFRgCU.js";
10
10
  import { _ as _sfc_main$6 } from "./LpSelect-D5mU4cZO.js";
11
11
  const _hoisted_1 = { class: "flex flex-col gap-3" };
12
12
  const _hoisted_2 = { class: "flex items-stretch gap-2" };
@@ -1,8 +1,8 @@
1
1
  import { defineComponent, computed, watch, openBlock, createElementBlock, createVNode, createSlots, withCtx, renderSlot, normalizeProps, guardReactiveProps, createElementVNode, normalizeClass, toDisplayString, createCommentVNode, createBlock } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
3
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$4 } from "./LpScrollArea-Du8tW8c5.js";
5
- import { _ as _sfc_main$1 } from "./LpSidebar-Bd0148dd.js";
4
+ import { _ as _sfc_main$4 } from "./LpScrollArea-D8xyKXcF.js";
5
+ import { _ as _sfc_main$1 } from "./LpSidebar-JvMaaYsy.js";
6
6
  const _hoisted_1 = { class: "flex h-dvh overflow-hidden bg-surface text-ink" };
7
7
  const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
8
8
  const _hoisted_3 = { class: "flex h-16 shrink-0 items-center gap-3 border-b border-line bg-surface px-4 md:px-6" };
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, openBlock, createBlock, withCtx, renderSlot, createVNode, createTextVNode, toDisplayString } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
- import { _ as _sfc_main$1 } from "./LpModal-DKFdzKwV.js";
3
+ import { _ as _sfc_main$1 } from "./LpModal-CNAFRgCU.js";
4
4
  const _sfc_main = /* @__PURE__ */ defineComponent({
5
5
  __name: "LpConfirmDialog",
6
6
  props: {
@@ -3,7 +3,7 @@ import { usePointerSwipe } from "@vueuse/core";
3
3
  import { DrawerRoot, DrawerPortal, DrawerOverlay, DrawerContent, DrawerHandle, DrawerTitle, DrawerDescription, DrawerClose } from "vaul-vue";
4
4
  import { CLOSE_ICON } from "../components/dropdown.js";
5
5
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
6
- import { _ as _sfc_main$2 } from "./LpScrollArea-Du8tW8c5.js";
6
+ import { _ as _sfc_main$2 } from "./LpScrollArea-D8xyKXcF.js";
7
7
  const _hoisted_1 = { class: "text-base font-semibold text-ink" };
8
8
  const _hoisted_2 = { class: "flex flex-col gap-1" };
9
9
  const _hoisted_3 = ["data-vaul-no-drag"];
@@ -2,7 +2,7 @@ import { defineComponent, ref, watch, computed, openBlock, createElementBlock, F
2
2
  import { formatSize, sortNodes, computeStats, subtreeIds, ancestorIds } from "../components/fileTree.js";
3
3
  import { _ as _sfc_main$1 } from "./LpEmptyState-CrfyRJUG.js";
4
4
  import { _ as _sfc_main$3 } from "./LpFileTreeNode-DFg4PhOK.js";
5
- import { _ as _sfc_main$2 } from "./LpScrollArea-Du8tW8c5.js";
5
+ import { _ as _sfc_main$2 } from "./LpScrollArea-D8xyKXcF.js";
6
6
  const _hoisted_1 = {
7
7
  key: 0,
8
8
  class: "flex h-full w-full min-w-0 flex-col gap-1 overflow-hidden"
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, computed, ref, watch, nextTick, onMounted, onBeforeUnmount, openBlock, createElementBlock, createVNode, normalizeStyle, withCtx, createElementVNode, toDisplayString, createCommentVNode, Fragment, createBlock, resolveDynamicComponent, TransitionGroup, mergeProps, renderList, normalizeClass, createTextVNode, Transition } from "vue";
2
2
  import { _ as _sfc_main$3 } from "./LpContextMenu-D0mzXqA7.js";
3
3
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$1 } from "./LpScrollArea-Du8tW8c5.js";
4
+ import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
5
5
  const _hoisted_1 = { class: "relative overflow-hidden rounded-card border border-line bg-surface font-mono text-xs leading-relaxed" };
6
6
  const _hoisted_2 = {
7
7
  key: 0,
@@ -2,7 +2,7 @@ import { defineComponent, computed, useSlots, ref, watch, onBeforeUnmount, openB
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose } from "reka-ui";
3
3
  import { CLOSE_ICON } from "../components/dropdown.js";
4
4
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
5
- import { _ as _sfc_main$2 } from "./LpScrollArea-Du8tW8c5.js";
5
+ import { _ as _sfc_main$2 } from "./LpScrollArea-D8xyKXcF.js";
6
6
  const _hoisted_1 = { class: "fixed inset-0 z-(--z-modal) flex items-center justify-center pointer-events-none" };
7
7
  const _hoisted_2 = {
8
8
  key: 0,
@@ -22,7 +22,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
22
22
  description: {},
23
23
  size: { default: "md" },
24
24
  width: {},
25
- fillBody: { type: Boolean }
25
+ fillBody: { type: Boolean },
26
+ autoFocus: { default: "auto" }
26
27
  },
27
28
  emits: ["update:open"],
28
29
  setup(__props) {
@@ -51,6 +52,37 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
51
52
  ].filter(Boolean).join(" ")
52
53
  );
53
54
  const panelRef = ref(null);
55
+ const AUTO_FOCUS_ORDER = [
56
+ "input:not([type=hidden]):not([disabled]):not([readonly])",
57
+ "textarea:not([disabled]):not([readonly])",
58
+ "select:not([disabled])",
59
+ "[data-lp-autofocus]",
60
+ "button:not([disabled]):not([data-lp-dialog-close])",
61
+ "[href]",
62
+ "[tabindex]:not([tabindex='-1'])"
63
+ ];
64
+ function onOpenAutoFocus(event) {
65
+ if (props.autoFocus === "none") return;
66
+ const panel = panelRef.value?.$el;
67
+ if (!(panel instanceof HTMLElement)) return;
68
+ const selectors = props.autoFocus === "auto" ? AUTO_FOCUS_ORDER : [props.autoFocus];
69
+ for (const selector of selectors) {
70
+ const target = panel.querySelector(selector);
71
+ if (!target || target.hasAttribute("disabled")) continue;
72
+ event.preventDefault();
73
+ target.setAttribute("data-lp-focus-ring", "");
74
+ target.addEventListener(
75
+ "blur",
76
+ () => target.removeAttribute("data-lp-focus-ring"),
77
+ { once: true }
78
+ );
79
+ target.focus();
80
+ if (target instanceof HTMLInputElement && target.type === "text") {
81
+ target.select();
82
+ }
83
+ return;
84
+ }
85
+ }
54
86
  const tweening = ref(false);
55
87
  const resizing = ref(false);
56
88
  let ro;
@@ -142,7 +174,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
142
174
  ref: panelRef,
143
175
  class: ["pointer-events-auto flex max-h-[min(90vh,calc(100dvh-2rem))] min-h-0 flex-col overflow-hidden rounded-card border border-line bg-surface-raised shadow-panel outline-none data-[state=open]:animate-[rise-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[rise-out_120ms_cubic-bezier(0.4,0,1,1)]", [widthClass.value, tweening.value ? "transition-[height] duration-fast ease-[var(--ease-emphasized)] motion-reduce:transition-none" : ""]],
144
176
  style: __props.width ? { width: __props.width } : void 0
145
- }, describedByAttrs.value), {
177
+ }, describedByAttrs.value, { onOpenAutoFocus }), {
146
178
  default: withCtx(() => [
147
179
  __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("header", _hoisted_2, [
148
180
  createElementVNode("div", _hoisted_3, [
@@ -165,6 +197,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
165
197
  })) : createCommentVNode("", true)
166
198
  ]),
167
199
  createVNode(unref(DialogClose), {
200
+ "data-lp-dialog-close": "",
168
201
  class: "group flex shrink-0 items-center rounded-md p-1 text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
169
202
  "aria-label": "Close"
170
203
  }, {
@@ -5,7 +5,7 @@ import { _ as _sfc_main$4 } from "./LpContextMenu-D0mzXqA7.js";
5
5
  import { _ as _sfc_main$2 } from "./LpEmptyState-CrfyRJUG.js";
6
6
  import { _ as _sfc_main$5 } from "./LpIcon-CCnX5_2j.js";
7
7
  import { _ as _sfc_main$1 } from "./LpPopover-8268UmlC.js";
8
- import { _ as _sfc_main$3 } from "./LpScrollArea-Du8tW8c5.js";
8
+ import { _ as _sfc_main$3 } from "./LpScrollArea-D8xyKXcF.js";
9
9
  const _hoisted_1 = { class: "flex items-center justify-between gap-2 px-3 py-2.5" };
10
10
  const _hoisted_2 = { class: "text-sm font-semibold" };
11
11
  const _hoisted_3 = {
@@ -31,6 +31,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
31
31
  atTop.value = el.scrollTop <= 1;
32
32
  atBottom.value = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;
33
33
  }
34
+ function syncViewportFocusable(el) {
35
+ const scrollable = el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth;
36
+ if (scrollable) el.setAttribute("tabindex", "0");
37
+ else el.removeAttribute("tabindex");
38
+ }
34
39
  function onViewportScroll(event) {
35
40
  if (props.fade) measureEdges(event.target);
36
41
  emit("scroll", event);
@@ -47,8 +52,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
47
52
  [viewportEl, () => props.fade],
48
53
  ([el, enabled]) => {
49
54
  stopEdgeWatch();
50
- if (!el || !enabled) return;
51
- const remeasure = () => measureEdges(el);
55
+ if (!el) return;
56
+ const remeasure = () => {
57
+ if (enabled) measureEdges(el);
58
+ syncViewportFocusable(el);
59
+ };
52
60
  remeasure();
53
61
  if (typeof ResizeObserver !== "undefined") {
54
62
  edgeResize = new ResizeObserver(remeasure);
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, computed, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps, createBlock } from "vue";
2
- import { _ as _sfc_main$2 } from "./LpDrawer-B4cNj39a.js";
3
- import { _ as _sfc_main$1 } from "./LpSidebarNav-BqGpNr4S.js";
2
+ import { _ as _sfc_main$2 } from "./LpDrawer-DAJN5rGK.js";
3
+ import { _ as _sfc_main$1 } from "./LpSidebarNav-BIYzk7e_.js";
4
4
  const _hoisted_1 = {
5
5
  key: 1,
6
6
  class: "mt-2 flex shrink-0 flex-col gap-2"
@@ -4,7 +4,7 @@ import { usePillTransition } from "../composables/usePillTransition.js";
4
4
  import { _ as _sfc_main$4 } from "./LpBadge-CXzBPnwO.js";
5
5
  import { _ as _sfc_main$2 } from "./LpContextMenu-D0mzXqA7.js";
6
6
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
7
- import { _ as _sfc_main$1 } from "./LpScrollArea-Du8tW8c5.js";
7
+ import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
8
8
  const _hoisted_1 = {
9
9
  key: 0,
10
10
  class: "flex min-h-0 flex-1 flex-col gap-4"
@@ -1,8 +1,9 @@
1
- import { defineComponent, computed, ref, watch, onBeforeUnmount, openBlock, createBlock, withCtx, createElementVNode, normalizeClass, createElementBlock, createVNode, createCommentVNode, Fragment, renderList, normalizeStyle, createTextVNode, toDisplayString, withModifiers, renderSlot } from "vue";
1
+ import { defineComponent, computed, ref, watch, onBeforeUnmount, openBlock, createBlock, withCtx, createElementVNode, normalizeClass, createElementBlock, createVNode, createCommentVNode, Fragment, renderList, normalizeStyle, createTextVNode, toDisplayString, unref, mergeProps, withModifiers, renderSlot } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpCheckbox-BO0zuuPh.js";
3
3
  import { _ as _sfc_main$4 } from "./LpContextMenu-D0mzXqA7.js";
4
4
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
5
- import { _ as _sfc_main$1 } from "./LpScrollArea-Du8tW8c5.js";
5
+ import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
6
+ import { useRovingFocus } from "../composables/useRovingFocus.js";
6
7
  const _hoisted_1 = { class: "w-full border-collapse text-sm" };
7
8
  const _hoisted_2 = { class: "border-b border-line bg-surface-soft" };
8
9
  const _hoisted_3 = {
@@ -91,6 +92,37 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
91
92
  emit("update:selected", [...next]);
92
93
  }
93
94
  const colSpan = computed(() => props.columns.length + (props.selectable ? 1 : 0));
95
+ const rovingItems = computed(
96
+ () => displayRows.value.map((row, index) => ({
97
+ id: String(keyFor(row, index)),
98
+ label: String(row[props.columns[0]?.key ?? ""] ?? "")
99
+ }))
100
+ );
101
+ const rowByKey = computed(() => {
102
+ const map = /* @__PURE__ */ new Map();
103
+ displayRows.value.forEach((row, index) => map.set(String(keyFor(row, index)), row));
104
+ return map;
105
+ });
106
+ const roving = useRovingFocus(rovingItems, {
107
+ onActivate: (id) => {
108
+ const row = rowByKey.value.get(id);
109
+ if (!row) return;
110
+ emit("rowClick", row);
111
+ }
112
+ });
113
+ function onRowKeydown(event) {
114
+ if (event.key === " " && props.selectable && roving.activeId.value) {
115
+ event.preventDefault();
116
+ const key = roving.activeId.value;
117
+ const row = rowByKey.value.get(key);
118
+ if (row) {
119
+ const rowKey = keyFor(row, displayRows.value.indexOf(row));
120
+ toggleRow(rowKey, !selectedSet.value.has(rowKey));
121
+ }
122
+ return;
123
+ }
124
+ roving.onKeydown(event);
125
+ }
94
126
  const headEl = ref(null);
95
127
  const headHeight = ref(0);
96
128
  let ro;
@@ -164,7 +196,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
164
196
  }), 128))
165
197
  ])
166
198
  ], 2),
167
- createElementVNode("tbody", null, [
199
+ createElementVNode("tbody", {
200
+ ref: (el) => unref(roving).setContainer(el)
201
+ }, [
168
202
  displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_6, [
169
203
  createElementVNode("td", {
170
204
  colspan: colSpan.value,
@@ -184,10 +218,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
184
218
  items: menuFor(row)
185
219
  }, {
186
220
  default: withCtx(() => [
187
- createElementVNode("tr", {
188
- class: normalizeClass(["border-b border-line/60 transition-colors last:border-0 hover:bg-surface-soft/60", selectedSet.value.has(keyFor(row, index)) ? "bg-brand-soft/40" : ""]),
189
- onClick: ($event) => emit("rowClick", row)
190
- }, [
221
+ createElementVNode("tr", mergeProps({
222
+ class: ["border-b border-line/60 outline-none transition-colors last:border-0 hover:bg-surface-soft/60 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring data-[active]:bg-surface-soft/40", selectedSet.value.has(keyFor(row, index)) ? "bg-brand-soft/40" : ""]
223
+ }, { ref_for: true }, unref(roving).itemProps(String(keyFor(row, index))), {
224
+ onClick: ($event) => emit("rowClick", row),
225
+ onKeydown: onRowKeydown
226
+ }), [
191
227
  __props.selectable ? (openBlock(), createElementBlock("td", {
192
228
  key: 0,
193
229
  class: "w-px px-4 py-3",
@@ -212,12 +248,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
212
248
  ])
213
249
  ], 2);
214
250
  }), 128))
215
- ], 10, _hoisted_8)
251
+ ], 16, _hoisted_8)
216
252
  ]),
217
253
  _: 2
218
254
  }, 1032, ["items"]);
219
255
  }), 128))
220
- ])
256
+ ], 512)
221
257
  ])
222
258
  ]),
223
259
  _: 3
@@ -5,25 +5,39 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
5
5
  __name: "LpTooltip",
6
6
  props: {
7
7
  content: {},
8
- sideOffset: {}
8
+ sideOffset: {},
9
+ side: { default: "top" },
10
+ label: { type: Boolean },
11
+ delay: { default: 200 },
12
+ showOnPointerFocus: { type: Boolean }
9
13
  },
10
14
  setup(__props) {
11
15
  return (_ctx, _cache) => {
12
- return openBlock(), createBlock(unref(TooltipProvider), { "delay-duration": 200 }, {
16
+ return openBlock(), createBlock(unref(TooltipProvider), { "delay-duration": __props.delay }, {
13
17
  default: withCtx(() => [
14
- createVNode(unref(TooltipRoot), null, {
18
+ createVNode(unref(TooltipRoot), {
19
+ "ignore-non-keyboard-focus": !__props.showOnPointerFocus
20
+ }, {
15
21
  default: withCtx(() => [
16
- createVNode(unref(TooltipTrigger), { "as-child": "" }, {
22
+ createVNode(unref(TooltipTrigger), {
23
+ "as-child": "",
24
+ "aria-label": __props.label ? __props.content : void 0
25
+ }, {
17
26
  default: withCtx(() => [
18
27
  renderSlot(_ctx.$slots, "default")
19
28
  ]),
20
29
  _: 3
21
- }),
30
+ }, 8, ["aria-label"]),
22
31
  createVNode(unref(TooltipPortal), null, {
23
32
  default: withCtx(() => [
24
33
  createVNode(unref(TooltipContent), {
34
+ side: __props.side,
25
35
  "side-offset": __props.sideOffset ?? 6,
26
- class: normalizeClass([unref(PANEL_SURFACE), unref(TOOLTIP_ANIM), "z-(--z-tooltip) px-2.5 py-1.5 text-xs text-ink"])
36
+ class: normalizeClass([
37
+ unref(PANEL_SURFACE),
38
+ unref(TOOLTIP_ANIM),
39
+ "z-(--z-tooltip) max-w-[min(20rem,90vw)] px-2.5 py-1.5 text-xs text-ink"
40
+ ])
27
41
  }, {
28
42
  default: withCtx(() => [
29
43
  renderSlot(_ctx.$slots, "content", {}, () => [
@@ -31,16 +45,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
31
45
  ])
32
46
  ]),
33
47
  _: 3
34
- }, 8, ["side-offset", "class"])
48
+ }, 8, ["side", "side-offset", "class"])
35
49
  ]),
36
50
  _: 3
37
51
  })
38
52
  ]),
39
53
  _: 3
40
- })
54
+ }, 8, ["ignore-non-keyboard-focus"])
41
55
  ]),
42
56
  _: 3
43
- });
57
+ }, 8, ["delay-duration"]);
44
58
  };
45
59
  }
46
60
  });
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAddressInput-B411MOJa.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAddressInput-Dah7asXy.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAppShell-CfM7fdr3.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAppShell-DGZv907S.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, ref, computed, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, withModifiers, createTextVNode, createElementVNode, withDirectives, withKeys, vModelText, createElementBlock, toDisplayString, createCommentVNode, Fragment, renderList, normalizeClass } from "vue";
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
3
3
  import { _ as _sfc_main$1 } from "../chunks/LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-Du8tW8c5.js";
4
+ import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-D8xyKXcF.js";
5
5
  import { useHotkeys } from "../composables/useHotkeys.js";
6
6
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
7
7
  import '../assets/LpCommandPalette-CEY-pajO.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmDialog-D8pBGPOI.js";
1
+ import { _ as _sfc_main } from "../chunks/LpConfirmDialog-CkMzeKdp.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpDrawer-B4cNj39a.js";
1
+ import { _ as _sfc_main } from "../chunks/LpDrawer-DAJN5rGK.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpFileTree-d9nXtSVo.js";
1
+ import { _ as _sfc_main } from "../chunks/LpFileTree-DWx77B1F.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpLogViewer-BXPBUV21.js";
1
+ import { _ as _sfc_main } from "../chunks/LpLogViewer-B1aLUVdz.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -15,16 +15,26 @@ type __VLS_Props = {
15
15
  * regions (e.g. multi-pane catalogues) — the panes scroll, not the modal.
16
16
  */
17
17
  fillBody?: boolean;
18
+ /**
19
+ * Where the keyboard lands when the dialog opens. Default `"auto"` picks
20
+ * the first meaningful control in the body — a field to type in, or failing
21
+ * that the primary action — instead of the close button, which is what
22
+ * happens if the DOM order is left to decide.
23
+ *
24
+ * `"none"` leaves reka's own behaviour alone; pass a CSS selector to name
25
+ * the element yourself.
26
+ */
27
+ autoFocus?: "auto" | "none" | string;
18
28
  };
19
- declare var __VLS_35: {}, __VLS_54: {}, __VLS_62: {}, __VLS_64: {};
29
+ declare var __VLS_37: {}, __VLS_56: {}, __VLS_64: {}, __VLS_66: {};
20
30
  type __VLS_Slots = {} & {
21
- title?: (props: typeof __VLS_35) => any;
31
+ title?: (props: typeof __VLS_37) => any;
22
32
  } & {
23
- default?: (props: typeof __VLS_54) => any;
33
+ default?: (props: typeof __VLS_56) => any;
24
34
  } & {
25
- default?: (props: typeof __VLS_62) => any;
35
+ default?: (props: typeof __VLS_64) => any;
26
36
  } & {
27
- footer?: (props: typeof __VLS_64) => any;
37
+ footer?: (props: typeof __VLS_66) => any;
28
38
  };
29
39
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
30
40
  "update:open": (value: boolean) => any;
@@ -32,6 +42,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
32
42
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
33
43
  }>, {
34
44
  size: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "full";
45
+ autoFocus: "auto" | "none" | string;
35
46
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
36
47
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
37
48
  declare const _default: typeof __VLS_export;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpModal-DKFdzKwV.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModal-CNAFRgCU.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpNotificationBell-Nges4kJk.js";
1
+ import { _ as _sfc_main } from "../chunks/LpNotificationBell-HSGo1pcf.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpScrollArea-Du8tW8c5.js";
1
+ import { _ as _sfc_main } from "../chunks/LpScrollArea-D8xyKXcF.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, openBlock, createBlock, withCtx, createElementVNode, createElementBlock, Fragment, renderList, toDisplayString, unref } from "vue";
2
- import { _ as _sfc_main$1 } from "../chunks/LpModal-DKFdzKwV.js";
2
+ import { _ as _sfc_main$1 } from "../chunks/LpModal-CNAFRgCU.js";
3
3
  import { appleModifierLabel } from "../composables/useHotkeys.js";
4
4
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
5
5
  import '../assets/LpShortcutsDialog-B7H-RZLQ.css';const _hoisted_1 = { class: "shortcut-groups" };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSidebar-Bd0148dd.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSidebar-JvMaaYsy.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSidebarNav-BqGpNr4S.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSidebarNav-BIYzk7e_.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTable-BBKlNR9j.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTable-DTj52qlg.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,6 +1,21 @@
1
1
  type __VLS_Props = {
2
2
  content?: string;
3
3
  sideOffset?: number;
4
+ /** Which edge to prefer; flips automatically when there is no room. */
5
+ side?: "top" | "right" | "bottom" | "left";
6
+ /**
7
+ * The tip names the control rather than describing it — for a trigger with
8
+ * no visible text of its own. Sets the accessible name instead of only
9
+ * adding a description.
10
+ */
11
+ label?: boolean;
12
+ /** Milliseconds before the tip appears on hover. */
13
+ delay?: number;
14
+ /**
15
+ * Show on any focus, not just keyboard focus. Off by default: a tip that
16
+ * pops up after every mouse click on the trigger is noise.
17
+ */
18
+ showOnPointerFocus?: boolean;
4
19
  };
5
20
  declare var __VLS_20: {}, __VLS_34: {};
6
21
  type __VLS_Slots = {} & {
@@ -8,7 +23,10 @@ type __VLS_Slots = {} & {
8
23
  } & {
9
24
  content?: (props: typeof __VLS_34) => any;
10
25
  };
11
- declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
26
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
27
+ delay: number;
28
+ side: "top" | "right" | "bottom" | "left";
29
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
12
30
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
13
31
  declare const _default: typeof __VLS_export;
14
32
  export default _default;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTooltip-CIwoRCag.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTooltip-D1hbjQWG.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -0,0 +1,49 @@
1
+ import { MaybeRefOrGetter } from 'vue';
2
+ export interface RovingItem {
3
+ /** Stable identity of the row. */
4
+ id: string;
5
+ /**
6
+ * What typeahead matches against. Omit to opt this row out of typeahead —
7
+ * a separator, say.
8
+ */
9
+ label?: string;
10
+ disabled?: boolean;
11
+ }
12
+ export interface UseRovingFocusOptions {
13
+ /**
14
+ * Which axis the arrows follow. `vertical` (default) uses ↑↓, `horizontal`
15
+ * uses ←→, `both` accepts either — for a grid whose wrapping the caller
16
+ * cannot describe here.
17
+ */
18
+ orientation?: "vertical" | "horizontal" | "both";
19
+ /** Wrap around at the ends instead of stopping. Default true. */
20
+ loop?: boolean;
21
+ /** Jump to an item by typing its first letters. Default true. */
22
+ typeahead?: boolean;
23
+ /** Called when the user activates the current item (Enter or Space). */
24
+ onActivate?: (id: string) => void;
25
+ /**
26
+ * Called when focus should leave the list without activating anything —
27
+ * Escape. Lets a dialog close, or a filter field take focus back.
28
+ */
29
+ onEscape?: () => void;
30
+ }
31
+ export declare function useRovingFocus(items: MaybeRefOrGetter<RovingItem[]>, options?: UseRovingFocusOptions): {
32
+ activeId: import('vue').Ref<string | undefined, string | undefined>;
33
+ focus: (id: string | undefined) => void;
34
+ move: (delta: number) => void;
35
+ first: () => void;
36
+ last: () => void;
37
+ onKeydown: (event: KeyboardEvent) => void;
38
+ setContainer: (el: HTMLElement | null) => void;
39
+ containerProps: import('vue').ComputedRef<{
40
+ ref: (el: unknown) => void;
41
+ onKeydown: (event: KeyboardEvent) => void;
42
+ }>;
43
+ itemProps: (id: string) => {
44
+ tabindex: number;
45
+ "data-active": string | undefined;
46
+ "data-roving-id": string;
47
+ onFocus: () => void;
48
+ };
49
+ };