@leavepulse/ui 0.28.2 → 0.28.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 (37) hide show
  1. package/dist/chunks/{LpAddressInput-BTqnUXZG.js → LpAddressInput-BoTkszLk.js} +3 -3
  2. package/dist/chunks/{LpAppShell-B5k0J3Cf.js → LpAppShell-CGX0DlIW.js} +11 -6
  3. package/dist/chunks/{LpCard-gu11ZmSt.js → LpCard-DSefTGEH.js} +7 -1
  4. package/dist/chunks/{LpChart-tNXs1ttr.js → LpChart-UiU4RhXP.js} +5 -4
  5. package/dist/chunks/{LpFormField-CesaPWPO.js → LpFormField-DEaakcHe.js} +1 -1
  6. package/dist/chunks/{LpInput-jwqXlAy0.js → LpInput-BXr40nqX.js} +1 -1
  7. package/dist/chunks/{LpPasswordInput-Bmo6q9Kd.js → LpPasswordInput-Bdv6o8ae.js} +1 -1
  8. package/dist/chunks/{LpSelect-Cw8-gL5F.js → LpSelect-ANIVtrpM.js} +1 -1
  9. package/dist/chunks/{LpSidebar-7Vpy2IJc.js → LpSidebar-CWehDCxN.js} +34 -8
  10. package/dist/chunks/LpSidebarNav-5RGNr2D3.js +185 -0
  11. package/dist/chunks/{LpTextarea-1ENb3ZAO.js → LpTextarea-tc8N4UO_.js} +1 -1
  12. package/dist/components/LpAddressInput.vue.js +1 -1
  13. package/dist/components/LpAppShell.vue.d.ts +17 -11
  14. package/dist/components/LpAppShell.vue.js +1 -1
  15. package/dist/components/LpCard.vue.js +1 -1
  16. package/dist/components/LpChart.vue.js +1 -1
  17. package/dist/components/LpFormField.vue.js +1 -1
  18. package/dist/components/LpInput.vue.js +1 -1
  19. package/dist/components/LpPasswordInput.vue.js +1 -1
  20. package/dist/components/LpSelect.vue.js +1 -1
  21. package/dist/components/LpSidebar.vue.d.ts +32 -10
  22. package/dist/components/LpSidebar.vue.js +1 -1
  23. package/dist/components/LpSidebarNav.vue.d.ts +11 -2
  24. package/dist/components/LpSidebarNav.vue.js +1 -1
  25. package/dist/components/LpTextarea.vue.js +1 -1
  26. package/dist/components/sidebar.d.ts +18 -0
  27. package/dist/index.js +10 -10
  28. package/package.json +1 -1
  29. package/src/components/LpAppShell.vue +27 -3
  30. package/src/components/LpCard.vue +7 -1
  31. package/src/components/LpChart.vue +23 -4
  32. package/src/components/LpFormField.vue +6 -2
  33. package/src/components/LpSelect.vue +0 -0
  34. package/src/components/LpSidebar.vue +67 -1
  35. package/src/components/LpSidebarNav.vue +83 -4
  36. package/src/components/sidebar.ts +18 -0
  37. package/dist/chunks/LpSidebarNav-CFX5NxGs.js +0 -126
@@ -3,11 +3,11 @@ import { OSM_TILES, createNominatimProvider, emptyAddress, formatAddress } from
3
3
  import { flagEmoji, loadCountries } from "../components/countries.js";
4
4
  import { _ as _sfc_main$2 } from "./LpAutocomplete-DExlIZe_.js";
5
5
  import { _ as _sfc_main$3 } from "./LpButton-5VXXCjwF.js";
6
- import { _ as _sfc_main$1 } from "./LpFormField-CesaPWPO.js";
6
+ import { _ as _sfc_main$1 } from "./LpFormField-DEaakcHe.js";
7
7
  import { _ as _sfc_main$4 } from "./LpIcon-CCnX5_2j.js";
8
- import { _ as _sfc_main$5 } from "./LpInput-jwqXlAy0.js";
8
+ import { _ as _sfc_main$5 } from "./LpInput-BXr40nqX.js";
9
9
  import { _ as _sfc_main$7 } from "./LpModal-D_o-56To.js";
