@leavepulse/ui 0.55.0 → 0.57.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 (73) hide show
  1. package/dist/chunks/{LpActionBar-CnfFVIwC.js → LpActionBar-C3hkVsFz.js} +1 -1
  2. package/dist/chunks/{LpAddressInput-iOJhmRzy.js → LpAddressInput-NUHmplCd.js} +1 -1
  3. package/dist/chunks/{LpAppShell-DcSXik4a.js → LpAppShell-Bl1Ch68N.js} +2 -2
  4. package/dist/chunks/{LpButton-CKSwC6Mu.js → LpButton-BdfZFNqi.js} +31 -7
  5. package/dist/chunks/{LpConfirmDialog-Ca-CTlxT.js → LpConfirmDialog-CrbUZgJE.js} +1 -1
  6. package/dist/chunks/{LpConfirmHost-BAaSaT2b.js → LpConfirmHost-BgMIV8r9.js} +1 -1
  7. package/dist/chunks/{LpDateRangePicker-Drd7EbIz.js → LpDateRangePicker-CxV5jW7p.js} +4 -13
  8. package/dist/chunks/{LpDrawer-CBFVD624.js → LpDrawer-D9lLOC0C.js} +4 -6
  9. package/dist/chunks/LpHintLayer-CI1oZ9Pd.js +154 -0
  10. package/dist/chunks/{LpModalNav-aWwc_5CD.js → LpModalNav-DXyAyhQl.js} +2 -2
  11. package/dist/chunks/{LpNotificationBell-wZ3meeim.js → LpNotificationBell-DEL-RoHS.js} +1 -1
  12. package/dist/chunks/{LpPie-B7ti5qCH.js → LpPie-CXka8Jvx.js} +1 -1
  13. package/dist/chunks/{LpSidebar-C2oolgwy.js → LpSidebar-hZ8D1cVr.js} +1 -1
  14. package/dist/chunks/{LpTableOfContents-BUcAfGPQ.js → LpTableOfContents-DYuqkByy.js} +2 -8
  15. package/dist/chunks/{LpTooltip-CXVKcOXT.js → LpTooltip-suFCM34F.js} +2 -2
  16. package/dist/chunks/LpTour-C1TC2GyY.js +315 -0
  17. package/dist/chunks/{LpUptimeBar-ugcv25xj.js → LpUptimeBar-B4ltCfno.js} +1 -1
  18. package/dist/chunks/TourCard-BQS3ztqj.js +100 -0
  19. package/dist/component-names.d.ts +1 -1
  20. package/dist/components/LpActionBar.vue.js +1 -1
  21. package/dist/components/LpAddressInput.vue.js +1 -1
  22. package/dist/components/LpAppShell.vue.js +1 -1
  23. package/dist/components/LpButton.vue.d.ts +10 -0
  24. package/dist/components/LpButton.vue.js +1 -1
  25. package/dist/components/LpConfirmDialog.vue.js +1 -1
  26. package/dist/components/LpConfirmHost.vue.js +1 -1
  27. package/dist/components/LpDateRangePicker.vue.js +1 -1
  28. package/dist/components/LpDrawer.vue.js +1 -1
  29. package/dist/components/LpHintLayer.vue.d.ts +33 -0
  30. package/dist/components/LpHintLayer.vue.js +4 -0
  31. package/dist/components/LpImageEditor.vue.js +1 -1
  32. package/dist/components/LpModalNav.vue.js +1 -1
  33. package/dist/components/LpNotificationBell.vue.js +1 -1
  34. package/dist/components/LpPie.vue.js +1 -1
  35. package/dist/components/LpSidebar.vue.js +1 -1
  36. package/dist/components/LpTable.vue.js +1 -1
  37. package/dist/components/LpTableOfContents.vue.js +1 -1
  38. package/dist/components/LpTooltip.vue.js +1 -1
  39. package/dist/components/LpTour.vue.d.ts +98 -0
  40. package/dist/components/LpTour.vue.js +4 -0
  41. package/dist/components/LpUptimeBar.vue.js +1 -1
  42. package/dist/components/TourCard.vue.d.ts +28 -0
  43. package/dist/components/TourCard.vue.js +4 -0
  44. package/dist/components/tour.d.ts +21 -0
  45. package/dist/components/tour.js +38 -0
  46. package/dist/composables/scroll.d.ts +17 -0
  47. package/dist/composables/scroll.js +29 -0
  48. package/dist/composables/useGamepadNav.js +2 -7
  49. package/dist/composables/useHints.d.ts +18 -0
  50. package/dist/composables/useHints.js +120 -0
  51. package/dist/composables/useMediaQuery.d.ts +2 -0
  52. package/dist/composables/useMediaQuery.js +18 -0
  53. package/dist/composables/usePaintSelect.js +1 -7
  54. package/dist/index.d.ts +10 -0
  55. package/dist/index.js +38 -22
  56. package/package.json +1 -1
  57. package/src/component-names.ts +2 -0
  58. package/src/components/LpButton.vue +28 -1
  59. package/src/components/LpDateRangePicker.vue +3 -12
  60. package/src/components/LpDrawer.vue +4 -7
  61. package/src/components/LpHintLayer.vue +148 -0
  62. package/src/components/LpTableOfContents.vue +2 -14
  63. package/src/components/LpTooltip.vue +2 -4
  64. package/src/components/LpTour.vue +338 -0
  65. package/src/components/TourCard.vue +41 -0
  66. package/src/components/tour.ts +57 -0
  67. package/src/composables/scroll.ts +54 -0
  68. package/src/composables/useGamepadNav.ts +2 -7
  69. package/src/composables/useHints.ts +151 -0
  70. package/src/composables/useMediaQuery.ts +20 -0
  71. package/src/composables/usePaintSelect.ts +1 -8
  72. package/src/index.ts +10 -0
  73. package/src/tokens/tokens.css +1 -0
