@leavepulse/ui 0.12.0 → 0.14.4

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 (160) 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-C22642JK.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-CnHtHWHm.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-CBNVhkg0.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-CDBjhXl6.js +469 -0
  30. package/dist/chunks/LpModal-D17Bocq7.js +128 -0
  31. package/dist/chunks/LpNotificationBell-Bm51SkgV.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-CcHul_XS.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-CTUdtX7W.js +152 -0
  46. package/dist/chunks/LpSidebarNav-BRwovIc8.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-PHE6UKor.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.js +4 -0
  106. package/dist/components/LpSegmented.vue.js +4 -0
  107. package/dist/components/LpSelect.vue.d.ts +2 -0
  108. package/dist/components/LpSelect.vue.js +4 -0
  109. package/dist/components/LpServiceNode.vue.js +4 -0
  110. package/dist/components/LpSidebar.vue.js +4 -0
  111. package/dist/components/LpSidebarNav.vue.js +4 -0
  112. package/dist/components/LpSkeleton.vue.js +4 -0
  113. package/dist/components/LpSlider.vue.js +4 -0
  114. package/dist/components/LpStat.vue.js +4 -0
  115. package/dist/components/LpStepper.vue.js +4 -0
  116. package/dist/components/LpSwitch.vue.js +4 -0
  117. package/dist/components/LpTable.vue.js +4 -0
  118. package/dist/components/LpTableOfContents.vue.js +4 -0
  119. package/dist/components/LpTabs.vue.d.ts +4 -2
  120. package/dist/components/LpTabs.vue.js +4 -0
  121. package/dist/components/LpTextarea.vue.js +4 -0
  122. package/dist/components/LpThemeSwitcher.vue.js +4 -0
  123. package/dist/components/LpTilt.vue.d.ts +31 -0
  124. package/dist/components/LpTilt.vue.js +4 -0
  125. package/dist/components/LpToaster.vue.js +4 -0
  126. package/dist/components/LpTooltip.vue.js +4 -0
  127. package/dist/components/LpTopologyCanvas.vue.js +4 -0
  128. package/dist/components/LpUptimeBar.vue.js +4 -0
  129. package/dist/components/codeHighlight.js +230 -0
  130. package/dist/{countries-data-9rgqJWHo.js → components/countries-data.js} +2 -2
  131. package/dist/components/countries.js +38 -0
  132. package/dist/components/dropdown.js +14 -0
  133. package/dist/components/sidebar.js +1 -0
  134. package/dist/composables/useInputFilter.js +44 -0
  135. package/dist/composables/usePillTransition.js +11 -0
  136. package/dist/composables/useTilt.d.ts +23 -0
  137. package/dist/composables/useTilt.js +57 -0
  138. package/dist/composables/useToast.d.ts +2 -0
  139. package/dist/composables/useToast.js +49 -0
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.js +197 -17596
  142. package/dist/layout/registry.js +10 -0
  143. package/dist/layout/tree.js +192 -0
  144. package/dist/layout/useLayout.js +61 -0
  145. package/package.json +5 -3
  146. package/src/component-names.ts +1 -0
  147. package/src/components/LpContextMenu.vue +14 -4
  148. package/src/components/LpDrawer.vue +29 -1
  149. package/src/components/LpLogViewer.vue +161 -31
  150. package/src/components/LpSelect.vue +0 -0
  151. package/src/components/LpSidebar.vue +5 -2
  152. package/src/components/LpTabs.vue +19 -6
  153. package/src/components/LpThemeSwitcher.vue +13 -2
  154. package/src/components/LpTilt.vue +61 -0
  155. package/src/components/LpToaster.vue +11 -4
  156. package/src/composables/useTilt.ts +103 -0
  157. package/src/composables/useToast.ts +2 -0
  158. package/src/index.ts +3 -0
  159. package/src/nuxt.ts +10 -1
  160. package/dist/index.css +0 -1
