@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,222 @@
1
+ import { defineComponent, computed, ref, openBlock, createBlock, unref, withCtx, createVNode, normalizeClass, createElementBlock, toDisplayString, withModifiers, createCommentVNode, createTextVNode, Fragment, renderList, normalizeStyle, createElementVNode } from "vue";
2
+ import { ComboboxRoot, ComboboxAnchor, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxInput, ComboboxViewport, ComboboxEmpty, ComboboxItem, ComboboxItemIndicator } from "reka-ui";
3
+ import { POPOVER_PANEL, OPTION_ITEM } from "../components/dropdown.js";
4
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
5
+ const _hoisted_1 = {
6
+ key: 0,
7
+ class: "truncate"
8
+ };
9
+ const _hoisted_2 = {
10
+ key: 1,
11
+ class: "truncate text-muted"
12
+ };
13
+ const _hoisted_3 = {
14
+ key: 0,
15
+ class: "border-b border-line p-2"
16
+ };
17
+ const _hoisted_4 = {
18
+ key: 0,
19
+ class: "px-3 py-4 text-center text-sm italic text-muted"
20
+ };
21
+ const _hoisted_5 = { class: "flex flex-col" };
22
+ const _hoisted_6 = {
23
+ key: 0,
24
+ class: "text-xs text-muted"
25
+ };
26
+ const EMPTY_SENTINEL = "\0__lp_empty__";
27
+ const _sfc_main = /* @__PURE__ */ defineComponent({
28
+ __name: "LpSelect",
29
+ props: {
30
+ modelValue: {},
31
+ options: {},
32
+ placeholder: { default: "Select…" },
33
+ searchPlaceholder: { default: "Search…" },
34
+ searchable: { type: Boolean, default: false },
35
+ multiple: { type: Boolean, default: false },
36
+ clearable: { type: Boolean, default: false },
37
+ disabled: { type: Boolean, default: false },
38
+ emptyText: { default: "Nothing found" },
39
+ searchTerm: { default: void 0 },
40
+ loading: { type: Boolean, default: false },
41
+ loadingText: { default: "Searching…" },
42
+ size: { default: "md" }
43
+ },
44
+ emits: ["update:modelValue", "change", "update:searchTerm"],
45
+ setup(__props, { emit: __emit }) {
46
+ const props = __props;
47
+ const SIZE_HEIGHT = {
48
+ sm: "h-(--size-control-sm)",
49
+ md: "h-(--size-control-md)",
50
+ lg: "h-(--size-control-lg)"
51
+ };
52
+ const anchorHeight = computed(() => SIZE_HEIGHT[props.size]);
53
+ const emit = __emit;
54
+ const serverSide = computed(() => props.searchTerm !== void 0);
55
+ const localQuery = ref("");
56
+ const query = computed({
57
+ get: () => serverSide.value ? props.searchTerm ?? "" : localQuery.value,
58
+ set: (v) => {
59
+ if (serverSide.value) emit("update:searchTerm", v);
60
+ else localQuery.value = v;
61
+ }
62
+ });
63
+ function encode(v) {
64
+ return v === "" ? EMPTY_SENTINEL : v;
65
+ }
66
+ function decode(v) {
67
+ return v === EMPTY_SENTINEL ? "" : v;
68
+ }
69
+ const comboModel = computed(() => {
70
+ const v = props.modelValue;
71
+ if (Array.isArray(v)) return v.map((item) => encode(item));
72
+ return encode(v);
73
+ });
74
+ const filtered = computed(() => {
75
+ if (serverSide.value) return props.options;
76
+ const q = query.value.trim().toLowerCase();
77
+ if (!props.searchable || !q) return props.options;
78
+ return props.options.filter(
79
+ (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q)
80
+ );
81
+ });
82
+ const displayLabel = computed(() => {
83
+ const v = props.modelValue;
84
+ if (props.multiple) {
85
+ const arr = v ?? [];
86
+ if (arr.length === 0) return "";
87
+ if (arr.length === 1)
88
+ return props.options.find((o) => o.value === arr[0])?.label ?? String(arr[0]);
89
+ return `${arr.length} selected`;
90
+ }
91
+ return props.options.find((o) => o.value === v)?.label ?? "";
92
+ });
93
+ const hasValue = computed(
94
+ () => props.multiple ? (props.modelValue?.length ?? 0) > 0 : props.modelValue !== void 0 && props.modelValue !== ""
95
+ );
96
+ function onUpdate(value) {
97
+ const decoded = Array.isArray(value) ? value.map((item) => decode(item)) : decode(value);
98
+ emit("update:modelValue", decoded);
99
+ if (!props.multiple) emit("change", decoded);
100
+ }
101
+ function clear() {
102
+ emit("update:modelValue", props.multiple ? [] : void 0);
103
+ }
104
+ return (_ctx, _cache) => {
105
+ return openBlock(), createBlock(unref(ComboboxRoot), {
106
+ "model-value": comboModel.value,
107
+ multiple: __props.multiple,
108
+ disabled: __props.disabled,
109
+ "ignore-filter": true,
110
+ class: "relative",
111
+ "onUpdate:modelValue": onUpdate
112
+ }, {
113
+ default: withCtx(() => [
114
+ createVNode(unref(ComboboxAnchor), {
115
+ class: normalizeClass([
116
+ anchorHeight.value,
117
+ "group flex w-full items-center gap-2 rounded-control border border-line bg-surface-soft px-3 text-sm text-ink transition-colors duration-[var(--duration-fast)] focus-within:border-brand focus-within:ring-2 focus-within:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-55"
118
+ ])
119
+ }, {
120
+ default: withCtx(() => [
121
+ createVNode(unref(ComboboxTrigger), { class: "flex flex-1 items-center gap-2 outline-none" }, {
122
+ default: withCtx(() => [
123
+ displayLabel.value ? (openBlock(), createElementBlock("span", _hoisted_1, toDisplayString(displayLabel.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.placeholder), 1))
124
+ ]),
125
+ _: 1
126
+ }),
127
+ __props.clearable && hasValue.value ? (openBlock(), createElementBlock("button", {
128
+ key: 0,
129
+ type: "button",
130
+ class: "group flex shrink-0 items-center text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink",
131
+ "aria-label": "Clear",
132
+ onPointerdown: withModifiers(clear, ["prevent"])
133
+ }, [
134
+ createVNode(_sfc_main$1, {
135
+ name: "lucide:x",
136
+ size: 16,
137
+ class: "transition-transform duration-200 ease-[var(--ease-emphasized)] group-hover:rotate-90 group-active:scale-90 motion-reduce:group-hover:rotate-0"
138
+ })
139
+ ], 32)) : createCommentVNode("", true),
140
+ createVNode(unref(ComboboxTrigger), { class: "group/trig flex shrink-0 items-center text-muted transition-[rotate,color] duration-200 ease-[var(--ease-emphasized)] group-hover:text-ink data-[state=open]:rotate-180" }, {
141
+ default: withCtx(() => [
142
+ createVNode(_sfc_main$1, {
143
+ name: "lucide:chevron-down",
144
+ size: 16,
145
+ class: "transition-transform duration-200 ease-[var(--ease-emphasized)] group-data-[state=closed]/trig:group-hover:translate-y-1"
146
+ })
147
+ ]),
148
+ _: 1
149
+ })
150
+ ]),
151
+ _: 1
152
+ }, 8, ["class"]),
153
+ createVNode(unref(ComboboxPortal), null, {
154
+ default: withCtx(() => [
155
+ createVNode(unref(ComboboxContent), {
156
+ position: "popper",
157
+ "side-offset": 6,
158
+ class: normalizeClass([unref(POPOVER_PANEL), "z-(--z-popover) max-h-72 w-(--reka-combobox-trigger-width) overflow-hidden"])
159
+ }, {
160
+ default: withCtx(() => [
161
+ __props.searchable || serverSide.value ? (openBlock(), createElementBlock("div", _hoisted_3, [
162
+ createVNode(unref(ComboboxInput), {
163
+ modelValue: query.value,
164
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => query.value = $event),
165
+ placeholder: __props.searchPlaceholder,
166
+ class: "h-(--size-control-sm) w-full rounded-md border border-line bg-surface-soft px-2.5 text-sm text-ink outline-none placeholder:text-muted focus:border-brand"
167
+ }, null, 8, ["modelValue", "placeholder"])
168
+ ])) : createCommentVNode("", true),
169
+ createVNode(unref(ComboboxViewport), { class: "max-h-56 overflow-y-auto p-1" }, {
170
+ default: withCtx(() => [
171
+ __props.loading ? (openBlock(), createElementBlock("div", _hoisted_4, toDisplayString(__props.loadingText), 1)) : (openBlock(), createBlock(unref(ComboboxEmpty), {
172
+ key: 1,
173
+ class: "px-3 py-4 text-center text-sm italic text-muted"
174
+ }, {
175
+ default: withCtx(() => [
176
+ createTextVNode(toDisplayString(__props.emptyText), 1)
177
+ ]),
178
+ _: 1
179
+ })),
180
+ (openBlock(true), createElementBlock(Fragment, null, renderList(filtered.value, (opt, i) => {
181
+ return openBlock(), createBlock(unref(ComboboxItem), {
182
+ key: String(opt.value),
183
+ value: encode(opt.value),
184
+ style: normalizeStyle({ animationDelay: `${Math.min(i, 12) * 22}ms` }),
185
+ class: normalizeClass([unref(OPTION_ITEM), "justify-between"])
186
+ }, {
187
+ default: withCtx(() => [
188
+ createElementVNode("span", _hoisted_5, [
189
+ createElementVNode("span", null, toDisplayString(opt.label), 1),
190
+ opt.description ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(opt.description), 1)) : createCommentVNode("", true)
191
+ ]),
192
+ createVNode(unref(ComboboxItemIndicator), { class: "flex shrink-0 items-center text-brand" }, {
193
+ default: withCtx(() => [
194
+ createVNode(_sfc_main$1, {
195
+ name: "lucide:check",
196
+ size: 16
197
+ })
198
+ ]),
199
+ _: 1
200
+ })
201
+ ]),
202
+ _: 2
203
+ }, 1032, ["value", "style", "class"]);
204
+ }), 128))
205
+ ]),
206
+ _: 1
207
+ })
208
+ ]),
209
+ _: 1
210
+ }, 8, ["class"])
211
+ ]),
212
+ _: 1
213
+ })
214
+ ]),
215
+ _: 1
216
+ }, 8, ["model-value", "multiple", "disabled"]);
217
+ };
218
+ }
219
+ });
220
+ export {
221
+ _sfc_main as _
222
+ };
@@ -0,0 +1,51 @@
1
+ import { defineComponent, computed, openBlock, createElementBlock, normalizeStyle, normalizeClass, createVNode, unref, createElementVNode, toDisplayString } from "vue";
2
+ import { Handle, Position } from "@vue-flow/core";
3
+ const _hoisted_1 = { class: "text-[11px] text-[var(--accent)]" };
4
+ const _hoisted_2 = { class: "flex-1 truncate text-[11px] font-medium text-ink" };
5
+ const _sfc_main = /* @__PURE__ */ defineComponent({
6
+ __name: "LpServiceNode",
7
+ props: {
8
+ data: {},
9
+ selected: { type: Boolean }
10
+ },
11
+ setup(__props) {
12
+ const props = __props;
13
+ const kindVar = {
14
+ service: "var(--color-brand)",
15
+ database: "var(--color-accent)",
16
+ infra: "var(--color-muted-strong)"
17
+ };
18
+ const accent = computed(() => kindVar[props.data.kind ?? "service"] ?? "var(--color-brand)");
19
+ const kindIcon = {
20
+ service: "◇",
21
+ database: "⛁",
22
+ infra: "⬡"
23
+ };
24
+ const icon = computed(() => kindIcon[props.data.kind ?? "service"] ?? "◇");
25
+ return (_ctx, _cache) => {
26
+ return openBlock(), createElementBlock("div", {
27
+ class: normalizeClass(["flex w-[132px] items-center gap-1.5 rounded-control border bg-surface-soft px-2 py-1.5 transition-[border-color,opacity]", [
28
+ __props.selected ? "border-[var(--accent)]" : "border-line",
29
+ __props.data.dimmed ? "opacity-30" : "opacity-100"
30
+ ]]),
31
+ style: normalizeStyle({ "--accent": accent.value })
32
+ }, [
33
+ createVNode(unref(Handle), {
34
+ type: "target",
35
+ position: unref(Position).Left,
36
+ class: "!size-1.5 !border !border-[var(--accent)] !bg-surface"
37
+ }, null, 8, ["position"]),
38
+ createVNode(unref(Handle), {
39
+ type: "source",
40
+ position: unref(Position).Right,
41
+ class: "!size-1.5 !border !border-[var(--accent)] !bg-surface"
42
+ }, null, 8, ["position"]),
43
+ createElementVNode("span", _hoisted_1, toDisplayString(icon.value), 1),
44
+ createElementVNode("span", _hoisted_2, toDisplayString(__props.data.name), 1)
45
+ ], 6);
46
+ };
47
+ }
48
+ });
49
+ export {
50
+ _sfc_main as _
51
+ };
@@ -0,0 +1,152 @@
1
+ import { defineComponent, computed, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps, createBlock } from "vue";
2
+ import { _ as _sfc_main$2 } from "./LpDrawer-Ce6g9ZMr.js";
3
+ import { _ as _sfc_main$1 } from "./LpSidebarNav-CpF7rZxx.js";
4
+ const _hoisted_1 = {
5
+ key: 1,
6
+ class: "mt-2 flex shrink-0 flex-col gap-2"
7
+ };
8
+ const _hoisted_2 = {
9
+ key: 2,
10
+ class: "mt-2 shrink-0 border-t border-line pt-3"
11
+ };
12
+ const _hoisted_3 = { class: "flex h-full flex-col gap-1" };
13
+ const _hoisted_4 = {
14
+ key: 1,
15
+ class: "mt-2 flex shrink-0 flex-col gap-2"
16
+ };
17
+ const _hoisted_5 = {
18
+ key: 2,
19
+ class: "mt-2 shrink-0 border-t border-line pt-3"
20
+ };
21
+ const _sfc_main = /* @__PURE__ */ defineComponent({
22
+ ...{ inheritAttrs: false },
23
+ __name: "LpSidebar",
24
+ props: {
25
+ modelValue: {},
26
+ items: {},
27
+ sections: {},
28
+ isActive: {},
29
+ loading: { type: Boolean },
30
+ skeletonRows: { default: 6 },
31
+ skeletonHeader: { type: Boolean, default: true },
32
+ responsive: { type: Boolean, default: false },
33
+ open: { type: Boolean },
34
+ mobileBreakpoint: { default: "md" },
35
+ edgeOpen: { type: Boolean },
36
+ divider: { type: Boolean, default: true }
37
+ },
38
+ emits: ["update:modelValue", "update:open", "select"],
39
+ setup(__props, { emit: __emit }) {
40
+ const props = __props;
41
+ const emit = __emit;
42
+ const groups = computed(
43
+ () => props.sections ?? (props.items ? [{ items: props.items }] : [])
44
+ );
45
+ function itemActive(item) {
46
+ return props.isActive ? props.isActive(item) : item.id === props.modelValue;
47
+ }
48
+ function activate(item) {
49
+ if (item.disabled) return;
50
+ emit("update:modelValue", item.id);
51
+ emit("select", item);
52
+ if (props.responsive && props.open) emit("update:open", false);
53
+ }
54
+ const baseId = `lp-sidebar-${useId()}`;
55
+ const railPillId = `${baseId}-rail`;
56
+ const drawerPillId = `${baseId}-drawer`;
57
+ const RAIL_VISIBILITY = {
58
+ sm: "hidden sm:flex",
59
+ md: "hidden md:flex",
60
+ lg: "hidden lg:flex",
61
+ xl: "hidden xl:flex"
62
+ };
63
+ const railClass = computed(
64
+ () => props.responsive ? RAIL_VISIBILITY[props.mobileBreakpoint] : "flex"
65
+ );
66
+ return (_ctx, _cache) => {
67
+ return openBlock(), createElementBlock(Fragment, null, [
68
+ createElementVNode("nav", mergeProps({
69
+ class: ["h-full w-60 flex-col gap-1 border-r border-line bg-surface-raised p-3", railClass.value],
70
+ "aria-label": "Sidebar"
71
+ }, _ctx.$attrs), [
72
+ _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
73
+ key: 0,
74
+ class: normalizeClass(["-mx-3 -mt-3 mb-3 flex h-16 shrink-0 items-center px-3", __props.divider ? "border-b border-line" : ""])
75
+ }, [
76
+ renderSlot(_ctx.$slots, "header")
77
+ ], 2)) : createCommentVNode("", true),
78
+ createVNode(_sfc_main$1, {
79
+ groups: groups.value,
80
+ "pill-id": railPillId,
81
+ "item-active": itemActive,
82
+ loading: __props.loading,
83
+ "skeleton-rows": __props.skeletonRows,
84
+ "skeleton-header": __props.skeletonHeader,
85
+ onActivate: activate
86
+ }, createSlots({ _: 2 }, [
87
+ _ctx.$slots.item ? {
88
+ name: "item",
89
+ fn: withCtx((slotProps) => [
90
+ renderSlot(_ctx.$slots, "item", normalizeProps(guardReactiveProps(slotProps)))
91
+ ]),
92
+ key: "0"
93
+ } : void 0
94
+ ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header"]),
95
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_1, [
96
+ renderSlot(_ctx.$slots, "actions")
97
+ ])) : createCommentVNode("", true),
98
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_2, [
99
+ renderSlot(_ctx.$slots, "footer")
100
+ ])) : createCommentVNode("", true)
101
+ ], 16),
102
+ __props.responsive ? (openBlock(), createBlock(_sfc_main$2, {
103
+ key: 0,
104
+ open: __props.open,
105
+ direction: "left",
106
+ size: "sm",
107
+ "edge-open": __props.edgeOpen,
108
+ "edge-breakpoint": __props.mobileBreakpoint,
109
+ "onUpdate:open": _cache[0] || (_cache[0] = (v) => emit("update:open", v))
110
+ }, {
111
+ default: withCtx(() => [
112
+ createElementVNode("div", _hoisted_3, [
113
+ _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
114
+ key: 0,
115
+ class: normalizeClass(["shrink-0", __props.divider ? "mb-3 border-b border-line pb-3" : "mb-2"])
116
+ }, [
117
+ renderSlot(_ctx.$slots, "header")
118
+ ], 2)) : createCommentVNode("", true),
119
+ createVNode(_sfc_main$1, {
120
+ groups: groups.value,
121
+ "pill-id": drawerPillId,
122
+ "item-active": itemActive,
123
+ loading: __props.loading,
124
+ "skeleton-rows": __props.skeletonRows,
125
+ "skeleton-header": __props.skeletonHeader,
126
+ onActivate: activate
127
+ }, createSlots({ _: 2 }, [
128
+ _ctx.$slots.item ? {
129
+ name: "item",
130
+ fn: withCtx((slotProps) => [
131
+ renderSlot(_ctx.$slots, "item", normalizeProps(guardReactiveProps(slotProps)))
132
+ ]),
133
+ key: "0"
134
+ } : void 0
135
+ ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header"]),
136
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_4, [
137
+ renderSlot(_ctx.$slots, "actions")
138
+ ])) : createCommentVNode("", true),
139
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_5, [
140
+ renderSlot(_ctx.$slots, "footer")
141
+ ])) : createCommentVNode("", true)
142
+ ])
143
+ ]),
144
+ _: 3
145
+ }, 8, ["open", "edge-open", "edge-breakpoint"])) : createCommentVNode("", true)
146
+ ], 64);
147
+ };
148
+ }
149
+ });
150
+ export {
151
+ _sfc_main as _
152
+ };
@@ -0,0 +1,126 @@
1
+ import { defineComponent, openBlock, createElementBlock, createElementVNode, createCommentVNode, Fragment, renderList, createBlock, withCtx, toDisplayString, resolveDynamicComponent, normalizeClass, unref, renderSlot, createTextVNode } from "vue";
2
+ import { Motion } from "motion-v";
3
+ import { usePillTransition } from "../composables/usePillTransition.js";
4
+ import { _ as _sfc_main$4 } from "./LpBadge-CXzBPnwO.js";
5
+ import { _ as _sfc_main$2 } from "./LpContextMenu-D0mzXqA7.js";
6
+ import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
7
+ import { _ as _sfc_main$1 } from "./LpScrollArea-K1x-azgY.js";
8
+ const _hoisted_1 = {
9
+ key: 0,
10
+ class: "flex min-h-0 flex-1 flex-col gap-4"
11
+ };
12
+ const _hoisted_2 = {
13
+ key: 0,
14
+ class: "flex items-center gap-3 px-1"
15
+ };
16
+ const _hoisted_3 = { class: "space-y-1" };
17
+ const _hoisted_4 = {
18
+ key: 0,
19
+ class: "px-2 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted"
20
+ };
21
+ const _hoisted_5 = { class: "relative z-10 min-w-0 flex-1 truncate text-left" };
22
+ const _sfc_main = /* @__PURE__ */ defineComponent({
23
+ __name: "LpSidebarNav",
24
+ props: {
25
+ groups: {},
26
+ pillId: {},
27
+ itemActive: {},
28
+ loading: { type: Boolean },
29
+ skeletonRows: { default: 6 },
30
+ skeletonHeader: { type: Boolean, default: true }
31
+ },
32
+ emits: ["activate"],
33
+ setup(__props, { emit: __emit }) {
34
+ const emit = __emit;
35
+ const pillTransition = usePillTransition();
36
+ return (_ctx, _cache) => {
37
+ return __props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [
38
+ __props.skeletonHeader ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[0] || (_cache[0] = [
39
+ createElementVNode("div", { class: "size-10 shrink-0 animate-pulse rounded-pill bg-surface-soft" }, null, -1),
40
+ createElementVNode("div", { class: "flex-1 space-y-2" }, [
41
+ createElementVNode("div", { class: "h-3.5 w-24 animate-pulse rounded bg-surface-soft" }),
42
+ createElementVNode("div", { class: "h-3 w-16 animate-pulse rounded bg-surface-soft/60" })
43
+ ], -1)
44
+ ])])) : createCommentVNode("", true),
45
+ createElementVNode("div", _hoisted_3, [
46
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.skeletonRows, (n) => {
47
+ return openBlock(), createElementBlock("div", {
48
+ key: n,
49
+ class: "h-9 animate-pulse rounded-control bg-surface-soft"
50
+ });
51
+ }), 128))
52
+ ])
53
+ ])) : (openBlock(), createBlock(_sfc_main$1, {
54
+ key: 1,
55
+ class: "min-h-0 flex-1",
56
+ "content-class": "flex min-h-full flex-col gap-4"
57
+ }, {
58
+ default: withCtx(() => [
59
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.groups, (section, si) => {
60
+ return openBlock(), createElementBlock("div", {
61
+ key: si,
62
+ class: "flex flex-col gap-0.5"
63
+ }, [
64
+ section.title ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(section.title), 1)) : createCommentVNode("", true),
65
+ (openBlock(true), createElementBlock(Fragment, null, renderList(section.items, (item) => {
66
+ return openBlock(), createBlock(_sfc_main$2, {
67
+ key: item.id,
68
+ items: item.menu ?? []
69
+ }, {
70
+ default: withCtx(() => [
71
+ (openBlock(), createBlock(resolveDynamicComponent(item.href && !item.disabled ? "a" : "button"), {
72
+ href: item.href && !item.disabled ? item.href : void 0,
73
+ type: item.href ? void 0 : "button",
74
+ disabled: item.href ? void 0 : item.disabled,
75
+ "aria-current": __props.itemActive(item) ? "page" : void 0,
76
+ "aria-disabled": item.disabled || void 0,
77
+ class: normalizeClass(["group/item relative flex items-center gap-3 rounded-control px-3 py-2 text-sm font-medium outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring", item.disabled ? "cursor-not-allowed text-muted/50" : __props.itemActive(item) ? "text-ink" : "text-muted hover:text-ink"]),
78
+ onClick: ($event) => emit("activate", item)
79
+ }, {
80
+ default: withCtx(() => [
81
+ __props.itemActive(item) ? (openBlock(), createBlock(unref(Motion), {
82
+ key: 0,
83
+ "layout-id": __props.pillId,
84
+ transition: unref(pillTransition),
85
+ class: "absolute inset-0 z-0 rounded-control bg-brand-soft"
86
+ }, null, 8, ["layout-id", "transition"])) : createCommentVNode("", true),
87
+ renderSlot(_ctx.$slots, "item", {
88
+ item,
89
+ active: __props.itemActive(item)
90
+ }, () => [
91
+ item.icon ? (openBlock(), createBlock(_sfc_main$3, {
92
+ key: 0,
93
+ name: item.icon,
94
+ size: 17,
95
+ class: normalizeClass(["relative z-10 shrink-0 transition-colors", __props.itemActive(item) ? "text-brand" : ""])
96
+ }, null, 8, ["name", "class"])) : createCommentVNode("", true),
97
+ createElementVNode("span", _hoisted_5, toDisplayString(item.label), 1),
98
+ item.badge != null ? (openBlock(), createBlock(_sfc_main$4, {
99
+ key: 1,
100
+ tone: __props.itemActive(item) ? "brand" : "neutral",
101
+ class: "relative z-10 shrink-0"
102
+ }, {
103
+ default: withCtx(() => [
104
+ createTextVNode(toDisplayString(item.badge), 1)
105
+ ]),
106
+ _: 2
107
+ }, 1032, ["tone"])) : createCommentVNode("", true)
108
+ ])
109
+ ]),
110
+ _: 2
111
+ }, 1032, ["href", "type", "disabled", "aria-current", "aria-disabled", "class", "onClick"]))
112
+ ]),
113
+ _: 2
114
+ }, 1032, ["items"]);
115
+ }), 128))
116
+ ]);
117
+ }), 128))
118
+ ]),
119
+ _: 3
120
+ }));
121
+ };
122
+ }
123
+ });
124
+ export {
125
+ _sfc_main as _
126
+ };
@@ -0,0 +1,22 @@
1
+ import { defineComponent, openBlock, createElementBlock, normalizeClass } from "vue";
2
+ const _sfc_main = /* @__PURE__ */ defineComponent({
3
+ __name: "LpSkeleton",
4
+ props: {
5
+ rounded: {}
6
+ },
7
+ setup(__props) {
8
+ return (_ctx, _cache) => {
9
+ return openBlock(), createElementBlock("div", {
10
+ "aria-hidden": "true",
11
+ class: normalizeClass(["animate-pulse bg-surface-soft", {
12
+ "rounded-control": __props.rounded === "control" || !__props.rounded,
13
+ "rounded-card": __props.rounded === "card",
14
+ "rounded-pill": __props.rounded === "pill"
15
+ }])
16
+ }, null, 2);
17
+ };
18
+ }
19
+ });
20
+ export {
21
+ _sfc_main as _
22
+ };
@@ -0,0 +1,53 @@
1
+ import { defineComponent, openBlock, createBlock, unref, withCtx, createVNode } from "vue";
2
+ import { SliderRoot, SliderTrack, SliderRange, SliderThumb } from "reka-ui";
3
+ const _sfc_main = /* @__PURE__ */ defineComponent({
4
+ __name: "LpSlider",
5
+ props: {
6
+ modelValue: { default: 0 },
7
+ min: { default: 0 },
8
+ max: { default: 100 },
9
+ step: { default: 1 },
10
+ disabled: { type: Boolean },
11
+ ariaLabel: {}
12
+ },
13
+ emits: ["update:modelValue", "change"],
14
+ setup(__props, { emit: __emit }) {
15
+ const props = __props;
16
+ const emit = __emit;
17
+ function onUpdate(v) {
18
+ if (v && v.length) emit("update:modelValue", v[0]);
19
+ }
20
+ function onCommit(v) {
21
+ if (v && v.length) emit("change", v[0]);
22
+ }
23
+ return (_ctx, _cache) => {
24
+ return openBlock(), createBlock(unref(SliderRoot), {
25
+ "model-value": [props.modelValue],
26
+ min: __props.min,
27
+ max: __props.max,
28
+ step: __props.step,
29
+ disabled: __props.disabled,
30
+ class: "relative flex h-5 w-full touch-none select-none items-center data-[disabled]:opacity-55",
31
+ "onUpdate:modelValue": onUpdate,
32
+ onValueCommit: onCommit
33
+ }, {
34
+ default: withCtx(() => [
35
+ createVNode(unref(SliderTrack), { class: "relative h-1.5 grow overflow-hidden rounded-pill bg-surface-soft" }, {
36
+ default: withCtx(() => [
37
+ createVNode(unref(SliderRange), { class: "absolute h-full rounded-pill bg-brand" })
38
+ ]),
39
+ _: 1
40
+ }),
41
+ createVNode(unref(SliderThumb), {
42
+ "aria-label": __props.ariaLabel,
43
+ class: "block size-4 rounded-pill border-2 border-brand bg-surface shadow outline-none transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:scale-110 active:scale-95 focus-visible:ring-2 focus-visible:ring-ring motion-reduce:hover:scale-100 motion-reduce:active:scale-100"
44
+ }, null, 8, ["aria-label"])
45
+ ]),
46
+ _: 1
47
+ }, 8, ["model-value", "min", "max", "step", "disabled"]);
48
+ };
49
+ }
50
+ });
51
+ export {
52
+ _sfc_main as _
53
+ };