@@ -0,0 +1,315 @@
1
+ import { defineComponent, useModel, computed, shallowRef, ref, watch, onBeforeUnmount, openBlock, createBlock, Teleport, createElementBlock, withModifiers, Fragment, renderList, normalizeStyle, normalizeClass, createCommentVNode, unref, withCtx, createVNode, renderSlot, mergeModels, nextTick } from "vue";
2
+ import { PopoverRoot, PopoverAnchor, PopoverPortal, PopoverContent } from "reka-ui";
3
+ import { prefersReducedMotion } from "../composables/easing.js";
4
+ import { hints } from "../composables/useHints.js";
5
+ import { useHotkeys } from "../composables/useHotkeys.js";
6
+ import { useLabels } from "../composables/useLpConfig.js";
7
+ import { useMediaQuery } from "../composables/useMediaQuery.js";
8
+ import { scrollToElement } from "../composables/scroll.js";
9
+ import { PANEL_SURFACE } from "../components/dropdown.js";
10
+ import { _ as _sfc_main$1 } from "./TourCard-BQS3ztqj.js";
11
+ import { holeOf, panelsAround } from "../components/tour.js";
12
+ const _hoisted_1 = ["aria-label"];
13
+ const _sfc_main = /* @__PURE__ */ defineComponent({
14
+ __name: "LpTour",
15
+ props: /* @__PURE__ */ mergeModels({
16
+ steps: {},
17
+ padding: { default: 6 },
18
+ labels: {}
19
+ }, {
20
+ "open": { type: Boolean, ...{ default: false } },
21
+ "openModifiers": {},
22
+ "step": { default: 0 },
23
+ "stepModifiers": {}
24
+ }),
25
+ emits: /* @__PURE__ */ mergeModels(["finish", "dismiss"], ["update:open", "update:step"]),
26
+ setup(__props, { emit: __emit }) {
27
+ const props = __props;
28
+ const emit = __emit;
29
+ const open = useModel(__props, "open");
30
+ const index = useModel(__props, "step");
31
+ const DEFAULT_LABELS = {
32
+ next: "Next",
33
+ back: "Back",
34
+ done: "Done",
35
+ close: "Close tour",
36
+ progress: "{n} of {total}",
37
+ perform: "Do it for me",
38
+ tryIt: "Try it: press the highlighted control."
39
+ };
40
+ const labels = useLabels("tour", DEFAULT_LABELS, () => props.labels);
41
+ const WAIT_MS = 800;
42
+ const TRY_SETTLE_MS = 120;
43
+ const wide = useMediaQuery("(min-width: 640px)");
44
+ const step = computed(() => props.steps[index.value]);
45
+ const target = shallowRef(null);
46
+ const box = ref(null);
47
+ const viewport = ref({ width: 0, height: 0 });
48
+ const ready = ref(false);
49
+ const cleanups = [];
50
+ const leaving = [];
51
+ let frame = 0;
52
+ let token = 0;
53
+ let direction = 1;
54
+ const hole = computed(() => box.value ? holeOf(box.value, props.padding, viewport.value) : null);
55
+ const panels = computed(
56
+ () => hole.value ? panelsAround(hole.value, viewport.value) : [{ x: 0, y: 0, width: viewport.value.width, height: viewport.value.height }]
57
+ );
58
+ const reference = {
59
+ getBoundingClientRect: () => {
60
+ const h = hole.value;
61
+ return h ? new DOMRect(h.x, h.y, h.width, h.height) : new DOMRect(viewport.value.width / 2, viewport.value.height / 2, 0, 0);
62
+ }
63
+ };
64
+ const last = computed(() => index.value >= props.steps.length - 1);
65
+ const progress = computed(() => labels.value.progress.replace("{n}", String(index.value + 1)).replace("{total}", String(props.steps.length)));
66
+ const smooth = () => !prefersReducedMotion();
67
+ function resolve(raw) {
68
+ if (!raw) return null;
69
+ if (typeof raw === "function") return raw();
70
+ if (typeof raw !== "string") return raw.isConnected ? raw : null;
71
+ return hints.element(raw) ?? document.querySelector(raw);
72
+ }
73
+ function waitFor(raw, mine) {
74
+ const started = performance.now();
75
+ return new Promise((done) => {
76
+ const tick = () => {
77
+ if (mine !== token) return done(null);
78
+ const el = resolve(raw);
79
+ if (el && el.getClientRects().length) return done(el);
80
+ if (performance.now() - started > WAIT_MS) return done(null);
81
+ requestAnimationFrame(tick);
82
+ };
83
+ tick();
84
+ });
85
+ }
86
+ function measure() {
87
+ viewport.value = { width: window.innerWidth, height: window.innerHeight };
88
+ const el = target.value;
89
+ if (!el || !el.isConnected) {
90
+ box.value = null;
91
+ return;
92
+ }
93
+ const r = el.getBoundingClientRect();
94
+ const prev = box.value;
95
+ if (!prev || prev.x !== r.x || prev.y !== r.y || prev.width !== r.width || prev.height !== r.height) {
96
+ box.value = { x: r.x, y: r.y, width: r.width, height: r.height };
97
+ }
98
+ }
99
+ function track() {
100
+ measure();
101
+ frame = requestAnimationFrame(track);
102
+ }
103
+ async function show() {
104
+ const mine = ++token;
105
+ ready.value = false;
106
+ leave();
107
+ const current = step.value;
108
+ if (!current) return;
109
+ await current.enter?.({ onLeave: (fn) => leaving.push(fn), onEnd: (fn) => cleanups.push(fn) });
110
+ if (mine !== token) return;
111
+ if (!current.target) {
112
+ target.value = null;
113
+ measure();
114
+ ready.value = true;
115
+ return;
116
+ }
117
+ const el = current.enter ? await waitFor(current.target, mine) : resolve(current.target);
118
+ if (mine !== token) return;
119
+ if (!el || !el.getClientRects().length) return skip();
120
+ target.value = el;
121
+ scrollToElement(el, { block: wide.value ? "nearest" : "center", behavior: smooth() ? "smooth" : "auto", margin: 48 });
122
+ await nextTick();
123
+ measure();
124
+ ready.value = true;
125
+ }
126
+ function skip() {
127
+ const nextIndex = index.value + direction;
128
+ if (nextIndex < 0 || nextIndex >= props.steps.length) return direction > 0 ? finish() : show();
129
+ index.value = nextIndex;
130
+ }
131
+ function next() {
132
+ direction = 1;
133
+ if (last.value) return finish();
134
+ index.value += 1;
135
+ }
136
+ function back() {
137
+ if (index.value === 0) return;
138
+ direction = -1;
139
+ index.value -= 1;
140
+ }
141
+ function forward() {
142
+ if (!step.value?.try) next();
143
+ }
144
+ async function perform() {
145
+ await step.value?.perform?.();
146
+ setTimeout(next, TRY_SETTLE_MS);
147
+ }
148
+ function leave() {
149
+ for (const cleanup of leaving.splice(0).reverse()) cleanup();
150
+ }
151
+ function end() {
152
+ token++;
153
+ leave();
154
+ cancelAnimationFrame(frame);
155
+ frame = 0;
156
+ target.value = null;
157
+ box.value = null;
158
+ for (const cleanup of cleanups.splice(0).reverse()) cleanup();
159
+ }
160
+ function finish() {
161
+ open.value = false;
162
+ emit("finish");
163
+ }
164
+ function dismiss() {
165
+ const at = index.value;
166
+ open.value = false;
167
+ emit("dismiss", at);
168
+ }
169
+ function onTargetClick(event) {
170
+ if (!step.value?.try || !target.value) return;
171
+ if (event.target instanceof Node && target.value.contains(event.target)) setTimeout(next, TRY_SETTLE_MS);
172
+ }
173
+ watch(
174
+ open,
175
+ (value) => {
176
+ if (value) {
177
+ direction = 1;
178
+ document.addEventListener("click", onTargetClick, true);
179
+ frame ||= requestAnimationFrame(track);
180
+ void show();
181
+ } else {
182
+ document.removeEventListener("click", onTargetClick, true);
183
+ end();
184
+ }
185
+ },
186
+ { immediate: true }
187
+ );
188
+ watch(index, () => {
189
+ if (open.value) void show();
190
+ });
191
+ onBeforeUnmount(() => {
192
+ document.removeEventListener("click", onTargetClick, true);
193
+ if (open.value) end();
194
+ });
195
+ useHotkeys(
196
+ () => [
197
+ { key: "Escape", handler: dismiss, overLayers: true, allowInInput: true },
198
+ { key: "ArrowRight", handler: forward, overLayers: true },
199
+ { key: "Enter", handler: forward, overLayers: true },
200
+ { key: "ArrowLeft", handler: back, overLayers: true }
201
+ ],
202
+ { enabled: open, priority: 100 }
203
+ );
204
+ const CARD = `${PANEL_SURFACE} rounded-card w-80 max-w-[calc(100vw-24px)] p-4 text-sm text-ink outline-none`;
205
+ return (_ctx, _cache) => {
206
+ return openBlock(), createBlock(Teleport, { to: "body" }, [
207
+ open.value ? (openBlock(), createElementBlock("div", {
208
+ key: 0,
209
+ class: "lp-tour pointer-events-none fixed inset-0 z-(--z-tour)",
210
+ onPointerdown: _cache[0] || (_cache[0] = withModifiers(() => {
211
+ }, ["stop"]))
212
+ }, [
213
+ (openBlock(true), createElementBlock(Fragment, null, renderList(panels.value, (panel, i) => {
214
+ return openBlock(), createElementBlock("div", {
215
+ key: i,
216
+ class: "lp-scrim pointer-events-auto absolute left-0 top-0 transition-[transform,width,height] duration-[var(--duration-medium)] ease-[var(--ease-emphasized)] motion-reduce:transition-none",
217
+ style: normalizeStyle({ transform: `translate(${panel.x}px, ${panel.y}px)`, width: `${panel.width}px`, height: `${panel.height}px` })
218
+ }, null, 4);
219
+ }), 128)),
220
+ hole.value ? (openBlock(), createElementBlock("div", {
221
+ key: 0,
222
+ class: normalizeClass(["absolute left-0 top-0 rounded-control ring-2 ring-brand transition-[transform,width,height] duration-[var(--duration-medium)] ease-[var(--ease-emphasized)] motion-reduce:transition-none", step.value?.try ? "pointer-events-none animate-pulse" : "pointer-events-auto"]),
223
+ style: normalizeStyle({ transform: `translate(${hole.value.x}px, ${hole.value.y}px)`, width: `${hole.value.width}px`, height: `${hole.value.height}px` })
224
+ }, null, 6)) : createCommentVNode("", true)
225
+ ], 32)) : createCommentVNode("", true),
226
+ open.value && unref(wide) ? (openBlock(), createBlock(unref(PopoverRoot), {
227
+ key: 1,
228
+ open: ready.value
229
+ }, {
230
+ default: withCtx(() => [
231
+ createVNode(unref(PopoverAnchor), { reference }),
232
+ createVNode(unref(PopoverPortal), null, {
233
+ default: withCtx(() => [
234
+ createVNode(unref(PopoverContent), {
235
+ side: step.value?.side ?? "bottom",
236
+ "side-offset": 12,
237
+ "collision-padding": 12,
238
+ "update-position-strategy": "always",
239
+ "trap-focus": false,
240
+ class: normalizeClass([CARD, "z-[calc(var(--z-tour)+1)] data-[state=open]:animate-[popover-in_var(--duration-medium)_var(--ease-emphasized)] motion-reduce:animate-none"]),
241
+ role: "dialog",
242
+ "aria-label": step.value?.title,
243
+ onPointerdown: _cache[1] || (_cache[1] = withModifiers(() => {
244
+ }, ["stop"])),
245
+ onInteractOutside: _cache[2] || (_cache[2] = withModifiers(() => {
246
+ }, ["prevent"])),
247
+ onEscapeKeyDown: _cache[3] || (_cache[3] = withModifiers(() => {
248
+ }, ["prevent"])),
249
+ onFocusOutside: _cache[4] || (_cache[4] = withModifiers(() => {
250
+ }, ["prevent"]))
251
+ }, {
252
+ default: withCtx(() => [
253
+ renderSlot(_ctx.$slots, "card", {
254
+ step: step.value,
255
+ index: index.value,
256
+ next,
257
+ back,
258
+ dismiss
259
+ }, () => [
260
+ createVNode(_sfc_main$1, {
261
+ step: step.value,
262
+ index: index.value,
263
+ last: last.value,
264
+ progress: progress.value,
265
+ labels: unref(labels),
266
+ onNext: next,
267
+ onBack: back,
268
+ onPerform: perform,
269
+ onDismiss: dismiss
270
+ }, null, 8, ["step", "index", "last", "progress", "labels"])
271
+ ])
272
+ ]),
273
+ _: 3
274
+ }, 8, ["side", "class", "aria-label"])
275
+ ]),
276
+ _: 3
277
+ })
278
+ ]),
279
+ _: 3
280
+ }, 8, ["open"])) : createCommentVNode("", true),
281
+ open.value && !unref(wide) && ready.value ? (openBlock(), createElementBlock("div", {
282
+ key: 2,
283
+ class: normalizeClass([CARD, "pointer-events-auto fixed inset-x-3 bottom-3 z-[calc(var(--z-tour)+1)] w-auto animate-[rise-in_var(--duration-medium)_var(--ease-emphasized)] motion-reduce:animate-none"]),
284
+ role: "dialog",
285
+ "aria-label": step.value?.title,
286
+ onPointerdown: _cache[5] || (_cache[5] = withModifiers(() => {
287
+ }, ["stop"]))
288
+ }, [
289
+ renderSlot(_ctx.$slots, "card", {
290
+ step: step.value,
291
+ index: index.value,
292
+ next,
293
+ back,
294
+ dismiss
295
+ }, () => [
296
+ createVNode(_sfc_main$1, {
297
+ step: step.value,
298
+ index: index.value,
299
+ last: last.value,
300
+ progress: progress.value,
301
+ labels: unref(labels),
302
+ onNext: next,
303
+ onBack: back,
304
+ onPerform: perform,
305
+ onDismiss: dismiss
306
+ }, null, 8, ["step", "index", "last", "progress", "labels"])
307
+ ])
308
+ ], 42, _hoisted_1)) : createCommentVNode("", true)
309
+ ]);
310
+ };
311
+ }
312
+ });
313
+ export {
314
+ _sfc_main as _
315
+ };
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, computed, ref, openBlock, createElementBlock, mergeProps, unref, createElementVNode, toDisplayString, createCommentVNode, createVNode, withCtx, Fragment, renderList, normalizeStyle, createBlock, createTextVNode } from "vue";
2
2
  import { _ as _sfc_main$3 } from "./LpNumberFlow-z4WPZcZu.js";
