@leavepulse/ui 0.59.0 → 0.61.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 (168) hide show
  1. package/README.md +8 -0
  2. package/dist/assets/{LpCommandPalette-BM_IyzwB.css → LpCommandPalette-DA5pmuPi.css} +21 -21
  3. package/dist/assets/{LpTable-B_QCQCbB.css → LpTable-DpXyPzs8.css} +19 -19
  4. package/dist/chunks/{ContextMenuItems-CioDScj3.js → ContextMenuItems-qXReFtQW.js} +1 -1
  5. package/dist/chunks/{LayoutCanvas-BcGLJVBq.js → LayoutCanvas-t7LWFCEn.js} +1 -1
  6. package/dist/chunks/{LayoutNode-BkBn6dvM.js → LayoutNode-DHsE6GwM.js} +1 -1
  7. package/dist/chunks/{LpActionBar-DCN-_pZP.js → LpActionBar-BsSp66S_.js} +2 -2
  8. package/dist/chunks/{LpAddressInput-D-H94m4q.js → LpAddressInput-CzdZguBo.js} +7 -7
  9. package/dist/chunks/{LpAlert-CXMn1GYE.js → LpAlert--KLL4NLk.js} +1 -1
  10. package/dist/chunks/{LpAppShell-BeMuKEjh.js → LpAppShell-BXMNDEpF.js} +3 -3
  11. package/dist/chunks/{LpAutocomplete-hJ_6CHlh.js → LpAutocomplete-D9mY5Tqk.js} +102 -37
  12. package/dist/chunks/{LpAvatar-CeW4Z5CL.js → LpAvatar-K6MOMfgn.js} +2 -2
  13. package/dist/chunks/{LpBreadcrumbs-BLzOEgAF.js → LpBreadcrumbs-CndzPYiG.js} +1 -1
  14. package/dist/chunks/{LpButton-vhlwmpBy.js → LpButton-CJSD7N0Z.js} +1 -1
  15. package/dist/chunks/{LpCalendar-BLoE8Qm7.js → LpCalendar-CXVDbb2M.js} +1 -1
  16. package/dist/chunks/{LpCard-Gbr8a1xK.js → LpCard-D9HVgX8Y.js} +1 -1
  17. package/dist/chunks/{LpCheckbox-B_C8sOoT.js → LpCheckbox-DV9W6T3H.js} +1 -1
  18. package/dist/chunks/{LpCodeBlock-D6zhp30a.js → LpCodeBlock-t6MLA3fb.js} +1 -1
  19. package/dist/chunks/{LpColorPicker-CVXwjEtX.js → LpColorPicker-BO1ZTY51.js} +2 -2
  20. package/dist/chunks/{LpConfirmDialog-DkgIT-Xg.js → LpConfirmDialog-tkgyY3eu.js} +3 -3
  21. package/dist/chunks/{LpConfirmHost-CYzXWFOI.js → LpConfirmHost-CoYIcUdl.js} +1 -1
  22. package/dist/chunks/{LpContextMenu-DRFd-iyc.js → LpContextMenu-Cv_F2iCG.js} +20 -5
  23. package/dist/chunks/{LpDatePicker-B-VMHMgy.js → LpDatePicker-DxdrVNCG.js} +3 -3
  24. package/dist/chunks/{LpDateRangePicker-B68KPKPl.js → LpDateRangePicker-DjeaqikC.js} +2 -2
  25. package/dist/chunks/{LpDisclosure-Ct-VBHxt.js → LpDisclosure-s8cQ7KQq.js} +1 -1
  26. package/dist/chunks/{LpDrawer-Rc6eAJrr.js → LpDrawer-C97yoWmh.js} +1 -1
  27. package/dist/chunks/{LpDropdownMenu-BoJQsjzt.js → LpDropdownMenu-CbyYu4Rw.js} +11 -4
  28. package/dist/chunks/{LpEmptyState-CBwwkkdA.js → LpEmptyState-CX8fdGSU.js} +1 -1
  29. package/dist/chunks/{LpFieldNotice-9hH4ITZa.js → LpFieldNotice-B--RzKfj.js} +1 -1
  30. package/dist/chunks/{LpFileTree-Bs57DhVa.js → LpFileTree-DTwUj0L-.js} +2 -2
  31. package/dist/chunks/{LpFileTreeNode-XgJW65v5.js → LpFileTreeNode-D-XLPZ6T.js} +3 -3
  32. package/dist/chunks/{LpFormField-BpQ6WJPe.js → LpFormField-DMPPL1jF.js} +1 -1
  33. package/dist/chunks/{LpHintLayer-B5-6FyEf.js → LpHintLayer-DsclGYcD.js} +1 -1
  34. package/dist/chunks/{LpHints-BqoZXHZk.js → LpHints-BTpvisgP.js} +10 -4
  35. package/dist/chunks/{LpIcon-B5guGKrW.js → LpIcon-CTuDVTYv.js} +1 -1
  36. package/dist/chunks/{LpInput-WvyP02ID.js → LpInput-C7FHxzj2.js} +2 -2
  37. package/dist/chunks/{LpLightbox-Dq-e36uT.js → LpLightbox-DiksFa4L.js} +1 -1
  38. package/dist/chunks/{LpLogViewer-B92bAftG.js → LpLogViewer-D9UgNz2m.js} +2 -2
  39. package/dist/chunks/{LpMapPicker-BH5csaBt.js → LpMapPicker-DybIlWnF.js} +1 -1
  40. package/dist/chunks/{LpMediaGallery-B1kDypJ-.js → LpMediaGallery-Cic9UHsa.js} +2 -2
  41. package/dist/chunks/{LpModal-DvGD6kEe.js → LpModal-QFfctZsj.js} +1 -1
  42. package/dist/chunks/{LpModalNav-B-_zRTS-.js → LpModalNav-D4rmflQn.js} +4 -4
  43. package/dist/chunks/{LpNotificationBell-63pvatBj.js → LpNotificationBell-CyylOlZR.js} +4 -4
  44. package/dist/chunks/{LpNumberField-CJPjmoDz.js → LpNumberField-BFSRVGkJ.js} +1 -1
  45. package/dist/chunks/{LpPagination-DehAaJLY.js → LpPagination-BFl0I7tL.js} +1 -1
  46. package/dist/chunks/{LpPasswordInput-BK25_vNG.js → LpPasswordInput-C1G4k_r0.js} +2 -2
  47. package/dist/chunks/{LpPhoneInput-Bxg7a_qD.js → LpPhoneInput-CZrpVxla.js} +2 -2
  48. package/dist/chunks/{LpPie-Coa2GMHt.js → LpPie-B2deu8CI.js} +2 -2
  49. package/dist/chunks/{LpRangeCalendar-D5sDID9W.js → LpRangeCalendar-COeOYF52.js} +1 -1
  50. package/dist/chunks/{LpSection-B19VPYmr.js → LpSection-BAkbf0OK.js} +1 -1
  51. package/dist/chunks/{LpSegmented-DbrUjuSA.js → LpSegmented-DslFku0N.js} +1 -1
  52. package/dist/chunks/{LpSelect-DynjWK1A.js → LpSelect-C4OXN_q3.js} +1 -1
  53. package/dist/chunks/{LpSidebar-CKamWtPo.js → LpSidebar-D8tub3bt.js} +3 -3
  54. package/dist/chunks/{LpSidebarNav-Y4LV0ZEn.js → LpSidebarNav-BBSRg34G.js} +2 -2
  55. package/dist/chunks/{LpStat-BS2TEXYK.js → LpStat-oYk6V1LZ.js} +1 -1
  56. package/dist/chunks/{LpStepper-BSglWF45.js → LpStepper-YgHGzgfD.js} +1 -1
  57. package/dist/chunks/LpSwap-D82jiecV.js +38 -0
  58. package/dist/chunks/{LpTableFilter-CwHXVxJt.js → LpTableFilter-Ba-rS4H1.js} +2 -2
  59. package/dist/chunks/{LpTabs-D01b8jBI.js → LpTabs-00v3VQx4.js} +1 -1
  60. package/dist/chunks/{LpTagsInput-CHbQoAAA.js → LpTagsInput-Sc56iy_j.js} +3 -3
  61. package/dist/chunks/{LpTextarea-Bz2IWhTH.js → LpTextarea-CQZccQI3.js} +1 -1
  62. package/dist/chunks/{LpThemeSwitcher-CbzL6ipO.js → LpThemeSwitcher-ZFFftBQn.js} +2 -2
  63. package/dist/chunks/{LpTimeField-DvGXgdES.js → LpTimeField-BTEt0kvL.js} +1 -1
  64. package/dist/chunks/{LpToaster-C9EacEfR.js → LpToaster-D3OisETH.js} +2 -2
  65. package/dist/chunks/{LpTour-D7m9ZxNk.js → LpTour-C29-1wha.js} +4 -1
  66. package/dist/chunks/{MenuTitle-B9HdaBwE.js → MenuTitle-FeC6I24N.js} +1 -1
  67. package/dist/chunks/{TourCard-DCHOjr6e.js → TourCard-AjN0uhs1.js} +2 -2
  68. package/dist/chunks/{icons-QqBscG5I.js → icons-CuO3W46H.js} +1 -1
  69. package/dist/component-names.d.ts +1 -1
  70. package/dist/components/ContextMenuItems.vue.js +1 -1
  71. package/dist/components/LayoutCanvas.vue.js +1 -1
  72. package/dist/components/LayoutNode.vue.js +1 -1
  73. package/dist/components/LpActionBar.vue.js +1 -1
  74. package/dist/components/LpAddressInput.vue.js +1 -1
  75. package/dist/components/LpAlert.vue.js +1 -1
  76. package/dist/components/LpAppShell.vue.js +1 -1
  77. package/dist/components/LpAutocomplete.vue.d.ts +24 -0
  78. package/dist/components/LpAutocomplete.vue.js +1 -1
  79. package/dist/components/LpAvatar.vue.js +1 -1
  80. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  81. package/dist/components/LpButton.vue.js +1 -1
  82. package/dist/components/LpCalendar.vue.js +1 -1
  83. package/dist/components/LpCard.vue.js +1 -1
  84. package/dist/components/LpChart.vue.js +2 -2
  85. package/dist/components/LpCheckbox.vue.js +1 -1
  86. package/dist/components/LpCodeBlock.vue.js +1 -1
  87. package/dist/components/LpColorPicker.vue.js +1 -1
  88. package/dist/components/LpCommandPalette.vue.js +30 -19
  89. package/dist/components/LpConfirmDialog.vue.js +1 -1
  90. package/dist/components/LpConfirmHost.vue.js +1 -1
  91. package/dist/components/LpContextMenu.vue.d.ts +7 -2
  92. package/dist/components/LpContextMenu.vue.js +1 -1
  93. package/dist/components/LpDatePicker.vue.js +1 -1
  94. package/dist/components/LpDateRangePicker.vue.js +1 -1
  95. package/dist/components/LpDisclosure.vue.js +1 -1
  96. package/dist/components/LpDrawer.vue.js +1 -1
  97. package/dist/components/LpDropdownMenu.vue.d.ts +7 -2
  98. package/dist/components/LpDropdownMenu.vue.js +1 -1
  99. package/dist/components/LpDropzone.vue.js +1 -1
  100. package/dist/components/LpEmptyState.vue.js +1 -1
  101. package/dist/components/LpFieldNotice.vue.js +1 -1
  102. package/dist/components/LpFileTree.vue.js +1 -1
  103. package/dist/components/LpFileTreeNode.vue.js +1 -1
  104. package/dist/components/LpFormField.vue.js +1 -1
  105. package/dist/components/LpHintLayer.vue.js +1 -1
  106. package/dist/components/LpHints.vue.js +1 -1
  107. package/dist/components/LpIcon.vue.js +1 -1
  108. package/dist/components/LpImageEditor.vue.js +4 -2
  109. package/dist/components/LpInput.vue.js +1 -1
  110. package/dist/components/LpLightbox.vue.js +1 -1
  111. package/dist/components/LpLogViewer.vue.js +1 -1
  112. package/dist/components/LpMapPicker.vue.js +1 -1
  113. package/dist/components/LpMediaGallery.vue.js +1 -1
  114. package/dist/components/LpModal.vue.js +1 -1
  115. package/dist/components/LpModalNav.vue.js +1 -1
  116. package/dist/components/LpNotificationBell.vue.js +1 -1
  117. package/dist/components/LpNumberField.vue.js +1 -1
  118. package/dist/components/LpPagination.vue.js +1 -1
  119. package/dist/components/LpPaletteFacts.vue.js +1 -1
  120. package/dist/components/LpPaletteHeader.vue.js +2 -2
  121. package/dist/components/LpPasswordInput.vue.js +1 -1
  122. package/dist/components/LpPhoneInput.vue.js +1 -1
  123. package/dist/components/LpPie.vue.js +1 -1
  124. package/dist/components/LpRangeCalendar.vue.js +1 -1
  125. package/dist/components/LpSection.vue.js +1 -1
  126. package/dist/components/LpSegmented.vue.js +1 -1
  127. package/dist/components/LpSelect.vue.js +1 -1
  128. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  129. package/dist/components/LpSidebar.vue.js +1 -1
  130. package/dist/components/LpSidebarNav.vue.js +1 -1
  131. package/dist/components/LpStat.vue.js +1 -1
  132. package/dist/components/LpStepper.vue.js +1 -1
  133. package/dist/components/LpSwap.vue.d.ts +19 -0
  134. package/dist/components/LpSwap.vue.js +4 -0
  135. package/dist/components/LpTable.vue.js +13 -11
  136. package/dist/components/LpTableFilter.vue.js +1 -1
  137. package/dist/components/LpTabs.vue.js +1 -1
  138. package/dist/components/LpTagsInput.vue.js +1 -1
  139. package/dist/components/LpTextarea.vue.js +1 -1
  140. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  141. package/dist/components/LpTimeField.vue.js +1 -1
  142. package/dist/components/LpToaster.vue.js +1 -1
  143. package/dist/components/LpTour.vue.js +1 -1
  144. package/dist/components/MenuTitle.vue.js +1 -1
  145. package/dist/components/TourCard.vue.js +1 -1
  146. package/dist/composables/useHintSystem.d.ts +67 -0
  147. package/dist/composables/useHintSystem.js +110 -12
  148. package/dist/composables/useToast.d.ts +13 -4
  149. package/dist/composables/useToast.js +13 -2
  150. package/dist/icons-all.js +1 -1
  151. package/dist/index.d.ts +5 -4
  152. package/dist/index.js +101 -95
  153. package/package.json +2 -1
  154. package/src/component-names.ts +1 -0
  155. package/src/components/LpAutocomplete.vue +110 -24
  156. package/src/components/LpCommandPalette.vue +26 -4
  157. package/src/components/LpContextMenu.vue +22 -1
  158. package/src/components/LpDropdownMenu.vue +13 -2
  159. package/src/components/LpHints.vue +7 -1
  160. package/src/components/LpSwap.vue +45 -0
  161. package/src/components/LpTable.vue +2 -1
  162. package/src/components/LpToaster.vue +1 -1
  163. package/src/components/LpTour.vue +3 -0
  164. package/src/composables/useHintSystem.ts +152 -12
  165. package/src/composables/useToast.ts +32 -5
  166. package/src/index.ts +5 -2
  167. package/src/kit-icons.ts +1 -1
  168. package/src/tokens/selection.css +20 -0
@@ -1,6 +1,55 @@
1
- import { provide, reactive, computed, inject, watch } from "vue";
1
+ import { shallowRef, provide, onBeforeUnmount, reactive, computed, inject, watch } from "vue";
2
2
  import { anyModalOpen } from "../components/modalDepth.js";
3
3
  import { hints } from "./useHints.js";
4
+ const HINT_SIGNALS = {
5
+ /** A context menu was opened (right click or long press). */
6
+ contextMenu: "lp.context-menu",
7
+ /** A "…" menu marked `rightClickToo` was opened: its items were one right click away. */
8
+ menuButton: "lp.menu-button",
9
+ /** A left click on something that also has a context menu. */
10
+ contextTarget: "lp.context-target",
11
+ /** The command palette was opened. */
12
+ palette: "lp.palette",
13
+ /** The current hint page changed: a navigation. */
14
+ navigate: "lp.navigate",
15
+ /** An item's actions were opened in the palette (Tab). */
16
+ paletteActions: "lp.palette-actions"
17
+ };
18
+ let lastContextTarget = null;
19
+ function noteContextTarget(el) {
20
+ lastContextTarget = new WeakRef(el);
21
+ }
22
+ const onScreen = (el) => {
23
+ const box = el.getBoundingClientRect();
24
+ return el.isConnected && box.width > 0 && box.bottom > 0 && box.top < window.innerHeight;
25
+ };
26
+ function rightClickTarget() {
27
+ const last = lastContextTarget?.deref();
28
+ if (last && onScreen(last)) return last;
29
+ const visible = (selector) => [...document.querySelectorAll(selector)].find(onScreen) ?? null;
30
+ return visible("[data-lp-context-row]") ?? visible("main [data-lp-context-menu]") ?? visible("[data-lp-context-menu]");
31
+ }
32
+ function contextMenuTip(text = {}) {
33
+ return {
34
+ id: "lp.tip.context-menu",
35
+ title: text.title ?? "Right-click works here",
36
+ text: text.text ?? "Rows and cards open their actions on right-click, even where no … button shows it.",
37
+ when: (count) => count(HINT_SIGNALS.contextMenu) === 0 && (count(HINT_SIGNALS.menuButton) >= 5 || count(HINT_SIGNALS.contextTarget) >= 25),
38
+ step: () => {
39
+ const target = rightClickTarget();
40
+ return target ? { target, title: text.title ?? "Right-click works here", text: text.stepText ?? "Right-click this to see what it can do.", try: true } : null;
41
+ }
42
+ };
43
+ }
44
+ function paletteTip(keys = "Ctrl+K", text = {}) {
45
+ return {
46
+ id: "lp.tip.palette",
47
+ title: text.title ?? "Jump anywhere",
48
+ text: text.text ?? "Search pages, people and settings from anywhere instead of the menu.",
49
+ keys,
50
+ when: (count) => count(HINT_SIGNALS.navigate) >= 15 && count(HINT_SIGNALS.palette) === 0
51
+ };
52
+ }
4
53
  const RANK = { seen: 0, explained: 1, used: 2 };