@@ -0,0 +1,16 @@
1
+
2
+ /* Each result eases in; honours reduced motion. */
3
+ .lp-cmd-item[data-v-d845063e] {
4
+ animation: lp-cmd-in-d845063e 140ms ease-out both;
5
+ }
6
+ @keyframes lp-cmd-in-d845063e {
7
+ from {
8
+ opacity: 0;
9
+ transform: translateY(3px);
10
+ }
11
+ }
12
+ @media (prefers-reduced-motion: reduce) {
13
+ .lp-cmd-item[data-v-d845063e] {
14
+ animation: none;
15
+ }
16
+ }
@@ -0,0 +1,50 @@
1
+ import { defineComponent, ref, openBlock, createElementBlock, createVNode, unref, withCtx, renderSlot, normalizeProps, guardReactiveProps } from "vue";
2
+ import { _ as _sfc_main$1 } from "./LayoutNode-DGpZA9LX.js";
3
+ import { reorderTab, removeBlock, setActiveTab, moveLeaf, resizeAt } from "../layout/tree.js";
4
+ const _hoisted_1 = { class: "flex min-h-0 min-w-0 flex-1" };
5
+ const _sfc_main = /* @__PURE__ */ defineComponent({
6
+ __name: "LayoutCanvas",
7
+ props: {
8
+ modelValue: {},
9
+ edit: { type: Boolean },
10
+ registry: {}
11
+ },
12
+ emits: ["update:modelValue"],
13
+ setup(__props) {
14
+ const props = __props;
15
+ const dragId = ref(null);
16
+ function onDrop(targetId, side) {
17
+ if (dragId.value) moveLeaf(props.modelValue, dragId.value, targetId, side);
18
+ dragId.value = null;
19
+ }
20
+ function onResize(parent, index, delta) {
21
+ resizeAt(parent, index, delta);
22
+ }
23
+ return (_ctx, _cache) => {
24
+ return openBlock(), createElementBlock("div", _hoisted_1, [
25
+ createVNode(_sfc_main$1, {
26
+ node: __props.modelValue,
27
+ "drag-id": dragId.value,
28
+ edit: !!__props.edit,
29
+ registry: __props.registry,
30
+ class: "flex-1",
31
+ onDragstart: _cache[0] || (_cache[0] = (id) => dragId.value = id),
32
+ onDragend: _cache[1] || (_cache[1] = ($event) => dragId.value = null),
33
+ onDrop,
34
+ onSetActive: _cache[2] || (_cache[2] = (leafId, i) => unref(setActiveTab)(__props.modelValue, leafId, i)),
35
+ onRemoveBlock: _cache[3] || (_cache[3] = (leafId, i) => unref(removeBlock)(__props.modelValue, leafId, i)),
36
+ onReorderTab: _cache[4] || (_cache[4] = (leafId, from, to) => unref(reorderTab)(__props.modelValue, leafId, from, to)),
37
+ onResize
38
+ }, {
39
+ block: withCtx((slotProps) => [
40
+ renderSlot(_ctx.$slots, "block", normalizeProps(guardReactiveProps(slotProps)))
41
+ ]),
42
+ _: 3
43
+ }, 8, ["node", "drag-id", "edit", "registry"])
44
+ ]);
45
+ };
46
+ }
47
+ });
48
+ export {
49
+ _sfc_main as _
50
+ };
@@ -0,0 +1,225 @@
1
+ import { defineComponent, ref, computed, resolveComponent, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createVNode, normalizeStyle, withCtx, renderSlot, mergeProps, createElementVNode, createCommentVNode, createBlock, unref, withModifiers, toDisplayString } from "vue";
2
+ import { Motion } from "motion-v";
3
+ import { blockTitle } from "../layout/registry.js";
4
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
5
+ const _hoisted_1 = ["onPointerdown"];
6
+ const _hoisted_2 = {
7
+ key: 1,
8
+ class: "shrink-0 basis-2.5"
9
+ };
10
+ const _hoisted_3 = ["draggable"];
11
+ const _hoisted_4 = ["onClick", "onDragstart", "onDragover", "onDrop"];
12
+ const _hoisted_5 = { class: "truncate" };
13
+ const _hoisted_6 = ["aria-label", "onClick"];
14
+ const _hoisted_7 = { class: "flex min-h-0 min-w-0 flex-1" };
15
+ const _sfc_main = /* @__PURE__ */ defineComponent({
16
+ __name: "LayoutNode",
17
+ props: {
18
+ node: {},
19
+ dragId: {},
20
+ edit: { type: Boolean },
21
+ registry: {}
22
+ },
23
+ emits: ["dragstart", "dragend", "drop", "set-active", "remove-block", "reorder-tab", "resize"],
24
+ setup(__props, { emit: __emit }) {
25
+ const props = __props;
26
+ const emit = __emit;
27
+ const hoverSide = ref(null);
28
+ const tabDrag = ref(null);
29
+ const tabOver = ref(null);
30
+ function onTabDragStart(index, ev) {
31
+ tabDrag.value = index;
32
+ ev.dataTransfer?.setData("text/plain", String(index));
33
+ if (ev.dataTransfer) ev.dataTransfer.effectAllowed = "move";
34
+ }
35
+ function onTabDragOver(index, ev) {
36
+ if (tabDrag.value === null) return;
37
+ ev.preventDefault();
38
+ tabOver.value = index;
39
+ }
40
+ function onTabDrop(index) {
41
+ const from = tabDrag.value;
42
+ tabDrag.value = null;
43
+ tabOver.value = null;
44
+ if (from === null || from === index || !leaf.value) return;
45
+ emit("reorder-tab", leaf.value.id, from, index);
46
+ }
47
+ function onTabDragEnd() {
48
+ tabDrag.value = null;
49
+ tabOver.value = null;
50
+ }
51
+ const hintInset = {
52
+ left: "inset-y-0 left-0 right-1/2",
53
+ right: "inset-y-0 right-0 left-1/2",
54
+ top: "inset-x-0 top-0 bottom-1/2",
55
+ bottom: "inset-x-0 bottom-0 top-1/2",
56
+ center: "inset-[12%]"
57
+ };
58
+ const leaf = computed(() => props.node.kind === "leaf" ? props.node : null);
59
+ const showTabs = computed(() => !!leaf.value && (props.edit || leaf.value.blocks.length > 1));
60
+ const activeBlock = computed(() => leaf.value?.blocks[leaf.value.active] ?? "");
61
+ function tabTitle(id) {
62
+ return props.registry ? blockTitle(props.registry, id) : id;
63
+ }
64
+ function tabIcon(id) {
65
+ return props.registry?.[id]?.icon;
66
+ }
67
+ function tabClosable(id) {
68
+ return props.registry?.[id]?.closable !== false;
69
+ }
70
+ function onDragOver(ev) {
71
+ ev.preventDefault();
72
+ const el = ev.currentTarget;
73
+ const r = el.getBoundingClientRect();
74
+ const px = (ev.clientX - r.left) / r.width;
75
+ const py = (ev.clientY - r.top) / r.height;
76
+ const edge = 0.3;
77
+ if (px < edge) hoverSide.value = "left";
78
+ else if (px > 1 - edge) hoverSide.value = "right";
79
+ else if (py < edge) hoverSide.value = "top";
80
+ else if (py > 1 - edge) hoverSide.value = "bottom";
81
+ else hoverSide.value = "center";
82
+ }
83
+ function startSplitter(ev, parent, index) {
84
+ ev.preventDefault();
85
+ const host = ev.currentTarget.parentElement;
86
+ if (!host) return;
87
+ const rect = host.getBoundingClientRect();
88
+ const horizontal = parent.dir === "row";
89
+ const span = horizontal ? rect.width : rect.height;
90
+ let last = horizontal ? ev.clientX : ev.clientY;
91
+ const move = (e) => {
92
+ const cur = horizontal ? e.clientX : e.clientY;
93
+ emit("resize", parent, index, (cur - last) / span);
94
+ last = cur;
95
+ };
96
+ const up = () => {
97
+ window.removeEventListener("pointermove", move);
98
+ window.removeEventListener("pointerup", up);
99
+ };
100
+ window.addEventListener("pointermove", move);
101
+ window.addEventListener("pointerup", up);
102
+ }
103
+ return (_ctx, _cache) => {
104
+ const _component_LayoutNode = resolveComponent("LayoutNode", true);
105
+ return __props.node.kind === "split" ? (openBlock(), createElementBlock("div", {
106
+ key: 0,
107
+ class: normalizeClass(["flex min-h-0 min-w-0 flex-1", __props.node.dir === "row" ? "flex-row" : "flex-col"])
108
+ }, [
109
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.node.children, (child, i) => {
110
+ return openBlock(), createElementBlock(Fragment, {
111
+ key: child.id
112
+ }, [
113
+ createVNode(_component_LayoutNode, {
114
+ node: child,
115
+ "drag-id": __props.dragId,
116
+ edit: __props.edit,
117
+ registry: __props.registry,
118
+ style: normalizeStyle({ flexGrow: child.size, flexBasis: "0px" }),
119
+ onDragstart: _cache[0] || (_cache[0] = (id) => emit("dragstart", id)),
120
+ onDragend: _cache[1] || (_cache[1] = ($event) => emit("dragend")),
121
+ onDrop: _cache[2] || (_cache[2] = (t, s) => emit("drop", t, s)),
122
+ onSetActive: _cache[3] || (_cache[3] = (l, idx) => emit("set-active", l, idx)),
123
+ onRemoveBlock: _cache[4] || (_cache[4] = (l, idx) => emit("remove-block", l, idx)),
124
+ onReorderTab: _cache[5] || (_cache[5] = (l, from, to) => emit("reorder-tab", l, from, to)),
125
+ onResize: _cache[6] || (_cache[6] = (p, idx, d) => emit("resize", p, idx, d))
126
+ }, {
127
+ block: withCtx((slotProps) => [
128
+ renderSlot(_ctx.$slots, "block", mergeProps({ ref_for: true }, slotProps))
129
+ ]),
130
+ _: 3
131
+ }, 8, ["node", "drag-id", "edit", "registry", "style"]),
132
+ __props.edit && i < __props.node.children.length - 1 ? (openBlock(), createElementBlock("div", {
133
+ key: 0,
134
+ class: normalizeClass(["group relative z-[6] shrink-0 basis-2.5", __props.node.dir === "row" ? "cursor-col-resize" : "cursor-row-resize"]),
135
+ onPointerdown: (e) => startSplitter(e, __props.node, i)
136
+ }, [
137
+ createElementVNode("span", {
138
+ class: normalizeClass(["absolute inset-0 m-auto rounded-full bg-line transition-colors group-hover:bg-brand", __props.node.dir === "row" ? "h-9 w-0.5" : "h-0.5 w-9"])
139
+ }, null, 2)
140
+ ], 42, _hoisted_1)) : i < __props.node.children.length - 1 ? (openBlock(), createElementBlock("div", _hoisted_2)) : createCommentVNode("", true)
141
+ ], 64);
142
+ }), 128))
143
+ ], 2)) : leaf.value ? (openBlock(), createBlock(unref(Motion), {
144
+ key: 1,
145
+ layout: true,
146
+ transition: { type: "spring", stiffness: 520, damping: 42, mass: 0.9 },
147
+ class: normalizeClass(["relative flex min-h-0 min-w-0 flex-col", { "opacity-35": __props.dragId === __props.node.id }])
148
+ }, {
149
+ default: withCtx(() => [
150
+ showTabs.value ? (openBlock(), createElementBlock("div", {
151
+ key: 0,
152
+ class: "flex shrink-0 items-center gap-1 overflow-x-auto border-b border-line px-1 py-1",
153
+ draggable: __props.edit,
154
+ onDragstart: _cache[7] || (_cache[7] = ($event) => emit("dragstart", __props.node.id)),
155
+ onDragend: _cache[8] || (_cache[8] = ($event) => (hoverSide.value = null, emit("dragend")))
156
+ }, [
157
+ (openBlock(true), createElementBlock(Fragment, null, renderList(leaf.value.blocks, (block, i) => {
158
+ return openBlock(), createElementBlock("button", {
159
+ key: block + i,
160
+ type: "button",
161
+ draggable: "true",
162
+ class: normalizeClass(["inline-flex max-w-40 cursor-grab items-center gap-1.5 rounded-control px-2 py-1 text-xs transition-colors active:cursor-grabbing", [
163
+ i === leaf.value.active ? "bg-surface-soft text-ink" : "text-muted hover:bg-surface-soft/60 hover:text-ink",
164
+ tabDrag.value === i ? "opacity-40" : "",
165
+ tabOver.value === i && tabDrag.value !== null && tabDrag.value !== i ? "ring-1 ring-brand" : ""
166
+ ]]),
167
+ onClick: ($event) => emit("set-active", __props.node.id, i),
168
+ onDragstart: withModifiers(($event) => onTabDragStart(i, $event), ["stop"]),
169
+ onDragover: ($event) => onTabDragOver(i, $event),
170
+ onDrop: withModifiers(($event) => onTabDrop(i), ["stop"]),
171
+ onDragend: onTabDragEnd
172
+ }, [
173
+ tabIcon(block) ? (openBlock(), createBlock(_sfc_main$1, {
174
+ key: 0,
175
+ name: tabIcon(block),
176
+ size: 13
177
+ }, null, 8, ["name"])) : createCommentVNode("", true),
178
+ createElementVNode("span", _hoisted_5, toDisplayString(tabTitle(block)), 1),
179
+ __props.edit && tabClosable(block) ? (openBlock(), createElementBlock("span", {
180
+ key: 1,
181
+ class: "grid size-3.5 place-items-center rounded-pill text-muted hover:bg-line hover:text-ink",
182
+ role: "button",
183
+ "aria-label": `Close ${tabTitle(block)}`,
184
+ onClick: withModifiers(($event) => emit("remove-block", __props.node.id, i), ["stop"])
185
+ }, [
186
+ createVNode(_sfc_main$1, {
187
+ name: "lucide:x",
188
+ size: 11
189
+ })
190
+ ], 8, _hoisted_6)) : createCommentVNode("", true)
191
+ ], 42, _hoisted_4);
192
+ }), 128))
193
+ ], 40, _hoisted_3)) : createCommentVNode("", true),
194
+ createElementVNode("div", _hoisted_7, [
195
+ renderSlot(_ctx.$slots, "block", {
196
+ block: activeBlock.value,
197
+ leafId: __props.node.id,
198
+ edit: __props.edit
199
+ })
200
+ ]),
201
+ __props.edit && __props.dragId && __props.dragId !== __props.node.id ? (openBlock(), createElementBlock("div", {
202
+ key: 1,
203
+ class: "absolute inset-0 z-[5]",
204
+ onDragover: onDragOver,
205
+ onDragleave: _cache[9] || (_cache[9] = ($event) => hoverSide.value = null),
206
+ onDrop: _cache[10] || (_cache[10] = () => {
207
+ const s = hoverSide.value;
208
+ hoverSide.value = null;
209
+ if (s) emit("drop", __props.node.id, s);
210
+ })
211
+ }, [
212
+ hoverSide.value ? (openBlock(), createElementBlock("div", {
213
+ key: 0,
214
+ class: normalizeClass(["pointer-events-none absolute rounded-card border-2 border-brand bg-brand/25 transition-all", hintInset[hoverSide.value]])
215
+ }, null, 2)) : createCommentVNode("", true)
216
+ ], 32)) : createCommentVNode("", true)
217
+ ]),
218
+ _: 3
219
+ }, 8, ["class"])) : createCommentVNode("", true);
220
+ };
221
+ }
222
+ });
223
+ export {
224
+ _sfc_main as _
225
+ };
@@ -0,0 +1,69 @@
1
+ import { defineComponent, computed, openBlock, createElementBlock, normalizeClass, createVNode, createElementVNode, toDisplayString, createCommentVNode, renderSlot } from "vue";
2
+ import { tv } from "tailwind-variants";
3
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
4
+ const _hoisted_1 = { class: "min-w-0" };
5
+ const _hoisted_2 = {
6
+ key: 0,
7
+ class: "font-semibold text-ink"
8
+ };
9
+ const _sfc_main = /* @__PURE__ */ defineComponent({
10
+ __name: "LpAlert",
11
+ props: {
12
+ variant: { default: "info" },
13
+ title: {},
14
+ icon: {}
15
+ },
16
+ setup(__props) {
17
+ const alert = tv({
18
+ base: "flex gap-3 rounded-card border p-4 text-sm",
19
+ variants: {
20
+ variant: {
21
+ info: "border-line bg-surface-soft text-ink",
22
+ success: "border-action/30 bg-action/10 text-ink",
23
+ warning: "border-accent/30 bg-accent/10 text-ink",
24
+ danger: "border-danger/30 bg-danger/10 text-ink"
25
+ }
26
+ },
27
+ defaultVariants: { variant: "info" }
28
+ });
29
+ const ICONS = {
30
+ info: "lucide:info",
31
+ success: "lucide:circle-check",
32
+ warning: "lucide:triangle-alert",
33
+ danger: "lucide:octagon-alert"
34
+ };
35
+ const ICON_TONE = {
36
+ info: "text-brand",
37
+ success: "text-action",
38
+ warning: "text-accent",
39
+ danger: "text-danger"
40
+ };
41
+ const props = __props;
42
+ const classes = computed(() => alert({ variant: props.variant }));
43
+ const resolvedIcon = computed(() => props.icon ?? ICONS[props.variant ?? "info"]);
44
+ const iconTone = computed(() => ICON_TONE[props.variant ?? "info"]);
45
+ return (_ctx, _cache) => {
46
+ return openBlock(), createElementBlock("div", {
47
+ class: normalizeClass(classes.value),
48
+ role: "alert"
49
+ }, [
50
+ createVNode(_sfc_main$1, {
51
+ name: resolvedIcon.value,
52
+ size: 18,
53
+ class: normalizeClass(["mt-0.5 shrink-0", iconTone.value])
54
+ }, null, 8, ["name", "class"]),
55
+ createElementVNode("div", _hoisted_1, [
56
+ __props.title ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
57
+ createElementVNode("div", {
58
+ class: normalizeClass(["text-muted-strong", __props.title ? "mt-0.5" : ""])
59
+ }, [
60
+ renderSlot(_ctx.$slots, "default")
61
+ ], 2)
62
+ ])
63
+ ], 2);
64
+ };
65
+ }
66
+ });
67
+ export {
68
+ _sfc_main as _
69
+ };
@@ -0,0 +1,170 @@
1
+ import { defineComponent, computed, watch, openBlock, createElementBlock, createVNode, createSlots, withCtx, renderSlot, normalizeProps, guardReactiveProps, createElementVNode, normalizeClass, toDisplayString, createCommentVNode, createBlock } from "vue";
2
+ import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
+ import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
4
+ import { _ as _sfc_main$4 } from "./LpScrollArea-CcHul_XS.js";
5
+ import { _ as _sfc_main$1 } from "./LpSidebar-CTUdtX7W.js";
6
+ const _hoisted_1 = { class: "flex h-dvh overflow-hidden bg-surface text-ink" };
7
+ const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
8
+ const _hoisted_3 = { class: "flex h-16 shrink-0 items-center gap-3 border-b border-line bg-surface px-4 md:px-6" };
9
+ const _hoisted_4 = { class: "truncate text-lg font-semibold" };
10
+ const _hoisted_5 = {
11
+ key: 0,
12
+ class: "ml-auto flex items-center gap-2"
13
+ };
14
+ const _hoisted_6 = {
15
+ key: 0,
16
+ class: "min-h-0 flex-1 overflow-hidden"
17
+ };
18
+ const _sfc_main = /* @__PURE__ */ defineComponent({
19
+ __name: "LpAppShell",
20
+ props: {
21
+ items: {},
22
+ sections: {},
23
+ modelValue: {},
24
+ path: {},
25
+ isActive: {},
26
+ title: {},
27
+ open: { type: Boolean },
28
+ mobileBreakpoint: { default: "lg" },
29
+ divider: { type: Boolean, default: true },
30
+ contentClass: { default: "mx-auto w-full max-w-6xl" },
31
+ fullBleed: { type: Boolean },
32
+ loading: { type: Boolean }
33
+ },
34
+ emits: ["update:modelValue", "update:open", "select"],
35
+ setup(__props, { expose: __expose, emit: __emit }) {
36
+ const props = __props;
37
+ const emit = __emit;
38
+ const flatItems = computed(
39
+ () => props.sections ? props.sections.flatMap((s) => s.items) : props.items ?? []
40
+ );
41
+ function defaultActive(item) {
42
+ if (props.path == null) return item.id === props.modelValue;
43
+ if (item.id === "/") return props.path === "/";
44
+ return props.path === item.id || props.path.startsWith(`${item.id}/`);
45
+ }
46
+ const activeTest = computed(() => props.isActive ?? defaultActive);
47
+ const pageTitle = computed(() => {
48
+ if (props.title != null) return props.title;
49
+ const test = activeTest.value;
50
+ const match = [...flatItems.value].sort((a, b) => b.id.length - a.id.length).find((item) => test(item));
51
+ return match?.label ?? "";
52
+ });
53
+ const drawerOpen = computed({
54
+ get: () => props.open ?? false,
55
+ set: (v) => emit("update:open", v)
56
+ });
57
+ watch(
58
+ () => props.path,
59
+ () => {
60
+ if (drawerOpen.value) emit("update:open", false);
61
+ }
62
+ );
63
+ function onSelect(item) {
64
+ emit("select", item);
65
+ }
66
+ function onModel(id) {
67
+ emit("update:modelValue", id);
68
+ }
69
+ const burgerHidden = {
70
+ sm: "sm:hidden",
71
+ md: "md:hidden",
72
+ lg: "lg:hidden",
73
+ xl: "xl:hidden"
74
+ };
75
+ const burgerClass = computed(() => burgerHidden[props.mobileBreakpoint]);
76
+ const _openDrawer = () => emit("update:open", true);
77
+ __expose({ openDrawer: _openDrawer });
78
+ return (_ctx, _cache) => {
79
+ return openBlock(), createElementBlock("div", _hoisted_1, [
80
+ createVNode(_sfc_main$1, {
81
+ "model-value": __props.modelValue,
82
+ items: __props.items,
83
+ sections: __props.sections,
84
+ "is-active": activeTest.value,
85
+ open: drawerOpen.value,
86
+ responsive: "",
87
+ "edge-open": "",
88
+ "mobile-breakpoint": __props.mobileBreakpoint,
89
+ divider: __props.divider,
90
+ loading: __props.loading,
91
+ class: "shrink-0",
92
+ "onUpdate:modelValue": onModel,
93
+ "onUpdate:open": _cache[0] || (_cache[0] = (v) => emit("update:open", v)),
94
+ onSelect
95
+ }, createSlots({ _: 2 }, [
96
+ _ctx.$slots.logo ? {
97
+ name: "header",
98
+ fn: withCtx(() => [
99
+ renderSlot(_ctx.$slots, "logo")
100
+ ]),
101
+ key: "0"
102
+ } : void 0,
103
+ _ctx.$slots["sidebar-actions"] ? {
104
+ name: "actions",
105
+ fn: withCtx(() => [
106
+ renderSlot(_ctx.$slots, "sidebar-actions")
107
+ ]),
108
+ key: "1"
109
+ } : void 0,
110
+ _ctx.$slots["sidebar-footer"] ? {
111
+ name: "footer",
112
+ fn: withCtx(() => [
113
+ renderSlot(_ctx.$slots, "sidebar-footer")
114
+ ]),
115
+ key: "2"
116
+ } : void 0,
117
+ _ctx.$slots["sidebar-item"] ? {
118
+ name: "item",
119
+ fn: withCtx((slotProps) => [
120
+ renderSlot(_ctx.$slots, "sidebar-item", normalizeProps(guardReactiveProps(slotProps)))
121
+ ]),
122
+ key: "3"
123
+ } : void 0
124
+ ]), 1032, ["model-value", "items", "sections", "is-active", "open", "mobile-breakpoint", "divider", "loading"]),
125
+ createElementVNode("div", _hoisted_2, [
126
+ createElementVNode("header", _hoisted_3, [
127
+ createVNode(_sfc_main$2, {
128
+ class: normalizeClass(burgerClass.value),
129
+ variant: "ghost",
130
+ size: "sm",
131
+ square: "",
132
+ "aria-label": "Open menu",
133
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("update:open", true))
134
+ }, {
135
+ default: withCtx(() => [
136
+ createVNode(_sfc_main$3, {
137
+ name: "lucide:menu",
138
+ size: 18
139
+ })
140
+ ]),
141
+ _: 1
142
+ }, 8, ["class"]),
143
+ renderSlot(_ctx.$slots, "header-title", {}, () => [
144
+ createElementVNode("h1", _hoisted_4, toDisplayString(pageTitle.value), 1)
145
+ ]),
146
+ _ctx.$slots["header-actions"] ? (openBlock(), createElementBlock("div", _hoisted_5, [
147
+ renderSlot(_ctx.$slots, "header-actions")
148
+ ])) : createCommentVNode("", true)
149
+ ]),
150
+ __props.fullBleed ? (openBlock(), createElementBlock("div", _hoisted_6, [
151
+ renderSlot(_ctx.$slots, "default")
152
+ ])) : (openBlock(), createBlock(_sfc_main$4, {
153
+ key: 1,
154
+ class: "min-h-0 flex-1",
155
+ "content-class": `px-4 py-6 md:px-6 ${__props.contentClass}`
156
+ }, {
157
+ default: withCtx(() => [
158
+ renderSlot(_ctx.$slots, "default")
159
+ ]),
160
+ _: 3
161
+ }, 8, ["content-class"]))
162
+ ]),
163
+ renderSlot(_ctx.$slots, "overlays")
164
+ ]);
165
+ };
166
+ }
167
+ });
168
+ export {
169
+ _sfc_main as _
170
+ };