3
3
  import { _ as _sfc_main$2 } from "./LpRollingText-DB7upf-5.js";
4
- import { _ as _sfc_main$1 } from "./LpTooltip-CXVKcOXT.js";
4
+ import { _ as _sfc_main$1 } from "./LpTooltip-suFCM34F.js";
5
5
  import { useMergedAttrs } from "../composables/useMergedClass.js";
6
6
  import { useLabels } from "../composables/useLpConfig.js";
7
7
  import '../assets/LpUptimeBar-B98o9krI.css';const _hoisted_1 = {
@@ -0,0 +1,100 @@
1
+ import { defineComponent, openBlock, createElementBlock, Fragment, createElementVNode, toDisplayString, createVNode, createCommentVNode, createBlock, withCtx, createTextVNode } from "vue";
2
+ import { _ as _sfc_main$2 } from "./LpButton-BdfZFNqi.js";
3
+ import { _ as _sfc_main$1 } from "./LpIcon-DYtaid0K.js";
4
+ import LpKeys from "../components/LpKeys.vue.js";
5
+ const _hoisted_1 = { class: "flex items-start justify-between gap-3" };
6
+ const _hoisted_2 = {
7
+ class: "font-medium",
8
+ "aria-live": "polite"
9
+ };
10
+ const _hoisted_3 = ["aria-label"];
11
+ const _hoisted_4 = {
12
+ key: 0,
13
+ class: "mt-1.5 text-muted"
14
+ };
15
+ const _hoisted_5 = {
16
+ key: 2,
17
+ class: "mt-2 text-xs text-brand"
18
+ };
19
+ const _hoisted_6 = { class: "mt-4 flex items-center justify-between gap-2" };
20
+ const _hoisted_7 = { class: "text-xs tabular-nums text-muted" };
21
+ const _hoisted_8 = { class: "flex gap-2" };
22
+ const _sfc_main = /* @__PURE__ */ defineComponent({
23
+ __name: "TourCard",
24
+ props: {
25
+ step: {},
26
+ index: {},
27
+ last: { type: Boolean },
28
+ progress: {},
29
+ labels: {}
30
+ },
31
+ emits: ["next", "back", "perform", "dismiss"],
32
+ setup(__props) {
33
+ return (_ctx, _cache) => {
34
+ return openBlock(), createElementBlock(Fragment, null, [
35
+ createElementVNode("div", _hoisted_1, [
36
+ createElementVNode("p", _hoisted_2, toDisplayString(__props.step?.title), 1),
37
+ createElementVNode("button", {
38
+ type: "button",
39
+ class: "text-muted hover:text-ink",
40
+ "aria-label": __props.labels.close,
41
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("dismiss"))
42
+ }, [
43
+ createVNode(_sfc_main$1, {
44
+ name: "lucide:x",
45
+ class: "size-4"
46
+ })
47
+ ], 8, _hoisted_3)
48
+ ]),
49
+ __props.step?.text ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(__props.step.text), 1)) : createCommentVNode("", true),
50
+ __props.step?.keys ? (openBlock(), createBlock(LpKeys, {
51
+ key: 1,
52
+ combo: __props.step.keys,
53
+ size: "sm",
54
+ class: "mt-2"
55
+ }, null, 8, ["combo"])) : createCommentVNode("", true),
56
+ __props.step?.try ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(__props.labels.tryIt), 1)) : createCommentVNode("", true),
57
+ createElementVNode("div", _hoisted_6, [
58
+ createElementVNode("span", _hoisted_7, toDisplayString(__props.progress), 1),
59
+ createElementVNode("div", _hoisted_8, [
60
+ __props.index > 0 ? (openBlock(), createBlock(_sfc_main$2, {
61
+ key: 0,
62
+ size: "sm",
63
+ variant: "ghost",
64
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("back"))
65
+ }, {
66
+ default: withCtx(() => [
67
+ createTextVNode(toDisplayString(__props.labels.back), 1)
68
+ ]),
69
+ _: 1
70
+ })) : createCommentVNode("", true),
71
+ __props.step?.try && __props.step.perform ? (openBlock(), createBlock(_sfc_main$2, {
72
+ key: 1,
73
+ size: "sm",
74
+ variant: "outline",
75
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("perform"))
76
+ }, {
77
+ default: withCtx(() => [
78
+ createTextVNode(toDisplayString(__props.labels.perform), 1)
79
+ ]),
80
+ _: 1
81
+ })) : createCommentVNode("", true),
82
+ createVNode(_sfc_main$2, {
83
+ size: "sm",
84
+ variant: __props.step?.try ? "ghost" : void 0,
85
+ onClick: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("next"))
86
+ }, {
87
+ default: withCtx(() => [
88
+ createTextVNode(toDisplayString(__props.last ? __props.labels.done : __props.labels.next), 1)
89
+ ]),
90
+ _: 1
91
+ }, 8, ["variant"])
92
+ ])
93
+ ])
94
+ ], 64);
95
+ };
96
+ }
97
+ });
98
+ export {
99
+ _sfc_main as _
100
+ };
@@ -1 +1 @@
1
- export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LpActionBar", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpColorPicker", "LpCommandPalette", "LpConfirmDialog", "LpConfirmHost", "LpContextMenu", "LpDatePicker", "LpDateRangePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpDropzone", "LpEmptyState", "LpFieldNotice", "LpFileTree", "LpFormField", "LpIcon", "LpImageEditor", "LpInfraNode", "LpInput", "LpKeys", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpMediaGallery", "LpModal", "LpModalNav", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPaletteFacts", "LpPaletteHeader", "LpPalettePreview", "LpPaletteStats", "LpPaletteSwatches", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRangeCalendar", "LpRangeSlider", "LpRollingText", "LpScrollArea", "LpSection", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTagsInput", "LpTextarea", "LpThemeProvider", "LpThemeSwitcher", "LpTilt", "LpTimeField", "LpToaster", "LpTooltip", "LpTooltipProvider", "LpTopologyCanvas", "LpUptimeBar", "LpVideoBackdrop"];
1
+ export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LpActionBar", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpColorPicker", "LpCommandPalette", "LpConfirmDialog", "LpConfirmHost", "LpContextMenu", "LpDatePicker", "LpDateRangePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpDropzone", "LpEmptyState", "LpFieldNotice", "LpFileTree", "LpFormField", "LpHintLayer", "LpIcon", "LpImageEditor", "LpInfraNode", "LpInput", "LpKeys", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpMediaGallery", "LpModal", "LpModalNav", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPaletteFacts", "LpPaletteHeader", "LpPalettePreview", "LpPaletteStats", "LpPaletteSwatches", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRangeCalendar", "LpRangeSlider", "LpRollingText", "LpScrollArea", "LpSection", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTagsInput", "LpTextarea", "LpThemeProvider", "LpThemeSwitcher", "LpTilt", "LpTimeField", "LpToaster", "LpTooltip", "LpTooltipProvider", "LpTopologyCanvas", "LpTour", "LpUptimeBar", "LpVideoBackdrop"];
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpActionBar-CnfFVIwC.js";
1
+ import { _ as _sfc_main } from "../chunks/LpActionBar-C3hkVsFz.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAddressInput-iOJhmRzy.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAddressInput-NUHmplCd.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAppShell-DcSXik4a.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAppShell-Bl1Ch68N.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -20,6 +20,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
20
20
  href?: string;