10
- import { _ as _sfc_main$6 } from "./LpSelect-Cw8-gL5F.js";
10
+ import { _ as _sfc_main$6 } from "./LpSelect-ANIVtrpM.js";
11
11
  const _hoisted_1 = { class: "flex flex-col gap-3" };
12
12
  const _hoisted_2 = { class: "flex items-stretch gap-2" };
13
13
  const _hoisted_3 = { class: "grid gap-3 sm:grid-cols-[minmax(0,1fr)_10rem]" };
@@ -3,10 +3,10 @@ import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
3
3
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
4
4
  import { _ as _sfc_main$5 } from "./LpScrollArea-D8xyKXcF.js";
5
5
  import { _ as _sfc_main$4 } from "./LpShift-DXNsauQZ.js";
6
- import { _ as _sfc_main$1 } from "./LpSidebar-7Vpy2IJc.js";
6
+ import { _ as _sfc_main$1 } from "./LpSidebar-CWehDCxN.js";
7
7
  const _hoisted_1 = { class: "flex h-dvh overflow-hidden bg-surface text-ink" };
8
8
  const _hoisted_2 = { class: "flex min-w-0 flex-1 flex-col" };
9
- 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_3 = { class: "relative flex h-16 shrink-0 items-center gap-3 border-b border-line bg-surface px-4 md:px-6" };
10
10
  const _hoisted_4 = { class: "truncate text-lg font-semibold" };