5
54
  const DAY = 24 * 3600 * 1e3;
6
55
  const DEFAULT_TIMING = {
@@ -69,12 +118,15 @@ function createHintSystem(options) {
69
118
  const features = options.features;
70
119
  const pages = options.pages ?? {};
71
120
  const news = options.news ?? [];
121
+ const tips = options.tips ?? [];
122
+ const TIP_MAX = 3;
72
123
  const storage = options.storage ?? localHintStorage();
73
124
  const sessionKey = options.sessionKey ?? "lp-hints:interrupted";
74
125
  const state = reactive({
75
126
  records: /* @__PURE__ */ new Map(),
76
127
  loaded: false,
77
128
  page: "",
129
+ overlay: null,
78
130
  tour: { open: false, step: 0, steps: [], ids: [], page: "" },
79
131
  offer: null,
80
132
  candidate: null,
@@ -87,6 +139,9 @@ function createHintSystem(options) {
87
139
  const pageKey = hintKey.page;
88
140
  const newsKey = hintKey.news;
89
141
  const nudgeKey = hintKey.nudge;
142
+ const signalKey = (name) => `u:${name}`;
143
+ const tipKey = (id) => `p:${id}`;
144
+ const count = (name) => state.records.get(signalKey(name))?.count ?? 0;
90
145
  function interrupted() {
91
146
  try {
92
147
  return sessionStorage.getItem(sessionKey) === "1";
@@ -213,21 +268,35 @@ function createHintSystem(options) {
213
268
  return;
214
269
  }
215
270
  const n = state.candidate;
216
- if (!n || n.page !== page) return;
217
- const seen = state.records.get(nudgeKey(n.id));
218
- if (seen?.dismissed || state.records.get(featureKey(n.feature))?.state === "used" || !hints.present(n.feature)) return;
219
- if (seen && Date.now() - Date.parse(seen.updatedAt) < timing.nudgeAgain) return;
220
- state.candidate = null;
221
- spend();
222
- record(nudgeKey(n.id), { add: 1 });
223
- state.offer = { kind: "nudge", page, nudge: n };
271
+ if (n && n.page === page) {
272
+ const seen = state.records.get(nudgeKey(n.id));
273
+ const f = features[n.feature];
274
+ const visible = !!f && (!!f.target || !!f.enter || hints.present(n.feature));
275
+ if (!seen?.dismissed && state.records.get(featureKey(n.feature))?.state !== "used" && visible && !(seen && Date.now() - Date.parse(seen.updatedAt) < timing.nudgeAgain)) {
276
+ state.candidate = null;
277
+ spend();
278
+ record(nudgeKey(n.id), { add: 1 });
279
+ state.offer = { kind: "nudge", page, nudge: n };
280
+ return;
281
+ }
282
+ }
283
+ for (const tip of tips) {
284
+ const seen = state.records.get(tipKey(tip.id));
285
+ if (seen?.dismissed || (seen?.count ?? 0) >= (tip.max ?? TIP_MAX)) continue;
286
+ if (seen && Date.now() - Date.parse(seen.updatedAt) < timing.nudgeAgain) continue;
287
+ if (!tip.when(count)) continue;
288
+ spend();
289
+ state.offer = { kind: "tip", page, tip };
290
+ return;
291
+ }
224
292
  }
225
293
  let stops = [];
226
294
  function start() {
227
295
  if (stops.length) return;
228
296
  const stopPage = watch(
229
- options.page,
230
- (page) => {
297
+ () => state.overlay ?? options.page(),
298
+ (page, previous) => {
299
+ if (previous !== void 0 && page !== previous && !state.overlay) record(signalKey(HINT_SIGNALS.navigate), { add: 1 });
231
300
  state.page = page;
232
301
  state.settledAt = Date.now();
233
302
  if (state.offer && state.offer.page !== page) state.offer = null;
@@ -249,6 +318,7 @@ function createHintSystem(options) {
249
318
  stopPage,
250
319
  hints.on("used", (id) => {
251
320
  if (features[id]) record(featureKey(id), { state: "used", add: 1 });
321
+ if (id.startsWith("lp.") || !features[id]) record(signalKey(id), { add: 1 });
252
322
  }),
253
323
  () => clearInterval(poll),
254
324
  () => window.removeEventListener("pagehide", flushOnLeave)
@@ -279,6 +349,16 @@ function createHintSystem(options) {
279
349
  nudge(n) {
280
350
  state.candidate = { ...n, page: state.page };
281
351
  },
352
+ /**
353
+ * A dialog acts as its own page while open (its dots and tour), then hands
354
+ * back. Pass null on close, and on unmount: a dialog left open by a route
355
+ * change would otherwise keep the page.
356
+ */
357
+ overlay(page) {
358
+ state.overlay = page;
359
+ },
360
+ /** How many times a signal was reported (for an app's own tips or reports). */
361
+ count,
282
362
  /** The user navigated on purpose (palette, notification): do not interrupt this arrival. */
283
363
  markIntent() {
284
364
  state.intent = true;
@@ -294,6 +374,7 @@ function createHintSystem(options) {
294
374
  if (id) record(featureKey(id), { state: "explained" });
295
375
  },
296
376
  tourEnded(finished) {
377
+ if (!state.tour.ids.length) return;
297
378
  record(pageKey(state.tour.page), finished ? { state: "explained" } : { add: 1 });
298
379
  baseline(state.tour.page);
299
380
  },
@@ -305,6 +386,10 @@ function createHintSystem(options) {
305
386
  const ids = offer.items.map((n) => n.feature).filter((id) => !!id);
306
387
  readNews(offer.page);
307
388
  if (choice === "show" && ids.length) startTour(offer.page, ids);
389
+ } else if (offer.kind === "tip") {
390
+ record(tipKey(offer.tip.id), { add: 1, dismissed: choice === "never" });
391
+ const step = choice === "show" ? offer.tip.step?.() : null;
392
+ if (step) Object.assign(state.tour, { open: true, step: 0, page: offer.page, ids: [], steps: [step] });
308
393
  } else if (offer.kind === "nudge") {
309
394
  if (choice === "show") startTour(features[offer.nudge.feature].page, [offer.nudge.feature]);
310
395
  else record(nudgeKey(offer.nudge.id), { dismissed: true });
@@ -318,17 +403,30 @@ function createHintSystem(options) {
318
403
  };
319
404
  }
320
405
  const HINT_SYSTEM = /* @__PURE__ */ Symbol.for("lp-hint-system");
406
+ const running = shallowRef(null);
321
407
  function provideHintSystem(system) {
322
408
  provide(HINT_SYSTEM, system);
409
+ running.value = system;
410
+ onBeforeUnmount(() => {
411
+ if (running.value === system) running.value = null;
412
+ });
323
413
  }
324
414
  function useHintSystem() {
325
- return inject(HINT_SYSTEM, null);
415
+ return inject(HINT_SYSTEM, null) ?? running.value;
416
+ }
417
+ function runningHintSystem() {
418
+ return running.value;
326
419
  }
327
420
  export {
421
+ HINT_SIGNALS,
422
+ contextMenuTip,
328
423
  createHintSystem,
329
424
  hintKey,
330
425
  hintSummary,
331
426
  localHintStorage,
427
+ noteContextTarget,
428
+ paletteTip,
332
429
  provideHintSystem,
430
+ runningHintSystem,
333
431
  useHintSystem
334
432
  };
@@ -19,6 +19,8 @@ export interface ToastItem {
19
19
  actions?: ToastAction[];
20
20
  /** Whole-toast click handler (UAProject-style clickable toast). */
21
21
  onClick?: () => void | Promise<void>;
22
+ /** Copied with the message, not shown: what a bug report needs (request, status, ids). */
23
+ details?: string;
22
24
  }
23
25
  export interface ToastOptions {
24
26
  /**
@@ -31,12 +33,19 @@ export interface ToastOptions {
31
33
  duration?: number;
32
34
  actions?: ToastAction[];
33
35
  onClick?: () => void | Promise<void>;
36
+ /** Copied with the message, not shown. An Error passed to `error()` brings its own `details`. */
37
+ details?: string;
38
+ /** The error behind a hand-written message ("Not saved: " + e.message): its `details` ride along. */
39
+ cause?: unknown;
34
40
  }
35
- declare function push(variant: ToastVariant, message: string, options?: ToastOptions): number;
41
+ export type ToastMessage = string | (Error & {
42
+ details?: string;
43
+ });
44
+ declare function push(variant: ToastVariant, input: ToastMessage, given?: ToastOptions): number;
36
45
  export interface ToastPromiseMessages<T> {
37
46
  loading: string;
38
47
  success: string | ((value: T) => string);
39
- error: string | ((error: unknown) => string);
48
+ error: string | ((error: unknown) => ToastMessage);
40
49
  }
41
50
  /**
42
51
  * One toast that follows a promise: a persistent "loading" toast that turns
@@ -50,8 +59,8 @@ export declare function useToast(): {
50
59
  toast: (message: string, o?: ToastOptions) => number;
51
60
  info: (message: string, o?: ToastOptions) => number;
52
61
  success: (message: string, o?: ToastOptions) => number;
53
- warning: (message: string, o?: ToastOptions) => number;
54
- error: (message: string, o?: ToastOptions) => number;
62
+ warning: (message: ToastMessage, o?: ToastOptions) => number;
63
+ error: (message: ToastMessage, o?: ToastOptions) => number;
55
64
  promise: typeof promise;
56
65
  /** Low-level push for bridges (e.g. @leavepulse/ui-sdk apiError). */
57
66
  push: typeof push;
@@ -1,11 +1,21 @@
1
1
  import { reactive } from "vue";
2
+ function detailsOf(source) {
3
+ const details = source?.details;
4
+ return typeof details === "string" && details ? details : void 0;
5
+ }
6
+ function split(message, options) {
7
+ const text = typeof message === "string" ? message : message.message;
8
+ const details = options.details ?? (typeof message === "string" ? void 0 : detailsOf(message)) ?? detailsOf(options.cause);
9
+ return [text, { ...options, details }];
10
+ }
2
11
  const DEFAULT_DURATION = 4500;
3
12
  const MAX_ACTIVE = 4;
4
13
  const STATE_KEY = /* @__PURE__ */ Symbol.for("@leavepulse/ui:toast-queue");
5
14
  const g = globalThis;
6
15
  const state = g[STATE_KEY] ??= { queue: reactive([]), nextId: 0 };
7
16
  const queue = state.queue;
8
- function push(variant, message, options = {}) {
17
+ function push(variant, input, given = {}) {
18
+ const [message, options] = split(input, given);
9
19
  if (typeof window === "undefined") return -1;
10
20
  const duration = options.duration ?? DEFAULT_DURATION;
11
21
  const fields = {
@@ -16,7 +26,8 @@ function push(variant, message, options = {}) {
16
26
  duration,
17
27
  dismissAt: duration > 0 ? Date.now() + duration : null,
18
28
  actions: options.actions,
19
- onClick: options.onClick
29
+ onClick: options.onClick,
30
+ details: options.details
20
31
  };
21
32
  const same = options.key === void 0 ? -1 : queue.findIndex((t) => t.key === options.key);
22
33
  const existing = queue[same];
package/dist/icons-all.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import lucide from "@iconify-json/lucide/icons.json";
2
- import { a as registerIconCollection } from "./chunks/icons-QqBscG5I.js";
2
+ import { a as registerIconCollection } from "./chunks/icons-CuO3W46H.js";
3
3
  registerIconCollection(lucide);
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { ActionBarAction } from "./components/LpActionBar.vue";
8
8
  export { default as LpAlert } from "./components/LpAlert.vue";
9
9
  export { default as LpAppShell } from "./components/LpAppShell.vue";
10
10
  export { default as LpAutocomplete } from "./components/LpAutocomplete.vue";
11
- export type { AutocompleteOption } from "./components/LpAutocomplete.vue";
11
+ export type { AutocompleteOption, AutocompleteSelection } from "./components/LpAutocomplete.vue";
12
12
  export { default as LpAvatar } from "./components/LpAvatar.vue";
13
13
  export { default as LpBadge } from "./components/LpBadge.vue";
14
14
  export { default as LpBreadcrumbs } from "./components/LpBreadcrumbs.vue";
@@ -125,6 +125,7 @@ export type { SelectOption, SelectValue } from "./components/LpSelect.vue";
125
125
  export { default as LpServiceNode } from "./components/LpServiceNode.vue";
126
126
  export type { ServiceNodeData } from "./components/LpServiceNode.vue";
127
127
  export { default as LpShift } from "./components/LpShift.vue";
128
+ export { default as LpSwap } from "./components/LpSwap.vue";
128
129
  export { default as LpShortcutsDialog } from "./components/LpShortcutsDialog.vue";
129
130
  export { default as LpSidebar } from "./components/LpSidebar.vue";
130
131
  export type { SidebarItem, SidebarSection } from "./components/LpSidebar.vue";
@@ -162,8 +163,8 @@ export type { TourContext, TourStep } from "./components/LpTour.vue";
162
163
  export { holeOf, openContextMenu, panelsAround } from "./components/tour";
163
164
  export { default as LpHintLayer } from "./components/LpHintLayer.vue";
164
165
  export { default as LpHints } from "./components/LpHints.vue";
165
- export { createHintSystem, hintKey, hintSummary, localHintStorage, provideHintSystem, useHintSystem } from "./composables/useHintSystem";
166
- export type { HintDelta, HintFeature, HintLevel, HintNews, HintNudge, HintOffer, HintPage, HintRecord, HintStorage, HintSummary, HintSystem, HintSystemOptions, HintTiming, } from "./composables/useHintSystem";
166
+ export { HINT_SIGNALS, contextMenuTip, createHintSystem, hintKey, hintSummary, localHintStorage, paletteTip, provideHintSystem, runningHintSystem, useHintSystem } from "./composables/useHintSystem";
167
+ export type { HintDelta, HintFeature, HintLevel, HintNews, HintNudge, HintOffer, HintPage, HintRecord, HintStorage, HintSummary, HintSystem, HintTip, HintSystemOptions, HintTiming, } from "./composables/useHintSystem";
167
168
  export type { HintNote } from "./components/LpHintLayer.vue";
168
169
  export { default as LpTooltipProvider } from "./components/LpTooltipProvider.vue";
169
170
  export { default as LpTopologyCanvas } from "./components/LpTopologyCanvas.vue";
@@ -237,7 +238,7 @@ export type { UseTilt, UseTiltOptions } from "./composables/useTilt";
237
238
  export { useZoomPan } from "./composables/useZoomPan";
238
239
  export type { UseZoomPan, UseZoomPanOptions } from "./composables/useZoomPan";
239
240
  export { useToast } from "./composables/useToast";
240
- export type { ToastAction, ToastItem, ToastOptions, ToastVariant, } from "./composables/useToast";
241
+ export type { ToastAction, ToastItem, ToastMessage, ToastOptions, ToastVariant, } from "./composables/useToast";
241
242
  export type { ToastPromiseMessages } from "./composables/useToast";
242
243
  export { cacheSystemThemes, normalizeTheme, prefersDarkScheme, themeEntries, } from "./theme/useTheme";
243
244
  export type { SystemThemes, UseTheme } from "./theme/useTheme";
package/dist/index.js CHANGED
@@ -1,24 +1,24 @@
1
- import { _ } from "./chunks/LayoutCanvas-BcGLJVBq.js";
2
- import { _ as _2 } from "./chunks/LpAddressInput-D-H94m4q.js";
3
- import { _ as _3 } from "./chunks/LpMapPicker-BH5csaBt.js";
1
+ import { _ } from "./chunks/LayoutCanvas-t7LWFCEn.js";
2
+ import { _ as _2 } from "./chunks/LpAddressInput-CzdZguBo.js";
3
+ import { _ as _3 } from "./chunks/LpMapPicker-DybIlWnF.js";
4
4
  import { OSM_TILES, createNominatimProvider, emptyAddress, formatAddress, project, tileUrl, unproject } from "./components/address.js";
5
- import { _ as _4 } from "./chunks/LpActionBar-DCN-_pZP.js";
6
- import { _ as _5 } from "./chunks/LpAlert-CXMn1GYE.js";
7
- import { _ as _6 } from "./chunks/LpAppShell-BeMuKEjh.js";
8
- import { _ as _7 } from "./chunks/LpAutocomplete-hJ_6CHlh.js";
9
- import { _ as _8 } from "./chunks/LpAvatar-CeW4Z5CL.js";
5
+ import { _ as _4 } from "./chunks/LpActionBar-BsSp66S_.js";
6
+ import { _ as _5 } from "./chunks/LpAlert--KLL4NLk.js";
7
+ import { _ as _6 } from "./chunks/LpAppShell-BXMNDEpF.js";
8
+ import { _ as _7 } from "./chunks/LpAutocomplete-D9mY5Tqk.js";
9
+ import { _ as _8 } from "./chunks/LpAvatar-K6MOMfgn.js";
10
10
  import { _ as _9 } from "./chunks/LpBadge-Fe0D1bYx.js";
11
- import { _ as _10 } from "./chunks/LpBreadcrumbs-BLzOEgAF.js";
12
- import { _ as _11 } from "./chunks/LpButton-vhlwmpBy.js";
13
- import { _ as _12 } from "./chunks/LpCalendar-BLoE8Qm7.js";
14
- import { _ as _13 } from "./chunks/LpCard-Gbr8a1xK.js";
11
+ import { _ as _10 } from "./chunks/LpBreadcrumbs-CndzPYiG.js";
12
+ import { _ as _11 } from "./chunks/LpButton-CJSD7N0Z.js";
13
+ import { _ as _12 } from "./chunks/LpCalendar-CXVDbb2M.js";
14
+ import { _ as _13 } from "./chunks/LpCard-D9HVgX8Y.js";
15
15
  import { default as default2 } from "./components/LpChart.vue.js";
16
16
  import { backgroundOf, csvField, downloadFile, fileStem, inlineSvg, resolveCssColor, svgToPng, toCsv } from "./components/exportData.js";
17
17
  import { CHART_PALETTE, axisTicks, chartSummary, formatTick, markerIndex, niceScale, resolveSlices } from "./components/chart.js";
18
- import { _ as _14 } from "./chunks/LpCheckbox-B_C8sOoT.js";
19
- import { _ as _15 } from "./chunks/LpCodeBlock-D6zhp30a.js";
18
+ import { _ as _14 } from "./chunks/LpCheckbox-DV9W6T3H.js";
19
+ import { _ as _15 } from "./chunks/LpCodeBlock-t6MLA3fb.js";
20
20
  import { tokenizeLines } from "./components/codeHighlight.js";
21
- import { _ as _16 } from "./chunks/LpColorPicker-CVXwjEtX.js";
21
+ import { _ as _16 } from "./chunks/LpColorPicker-BO1ZTY51.js";
22
22
  import { DEFAULT_SWATCHES, clampHsv, formatColor, hsvToHsl, hsvToRgb, isLight, normalizeHue, opaqueCss, parseColor, parseHex, rgbToHex, rgbToHsv } from "./components/color.js";
23
23
  import { default as default3 } from "./components/LpCommandPalette.vue.js";
24
24
  import { applyQueryFilters, highlightParts, parseCommandQuery, parsePaletteQuery, rankCommandItems } from "./components/commandSearch.js";
@@ -30,46 +30,46 @@ import { default as default6 } from "./components/LpPaletteStats.vue.js";
30
30
  import { default as default7 } from "./components/LpPaletteSwatches.vue.js";
31
31
  import { default as default8 } from "./components/LpKeys.vue.js";
32
32
  import { comboKeys, comboSteps } from "./components/keys.js";
33
- import { _ as _18 } from "./chunks/LpConfirmDialog-DkgIT-Xg.js";
34
- import { _ as _19 } from "./chunks/LpConfirmHost-CYzXWFOI.js";
33
+ import { _ as _18 } from "./chunks/LpConfirmDialog-tkgyY3eu.js";
34
+ import { _ as _19 } from "./chunks/LpConfirmHost-CoYIcUdl.js";
35
35
  import { confirm, useConfirm } from "./components/confirm.js";
36
- import { _ as _20 } from "./chunks/LpContextMenu-DRFd-iyc.js";
37
- import { _ as _21 } from "./chunks/LpDatePicker-B-VMHMgy.js";
38
- import { _ as _22 } from "./chunks/LpDateRangePicker-B68KPKPl.js";
39
- import { _ as _23 } from "./chunks/LpRangeCalendar-D5sDID9W.js";
36
+ import { _ as _20 } from "./chunks/LpContextMenu-Cv_F2iCG.js";
37
+ import { _ as _21 } from "./chunks/LpDatePicker-DxdrVNCG.js";
38
+ import { _ as _22 } from "./chunks/LpDateRangePicker-DjeaqikC.js";
39
+ import { _ as _23 } from "./chunks/LpRangeCalendar-COeOYF52.js";
40
40
  import { clampRange, defaultRangePresets, formatRange, normalizeRange, sameRange } from "./components/dateRange.js";
41
- import { _ as _24 } from "./chunks/LpDisclosure-Ct-VBHxt.js";
41
+ import { _ as _24 } from "./chunks/LpDisclosure-s8cQ7KQq.js";
42
42
  import { _ as _25 } from "./chunks/LpDivider-CUX46KR0.js";
43
- import { _ as _26 } from "./chunks/LpDrawer-Rc6eAJrr.js";
44
- import { _ as _27 } from "./chunks/LpDropdownMenu-BoJQsjzt.js";
43
+ import { _ as _26 } from "./chunks/LpDrawer-C97yoWmh.js";
44
+ import { _ as _27 } from "./chunks/LpDropdownMenu-CbyYu4Rw.js";
45
45
  import { default as default9 } from "./components/LpDropzone.vue.js";
46
- import { _ as _28 } from "./chunks/LpEmptyState-CBwwkkdA.js";
47
- import { _ as _29 } from "./chunks/LpFileTree-Bs57DhVa.js";
46
+ import { _ as _28 } from "./chunks/LpEmptyState-CX8fdGSU.js";
47
+ import { _ as _29 } from "./chunks/LpFileTree-DTwUj0L-.js";
48
48
  import { ancestorIds, checkStateOf, checkedCount, computeStats, fileIcon, formatModified, formatSize, sortNodes, subtreeIds, subtreeSize } from "./components/fileTree.js";
49
- import { _ as _30 } from "./chunks/LpFieldNotice-9hH4ITZa.js";
50
- import { _ as _31 } from "./chunks/LpFormField-BpQ6WJPe.js";
51
- import { _ as _32 } from "./chunks/LpIcon-B5guGKrW.js";
52
- import { i, b, a, c } from "./chunks/icons-QqBscG5I.js";
49
+ import { _ as _30 } from "./chunks/LpFieldNotice-B--RzKfj.js";
50
+ import { _ as _31 } from "./chunks/LpFormField-DMPPL1jF.js";
51
+ import { _ as _32 } from "./chunks/LpIcon-CTuDVTYv.js";
52
+ import { i, b, a, c } from "./chunks/icons-CuO3W46H.js";
53
53
  import { default as default10 } from "./components/LpImageEditor.vue.js";
54
54
  import { _ as _33 } from "./chunks/LpInfraNode-Ds_8SZgN.js";
55
- import { _ as _34 } from "./chunks/LpInput-WvyP02ID.js";
56
- import { _ as _35 } from "./chunks/LpLightbox-Dq-e36uT.js";
55
+ import { _ as _34 } from "./chunks/LpInput-C7FHxzj2.js";
56
+ import { _ as _35 } from "./chunks/LpLightbox-DiksFa4L.js";
57
57
  import { fileNameOf } from "./components/lightbox.js";
58
58
  import { _ as _36 } from "./chunks/LpLink-Krkjhe_y.js";
59
- import { _ as _37 } from "./chunks/LpLogViewer-B92bAftG.js";
59
+ import { _ as _37 } from "./chunks/LpLogViewer-D9UgNz2m.js";
60
60
  import { countLevels, matchPositions, matchesTerm, ringWindow, stepMatch } from "./components/logSearch.js";
61
- import { _ as _38 } from "./chunks/LpMediaGallery-B1kDypJ-.js";
62
- import { _ as _39 } from "./chunks/LpModal-DvGD6kEe.js";
63
- import { _ as _40 } from "./chunks/LpModalNav-B-_zRTS-.js";
64
- import { _ as _41 } from "./chunks/LpNotificationBell-63pvatBj.js";
65
- import { _ as _42 } from "./chunks/LpNumberField-CJPjmoDz.js";
66
- import { _ as _43 } from "./chunks/LpTimeField-DvGXgdES.js";
61
+ import { _ as _38 } from "./chunks/LpMediaGallery-Cic9UHsa.js";
62
+ import { _ as _39 } from "./chunks/LpModal-QFfctZsj.js";
63
+ import { _ as _40 } from "./chunks/LpModalNav-D4rmflQn.js";
64
+ import { _ as _41 } from "./chunks/LpNotificationBell-CyylOlZR.js";
65
+ import { _ as _42 } from "./chunks/LpNumberField-BFSRVGkJ.js";
66
+ import { _ as _43 } from "./chunks/LpTimeField-BTEt0kvL.js";
67
67
  import { _ as _44 } from "./chunks/LpNumberFlow-z4WPZcZu.js";
68
68
  import { _ as _45 } from "./chunks/LpOtpInput-PbeNJ5In.js";
69
- import { _ as _46 } from "./chunks/LpPagination-DehAaJLY.js";
70
- import { _ as _47 } from "./chunks/LpPasswordInput-BK25_vNG.js";
71
- import { _ as _48 } from "./chunks/LpPie-Coa2GMHt.js";
72
- import { _ as _49 } from "./chunks/LpPhoneInput-Bxg7a_qD.js";
69
+ import { _ as _46 } from "./chunks/LpPagination-BFl0I7tL.js";
70
+ import { _ as _47 } from "./chunks/LpPasswordInput-C1G4k_r0.js";
71
+ import { _ as _48 } from "./chunks/LpPie-B2deu8CI.js";
72
+ import { _ as _49 } from "./chunks/LpPhoneInput-CZrpVxla.js";
73
73
  import { filterCountries, flagEmoji, loadCountries, matchCountryByValue } from "./components/countries.js";
74
74
  import { _ as _50 } from "./chunks/LpPopover-DCKeqiVn.js";
75
75
  import { _ as _51 } from "./chunks/LpProgress-CBU1iI69.js";
@@ -77,41 +77,42 @@ import { _ as _52 } from "./chunks/LpRadio-CWA5Eb3M.js";
77
77
  import { _ as _53 } from "./chunks/LpRadioGroup-CCn-Q2_c.js";
78
78
  import { _ as _54 } from "./chunks/LpRollingText-DB7upf-5.js";
79
79
  import { _ as _55 } from "./chunks/LpScrollArea-Hz3-JWUG.js";
80
- import { _ as _56 } from "./chunks/LpSegmented-DbrUjuSA.js";
81
- import { _ as _57 } from "./chunks/LpSection-B19VPYmr.js";
82
- import { _ as _58 } from "./chunks/LpSelect-DynjWK1A.js";
80
+ import { _ as _56 } from "./chunks/LpSegmented-DslFku0N.js";
81
+ import { _ as _57 } from "./chunks/LpSection-BAkbf0OK.js";
82
+ import { _ as _58 } from "./chunks/LpSelect-C4OXN_q3.js";
83
83
  import { _ as _59 } from "./chunks/LpServiceNode-D8uJ8sGk.js";
84
84
  import { _ as _60 } from "./chunks/LpShift-DXNsauQZ.js";
85
+ import { _ as _61 } from "./chunks/LpSwap-D82jiecV.js";
85
86
  import { default as default11 } from "./components/LpShortcutsDialog.vue.js";
86
- import { _ as _61 } from "./chunks/LpSidebar-CKamWtPo.js";
87
- import { _ as _62 } from "./chunks/LpSkeleton-BB6XIV-w.js";
88
- import { _ as _63 } from "./chunks/LpSlider-Cuzmrd7p.js";
89
- import { _ as _64 } from "./chunks/LpRangeSlider-C1yF9-nP.js";
90
- import { _ as _65 } from "./chunks/LpVideoBackdrop-qWRYBOTQ.js";
87
+ import { _ as _62 } from "./chunks/LpSidebar-D8tub3bt.js";
88
+ import { _ as _63 } from "./chunks/LpSkeleton-BB6XIV-w.js";
89
+ import { _ as _64 } from "./chunks/LpSlider-Cuzmrd7p.js";
90
+ import { _ as _65 } from "./chunks/LpRangeSlider-C1yF9-nP.js";
91
+ import { _ as _66 } from "./chunks/LpVideoBackdrop-qWRYBOTQ.js";
91
92
  import { formatClipTime, isNativeLoop, planLoop, seamProgress, seamReached } from "./components/videoBackdrop.js";
92
- import { _ as _66 } from "./chunks/LpSparkline-CB80N8SJ.js";
93
- import { _ as _67 } from "./chunks/LpStat-BS2TEXYK.js";
94
- import { _ as _68 } from "./chunks/LpStepper-BSglWF45.js";
95
- import { _ as _69 } from "./chunks/LpSwitch-DG2AhXIL.js";
93
+ import { _ as _67 } from "./chunks/LpSparkline-CB80N8SJ.js";
94
+ import { _ as _68 } from "./chunks/LpStat-oYk6V1LZ.js";
95
+ import { _ as _69 } from "./chunks/LpStepper-YgHGzgfD.js";
96
+ import { _ as _70 } from "./chunks/LpSwitch-DG2AhXIL.js";
96
97
  import { default as default12 } from "./components/LpTable.vue.js";
97
98
  import { compareValues } from "./components/tableSort.js";
98
- import { _ as _70 } from "./chunks/LpTableOfContents-DYuqkByy.js";
99
- import { _ as _71 } from "./chunks/LpTabs-D01b8jBI.js";
100
- import { _ as _72 } from "./chunks/LpTagsInput-CHbQoAAA.js";
99
+ import { _ as _71 } from "./chunks/LpTableOfContents-DYuqkByy.js";
100
+ import { _ as _72 } from "./chunks/LpTabs-00v3VQx4.js";
101
+ import { _ as _73 } from "./chunks/LpTagsInput-Sc56iy_j.js";
101
102
  import { addTags, splitTags } from "./components/tags.js";
102
- import { _ as _73 } from "./chunks/LpTextarea-Bz2IWhTH.js";
103
- import { _ as _74 } from "./chunks/LpThemeSwitcher-CbzL6ipO.js";
104
- import { _ as _75 } from "./chunks/LpTilt-B7KHX1zH.js";
105
- import { _ as _76 } from "./chunks/LpToaster-C9EacEfR.js";
106
- import { _ as _77 } from "./chunks/LpTooltip-suFCM34F.js";
107
- import { _ as _78 } from "./chunks/LpTour-D7m9ZxNk.js";
103
+ import { _ as _74 } from "./chunks/LpTextarea-CQZccQI3.js";
104
+ import { _ as _75 } from "./chunks/LpThemeSwitcher-ZFFftBQn.js";
105
+ import { _ as _76 } from "./chunks/LpTilt-B7KHX1zH.js";
106
+ import { _ as _77 } from "./chunks/LpToaster-D3OisETH.js";
107
+ import { _ as _78 } from "./chunks/LpTooltip-suFCM34F.js";
108
+ import { _ as _79 } from "./chunks/LpTour-C29-1wha.js";
108
109
  import { holeOf, openContextMenu, panelsAround } from "./components/tour.js";
109
- import { _ as _79 } from "./chunks/LpHintLayer-B5-6FyEf.js";
110
- import { _ as _80 } from "./chunks/LpHints-BqoZXHZk.js";
111
- import { createHintSystem, hintKey, hintSummary, localHintStorage, provideHintSystem, useHintSystem } from "./composables/useHintSystem.js";
112
- import { _ as _81 } from "./chunks/LpTooltipProvider-CftjV7Xc.js";
113
- import { _ as _82 } from "./chunks/LpTopologyCanvas-6ozNrQKh.js";
114
- import { _ as _83 } from "./chunks/LpUptimeBar-B4ltCfno.js";
110
+ import { _ as _80 } from "./chunks/LpHintLayer-DsclGYcD.js";
111
+ import { _ as _81 } from "./chunks/LpHints-BTpvisgP.js";
112
+ import { HINT_SIGNALS, contextMenuTip, createHintSystem, hintKey, hintSummary, localHintStorage, paletteTip, provideHintSystem, runningHintSystem, useHintSystem } from "./composables/useHintSystem.js";
113
+ import { _ as _82 } from "./chunks/LpTooltipProvider-CftjV7Xc.js";
114
+ import { _ as _83 } from "./chunks/LpTopologyCanvas-6ozNrQKh.js";
115
+ import { _ as _84 } from "./chunks/LpUptimeBar-B4ltCfno.js";
115
116
  import { deserializeLayout, serializeLayout } from "./layout/tree.js";
116
117
  import { addLeaf, addTab, countBlocks, countLeaves, makeLayout, moveLeaf, removeBlock, removeLeaf, reorderTab, resizeAt, setActiveTab } from "./layout/tree.js";
117
118
  import { blockTitle, defineBlocks } from "./layout/registry.js";
@@ -145,7 +146,7 @@ import { useShift } from "./composables/useShift.js";
145
146
  import { useTilt } from "./composables/useTilt.js";
146
147
  import { useZoomPan } from "./composables/useZoomPan.js";
147
148
  import { useToast } from "./composables/useToast.js";
148
- import { _ as _84 } from "./chunks/LpThemeProvider-CQ2jC9TA.js";
149
+ import { _ as _85 } from "./chunks/LpThemeProvider-CQ2jC9TA.js";
149
150
  import { isInternalHref, resolveLink } from "./components/link.js";
150
151
  function defineTheme(base, overrides = {}) {
151
152
  const src = typeof base === "string" ? presets[base] : base;
@@ -184,6 +185,7 @@ export {
184
185
  DEFAULT_SWATCHES,
185
186
  FIELD_NOTICE_MS,
186
187
  G as GLASS_BACKDROP_ATTR,
188
+ HINT_SIGNALS,
187
189
  LP_CONFIG,
188
190
  LP_FIELD,
189
191
  _ as LayoutCanvas,
@@ -217,8 +219,8 @@ export {
217
219
  _30 as LpFieldNotice,
218
220
  _29 as LpFileTree,
219
221
  _31 as LpFormField,
220
- _79 as LpHintLayer,
221
- _80 as LpHints,
222
+ _80 as LpHintLayer,
223
+ _81 as LpHints,
222
224
  _32 as LpIcon,
223
225
  default10 as LpImageEditor,
224
226
  _33 as LpInfraNode,
@@ -249,7 +251,7 @@ export {
249
251
  _52 as LpRadio,
250
252
  _53 as LpRadioGroup,
251
253
  _23 as LpRangeCalendar,
252
- _64 as LpRangeSlider,
254
+ _65 as LpRangeSlider,
253
255
  _54 as LpRollingText,
254
256
  _55 as LpScrollArea,
255
257
  _57 as LpSection,
@@ -258,29 +260,30 @@ export {
258
260
  _59 as LpServiceNode,
259
261
  _60 as LpShift,
260
262
  default11 as LpShortcutsDialog,
261
- _61 as LpSidebar,
262
- _62 as LpSkeleton,
263
- _63 as LpSlider,
264
- _66 as LpSparkline,
265
- _67 as LpStat,
266
- _68 as LpStepper,
267
- _69 as LpSwitch,
263
+ _62 as LpSidebar,
264
+ _63 as LpSkeleton,
265
+ _64 as LpSlider,
266
+ _67 as LpSparkline,
267
+ _68 as LpStat,
268
+ _69 as LpStepper,
269
+ _61 as LpSwap,
270
+ _70 as LpSwitch,
268
271
  default12 as LpTable,
269
- _70 as LpTableOfContents,
270
- _71 as LpTabs,
271
- _72 as LpTagsInput,
272
- _73 as LpTextarea,
273
- _84 as LpThemeProvider,
274
- _74 as LpThemeSwitcher,
275
- _75 as LpTilt,
272
+ _71 as LpTableOfContents,
273
+ _72 as LpTabs,
274
+ _73 as LpTagsInput,
275
+ _74 as LpTextarea,
276
+ _85 as LpThemeProvider,
277
+ _75 as LpThemeSwitcher,
278
+ _76 as LpTilt,
276
279
  _43 as LpTimeField,
277
- _76 as LpToaster,
278
- _77 as LpTooltip,
279
- _81 as LpTooltipProvider,
280
- _82 as LpTopologyCanvas,
281
- _78 as LpTour,
282
- _83 as LpUptimeBar,
283
- _65 as LpVideoBackdrop,
280
+ _77 as LpToaster,
281
+ _78 as LpTooltip,
282
+ _82 as LpTooltipProvider,
283
+ _83 as LpTopologyCanvas,
284
+ _79 as LpTour,
285
+ _84 as LpUptimeBar,
286
+ _66 as LpVideoBackdrop,
284
287
  N as NO_BACKDROP_ATTR,
285
288
  OSM_TILES,
286
289
  T as THEME_COOKIE,
@@ -314,6 +317,7 @@ export {
314
317
  compareValues,
315
318
  computeStats,
316
319
  confirm,
320
+ contextMenuTip,
317
321
  countBlocks,
318
322
  countLeaves,
319
323
  countLevels,
@@ -388,6 +392,7 @@ export {
388
392
  k as normalizeTheme,
389
393
  opaqueCss,
390
394
  openContextMenu,
395
+ paletteTip,
391
396
  panelsAround,
392
397
  parseColor,
393
398
  parseCommandQuery,
@@ -424,6 +429,7 @@ export {
424
429
  rgbToHsv,
425
430
  ringWindow,
426
431
  o as rose,
432
+ runningHintSystem,
427
433
  sameRange,
428
434
  scrollParent,
429
435
  scrollToElement,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.59.0",
3
+ "version": "0.61.0",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -30,6 +30,7 @@
30
30
  "./css": "./src/index.css",
31
31
  "./tokens.css": "./src/tokens/tokens.css",
32
32
  "./scrollbar.css": "./src/tokens/scrollbar.css",
33
+ "./selection.css": "./src/tokens/selection.css",
33
34
  "./canvas.css": "./src/canvas.css",
34
35
  "./package.json": "./package.json",
35
36
  "./dist/*.js": {
@@ -80,6 +80,7 @@ export const COMPONENT_NAMES = [
80
80
  "LpSparkline",
81
81
  "LpStat",
82
82
  "LpStepper",
83
+ "LpSwap",
83
84
  "LpSwitch",
84
85
  "LpTable",
85
86
  "LpTableOfContents",