@leavepulse/ui 0.12.0 → 0.14.6

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 (162) hide show
  1. package/dist/assets/LpCommandPalette-D315B47-.css +16 -0
  2. package/dist/chunks/LayoutCanvas-Dd20boUG.js +50 -0
  3. package/dist/chunks/LayoutNode-DGpZA9LX.js +225 -0
  4. package/dist/chunks/LpAlert-BAYHDSS1.js +69 -0
  5. package/dist/chunks/LpAppShell-DBTsNQaM.js +170 -0
  6. package/dist/chunks/LpAutocomplete-B9uoCs4t.js +196 -0
  7. package/dist/chunks/LpAvatar-B1Ez0ZAx.js +88 -0
  8. package/dist/chunks/LpBadge-CXzBPnwO.js +42 -0
  9. package/dist/chunks/LpBreadcrumbs-B7Aqatzw.js +42 -0
  10. package/dist/chunks/LpButton-5VXXCjwF.js +101 -0
  11. package/dist/chunks/LpCalendar-B7ZL0ty3.js +150 -0
  12. package/dist/chunks/LpCard-1yvWT9fx.js +66 -0
  13. package/dist/chunks/LpCheckbox-BO0zuuPh.js +55 -0
  14. package/dist/chunks/LpCodeBlock-CSiOSPs8.js +253 -0
  15. package/dist/chunks/LpConfirmDialog-KLtTtCiT.js +62 -0
  16. package/dist/chunks/LpContextMenu-D0mzXqA7.js +151 -0
  17. package/dist/chunks/LpDatePicker-dY2q4dr4.js +122 -0
  18. package/dist/chunks/LpDisclosure-DP6yfgfM.js +76 -0
  19. package/dist/chunks/LpDivider-CUX46KR0.js +43 -0
  20. package/dist/chunks/LpDrawer-Ce6g9ZMr.js +310 -0
  21. package/dist/chunks/LpDropdownMenu-DJpoqRCb.js +65 -0
  22. package/dist/chunks/LpEmptyState-CrfyRJUG.js +47 -0
  23. package/dist/chunks/LpFormField-Bn-ZwC6z.js +47 -0
  24. package/dist/chunks/LpIcon-CCnX5_2j.js +41 -0
  25. package/dist/chunks/LpInfraNode-C_PHcthC.js +99 -0
  26. package/dist/chunks/LpInput-BauZRyzm.js +136 -0
  27. package/dist/chunks/LpLaneNode-HtnQf2FF.js +33 -0
  28. package/dist/chunks/LpLink-DHwOEp4e.js +36 -0
  29. package/dist/chunks/LpLogViewer-hC0OKkeE.js +482 -0
  30. package/dist/chunks/LpModal-CWoOExzT.js +128 -0
  31. package/dist/chunks/LpNotificationBell-BDy0tQwr.js +232 -0
  32. package/dist/chunks/LpNumberField-C5ar-OwE.js +55 -0
  33. package/dist/chunks/LpOtpInput-DqaT0Z75.js +65 -0
  34. package/dist/chunks/LpPagination-CeGuNe_q.js +132 -0
  35. package/dist/chunks/LpPasswordInput-DIHFw4u0.js +64 -0
  36. package/dist/chunks/LpPhoneInput-LQvVFGMw.js +199 -0
  37. package/dist/chunks/LpPopover-8268UmlC.js +54 -0
  38. package/dist/chunks/LpProgress-BhI0IbjC.js +37 -0
  39. package/dist/chunks/LpRadio-CL-pI0_O.js +39 -0
  40. package/dist/chunks/LpRadioGroup-B4yDTmi6.js +52 -0
  41. package/dist/chunks/LpScrollArea-K1x-azgY.js +67 -0
  42. package/dist/chunks/LpSegmented-BmpanyAo.js +74 -0
  43. package/dist/chunks/LpSelect-DznhPEWX.js +222 -0
  44. package/dist/chunks/LpServiceNode-Dc-Ut5RS.js +51 -0
  45. package/dist/chunks/LpSidebar-BPQabjae.js +152 -0
  46. package/dist/chunks/LpSidebarNav-CpF7rZxx.js +126 -0
  47. package/dist/chunks/LpSkeleton-eSFIo4kD.js +22 -0
  48. package/dist/chunks/LpSlider-B1SF3pRV.js +53 -0
  49. package/dist/chunks/LpStat-CdbEFOvn.js +88 -0
  50. package/dist/chunks/LpStepper-5dFTrW21.js +53 -0
  51. package/dist/chunks/LpSwitch-v6fnccSM.js +28 -0
  52. package/dist/chunks/LpTable-CJ4Zt1UH.js +229 -0
  53. package/dist/chunks/LpTableOfContents-CjvxPMpU.js +155 -0
  54. package/dist/chunks/LpTabs-D7aTVPOb.js +115 -0
  55. package/dist/chunks/LpTextarea-CRAkhemZ.js +44 -0
  56. package/dist/chunks/LpThemeSwitcher-BgWwfkxs.js +601 -0
  57. package/dist/chunks/LpTilt-DuyKbpkA.js +49 -0
  58. package/dist/chunks/LpToaster-gDB1EaU3.js +196 -0
  59. package/dist/chunks/LpTooltip-CIwoRCag.js +49 -0
  60. package/dist/chunks/LpTopologyCanvas-DVwyQfKa.js +237 -0
  61. package/dist/chunks/LpUptimeBar-CB366k0O.js +127 -0
  62. package/dist/component-names.d.ts +1 -1
  63. package/dist/components/LayoutCanvas.vue.js +4 -0
  64. package/dist/components/LayoutNode.vue.js +4 -0
  65. package/dist/components/LpAlert.vue.js +4 -0
  66. package/dist/components/LpAppShell.vue.js +4 -0
  67. package/dist/components/LpAutocomplete.vue.js +4 -0
  68. package/dist/components/LpAvatar.vue.js +4 -0
  69. package/dist/components/LpBadge.vue.js +4 -0
  70. package/dist/components/LpBreadcrumbs.vue.js +4 -0
  71. package/dist/components/LpButton.vue.js +4 -0
  72. package/dist/components/LpCalendar.vue.js +4 -0
  73. package/dist/components/LpCard.vue.js +4 -0
  74. package/dist/components/LpCheckbox.vue.js +4 -0
  75. package/dist/components/LpCodeBlock.vue.js +4 -0
  76. package/dist/components/LpCommandPalette.vue.js +310 -0
  77. package/dist/components/LpConfirmDialog.vue.js +4 -0
  78. package/dist/components/LpContextMenu.vue.d.ts +7 -0
  79. package/dist/components/LpContextMenu.vue.js +4 -0
  80. package/dist/components/LpDatePicker.vue.js +4 -0
  81. package/dist/components/LpDisclosure.vue.js +4 -0
  82. package/dist/components/LpDivider.vue.js +4 -0
  83. package/dist/components/LpDrawer.vue.d.ts +8 -0
  84. package/dist/components/LpDrawer.vue.js +4 -0
  85. package/dist/components/LpDropdownMenu.vue.js +4 -0
  86. package/dist/components/LpEmptyState.vue.js +4 -0
  87. package/dist/components/LpFormField.vue.js +4 -0
  88. package/dist/components/LpIcon.vue.js +4 -0
  89. package/dist/components/LpInfraNode.vue.js +4 -0
  90. package/dist/components/LpInput.vue.js +4 -0
  91. package/dist/components/LpLaneNode.vue.js +4 -0
  92. package/dist/components/LpLink.vue.js +4 -0
  93. package/dist/components/LpLogViewer.vue.js +4 -0
  94. package/dist/components/LpModal.vue.js +4 -0
  95. package/dist/components/LpNotificationBell.vue.js +4 -0
  96. package/dist/components/LpNumberField.vue.js +4 -0
  97. package/dist/components/LpOtpInput.vue.js +4 -0
  98. package/dist/components/LpPagination.vue.js +4 -0
  99. package/dist/components/LpPasswordInput.vue.js +4 -0
  100. package/dist/components/LpPhoneInput.vue.js +4 -0
  101. package/dist/components/LpPopover.vue.js +4 -0
  102. package/dist/components/LpProgress.vue.js +4 -0
  103. package/dist/components/LpRadio.vue.js +4 -0
  104. package/dist/components/LpRadioGroup.vue.js +4 -0
  105. package/dist/components/LpScrollArea.vue.d.ts +2 -2
  106. package/dist/components/LpScrollArea.vue.js +4 -0
  107. package/dist/components/LpSegmented.vue.js +4 -0
  108. package/dist/components/LpSelect.vue.d.ts +2 -0
  109. package/dist/components/LpSelect.vue.js +4 -0
  110. package/dist/components/LpServiceNode.vue.js +4 -0
  111. package/dist/components/LpSidebar.vue.js +4 -0
  112. package/dist/components/LpSidebarNav.vue.js +4 -0
  113. package/dist/components/LpSkeleton.vue.js +4 -0
  114. package/dist/components/LpSlider.vue.js +4 -0
  115. package/dist/components/LpStat.vue.js +4 -0
  116. package/dist/components/LpStepper.vue.js +4 -0
  117. package/dist/components/LpSwitch.vue.js +4 -0
  118. package/dist/components/LpTable.vue.js +4 -0
  119. package/dist/components/LpTableOfContents.vue.js +4 -0
  120. package/dist/components/LpTabs.vue.d.ts +4 -2
  121. package/dist/components/LpTabs.vue.js +4 -0
  122. package/dist/components/LpTextarea.vue.js +4 -0
  123. package/dist/components/LpThemeSwitcher.vue.js +4 -0
  124. package/dist/components/LpTilt.vue.d.ts +31 -0
  125. package/dist/components/LpTilt.vue.js +4 -0
  126. package/dist/components/LpToaster.vue.js +4 -0
  127. package/dist/components/LpTooltip.vue.js +4 -0
  128. package/dist/components/LpTopologyCanvas.vue.js +4 -0
  129. package/dist/components/LpUptimeBar.vue.js +4 -0
  130. package/dist/components/codeHighlight.js +230 -0
  131. package/dist/{countries-data-9rgqJWHo.js → components/countries-data.js} +2 -2
  132. package/dist/components/countries.js +38 -0
  133. package/dist/components/dropdown.js +14 -0
  134. package/dist/components/sidebar.js +1 -0
  135. package/dist/composables/useInputFilter.js +44 -0
  136. package/dist/composables/usePillTransition.js +11 -0
  137. package/dist/composables/useTilt.d.ts +23 -0
  138. package/dist/composables/useTilt.js +57 -0
  139. package/dist/composables/useToast.d.ts +2 -0
  140. package/dist/composables/useToast.js +49 -0
  141. package/dist/index.d.ts +3 -0
  142. package/dist/index.js +197 -17596
  143. package/dist/layout/registry.js +10 -0
  144. package/dist/layout/tree.js +192 -0
  145. package/dist/layout/useLayout.js +61 -0
  146. package/package.json +5 -3
  147. package/src/component-names.ts +1 -0
  148. package/src/components/LpContextMenu.vue +14 -4
  149. package/src/components/LpDrawer.vue +29 -1
  150. package/src/components/LpLogViewer.vue +180 -31
  151. package/src/components/LpScrollArea.vue +20 -15
  152. package/src/components/LpSelect.vue +0 -0
  153. package/src/components/LpSidebar.vue +5 -2
  154. package/src/components/LpTabs.vue +19 -6
  155. package/src/components/LpThemeSwitcher.vue +13 -2
  156. package/src/components/LpTilt.vue +61 -0
  157. package/src/components/LpToaster.vue +11 -4
  158. package/src/composables/useTilt.ts +103 -0
  159. package/src/composables/useToast.ts +2 -0
  160. package/src/index.ts +3 -0
  161. package/src/nuxt.ts +10 -1
  162. package/dist/index.css +0 -1
@@ -0,0 +1,196 @@
1
+ import { defineComponent, ref, watch, onBeforeUnmount, openBlock, createBlock, unref, withCtx, createElementBlock, Fragment, renderList, normalizeClass, createElementVNode, createVNode, createTextVNode, toDisplayString, createCommentVNode, withModifiers, normalizeStyle, Teleport } from "vue";
2
+ import { ToastProvider, ToastRoot, ToastTitle, ToastDescription, ToastViewport } from "reka-ui";
3
+ import { useToast } from "../composables/useToast.js";
4
+ import { CLOSE_ICON } from "../components/dropdown.js";
5
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
6
+ const _hoisted_1 = { class: "flex items-start gap-3 p-3.5" };
7
+ const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col gap-0.5" };
8
+ const _hoisted_3 = ["onClick"];
9
+ const _hoisted_4 = ["onClick"];
10
+ const _sfc_main = /* @__PURE__ */ defineComponent({
11
+ __name: "LpToaster",
12
+ setup(__props) {
13
+ const { queue, dismiss } = useToast();
14
+ const closing = ref(/* @__PURE__ */ new Set());
15
+ function beginClose(id) {
16
+ if (closing.value.has(id)) return;
17
+ closing.value = new Set(closing.value).add(id);
18
+ window.setTimeout(() => finishClose(id), 220);
19
+ }
20
+ function finishClose(id) {
21
+ if (!closing.value.has(id)) return;
22
+ const next = new Set(closing.value);
23
+ next.delete(id);
24
+ closing.value = next;
25
+ dismiss(id);
26
+ }
27
+ function onAnimEnd(e, id) {
28
+ if (e.animationName === "toast-out") finishClose(id);
29
+ }
30
+ const variantIcon = {
31
+ info: "lucide:info",
32
+ success: "lucide:circle-check",
33
+ warning: "lucide:triangle-alert",
34
+ error: "lucide:circle-x"
35
+ };
36
+ const variantColor = {
37
+ info: "text-brand",
38
+ success: "text-action",
39
+ warning: "text-accent",
40
+ error: "text-danger"
41
+ };
42
+ const variantBar = {
43
+ info: "bg-brand",
44
+ success: "bg-action",
45
+ warning: "bg-accent",
46
+ error: "bg-danger"
47
+ };
48
+ const pausedAt = /* @__PURE__ */ new Map();
49
+ const now = ref(Date.now());
50
+ let timer = null;
51
+ function startTimer() {
52
+ if (timer === null) timer = setInterval(() => now.value = Date.now(), 80);
53
+ }
54
+ function stopTimer() {
55
+ if (timer !== null) {
56
+ clearInterval(timer);
57
+ timer = null;
58
+ }
59
+ }
60
+ watch(
61
+ () => queue.length,
62
+ () => {
63
+ for (const id of pausedAt.keys()) {
64
+ if (!queue.some((t) => t.id === id)) pausedAt.delete(id);
65
+ }
66
+ if (closing.value.size) {
67
+ const live = new Set([...closing.value].filter((id) => queue.some((t) => t.id === id)));
68
+ if (live.size !== closing.value.size) closing.value = live;
69
+ }
70
+ if (queue.some((t) => t.dismissAt !== null)) startTimer();
71
+ else stopTimer();
72
+ },
73
+ { immediate: true }
74
+ );
75
+ onBeforeUnmount(stopTimer);
76
+ function onPause(t) {
77
+ pausedAt.set(t.id, now.value);
78
+ }
79
+ function onResume(t) {
80
+ const since = pausedAt.get(t.id);
81
+ if (since !== void 0 && t.dismissAt !== null) {
82
+ t.dismissAt += Date.now() - since;
83
+ }
84
+ pausedAt.delete(t.id);
85
+ }
86
+ function progress(t) {
87
+ if (!t.dismissAt || t.duration <= 0) return 0;
88
+ const at = pausedAt.get(t.id) ?? now.value;
89
+ const remaining = t.dismissAt - at;
90
+ return Math.max(0, Math.min(100, remaining / t.duration * 100));
91
+ }
92
+ async function runClick(t) {
93
+ if (t.onClick) {
94
+ await t.onClick();
95
+ beginClose(t.id);
96
+ }
97
+ }
98
+ async function runAction(t, action) {
99
+ await action.onClick();
100
+ beginClose(t.id);
101
+ }
102
+ return (_ctx, _cache) => {
103
+ return openBlock(), createBlock(unref(ToastProvider), null, {
104
+ default: withCtx(() => [
105
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(queue), (t) => {
106
+ return openBlock(), createBlock(unref(ToastRoot), {
107
+ key: t.id,
108
+ open: !closing.value.has(t.id),
109
+ duration: t.duration,
110
+ class: normalizeClass(["pointer-events-auto relative overflow-hidden rounded-card border border-line bg-surface-raised shadow-panel data-[state=open]:animate-[toast-in_200ms_var(--ease-emphasized)] data-[state=closed]:animate-[toast-out_140ms_ease]", { "cursor-pointer": t.onClick }]),
111
+ "onUpdate:open": (open) => !open && beginClose(t.id),
112
+ onAnimationend: (e) => onAnimEnd(e, t.id),
113
+ onPause: ($event) => onPause(t),
114
+ onResume: ($event) => onResume(t),
115
+ onClick: ($event) => runClick(t)
116
+ }, {
117
+ default: withCtx(() => [
118
+ createElementVNode("div", _hoisted_1, [
119
+ createVNode(_sfc_main$1, {
120
+ name: variantIcon[t.variant],
121
+ size: 18,
122
+ class: normalizeClass(["mt-0.5 shrink-0", variantColor[t.variant]])
123
+ }, null, 8, ["name", "class"]),
124
+ createElementVNode("div", _hoisted_2, [
125
+ t.title ? (openBlock(), createBlock(unref(ToastTitle), {
126
+ key: 0,
127
+ class: "text-sm font-semibold text-ink"
128
+ }, {
129
+ default: withCtx(() => [
130
+ createTextVNode(toDisplayString(t.title), 1)
131
+ ]),
132
+ _: 2
133
+ }, 1024)) : createCommentVNode("", true),
134
+ createVNode(unref(ToastDescription), { class: "break-words text-xs text-muted" }, {
135
+ default: withCtx(() => [
136
+ createTextVNode(toDisplayString(t.message), 1)
137
+ ]),
138
+ _: 2
139
+ }, 1024),
140
+ t.actions?.length ? (openBlock(), createElementBlock("div", {
141
+ key: 1,
142
+ class: "mt-2 flex flex-wrap gap-2",
143
+ onClick: _cache[0] || (_cache[0] = withModifiers(() => {
144
+ }, ["stop"]))
145
+ }, [
146
+ (openBlock(true), createElementBlock(Fragment, null, renderList(t.actions, (action, i) => {
147
+ return openBlock(), createElementBlock("button", {
148
+ key: i,
149
+ type: "button",
150
+ class: "inline-flex items-center gap-1.5 rounded-control border border-line bg-surface-soft px-2.5 py-1 text-xs font-medium text-ink outline-none transition-[border-color,background-color,scale] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:border-line-strong hover:bg-surface-soft/70 active:scale-95 motion-reduce:active:scale-100 focus-visible:ring-2 focus-visible:ring-ring",
151
+ onClick: ($event) => runAction(t, action)
152
+ }, [
153
+ action.icon ? (openBlock(), createBlock(_sfc_main$1, {
154
+ key: 0,
155
+ name: action.icon,
156
+ size: 14
157
+ }, null, 8, ["name"])) : createCommentVNode("", true),
158
+ createTextVNode(" " + toDisplayString(action.label), 1)
159
+ ], 8, _hoisted_3);
160
+ }), 128))
161
+ ])) : createCommentVNode("", true)
162
+ ]),
163
+ createElementVNode("button", {
164
+ type: "button",
165
+ class: "group -mr-1 -mt-1 rounded-md p-1 text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink",
166
+ "aria-label": "Dismiss",
167
+ onClick: withModifiers(($event) => beginClose(t.id), ["stop"])
168
+ }, [
169
+ createVNode(_sfc_main$1, {
170
+ name: "lucide:x",
171
+ size: 16,
172
+ class: normalizeClass(unref(CLOSE_ICON))
173
+ }, null, 8, ["class"])
174
+ ], 8, _hoisted_4)
175
+ ]),
176
+ t.dismissAt ? (openBlock(), createElementBlock("div", {
177
+ key: 0,
178
+ class: normalizeClass(["absolute inset-x-0 bottom-0 h-0.5 origin-left transition-transform duration-100 ease-linear motion-reduce:transition-none", variantBar[t.variant]]),
179
+ style: normalizeStyle({ transform: `scaleX(${progress(t) / 100})` })
180
+ }, null, 6)) : createCommentVNode("", true)
181
+ ]),
182
+ _: 2
183
+ }, 1032, ["open", "duration", "class", "onUpdate:open", "onAnimationend", "onPause", "onResume", "onClick"]);
184
+ }), 128)),
185
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
186
+ createVNode(unref(ToastViewport), { class: "fixed bottom-0 right-0 z-(--z-toast) flex w-[min(92vw,22rem)] flex-col gap-2 p-4 outline-none" })
187
+ ]))
188
+ ]),
189
+ _: 1
190
+ });
191
+ };
192
+ }
193
+ });
194
+ export {
195
+ _sfc_main as _
196
+ };
@@ -0,0 +1,49 @@
1
+ import { defineComponent, openBlock, createBlock, unref, withCtx, createVNode, renderSlot, normalizeClass, createTextVNode, toDisplayString } from "vue";
2
+ import { TooltipProvider, TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent } from "reka-ui";
3
+ import { PANEL_SURFACE, TOOLTIP_ANIM } from "../components/dropdown.js";
4
+ const _sfc_main = /* @__PURE__ */ defineComponent({
5
+ __name: "LpTooltip",
6
+ props: {
7
+ content: {},
8
+ sideOffset: {}
9
+ },
10
+ setup(__props) {
11
+ return (_ctx, _cache) => {
12
+ return openBlock(), createBlock(unref(TooltipProvider), { "delay-duration": 200 }, {
13
+ default: withCtx(() => [
14
+ createVNode(unref(TooltipRoot), null, {
15
+ default: withCtx(() => [
16
+ createVNode(unref(TooltipTrigger), { "as-child": "" }, {
17
+ default: withCtx(() => [
18
+ renderSlot(_ctx.$slots, "default")
19
+ ]),
20
+ _: 3
21
+ }),
22
+ createVNode(unref(TooltipPortal), null, {
23
+ default: withCtx(() => [
24
+ createVNode(unref(TooltipContent), {
25
+ "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"])
27
+ }, {
28
+ default: withCtx(() => [
29
+ renderSlot(_ctx.$slots, "content", {}, () => [
30
+ createTextVNode(toDisplayString(__props.content), 1)
31
+ ])
32
+ ]),
33
+ _: 3
34
+ }, 8, ["side-offset", "class"])
35
+ ]),
36
+ _: 3
37
+ })
38
+ ]),
39
+ _: 3
40
+ })
41
+ ]),
42
+ _: 3
43
+ });
44
+ };
45
+ }
46
+ });
47
+ export {
48
+ _sfc_main as _
49
+ };
@@ -0,0 +1,237 @@
1
+ import { defineComponent, markRaw, computed, watch, openBlock, createBlock, unref, withCtx, createVNode, createElementVNode, createElementBlock, Fragment, renderList, createTextVNode, toDisplayString, createCommentVNode } from "vue";
2
+ import { Background } from "@vue-flow/background";
3
+ import { Controls } from "@vue-flow/controls";
4
+ import { MarkerType, useVueFlow, VueFlow, SelectionMode, Panel } from "@vue-flow/core";
5
+ import { MiniMap } from "@vue-flow/minimap";
6
+ import { _ as _sfc_main$3 } from "./LpInfraNode-C_PHcthC.js";
7
+ import { _ as _sfc_main$1 } from "./LpLaneNode-HtnQf2FF.js";
8
+ import { _ as _sfc_main$2 } from "./LpServiceNode-Dc-Ut5RS.js";
9
+ const _hoisted_1 = { class: "flex flex-col gap-1.5 rounded-card border border-line bg-surface-overlay/90 px-3 py-2 text-[11px] backdrop-blur" };
10
+ const _hoisted_2 = {
11
+ width: "22",
12
+ height: "6",
13
+ class: "shrink-0",
14
+ "aria-hidden": "true"
15
+ };
16
+ const _hoisted_3 = ["stroke", "stroke-width", "stroke-dasharray"];
17
+ const _sfc_main = /* @__PURE__ */ defineComponent({
18
+ __name: "LpTopologyCanvas",
19
+ props: {
20
+ nodes: {},
21
+ edges: {},
22
+ connectable: { type: Boolean, default: false },
23
+ selectable: { type: Boolean, default: false },
24
+ legend: { type: Boolean, default: true },
25
+ lanes: { default: () => [] }
26
+ },
27
+ emits: ["connect", "node-select", "node-contextmenu", "edge-contextmenu", "pane-click", "selection-change", "update:nodes", "node-drag-stop", "viewport-change"],
28
+ setup(__props, { expose: __expose, emit: __emit }) {
29
+ const props = __props;
30
+ const emit = __emit;
31
+ const nodeTypes = {
32
+ infra: markRaw(_sfc_main$3),
33
+ service: markRaw(_sfc_main$2),
34
+ lane: markRaw(_sfc_main$1)
35
+ };
36
+ const laneNodes = computed(
37
+ () => props.lanes.map(
38
+ (l) => ({
39
+ id: `lane-${l.id}`,
40
+ type: "lane",
41
+ position: { x: l.x, y: l.y },
42
+ data: { label: l.label, accent: l.accent, width: l.width, height: l.height },
43
+ selectable: false,
44
+ draggable: false,
45
+ connectable: false,
46
+ focusable: false,
47
+ zIndex: 0
48
+ })
49
+ )
50
+ );
51
+ const graphNodes = computed(
52
+ () => props.nodes.map((n) => {
53
+ const type = n.type ?? "infra";
54
+ const node = {
55
+ id: n.id,
56
+ type,
57
+ position: n.position,
58
+ data: n.data,
59
+ zIndex: 1,
60
+ ...n.parent ? { parentNode: n.parent } : {}
61
+ };
62
+ if (type === "group") {
63
+ node.style = {
64
+ width: `${n.width ?? 260}px`,
65
+ height: `${n.height ?? 160}px`,
66
+ background: "color-mix(in srgb, var(--color-surface-soft) 60%, transparent)",
67
+ border: "1px solid var(--color-line)",
68
+ borderRadius: "var(--radius-card)",
69
+ opacity: n.data.dimmed ? "0.35" : "1",
70
+ transition: "opacity var(--duration-fast)"
71
+ };
72
+ node.label = n.label ?? n.data.name;
73
+ }
74
+ return node;
75
+ })
76
+ );
77
+ const flowNodes = computed(() => [
78
+ ...laneNodes.value,
79
+ ...graphNodes.value
80
+ ]);
81
+ function edgeCategory(e) {
82
+ return e.category ?? (e.kind === "depends_on" ? "structural" : "network");
83
+ }
84
+ const CATEGORY_COLOR = {
85
+ network: "var(--color-brand)",
86
+ structural: "var(--color-accent)"
87
+ };
88
+ function edgeColor(cat, o) {
89
+ return o === "drift" ? "var(--color-danger)" : CATEGORY_COLOR[cat];
90
+ }
91
+ function edgeDash(cat, o) {
92
+ if (o !== "applied") return "6 5";
93
+ return cat === "structural" ? "1 6" : "0";
94
+ }
95
+ const flowEdges = computed(
96
+ () => props.edges.map((e) => {
97
+ const obs = e.observed ?? "applied";
98
+ const cat = edgeCategory(e);
99
+ const color = edgeColor(cat, obs);
100
+ return {
101
+ id: e.id,
102
+ source: e.source,
103
+ target: e.target,
104
+ type: "default",
105
+ animated: obs !== "applied",
106
+ label: e.kind,
107
+ labelBgStyle: { fill: "var(--color-surface)" },
108
+ labelStyle: { fill: "var(--color-muted-strong)", fontSize: "10px" },
109
+ style: {
110
+ stroke: color,
111
+ strokeWidth: cat === "structural" ? 1.5 : 2,
112
+ strokeDasharray: edgeDash(cat, obs),
113
+ strokeLinecap: "round"
114
+ },
115
+ markerEnd: { type: MarkerType.ArrowClosed, color }
116
+ };
117
+ })
118
+ );
119
+ const {
120
+ onNodeClick,
121
+ onNodeContextMenu,
122
+ onEdgeContextMenu,
123
+ onPaneClick,
124
+ onConnect,
125
+ onNodeDragStop,
126
+ onMoveEnd,
127
+ getSelectedNodes,
128
+ fitView,
129
+ setViewport
130
+ } = useVueFlow();
131
+ onNodeClick(({ node }) => emit("node-select", node.id));
132
+ onNodeDragStop(
133
+ ({ node }) => emit("node-drag-stop", { id: node.id, position: { ...node.position } })
134
+ );
135
+ onMoveEnd(({ flowTransform }) => {
136
+ if (flowTransform)
137
+ emit("viewport-change", {
138
+ zoom: flowTransform.zoom,
139
+ x: flowTransform.x,
140
+ y: flowTransform.y
141
+ });
142
+ });
143
+ watch(
144
+ () => getSelectedNodes.value.map((n) => n.id),
145
+ (ids) => emit("selection-change", ids)
146
+ );
147
+ onNodeContextMenu(({ node, event }) => {
148
+ const e = event;
149
+ e.preventDefault?.();
150
+ emit("node-contextmenu", { id: node.id, x: e.clientX, y: e.clientY });
151
+ });
152
+ const legendItems = [
153
+ { label: "Network", color: CATEGORY_COLOR.network, width: 2, dash: "0" },
154
+ { label: "Depends-on", color: CATEGORY_COLOR.structural, width: 1.5, dash: "1 5" },
155
+ { label: "Pending", color: "var(--color-brand)", width: 2, dash: "6 5" },
156
+ { label: "Drift", color: "var(--color-danger)", width: 2, dash: "6 5" }
157
+ ];
158
+ onEdgeContextMenu(({ edge, event }) => {
159
+ const e = event;
160
+ e.preventDefault?.();
161
+ emit("edge-contextmenu", { id: edge.id, x: e.clientX, y: e.clientY });
162
+ });
163
+ onPaneClick(() => emit("pane-click"));
164
+ onConnect((conn) => emit("connect", conn));
165
+ async function applyViewport(v) {
166
+ await setViewport({ x: v.x, y: v.y, zoom: v.zoom });
167
+ }
168
+ __expose({ fitView, setViewport: applyViewport });
169
+ return (_ctx, _cache) => {
170
+ return openBlock(), createBlock(unref(VueFlow), {
171
+ nodes: flowNodes.value,
172
+ edges: flowEdges.value,
173
+ "node-types": nodeTypes,
174
+ "nodes-connectable": __props.connectable,
175
+ "selection-on-drag": __props.selectable,
176
+ "pan-on-drag": __props.selectable ? [1, 2] : true,
177
+ "selection-key-code": __props.selectable ? true : null,
178
+ "multi-selection-key-code": "Shift",
179
+ "selection-mode": unref(SelectionMode).Partial,
180
+ "default-viewport": { zoom: 0.9 },
181
+ "min-zoom": 0.3,
182
+ "max-zoom": 2,
183
+ "fit-view-on-init": "",
184
+ class: "lp-topology"
185
+ }, {
186
+ default: withCtx(() => [
187
+ createVNode(unref(Background), {
188
+ gap: 22,
189
+ size: 1.4,
190
+ "pattern-color": "var(--color-line-strong)"
191
+ }),
192
+ createVNode(unref(MiniMap), {
193
+ pannable: "",
194
+ zoomable: "",
195
+ "node-color": "var(--color-surface-soft)",
196
+ "mask-color": "rgba(0,0,0,0.55)"
197
+ }),
198
+ createVNode(unref(Controls)),
199
+ __props.legend ? (openBlock(), createBlock(unref(Panel), {
200
+ key: 0,
201
+ position: "top-right"
202
+ }, {
203
+ default: withCtx(() => [
204
+ createElementVNode("div", _hoisted_1, [
205
+ (openBlock(), createElementBlock(Fragment, null, renderList(legendItems, (l) => {
206
+ return createElementVNode("div", {
207
+ key: l.label,
208
+ class: "flex items-center gap-2 text-muted"
209
+ }, [
210
+ (openBlock(), createElementBlock("svg", _hoisted_2, [
211
+ createElementVNode("line", {
212
+ x1: "0",
213
+ y1: "3",
214
+ x2: "22",
215
+ y2: "3",
216
+ stroke: l.color,
217
+ "stroke-width": l.width,
218
+ "stroke-dasharray": l.dash,
219
+ "stroke-linecap": "round"
220
+ }, null, 8, _hoisted_3)
221
+ ])),
222
+ createTextVNode(" " + toDisplayString(l.label), 1)
223
+ ]);
224
+ }), 64))
225
+ ])
226
+ ]),
227
+ _: 1
228
+ })) : createCommentVNode("", true)
229
+ ]),
230
+ _: 1
231
+ }, 8, ["nodes", "edges", "nodes-connectable", "selection-on-drag", "pan-on-drag", "selection-key-code", "selection-mode"]);
232
+ };
233
+ }
234
+ });
235
+ export {
236
+ _sfc_main as _
237
+ };
@@ -0,0 +1,127 @@
1
+ import { defineComponent, computed, openBlock, createElementBlock, toDisplayString, createTextVNode, createElementVNode, createCommentVNode, createVNode, unref, withCtx, Fragment, renderList, createBlock, normalizeStyle, normalizeClass } from "vue";
2
+ import { TooltipProvider, TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent } from "reka-ui";
3
+ import { PANEL_SURFACE, TOOLTIP_ANIM } from "../components/dropdown.js";
4
+ const _hoisted_1 = { class: "flex flex-col gap-1.5" };
5
+ const _hoisted_2 = {
6
+ key: 0,
7
+ class: "flex items-baseline justify-between gap-3 text-xs"
8
+ };
9
+ const _hoisted_3 = {
10
+ key: 0,
11
+ class: "font-medium text-ink"
12
+ };
13
+ const _hoisted_4 = { key: 1 };
14
+ const _hoisted_5 = {
15
+ key: 2,
16
+ class: "tabular-nums text-muted-strong"
17
+ };
18
+ const _hoisted_6 = { class: "flex h-7 items-stretch gap-0.5" };
19
+ const _hoisted_7 = ["aria-label"];
20
+ const _hoisted_8 = { class: "flex items-center gap-1.5" };
21
+ const _hoisted_9 = {
22
+ key: 1,
23
+ class: "flex items-center justify-between text-xs text-muted"
24
+ };
25
+ const _sfc_main = /* @__PURE__ */ defineComponent({
26
+ __name: "LpUptimeBar",
27
+ props: {
28
+ segments: {},
29
+ startLabel: {},
30
+ endLabel: {},
31
+ showUptime: { type: Boolean, default: true },
32
+ title: {},
33
+ colors: {}
34
+ },
35
+ setup(__props) {
36
+ const props = __props;
37
+ const defaultColor = {
38
+ operational: "var(--color-brand)",
39
+ degraded: "var(--color-accent)",
40
+ down: "var(--color-danger)",
41
+ maintenance: "var(--color-action)",
42
+ empty: "var(--color-surface-soft)"
43
+ };
44
+ const colorFor = (status) => props.colors?.[status] ?? defaultColor[status];
45
+ const statusLabel = {
46
+ operational: "Operational",
47
+ degraded: "Degraded",
48
+ down: "Down",
49
+ maintenance: "Maintenance",
50
+ empty: "No data"
51
+ };
52
+ const uptimePct = computed(() => {
53
+ const tracked = props.segments.filter((s) => s.status !== "empty");
54
+ if (!tracked.length) return null;
55
+ const up = tracked.filter((s) => s.status === "operational" || s.status === "maintenance").length;
56
+ return up / tracked.length * 100;
57
+ });
58
+ const uptimeText = computed(() => {
59
+ const v = uptimePct.value;
60
+ if (v == null) return "—";
61
+ return `${Number(v.toFixed(2))}%`;
62
+ });
63
+ return (_ctx, _cache) => {
64
+ return openBlock(), createElementBlock("div", _hoisted_1, [
65
+ __props.showUptime || __props.title ? (openBlock(), createElementBlock("div", _hoisted_2, [
66
+ __props.title ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(__props.title), 1)) : (openBlock(), createElementBlock("span", _hoisted_4)),
67
+ __props.showUptime ? (openBlock(), createElementBlock("span", _hoisted_5, [
68
+ createTextVNode(toDisplayString(uptimeText.value), 1),
69
+ _cache[0] || (_cache[0] = createElementVNode("span", { class: "text-muted" }, " uptime", -1))
70
+ ])) : createCommentVNode("", true)
71
+ ])) : createCommentVNode("", true),
72
+ createVNode(unref(TooltipProvider), { "delay-duration": 120 }, {
73
+ default: withCtx(() => [
74
+ createElementVNode("div", _hoisted_6, [
75
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.segments, (seg, i) => {
76
+ return openBlock(), createBlock(unref(TooltipRoot), { key: i }, {
77
+ default: withCtx(() => [
78
+ createVNode(unref(TooltipTrigger), { "as-child": "" }, {
79
+ default: withCtx(() => [
80
+ createElementVNode("button", {
81
+ type: "button",
82
+ class: normalizeClass(["min-w-0 flex-1 rounded-xs outline-none transition-[scale,opacity] duration-150 hover:scale-y-110 focus-visible:ring-2 focus-visible:ring-ring", seg.status === "empty" ? "opacity-50" : ""]),
83
+ style: normalizeStyle({ backgroundColor: colorFor(seg.status) }),
84
+ "aria-label": seg.label ?? statusLabel[seg.status]
85
+ }, null, 14, _hoisted_7)
86
+ ]),
87
+ _: 2
88
+ }, 1024),
89
+ createVNode(unref(TooltipPortal), null, {
90
+ default: withCtx(() => [
91
+ createVNode(unref(TooltipContent), {
92
+ "side-offset": 6,
93
+ class: normalizeClass([unref(PANEL_SURFACE), unref(TOOLTIP_ANIM), "z-(--z-tooltip) px-2.5 py-1.5 text-xs text-ink"])
94
+ }, {
95
+ default: withCtx(() => [
96
+ createElementVNode("span", _hoisted_8, [
97
+ createElementVNode("span", {
98
+ class: "size-1.5 shrink-0 rounded-full",
99
+ style: normalizeStyle({ backgroundColor: colorFor(seg.status) })
100
+ }, null, 4),
101
+ createTextVNode(" " + toDisplayString(seg.label ?? statusLabel[seg.status]), 1)
102
+ ])
103
+ ]),
104
+ _: 2
105
+ }, 1032, ["class"])
106
+ ]),
107
+ _: 2
108
+ }, 1024)
109
+ ]),
110
+ _: 2
111
+ }, 1024);
112
+ }), 128))
113
+ ])
114
+ ]),
115
+ _: 1
116
+ }),
117
+ __props.startLabel || __props.endLabel ? (openBlock(), createElementBlock("div", _hoisted_9, [
118
+ createElementVNode("span", null, toDisplayString(__props.startLabel), 1),
119
+ createElementVNode("span", null, toDisplayString(__props.endLabel), 1)
120
+ ])) : createCommentVNode("", true)
121
+ ]);
122
+ };
123
+ }
124
+ });
125
+ export {
126
+ _sfc_main as _
127
+ };
@@ -1 +1 @@
1
- export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpCheckbox", "LpCodeBlock", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpEmptyState", "LpFormField", "LpIcon", "LpInfraNode", "LpInput", "LpLaneNode", "LpLink", "LpLogViewer", "LpModal", "LpNotificationBell", "LpNumberField", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpScrollArea", "LpSegmented", "LpSelect", "LpServiceNode", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar"];
1
+ export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpCheckbox", "LpCodeBlock", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpEmptyState", "LpFormField", "LpIcon", "LpInfraNode", "LpInput", "LpLaneNode", "LpLink", "LpLogViewer", "LpModal", "LpNotificationBell", "LpNumberField", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpScrollArea", "LpSegmented", "LpSelect", "LpServiceNode", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpTilt", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar"];
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LayoutCanvas-Dd20boUG.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LayoutNode-DGpZA9LX.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpAlert-BAYHDSS1.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpAppShell-DBTsNQaM.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpAutocomplete-B9uoCs4t.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpAvatar-B1Ez0ZAx.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpBadge-CXzBPnwO.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpBreadcrumbs-B7Aqatzw.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpButton-5VXXCjwF.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "../chunks/LpCalendar-B7ZL0ty3.js";
2
+ export {
3
+ _sfc_main as default
4
+ };