11
11
  const _hoisted_5 = {
12
12
  key: 0,
@@ -17,6 +17,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
17
17
  props: {
18
18
  items: {},
19
19
  sections: {},
20
+ collapsed: {},
21
+ autoCollapseAfter: {},
20
22
  modelValue: {},
21
23
  path: {},
22
24
  isActive: {},
@@ -28,7 +30,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
28
30
  fullBleed: { type: Boolean },
29
31
  loading: { type: Boolean }
30
32
  },
31
- emits: ["update:modelValue", "update:open", "select"],
33
+ emits: ["update:modelValue", "update:open", "update:collapsed", "select"],
32
34
  setup(__props, { expose: __expose, emit: __emit }) {
33
35
  const props = __props;
34
36
  const emit = __emit;
@@ -91,9 +93,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
91
93
  "mobile-breakpoint": __props.mobileBreakpoint,
92
94
  divider: __props.divider,
93
95
  loading: __props.loading,
96
+ collapsed: __props.collapsed,
97
+ "auto-collapse-after": __props.autoCollapseAfter,
94
98
  class: "shrink-0",
95
99
  "onUpdate:modelValue": onModel,
96
100
  "onUpdate:open": _cache[0] || (_cache[0] = (v) => emit("update:open", v)),
101
+ "onUpdate:collapsed": _cache[1] || (_cache[1] = (v) => emit("update:collapsed", v)),
97
102
  onSelect
98
103
  }, createSlots({ _: 2 }, [
99
104
  _ctx.$slots.logo ? {
@@ -124,7 +129,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
124
129
  ]),
125
130
  key: "3"
126
131
  } : void 0
127
- ]), 1032, ["model-value", "items", "sections", "is-active", "open", "mobile-breakpoint", "divider", "loading"]),
132
+ ]), 1032, ["model-value", "items", "sections", "is-active", "open", "mobile-breakpoint", "divider", "loading", "collapsed", "auto-collapse-after"]),
128
133
  createElementVNode("div", _hoisted_2, [
129
134
  createElementVNode("header", _hoisted_3, [
130
135
  createVNode(_sfc_main$2, {
@@ -133,7 +138,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
133
138
  size: "sm",
134
139
  square: "",
135
140
  "aria-label": "Open menu",
136
- onClick: _cache[1] || (_cache[1] = ($event) => emit("update:open", true))
141
+ onClick: _cache[2] || (_cache[2] = ($event) => emit("update:open", true))
137
142
  }, {
138
143
  default: withCtx(() => [
139
144
  createVNode(_sfc_main$3, {
@@ -156,7 +161,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
156
161
  }),
157
162
  createVNode(_sfc_main$4, {
158
163
  axis: "width",
159
- class: "ml-auto flex shrink-0 items-center gap-2"
164
+ class: "ml-auto flex max-w-[66%] shrink items-center gap-2 overflow-x-auto lp-scrollbar-none md:max-w-none md:shrink-0 md:overflow-visible"
160
165
  }, {
161
166
  default: withCtx(() => [
162
167
  renderSlot(_ctx.$slots, "header-actions")
@@ -22,7 +22,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
22
22
  // renders: two lines that look identical must not wrap differently.
23
23
  // Anything that genuinely must not break (a code block, a log line) sets its
24
24
  // own overflow and scrolls instead.
25
- base: "rounded-card border bg-surface-raised break-words",
25
+ // min-w-0: a card is nearly always laid out by a grid or a flex row, and both
26
+ // give their children `min-width: auto` — meaning "never narrower than your
27
+ // contents". A card holding a form then refuses to shrink and pushes its own
28
+ // column past the viewport: measured at 490px inside a 358px grid, with the
29
+ // inputs ending up off-screen on a phone. The card is a container; it takes
30
+ // the width it is given and wraps what is inside it.
31
+ base: "min-w-0 rounded-card border bg-surface-raised break-words",
26
32
  variants: {
27
33
  variant: {
28
34
  // raised opts into the skin painter (.lp-skin-panel) so it follows the
@@ -379,6 +379,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
379
379
  { deep: true }
380
380
  );
381
381
  const clipId = `lp-chart-${Math.random().toString(36).slice(2, 9)}`;
382
+ const gradientId = (name, index) => `${clipId}-g-${index}-${name.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
382
383
  return (_ctx, _cache) => {
383
384
  return openBlock(), createElementBlock("div", {
384
385
  ref_key: "root",
@@ -435,9 +436,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
435
436
  onContextmenu: onContextMenu
436
437
  }, [
437
438
  createElementVNode("defs", null, [
438
- (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (s) => {
439
+ (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (s, i) => {
439
440
  return openBlock(), createElementBlock("linearGradient", {
440
- id: `${clipId}-g-${s.name}`,
441
+ id: gradientId(s.name, i),
441
442
  key: s.name,
442
443
  x1: "0",
443
444
  y1: "0",
@@ -543,11 +544,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
543
544
  opacity: active.value < 0 || active.value === b.index ? 1 : 0.45
544
545
  }, null, 8, _hoisted_25);
545
546
  }), 128)),
546
- (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (s) => {
547
+ (openBlock(true), createElementBlock(Fragment, null, renderList(lines.value, (s, i) => {
547
548
  return withDirectives((openBlock(), createElementBlock("path", {
548
549
  key: `f-${s.name}`,
549
550
  d: s.fill,
550
- fill: `url(#${clipId}-g-${s.name})`
551
+ fill: `url(#${gradientId(s.name, i)})`
551
552
  }, null, 8, _hoisted_26)), [
552
553
  [vShow, __props.type === "area"]
553
554
  ]);
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, useId, openBlock, createElementBlock, createBlock, unref, withCtx, createTextVNode, toDisplayString, createCommentVNode, renderSlot, createVNode } from "vue";
2
2
  import { Label } from "reka-ui";
3
3
  import { _ as _sfc_main$1 } from "./LpShift-DXNsauQZ.js";
4
- const _hoisted_1 = { class: "flex flex-col gap-1.5" };
4
+ const _hoisted_1 = { class: "flex min-w-0 flex-col gap-1.5" };
5
5
  const _hoisted_2 = {
6
6
  key: 0,
7
7
  class: "text-danger"
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, computed, useSlots, useAttrs, ref, openBlock, createBlock, resolveDynamicComponent, normalizeStyle, normalizeClass, withCtx, createElementVNode, createElementBlock, renderSlot, createCommentVNode, mergeProps, unref } from "vue";
2
2
  import { tv } from "tailwind-variants";
3
3
  import { useInputFilter } from "../composables/useInputFilter.js";
4
- import { _ as _sfc_main$1 } from "./LpFormField-CesaPWPO.js";
4
+ import { _ as _sfc_main$1 } from "./LpFormField-DEaakcHe.js";
5
5
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
6
6
  const _hoisted_1 = {
7
7
  key: 0,
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, ref, openBlock, createBlock, createSlots, withCtx, createElementVNode, createVNode, renderSlot } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
3
- import { _ as _sfc_main$1 } from "./LpInput-jwqXlAy0.js";
3
+ import { _ as _sfc_main$1 } from "./LpInput-BXr40nqX.js";
4
4
  const _hoisted_1 = ["aria-label"];
5
5
  const __default__ = { inheritAttrs: false };
6
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -128,7 +128,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
128
128
  ])
129
129
  }, {
130
130
  default: withCtx(() => [
131
- createVNode(unref(ComboboxTrigger), { class: "flex flex-1 items-center gap-2 outline-none" }, {
131
+ createVNode(unref(ComboboxTrigger), { class: "flex min-w-0 flex-1 items-center gap-2 outline-none" }, {
132
132
  default: withCtx(() => [
133
133
  displayLabel.value ? (openBlock(), createElementBlock("span", _hoisted_1, toDisplayString(displayLabel.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.placeholder), 1))
134
134
  ]),
@@ -1,6 +1,6 @@
1
- import { defineComponent, computed, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps, createBlock } from "vue";
1
+ import { defineComponent, computed, ref, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps, createBlock } from "vue";
2
2
  import { _ as _sfc_main$2 } from "./LpDrawer-DAJN5rGK.js";
3
- import { _ as _sfc_main$1 } from "./LpSidebarNav-CFX5NxGs.js";
3
+ import { _ as _sfc_main$1 } from "./LpSidebarNav-5RGNr2D3.js";
4
4
  const _hoisted_1 = {
5
5
  key: 1,
6
6
  class: "mt-2 flex shrink-0 flex-col gap-2"
@@ -33,9 +33,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
33
33
  open: { type: Boolean },
34
34
  mobileBreakpoint: { default: "md" },
35
35
  edgeOpen: { type: Boolean },
36
- divider: { type: Boolean, default: true }
36
+ divider: { type: Boolean, default: true },
37
+ collapsed: {},
38
+ autoCollapseAfter: { default: 14 }
37
39
  },
38
- emits: ["update:modelValue", "update:open", "select"],
40
+ emits: ["update:modelValue", "update:open", "update:collapsed", "select"],
39
41
  setup(__props, { emit: __emit }) {
40
42
  const props = __props;
41
43
  const emit = __emit;
@@ -45,6 +47,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
45
47
  function itemActive(item) {
46
48
  return props.isActive ? props.isActive(item) : item.id === props.modelValue;
47
49
  }
50
+ function keyOf(section) {
51
+ return section.key ?? section.title ?? "";
52
+ }
53
+ const ownCollapsed = ref(null);
54
+ const navLength = computed(
55
+ () => groups.value.reduce((n, g) => n + g.items.length + (g.title ? 1 : 0), 0)
56
+ );
57
+ const autoCollapsed = computed(() => {
58
+ const limit = props.autoCollapseAfter;
59
+ if (!limit || navLength.value <= limit) return [];
60
+ return groups.value.filter((g) => g.collapsible && !g.items.some(itemActive)).map(keyOf).filter(Boolean);
61
+ });
62
+ const collapsedKeys = computed(
63
+ () => props.collapsed ?? ownCollapsed.value ?? autoCollapsed.value
64
+ );
65
+ function toggleSection(key, collapsed) {
66
+ const next = collapsed ? [.../* @__PURE__ */ new Set([...collapsedKeys.value, key])] : collapsedKeys.value.filter((k) => k !== key);
67
+ ownCollapsed.value = next;
68
+ emit("update:collapsed", next);
69
+ }
48
70
  function activate(item) {
49
71
  if (item.disabled) return;
50
72
  emit("update:modelValue", item.id);
@@ -82,7 +104,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
82
104
  loading: __props.loading,
83
105
  "skeleton-rows": __props.skeletonRows,
84
106
  "skeleton-header": __props.skeletonHeader,
85
- onActivate: activate
107
+ "collapsed-keys": collapsedKeys.value,
108
+ onActivate: activate,
109
+ onToggleSection: toggleSection
86
110
  }, createSlots({ _: 2 }, [
87
111
  _ctx.$slots.item ? {
88
112
  name: "item",
@@ -91,7 +115,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
91
115
  ]),
92
116
  key: "0"
93
117
  } : void 0
94
- ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header"]),
118
+ ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header", "collapsed-keys"]),
95
119
  _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_1, [
96
120
  renderSlot(_ctx.$slots, "actions")
97
121
  ])) : createCommentVNode("", true),
@@ -123,7 +147,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
123
147
  loading: __props.loading,
124
148
  "skeleton-rows": __props.skeletonRows,
125
149
  "skeleton-header": __props.skeletonHeader,
126
- onActivate: activate
150
+ "collapsed-keys": collapsedKeys.value,
151
+ onActivate: activate,
152
+ onToggleSection: toggleSection
127
153
  }, createSlots({ _: 2 }, [
128
154
  _ctx.$slots.item ? {
129
155
  name: "item",
@@ -132,7 +158,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
132
158
  ]),
133
159
  key: "0"
134
160
  } : void 0
135
- ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header"]),
161
+ ]), 1032, ["groups", "loading", "skeleton-rows", "skeleton-header", "collapsed-keys"]),
136
162
  _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_4, [
137
163
  renderSlot(_ctx.$slots, "actions")
138
164
  ])) : createCommentVNode("", true),
@@ -0,0 +1,185 @@
1
+ import { defineComponent, computed, openBlock, createElementBlock, createElementVNode, createCommentVNode, Fragment, renderList, createBlock, withCtx, unref, toDisplayString, createVNode, normalizeClass, createTextVNode, resolveDynamicComponent, renderSlot } from "vue";
2
+ import { Motion } from "motion-v";
3
+ import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "reka-ui";
4
+ import { usePillTransition } from "../composables/usePillTransition.js";
5
+ import { _ as _sfc_main$3 } from "./LpBadge-BPodVcJa.js";
6
+ import { _ as _sfc_main$4 } from "./LpContextMenu-D0mzXqA7.js";
7
+ import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
8
+ import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
9
+ const _hoisted_1 = {
10
+ key: 0,
11
+ class: "flex min-h-0 flex-1 flex-col gap-4"
12
+ };
13
+ const _hoisted_2 = {
14
+ key: 0,
15
+ class: "flex items-center gap-3 px-1"
16
+ };
17
+ const _hoisted_3 = { class: "space-y-1" };
18
+ const _hoisted_4 = { class: "min-w-0 flex-1 truncate text-left" };
19
+ const _hoisted_5 = {
20
+ key: 1,
21
+ class: "px-2 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted"
22
+ };
23
+ const _hoisted_6 = { class: "relative z-10 min-w-0 flex-1 truncate text-left" };
24
+ const _sfc_main = /* @__PURE__ */ defineComponent({
25
+ __name: "LpSidebarNav",
26
+ props: {
27
+ groups: {},
28
+ pillId: {},
29
+ itemActive: {},
30
+ loading: { type: Boolean },
31
+ skeletonRows: { default: 6 },
32
+ skeletonHeader: { type: Boolean, default: true },
33
+ collapsedKeys: { default: () => [] }
34
+ },
35
+ emits: ["activate", "toggle-section"],
36
+ setup(__props, { emit: __emit }) {
37
+ const props = __props;
38
+ const emit = __emit;
39
+ function sectionKey(section) {
40
+ return section.key ?? section.title ?? "";
41
+ }
42
+ const foldedKeys = computed(() => {
43
+ const holdsActive = new Set(
44
+ props.groups.filter((g) => g.items.some((i) => props.itemActive(i))).map(sectionKey)
45
+ );
46
+ return new Set(
47
+ props.collapsedKeys.filter((k) => k && !holdsActive.has(k))
48
+ );
49
+ });
50
+ function isOpen(section) {
51
+ return !foldedKeys.value.has(sectionKey(section));
52
+ }
53
+ const pillTransition = usePillTransition();
54
+ return (_ctx, _cache) => {
55
+ return __props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [
56
+ __props.skeletonHeader ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[0] || (_cache[0] = [
57
+ createElementVNode("div", { class: "size-10 shrink-0 animate-pulse rounded-pill bg-surface-soft" }, null, -1),
58
+ createElementVNode("div", { class: "flex-1 space-y-2" }, [
59
+ createElementVNode("div", { class: "h-3.5 w-24 animate-pulse rounded bg-surface-soft" }),
60
+ createElementVNode("div", { class: "h-3 w-16 animate-pulse rounded bg-surface-soft/60" })
61
+ ], -1)
62
+ ])])) : createCommentVNode("", true),
63
+ createElementVNode("div", _hoisted_3, [
64
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.skeletonRows, (n) => {
65
+ return openBlock(), createElementBlock("div", {
66
+ key: n,
67
+ class: "h-9 animate-pulse rounded-control bg-surface-soft"
68
+ });
69
+ }), 128))
70
+ ])
71
+ ])) : (openBlock(), createBlock(_sfc_main$1, {
72
+ key: 1,
73
+ class: "min-h-0 flex-1",
74
+ "content-class": "flex min-h-full flex-col gap-4"
75
+ }, {
76
+ default: withCtx(() => [
77
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.groups, (section, si) => {
78
+ return openBlock(), createBlock(unref(CollapsibleRoot), {
79
+ key: si,
80
+ as: "div",
81
+ class: "flex flex-col gap-0.5",
82
+ open: isOpen(section),
83
+ disabled: !section.collapsible || !section.title,
84
+ "onUpdate:open": (o) => emit("toggle-section", sectionKey(section), !o)
85
+ }, {
86
+ default: withCtx(() => [
87
+ section.title && section.collapsible ? (openBlock(), createBlock(unref(CollapsibleTrigger), {
88
+ key: 0,
89
+ class: "group/section mt-2 flex cursor-pointer items-center gap-2 rounded-control px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:bg-white/[0.04] hover:text-ink focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring"
90
+ }, {
91
+ default: withCtx(() => [
92
+ section.icon ? (openBlock(), createBlock(_sfc_main$2, {
93
+ key: 0,
94
+ name: section.icon,
95
+ size: 14,
96
+ class: "shrink-0"
97
+ }, null, 8, ["name"])) : createCommentVNode("", true),
98
+ createElementVNode("span", _hoisted_4, toDisplayString(section.title), 1),
99
+ createVNode(_sfc_main$3, {
100
+ tone: "neutral",
101
+ class: normalizeClass(["shrink-0 transition-opacity duration-[var(--duration-fast)] motion-reduce:transition-none", isOpen(section) ? "opacity-0" : "opacity-100"]),
102
+ "aria-hidden": isOpen(section) || void 0
103
+ }, {
104
+ default: withCtx(() => [
105
+ createTextVNode(toDisplayString(section.items.length), 1)
106
+ ]),
107
+ _: 2
108
+ }, 1032, ["class", "aria-hidden"]),
109
+ createVNode(_sfc_main$2, {
110
+ name: "lucide:chevron-down",
111
+ size: 14,
112
+ class: "shrink-0 text-muted transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-data-[state=closed]/section:-rotate-90 motion-reduce:transition-none"
113
+ })
114
+ ]),
115
+ _: 2
116
+ }, 1024)) : section.title ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(section.title), 1)) : createCommentVNode("", true),
117
+ createVNode(unref(CollapsibleContent), { class: "flex flex-col gap-0.5 overflow-hidden data-[state=open]:animate-[collapsible-down_260ms_var(--ease-emphasized)] data-[state=closed]:animate-[collapsible-up_200ms_var(--ease-emphasized)] motion-reduce:animate-none" }, {
118
+ default: withCtx(() => [
119
+ (openBlock(true), createElementBlock(Fragment, null, renderList(section.items, (item) => {
120
+ return openBlock(), createBlock(_sfc_main$4, {
121
+ key: item.id,
122
+ items: item.menu ?? []
123
+ }, {
124
+ default: withCtx(() => [
125
+ (openBlock(), createBlock(resolveDynamicComponent(item.href && !item.disabled ? "a" : "button"), {
126
+ href: item.href && !item.disabled ? item.href : void 0,
127
+ type: item.href ? void 0 : "button",
128
+ disabled: item.href ? void 0 : item.disabled,
129
+ "aria-current": __props.itemActive(item) ? "page" : void 0,
130
+ "aria-disabled": item.disabled || void 0,
131
+ 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-inset focus-visible:ring-ring", item.disabled ? "cursor-not-allowed text-muted/50" : __props.itemActive(item) ? "text-ink" : "text-muted hover:text-ink"]),
132
+ onClick: ($event) => emit("activate", item)
133
+ }, {
134
+ default: withCtx(() => [
135
+ __props.itemActive(item) ? (openBlock(), createBlock(unref(Motion), {
136
+ key: 0,
137
+ "layout-id": __props.pillId,
138
+ transition: unref(pillTransition),
139
+ class: "absolute inset-0 z-0 rounded-control bg-brand-soft"
140
+ }, null, 8, ["layout-id", "transition"])) : createCommentVNode("", true),
141
+ renderSlot(_ctx.$slots, "item", {
142
+ item,
143
+ active: __props.itemActive(item)
144
+ }, () => [
145
+ item.icon ? (openBlock(), createBlock(_sfc_main$2, {
146
+ key: 0,
147
+ name: item.icon,
148
+ size: 17,
149
+ class: normalizeClass(["relative z-10 shrink-0 transition-colors", __props.itemActive(item) ? "text-brand" : ""])
150
+ }, null, 8, ["name", "class"])) : createCommentVNode("", true),
151
+ createElementVNode("span", _hoisted_6, toDisplayString(item.label), 1),
152
+ item.badge != null ? (openBlock(), createBlock(_sfc_main$3, {
153
+ key: 1,
154
+ tone: __props.itemActive(item) ? "brand" : "neutral",
155
+ class: "relative z-10 shrink-0"
156
+ }, {
157
+ default: withCtx(() => [
158
+ createTextVNode(toDisplayString(item.badge), 1)
159
+ ]),
160
+ _: 2
161
+ }, 1032, ["tone"])) : createCommentVNode("", true)
162
+ ])
163
+ ]),
164
+ _: 2
165
+ }, 1032, ["href", "type", "disabled", "aria-current", "aria-disabled", "class", "onClick"]))
166
+ ]),
167
+ _: 2
168
+ }, 1032, ["items"]);
169
+ }), 128))
170
+ ]),
171
+ _: 2
172
+ }, 1024)
173
+ ]),
174
+ _: 2
175
+ }, 1032, ["open", "disabled", "onUpdate:open"]);
176
+ }), 128))
177
+ ]),
178
+ _: 3
179
+ }));
180
+ };
181
+ }
182
+ });
183
+ export {
184
+ _sfc_main as _
185
+ };
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, computed, openBlock, createBlock, resolveDynamicComponent, normalizeClass, withCtx, createElementVNode } from "vue";
2
- import { _ as _sfc_main$1 } from "./LpFormField-CesaPWPO.js";
2
+ import { _ as _sfc_main$1 } from "./LpFormField-DEaakcHe.js";
3
3
  const _hoisted_1 = ["value", "placeholder", "rows", "disabled", "required"];
4
4
  const _sfc_main = /* @__PURE__ */ defineComponent({
5
5
  __name: "LpTextarea",
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAddressInput-BTqnUXZG.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAddressInput-BoTkszLk.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -4,6 +4,10 @@ type __VLS_Props = {
4
4
  /** Flat items, or sections for grouped nav. Forwarded to LpSidebar. */
5
5
  items?: SidebarItem[];
6
6
  sections?: SidebarSection[];
7
+ /** Folded nav groups (v-model:collapsed). Forwarded to LpSidebar. */
8
+ collapsed?: string[];
9
+ /** Fold long navs automatically; 0 disables. Forwarded to LpSidebar. */
10
+ autoCollapseAfter?: number;
7
11
  /** Active item id (v-model) when not using a custom `isActive`. */
8
12
  modelValue?: string;
9
13
  /**
@@ -35,28 +39,28 @@ type __VLS_Props = {
35
39
  /** Loading skeleton for the nav. */
36
40
  loading?: boolean;
37
41
  };
38
- declare var __VLS_12: {}, __VLS_15: {}, __VLS_18: {}, __VLS_21: {
42
+ declare var __VLS_13: {}, __VLS_16: {}, __VLS_19: {}, __VLS_22: {
39
43
  item: SidebarItem;
40
44
  active: boolean;
41
- }, __VLS_42: {}, __VLS_50: {}, __VLS_52: {}, __VLS_60: {}, __VLS_62: {};
45
+ }, __VLS_43: {}, __VLS_51: {}, __VLS_53: {}, __VLS_61: {}, __VLS_63: {};
42
46
  type __VLS_Slots = {} & {
43
- logo?: (props: typeof __VLS_12) => any;
47
+ logo?: (props: typeof __VLS_13) => any;
44
48
  } & {
45
- 'sidebar-actions'?: (props: typeof __VLS_15) => any;
49
+ 'sidebar-actions'?: (props: typeof __VLS_16) => any;
46
50
  } & {
47
- 'sidebar-footer'?: (props: typeof __VLS_18) => any;
51
+ 'sidebar-footer'?: (props: typeof __VLS_19) => any;
48
52
  } & {
49
- 'sidebar-item'?: (props: typeof __VLS_21) => any;
53
+ 'sidebar-item'?: (props: typeof __VLS_22) => any;
50
54
  } & {
51
- 'header-title'?: (props: typeof __VLS_42) => any;
55
+ 'header-title'?: (props: typeof __VLS_43) => any;
52
56
  } & {
53
- 'header-actions'?: (props: typeof __VLS_50) => any;
57
+ 'header-actions'?: (props: typeof __VLS_51) => any;
54
58
  } & {
55
- default?: (props: typeof __VLS_52) => any;
59
+ default?: (props: typeof __VLS_53) => any;
56
60
  } & {
57
- default?: (props: typeof __VLS_60) => any;
61
+ default?: (props: typeof __VLS_61) => any;
58
62
  } & {
59
- overlays?: (props: typeof __VLS_62) => any;
63
+ overlays?: (props: typeof __VLS_63) => any;
60
64
  };
61
65
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
62
66
  openDrawer: () => void;
@@ -64,10 +68,12 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
64
68
  select: (item: SidebarItem) => any;
65
69
  "update:modelValue": (id: string) => any;
66
70
  "update:open": (value: boolean) => any;
71
+ "update:collapsed": (keys: string[]) => any;
67
72
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
68
73
  onSelect?: ((item: SidebarItem) => any) | undefined;
69
74
  "onUpdate:modelValue"?: ((id: string) => any) | undefined;
70
75
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
76
+ "onUpdate:collapsed"?: ((keys: string[]) => any) | undefined;
71
77
  }>, {
72
78
  contentClass: string;
73
79
  mobileBreakpoint: "sm" | "md" | "lg" | "xl";
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpAppShell-B5k0J3Cf.js";
1
+ import { _ as _sfc_main } from "../chunks/LpAppShell-CGX0DlIW.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpCard-gu11ZmSt.js";
1
+ import { _ as _sfc_main } from "../chunks/LpCard-DSefTGEH.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpChart-tNXs1ttr.js";
1
+ import { _ as _sfc_main } from "../chunks/LpChart-UiU4RhXP.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpFormField-CesaPWPO.js";
1
+ import { _ as _sfc_main } from "../chunks/LpFormField-DEaakcHe.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpInput-jwqXlAy0.js";
1
+ import { _ as _sfc_main } from "../chunks/LpInput-BXr40nqX.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpPasswordInput-Bmo6q9Kd.js";
1
+ import { _ as _sfc_main } from "../chunks/LpPasswordInput-Bdv6o8ae.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpSelect-Cw8-gL5F.js";
1
+ import { _ as _sfc_main } from "../chunks/LpSelect-ANIVtrpM.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };