@leavepulse/ui 0.28.3 → 0.28.5
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.
- package/dist/chunks/{LpAddressInput-BTqnUXZG.js → LpAddressInput-Bk6D8Bcy.js} +3 -3
- package/dist/chunks/{LpAppShell-B5k0J3Cf.js → LpAppShell-CGX0DlIW.js} +11 -6
- package/dist/chunks/{LpCard-gu11ZmSt.js → LpCard-DSefTGEH.js} +7 -1
- package/dist/chunks/{LpFormField-CesaPWPO.js → LpFormField-fV_2ZdCk.js} +7 -3
- package/dist/chunks/{LpInput-jwqXlAy0.js → LpInput-CYcTL9gj.js} +1 -1
- package/dist/chunks/{LpPasswordInput-Bmo6q9Kd.js → LpPasswordInput-DrYE4J5d.js} +1 -1
- package/dist/chunks/{LpSelect-Cw8-gL5F.js → LpSelect-ANIVtrpM.js} +1 -1
- package/dist/chunks/{LpSidebar-7Vpy2IJc.js → LpSidebar-CWehDCxN.js} +34 -8
- package/dist/chunks/LpSidebarNav-5RGNr2D3.js +185 -0
- package/dist/chunks/{LpTextarea-1ENb3ZAO.js → LpTextarea-BMIOfw5l.js} +1 -1
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAppShell.vue.d.ts +17 -11
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpFormField.vue.d.ts +3 -1
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpSelect.vue.js +1 -1
- package/dist/components/LpSidebar.vue.d.ts +32 -10
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.d.ts +11 -2
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/sidebar.d.ts +18 -0
- package/dist/index.js +9 -9
- package/package.json +1 -1
- package/src/components/LpAppShell.vue +27 -3
- package/src/components/LpCard.vue +7 -1
- package/src/components/LpFormField.vue +13 -3
- package/src/components/LpSelect.vue +0 -0
- package/src/components/LpSidebar.vue +67 -1
- package/src/components/LpSidebarNav.vue +83 -4
- package/src/components/sidebar.ts +18 -0
- 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-
|
|
6
|
+
import { _ as _sfc_main$1 } from "./LpFormField-fV_2ZdCk.js";
|
|
7
7
|
import { _ as _sfc_main$4 } from "./LpIcon-CCnX5_2j.js";
|
|
8
|
-
import { _ as _sfc_main$5 } from "./LpInput-
|
|
8
|
+
import { _ as _sfc_main$5 } from "./LpInput-CYcTL9gj.js";
|
|
9
9
|
import { _ as _sfc_main$7 } from "./LpModal-D_o-56To.js";
|
|
10
|
-
import { _ as _sfc_main$6 } from "./LpSelect-
|
|
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-
|
|
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[
|
|
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
|
|
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
|
-
|
|
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
|
|
@@ -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"
|
|
@@ -40,9 +40,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
40
40
|
renderSlot(_ctx.$slots, "default", { id: unref(id) }),
|
|
41
41
|
createVNode(_sfc_main$1, { axis: "height" }, {
|
|
42
42
|
default: withCtx(() => [
|
|
43
|
-
__props.error ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.error), 1)) : __props.hint ? (openBlock(), createElementBlock("p", _hoisted_4,
|
|
43
|
+
__props.error ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.error), 1)) : __props.hint || _ctx.$slots.hint ? (openBlock(), createElementBlock("p", _hoisted_4, [
|
|
44
|
+
renderSlot(_ctx.$slots, "hint", {}, () => [
|
|
45
|
+
createTextVNode(toDisplayString(__props.hint), 1)
|
|
46
|
+
])
|
|
47
|
+
])) : createCommentVNode("", true)
|
|
44
48
|
]),
|
|
45
|
-
_:
|
|
49
|
+
_: 3
|
|
46
50
|
})
|
|
47
51
|
]);
|
|
48
52
|
};
|
|
@@ -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-
|
|
4
|
+
import { _ as _sfc_main$1 } from "./LpFormField-fV_2ZdCk.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-
|
|
3
|
+
import { _ as _sfc_main$1 } from "./LpInput-CYcTL9gj.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-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
2
|
+
import { _ as _sfc_main$1 } from "./LpFormField-fV_2ZdCk.js";
|
|
3
3
|
const _hoisted_1 = ["value", "placeholder", "rows", "disabled", "required"];
|
|
4
4
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
5
5
|
__name: "LpTextarea",
|
|
@@ -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
|
|
42
|
+
declare var __VLS_13: {}, __VLS_16: {}, __VLS_19: {}, __VLS_22: {
|
|
39
43
|
item: SidebarItem;
|
|
40
44
|
active: boolean;
|
|
41
|
-
},
|
|
45
|
+
}, __VLS_43: {}, __VLS_51: {}, __VLS_53: {}, __VLS_61: {}, __VLS_63: {};
|
|
42
46
|
type __VLS_Slots = {} & {
|
|
43
|
-
logo?: (props: typeof
|
|
47
|
+
logo?: (props: typeof __VLS_13) => any;
|
|
44
48
|
} & {
|
|
45
|
-
'sidebar-actions'?: (props: typeof
|
|
49
|
+
'sidebar-actions'?: (props: typeof __VLS_16) => any;
|
|
46
50
|
} & {
|
|
47
|
-
'sidebar-footer'?: (props: typeof
|
|
51
|
+
'sidebar-footer'?: (props: typeof __VLS_19) => any;
|
|
48
52
|
} & {
|
|
49
|
-
'sidebar-item'?: (props: typeof
|
|
53
|
+
'sidebar-item'?: (props: typeof __VLS_22) => any;
|
|
50
54
|
} & {
|
|
51
|
-
'header-title'?: (props: typeof
|
|
55
|
+
'header-title'?: (props: typeof __VLS_43) => any;
|
|
52
56
|
} & {
|
|
53
|
-
'header-actions'?: (props: typeof
|
|
57
|
+
'header-actions'?: (props: typeof __VLS_51) => any;
|
|
54
58
|
} & {
|
|
55
|
-
default?: (props: typeof
|
|
59
|
+
default?: (props: typeof __VLS_53) => any;
|
|
56
60
|
} & {
|
|
57
|
-
default?: (props: typeof
|
|
61
|
+
default?: (props: typeof __VLS_61) => any;
|
|
58
62
|
} & {
|
|
59
|
-
overlays?: (props: typeof
|
|
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";
|
|
@@ -6,9 +6,11 @@ type __VLS_Props = {
|
|
|
6
6
|
};
|
|
7
7
|
declare var __VLS_7: {
|
|
8
8
|
id: string;
|
|
9
|
-
};
|
|
9
|
+
}, __VLS_15: {};
|
|
10
10
|
type __VLS_Slots = {} & {
|
|
11
11
|
default?: (props: typeof __VLS_7) => any;
|
|
12
|
+
} & {
|
|
13
|
+
hint?: (props: typeof __VLS_15) => any;
|
|
12
14
|
};
|
|
13
15
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
14
16
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -35,45 +35,67 @@ type __VLS_Props = {
|
|
|
35
35
|
* flush, header-less look.
|
|
36
36
|
*/
|
|
37
37
|
divider?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Which collapsible groups are folded away (v-model:collapsed). Leave it
|
|
40
|
+
* unbound to let the sidebar fold long navs on its own — see
|
|
41
|
+
* `autoCollapseAfter`.
|
|
42
|
+
*/
|
|
43
|
+
collapsed?: string[];
|
|
44
|
+
/**
|
|
45
|
+
* Fold collapsible groups automatically once the nav has more than this
|
|
46
|
+
* many rows, counting headings and items alike.
|
|
47
|
+
*
|
|
48
|
+
* The reason is the reader, not the pixels: a short nav is taken in at a
|
|
49
|
+
* glance, a long one has to be searched, and searching a list you did not
|
|
50
|
+
* choose to have is the part that grates. Past the threshold the groups
|
|
51
|
+
* that are not today's work fold themselves, and the one holding the
|
|
52
|
+
* current page always stays open.
|
|
53
|
+
*
|
|
54
|
+
* 0 turns it off — the app then owns the state through `collapsed`.
|
|
55
|
+
*/
|
|
56
|
+
autoCollapseAfter?: number;
|
|
38
57
|
};
|
|
39
|
-
declare var __VLS_1: {},
|
|
58
|
+
declare var __VLS_1: {}, __VLS_13: {
|
|
40
59
|
item: SidebarItem;
|
|
41
60
|
active: boolean;
|
|
42
|
-
},
|
|
61
|
+
}, __VLS_15: {}, __VLS_17: {}, __VLS_27: {}, __VLS_39: {
|
|
43
62
|
item: SidebarItem;
|
|
44
63
|
active: boolean;
|
|
45
|
-
},
|
|
64
|
+
}, __VLS_41: {}, __VLS_43: {};
|
|
46
65
|
type __VLS_Slots = {} & {
|
|
47
66
|
header?: (props: typeof __VLS_1) => any;
|
|
48
67
|
} & {
|
|
49
|
-
item?: (props: typeof
|
|
68
|
+
item?: (props: typeof __VLS_13) => any;
|
|
50
69
|
} & {
|
|
51
|
-
actions?: (props: typeof
|
|
70
|
+
actions?: (props: typeof __VLS_15) => any;
|
|
52
71
|
} & {
|
|
53
|
-
footer?: (props: typeof
|
|
72
|
+
footer?: (props: typeof __VLS_17) => any;
|
|
54
73
|
} & {
|
|
55
|
-
header?: (props: typeof
|
|
74
|
+
header?: (props: typeof __VLS_27) => any;
|
|
56
75
|
} & {
|
|
57
|
-
item?: (props: typeof
|
|
76
|
+
item?: (props: typeof __VLS_39) => any;
|
|
58
77
|
} & {
|
|
59
|
-
actions?: (props: typeof
|
|
78
|
+
actions?: (props: typeof __VLS_41) => any;
|
|
60
79
|
} & {
|
|
61
|
-
footer?: (props: typeof
|
|
80
|
+
footer?: (props: typeof __VLS_43) => any;
|
|
62
81
|
};
|
|
63
82
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
64
83
|
select: (item: SidebarItem) => any;
|
|
65
84
|
"update:modelValue": (id: string) => any;
|
|
66
85
|
"update:open": (value: boolean) => any;
|
|
86
|
+
"update:collapsed": (keys: string[]) => any;
|
|
67
87
|
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
68
88
|
onSelect?: ((item: SidebarItem) => any) | undefined;
|
|
69
89
|
"onUpdate:modelValue"?: ((id: string) => any) | undefined;
|
|
70
90
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
91
|
+
"onUpdate:collapsed"?: ((keys: string[]) => any) | undefined;
|
|
71
92
|
}>, {
|
|
72
93
|
skeletonRows: number;
|
|
73
94
|
skeletonHeader: boolean;
|
|
74
95
|
responsive: boolean;
|
|
75
96
|
mobileBreakpoint: "sm" | "md" | "lg" | "xl";
|
|
76
97
|
divider: boolean;
|
|
98
|
+
autoCollapseAfter: number;
|
|
77
99
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
78
100
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
79
101
|
declare const _default: typeof __VLS_export;
|