21
21
  type?: "button" | "submit" | "reset";
22
22
  disabled?: boolean;
23
+ /**
24
+ * Busy state: blocks clicks like `disabled` without dimming, fades the label out
25
+ * in place and shows a spinner over it, so the width never jumps. Sets `aria-busy`.
26
+ */
27
+ loading?: boolean;
23
28
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
24
29
  variant?: "ghost" | "action" | "muted" | "outline" | "danger" | "solid" | "light" | "soft" | undefined;
25
30
  size?: "md" | "sm" | "lg" | "xs" | undefined;
@@ -38,6 +43,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
38
43
  href?: string;
39
44
  type?: "button" | "submit" | "reset";
40
45
  disabled?: boolean;
46
+ /**
47
+ * Busy state: blocks clicks like `disabled` without dimming, fades the label out
48
+ * in place and shows a spinner over it, so the width never jumps. Sets `aria-busy`.
49
+ */
50
+ loading?: boolean;
41
51
  }> & Readonly<{}>, {
42
52
  type: "button" | "submit" | "reset";
43
53
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpButton-CKSwC6Mu.js";
1
+ import { _ as _sfc_main } from "../chunks/LpButton-BdfZFNqi.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmDialog-Ca-CTlxT.js";
1
+ import { _ as _sfc_main } from "../chunks/LpConfirmDialog-CrbUZgJE.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpConfirmHost-BAaSaT2b.js";
1
+ import { _ as _sfc_main } from "../chunks/LpConfirmHost-BgMIV8r9.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpDateRangePicker-Drd7EbIz.js";
1
+ import { _ as _sfc_main } from "../chunks/LpDateRangePicker-CxV5jW7p.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpDrawer-CBFVD624.js";
1
+ import { _ as _sfc_main } from "../chunks/LpDrawer-D9lLOC0C.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -0,0 +1,33 @@
1
+ export interface HintNote {
2
+ title: string;
3
+ text?: string;
4
+ }
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
7
+ declare const __VLS_export: import("vue").DefineComponent<{
8
+ /** Ids to mark, most important first. */
9
+ fresh: string[];
10
+ notes: Record<string, HintNote>;
11
+ /** At most this many dots at once, so a page full of news stays calm. */
12
+ limit?: number;
13
+ labels?: Partial<{
14
+ gotIt: string;
15
+ badge: string;
16
+ }>;
17
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
18
+ read: (id: string) => any;
19
+ }, string, import("vue").PublicProps, Readonly<{
20
+ /** Ids to mark, most important first. */
21
+ fresh: string[];
22
+ notes: Record<string, HintNote>;
23
+ /** At most this many dots at once, so a page full of news stays calm. */
24
+ limit?: number;
25
+ labels?: Partial<{
26
+ gotIt: string;
27
+ badge: string;
28
+ }>;
29
+ }> & Readonly<{
30
+ onRead?: ((id: string) => any) | undefined;
31
+ }>, {
32
+ limit: number;
33
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpHintLayer-CI1oZ9Pd.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -4,7 +4,7 @@ import { isSideways, coverScale, cropGeometry } from "./imageCrop.js";
4
4
  import { useHotkeys } from "../composables/useHotkeys.js";
5
5
  import { useReveal } from "../composables/useReveal.js";
6
6
  import { useZoomPan } from "../composables/useZoomPan.js";
7
- import { _ as _sfc_main$1 } from "../chunks/LpButton-CKSwC6Mu.js";
7
+ import { _ as _sfc_main$1 } from "../chunks/LpButton-BdfZFNqi.js";
8
8
  import "reka-ui";
9
9
  import { _ as _sfc_main$2 } from "../chunks/LpIcon-DYtaid0K.js";
10
10
  import { useMergedAttrs } from "../composables/useMergedClass.js";
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpModalNav-aWwc_5CD.js";
1
+ import { _ as _sfc_main } from "../chunks/LpModalNav-DXyAyhQl.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpNotificationBell-wZ3meeim.js";
1
+ import { _ as _sfc_main } from "../chunks/LpNotificationBell-DEL-RoHS.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpPie-B7ti5qCH.js";
1
+ import { _ as _sfc_main } from "../chunks/LpPie-CXka8Jvx.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSidebar-C2oolgwy.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSidebar-hZ8D1cVr.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -14,7 +14,7 @@ import { usePaintSelect } from "../composables/usePaintSelect.js";
14
14
  import { useRovingFocus } from "../composables/useRovingFocus.js";
15
15
  import { useLabels } from "../composables/useLpConfig.js";
16
16
  import { compareValues } from "./tableSort.js";
17
- import { _ as _sfc_main$1 } from "../chunks/LpButton-CKSwC6Mu.js";
17
+ import { _ as _sfc_main$1 } from "../chunks/LpButton-BdfZFNqi.js";
18
18
  import { toCsv, downloadFile, fileStem } from "./exportData.js";
19
19
  import { summarizeShown, parseTableState, serializeTableState, countValues } from "./tableFilter.js";
20
20
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTableOfContents-BUcAfGPQ.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTableOfContents-DYuqkByy.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpTooltip-CXVKcOXT.js";
1
+ import { _ as _sfc_main } from "../chunks/LpTooltip-suFCM34F.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };