@leavepulse/ui 0.30.0 → 0.31.0
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/assets/{LpTable-Bz3uJNa3.css → LpTable-Ckoi05Am.css} +8 -8
- package/dist/chunks/{LpActionBar-CxmBZpGu.js → LpActionBar-BlvtGB2P.js} +1 -1
- package/dist/chunks/{LpAddressInput-Bk6D8Bcy.js → LpAddressInput-BDkp3-Bp.js} +1 -1
- package/dist/chunks/{LpAppShell-DnocEJAu.js → LpAppShell-Chz8Vbtu.js} +1 -1
- package/dist/chunks/LpBadge-Fe0D1bYx.js +62 -0
- package/dist/chunks/{LpDisclosure-C1_YkMrd.js → LpDisclosure-B4kVAWfg.js} +1 -1
- package/dist/chunks/{LpInput-CYcTL9gj.js → LpInput-Bt4J71xn.js} +3 -2
- package/dist/chunks/{LpNotificationBell-CTsIcPqX.js → LpNotificationBell-gdvQY89m.js} +1 -1
- package/dist/chunks/{LpPasswordInput-DrYE4J5d.js → LpPasswordInput-BqMAc5HA.js} +1 -1
- package/dist/chunks/{LpSidebar-CWSbczWi.js → LpSidebar-BiWM_lDB.js} +64 -14
- package/dist/chunks/{LpSidebarNav-D6v12-36.js → LpSidebarNav-CsgeuGAu.js} +1 -1
- package/dist/components/LpActionBar.vue.js +1 -1
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpBadge.vue.d.ts +13 -43
- package/dist/components/LpBadge.vue.js +1 -1
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpSidebar.vue.d.ts +28 -10
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpTable.vue.js +47 -44
- package/dist/components/sidebar.d.ts +6 -0
- package/dist/composables/useMergedClass.d.ts +22 -0
- package/dist/composables/useMergedClass.js +13 -0
- package/dist/index.js +9 -9
- package/package.json +1 -1
- package/src/components/LpActionBar.vue +9 -1
- package/src/components/LpBadge.vue +32 -6
- package/src/components/LpDisclosure.vue +7 -1
- package/src/components/LpInput.vue +2 -1
- package/src/components/LpSidebar.vue +86 -3
- package/src/components/LpTable.vue +59 -39
- package/src/components/sidebar.ts +6 -0
- package/src/composables/useMergedClass.ts +56 -0
- package/dist/chunks/LpBadge-BPodVcJa.js +0 -45
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
* fade before closing the gap and the whole list lurches at the end instead of
|
|
12
12
|
* gliding.
|
|
13
13
|
*/
|
|
14
|
-
.lp-row-enter-active[data-v-
|
|
15
|
-
.lp-row-leave-active[data-v-
|
|
14
|
+
.lp-row-enter-active[data-v-d139c3bb],
|
|
15
|
+
.lp-row-leave-active[data-v-d139c3bb] {
|
|
16
16
|
transition:
|
|
17
17
|
opacity var(--duration-fast) var(--ease-emphasized),
|
|
18
18
|
transform var(--duration-fast) var(--ease-emphasized);
|
|
19
19
|
}
|
|
20
|
-
.lp-row-move[data-v-
|
|
20
|
+
.lp-row-move[data-v-d139c3bb] {
|
|
21
21
|
transition: transform var(--duration-medium) var(--ease-emphasized);
|
|
22
22
|
}
|
|
23
|
-
.lp-row-enter-from[data-v-
|
|
24
|
-
.lp-row-leave-to[data-v-
|
|
23
|
+
.lp-row-enter-from[data-v-d139c3bb],
|
|
24
|
+
.lp-row-leave-to[data-v-d139c3bb] {
|
|
25
25
|
opacity: 0;
|
|
26
26
|
transform: translateX(-0.5rem);
|
|
27
27
|
}
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
/* A filter that redraws the list is information, not decoration: with motion
|
|
38
38
|
turned down the rows change without animating rather than not changing. */
|
|
39
39
|
@media (prefers-reduced-motion: reduce) {
|
|
40
|
-
.lp-row-enter-active[data-v-
|
|
41
|
-
.lp-row-leave-active[data-v-
|
|
42
|
-
.lp-row-move[data-v-
|
|
40
|
+
.lp-row-enter-active[data-v-d139c3bb],
|
|
41
|
+
.lp-row-leave-active[data-v-d139c3bb],
|
|
42
|
+
.lp-row-move[data-v-d139c3bb] {
|
|
43
43
|
transition: none;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -79,7 +79,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
79
79
|
return openBlock(), createBlock(Teleport, { to: "body" }, [
|
|
80
80
|
createVNode(Transition, {
|
|
81
81
|
"enter-active-class": "animate-[rise-in_var(--duration-medium)_var(--ease-emphasized)]",
|
|
82
|
-
"leave-active-class": "animate-[rise-out_var(--duration-fast)
|
|
82
|
+
"leave-active-class": "animate-[rise-out_var(--duration-fast)_ease_forwards] motion-reduce:animate-none"
|
|
83
83
|
}, {
|
|
84
84
|
default: withCtx(() => [
|
|
85
85
|
__props.open ? (openBlock(), createElementBlock("div", {
|
|
@@ -5,7 +5,7 @@ import { _ as _sfc_main$2 } from "./LpAutocomplete-DExlIZe_.js";
|
|
|
5
5
|
import { _ as _sfc_main$3 } from "./LpButton-5VXXCjwF.js";
|
|
6
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-Bt4J71xn.js";
|
|
9
9
|
import { _ as _sfc_main$7 } from "./LpModal-D_o-56To.js";
|
|
10
10
|
import { _ as _sfc_main$6 } from "./LpSelect-ANIVtrpM.js";
|
|
11
11
|
const _hoisted_1 = { class: "flex flex-col gap-3" };
|
|
@@ -3,7 +3,7 @@ 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-BiWM_lDB.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
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" };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { defineComponent, openBlock, createElementBlock, mergeProps, unref, createCommentVNode, renderSlot } from "vue";
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
import { useMergedClass } from "../composables/useMergedClass.js";
|
|
4
|
+
const _hoisted_1 = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "size-1.5 rounded-full bg-current"
|
|
7
|
+
};
|
|
8
|
+
const __default__ = { inheritAttrs: false };
|
|
9
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
10
|
+
...__default__,
|
|
11
|
+
__name: "LpBadge",
|
|
12
|
+
props: {
|
|
13
|
+
tone: {},
|
|
14
|
+
size: {},
|
|
15
|
+
dot: { type: Boolean }
|
|
16
|
+
},
|
|
17
|
+
setup(__props) {
|
|
18
|
+
const badge = tv({
|
|
19
|
+
/*
|
|
20
|
+
* `align-middle` and a line-height pinned to the box, because the default
|
|
21
|
+
* `inline-flex` baseline is the one thing a badge must not bring with it: a
|
|
22
|
+
* badge dropped next to a text-sm heading sat a pixel or two off the text's
|
|
23
|
+
* baseline and pushed the whole row taller, so a section title grew a step
|
|
24
|
+
* the moment it gained a status. The badge now occupies the height it says it
|
|
25
|
+
* does and leaves the line it sits on alone.
|
|
26
|
+
*/
|
|
27
|
+
base: "inline-flex shrink-0 items-center gap-1.5 rounded-pill align-middle font-medium leading-[1.2]",
|
|
28
|
+
variants: {
|
|
29
|
+
size: {
|
|
30
|
+
// Fits inside a text-sm line without growing it — for a badge beside a
|
|
31
|
+
// heading, in a table cell, or anywhere a row's height is already set.
|
|
32
|
+
sm: "h-[18px] px-1.5 text-[11px]",
|
|
33
|
+
md: "px-2.5 py-0.5 text-xs",
|
|
34
|
+
lg: "px-3 py-1 text-sm"
|
|
35
|
+
},
|
|
36
|
+
tone: {
|
|
37
|
+
neutral: "bg-surface-soft text-muted-strong",
|
|
38
|
+
brand: "bg-brand-soft text-brand",
|
|
39
|
+
action: "bg-action/15 text-action",
|
|
40
|
+
success: "bg-action/15 text-action",
|
|
41
|
+
// Partial trouble, which every status surface eventually needs: without
|
|
42
|
+
// it a half-failed thing has to render as either fine or broken.
|
|
43
|
+
warning: "bg-accent/15 text-accent",
|
|
44
|
+
danger: "bg-danger-soft text-danger",
|
|
45
|
+
outline: "border border-line text-ink"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: { tone: "neutral", size: "md" }
|
|
49
|
+
});
|
|
50
|
+
const props = __props;
|
|
51
|
+
const classes = useMergedClass(() => badge({ tone: props.tone, size: props.size }));
|
|
52
|
+
return (_ctx, _cache) => {
|
|
53
|
+
return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, { class: unref(classes) }), [
|
|
54
|
+
__props.dot ? (openBlock(), createElementBlock("span", _hoisted_1)) : createCommentVNode("", true),
|
|
55
|
+
renderSlot(_ctx.$slots, "default")
|
|
56
|
+
], 16);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
export {
|
|
61
|
+
_sfc_main as _
|
|
62
|
+
};
|
|
@@ -2,7 +2,7 @@ import { defineComponent, getCurrentInstance, computed, ref, openBlock, createBl
|
|
|
2
2
|
import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "reka-ui";
|
|
3
3
|
import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
|
|
4
4
|
const _hoisted_1 = { class: "min-w-0 flex-1 text-left" };
|
|
5
|
-
const _hoisted_2 = { class: "grid gap-2.5 px-3 pt-1 pb-3
|
|
5
|
+
const _hoisted_2 = { class: "grid gap-2.5 px-3 pt-1 pb-3 group-data-[state=open]/content:animate-[disclosure-body-in_300ms_var(--ease-emphasized)] motion-reduce:animate-none" };
|
|
6
6
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
7
7
|
__name: "LpDisclosure",
|
|
8
8
|
props: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { defineComponent, computed, useSlots, useAttrs, ref, openBlock, createBlock, resolveDynamicComponent, normalizeStyle, normalizeClass, withCtx, createElementVNode, createElementBlock, renderSlot, createCommentVNode, mergeProps
|
|
1
|
+
import { defineComponent, computed, useSlots, useAttrs, ref, openBlock, createBlock, resolveDynamicComponent, normalizeStyle, normalizeClass, withCtx, createElementVNode, unref, createElementBlock, renderSlot, createCommentVNode, mergeProps } from "vue";
|
|
2
2
|
import { tv } from "tailwind-variants";
|
|
3
3
|
import { useInputFilter } from "../composables/useInputFilter.js";
|
|
4
|
+
import { mergeClass } from "../composables/useMergedClass.js";
|
|
4
5
|
import { _ as _sfc_main$1 } from "./LpFormField-fV_2ZdCk.js";
|
|
5
6
|
import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
|
|
6
7
|
const _hoisted_1 = {
|
|
@@ -98,7 +99,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
98
99
|
default: withCtx(() => [
|
|
99
100
|
createElementVNode("div", {
|
|
100
101
|
"data-lp-ring-owner": "",
|
|
101
|
-
class: normalizeClass(
|
|
102
|
+
class: normalizeClass(unref(mergeClass)(shellClass.value, hasLeading.value ? "pl-2.5" : "", hasTrailing.value ? "pr-1.5" : "", hasField.value ? "" : rootClass.value)),
|
|
102
103
|
style: normalizeStyle(hasField.value ? void 0 : rootStyle.value)
|
|
103
104
|
}, [
|
|
104
105
|
hasLeading.value ? (openBlock(), createElementBlock("span", _hoisted_1, [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent, computed, useModel, getCurrentInstance, openBlock, createBlock, withCtx, createElementVNode, toDisplayString, createElementBlock, createCommentVNode, createVNode, Fragment, renderList, resolveDynamicComponent, normalizeClass, createTextVNode, mergeModels } from "vue";
|
|
2
|
-
import { _ as _sfc_main$8 } from "./LpBadge-
|
|
2
|
+
import { _ as _sfc_main$8 } from "./LpBadge-Fe0D1bYx.js";
|
|
3
3
|
import { _ as _sfc_main$7 } from "./LpButton-5VXXCjwF.js";
|
|
4
4
|
import { _ as _sfc_main$5 } from "./LpContextMenu-B6WBLleS.js";
|
|
5
5
|
import { _ as _sfc_main$3 } from "./LpEmptyState-BV3q7Qyi.js";
|
|
@@ -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-Bt4J71xn.js";
|
|
4
4
|
const _hoisted_1 = ["aria-label"];
|
|
5
5
|
const __default__ = { inheritAttrs: false };
|
|
6
6
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import { defineComponent, computed, ref, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps
|
|
2
|
-
import { _ as _sfc_main$
|
|
3
|
-
import { _ as _sfc_main$1 } from "./
|
|
1
|
+
import { defineComponent, computed, ref, useId, openBlock, createElementBlock, Fragment, createElementVNode, mergeProps, normalizeClass, renderSlot, createCommentVNode, createBlock, createVNode, createSlots, withCtx, normalizeProps, guardReactiveProps } from "vue";
|
|
2
|
+
import { _ as _sfc_main$3 } from "./LpDrawer-DAJN5rGK.js";
|
|
3
|
+
import { _ as _sfc_main$1 } from "./LpInput-Bt4J71xn.js";
|
|
4
|
+
import { _ as _sfc_main$2 } from "./LpSidebarNav-CsgeuGAu.js";
|
|
4
5
|
const _hoisted_1 = {
|
|
5
|
-
key:
|
|
6
|
+
key: 2,
|
|
6
7
|
class: "mt-2 flex shrink-0 flex-col gap-2"
|
|
7
8
|
};
|
|
8
9
|
const _hoisted_2 = {
|
|
9
|
-
key:
|
|
10
|
+
key: 3,
|
|
10
11
|
class: "mt-2 shrink-0 border-t border-line pt-3"
|
|
11
12
|
};
|
|
12
13
|
const _hoisted_3 = { class: "flex h-full flex-col gap-1" };
|
|
13
14
|
const _hoisted_4 = {
|
|
14
|
-
key:
|
|
15
|
+
key: 2,
|
|
15
16
|
class: "mt-2 flex shrink-0 flex-col gap-2"
|
|
16
17
|
};
|
|
17
18
|
const _hoisted_5 = {
|
|
18
|
-
key:
|
|
19
|
+
key: 3,
|
|
19
20
|
class: "mt-2 shrink-0 border-t border-line pt-3"
|
|
20
21
|
};
|
|
21
22
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
@@ -26,6 +27,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
26
27
|
items: {},
|
|
27
28
|
sections: {},
|
|
28
29
|
isActive: {},
|
|
30
|
+
searchable: { type: Boolean },
|
|
31
|
+
searchPlaceholder: { default: "Search" },
|
|
32
|
+
search: {},
|
|
29
33
|
loading: { type: Boolean },
|
|
30
34
|
skeletonRows: { default: 6 },
|
|
31
35
|
skeletonHeader: { type: Boolean, default: true },
|
|
@@ -39,13 +43,34 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
39
43
|
collapsed: {},
|
|
40
44
|
autoCollapseAfter: { default: 14 }
|
|
41
45
|
},
|
|
42
|
-
emits: ["update:modelValue", "update:open", "update:collapsed", "select"],
|
|
46
|
+
emits: ["update:modelValue", "update:open", "update:collapsed", "select", "update:search"],
|
|
43
47
|
setup(__props, { emit: __emit }) {
|
|
44
48
|
const props = __props;
|
|
45
49
|
const emit = __emit;
|
|
46
|
-
const
|
|
50
|
+
const allGroups = computed(
|
|
47
51
|
() => props.sections ?? (props.items ? [{ items: props.items }] : [])
|
|
48
52
|
);
|
|
53
|
+
const ownSearch = ref("");
|
|
54
|
+
const query = computed({
|
|
55
|
+
get: () => props.search ?? ownSearch.value,
|
|
56
|
+
set: (v) => {
|
|
57
|
+
ownSearch.value = v;
|
|
58
|
+
emit("update:search", v);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
function normalise(s) {
|
|
62
|
+
return s.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
function matches(item, needle) {
|
|
65
|
+
if (normalise(item.label).includes(needle)) return true;
|
|
66
|
+
return (item.keywords ?? []).some((k) => normalise(k).includes(needle));
|
|
67
|
+
}
|
|
68
|
+
const groups = computed(() => {
|
|
69
|
+
const needle = normalise(query.value.trim());
|
|
70
|
+
if (!needle) return allGroups.value;
|
|
71
|
+
return allGroups.value.map((section) => ({ ...section, items: section.items.filter((i) => matches(i, needle)) })).filter((section) => section.items.length > 0);
|
|
72
|
+
});
|
|
73
|
+
const filtering = computed(() => query.value.trim().length > 0);
|
|
49
74
|
function itemActive(item) {
|
|
50
75
|
return props.isActive ? props.isActive(item) : item.id === props.modelValue;
|
|
51
76
|
}
|
|
@@ -62,7 +87,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
62
87
|
return groups.value.filter((g) => g.collapsible && !g.items.some(itemActive)).map(keyOf).filter(Boolean);
|
|
63
88
|
});
|
|
64
89
|
const collapsedKeys = computed(
|
|
65
|
-
() =>
|
|
90
|
+
() => (
|
|
91
|
+
// Nothing stays folded while a query is on: a section that matched but is
|
|
92
|
+
// closed looks exactly like a section that did not match, and the person is
|
|
93
|
+
// typing precisely because they cannot find the thing by eye.
|
|
94
|
+
filtering.value ? [] : props.collapsed ?? ownCollapsed.value ?? autoCollapsed.value
|
|
95
|
+
)
|
|
66
96
|
);
|
|
67
97
|
function toggleSection(key, collapsed) {
|
|
68
98
|
const next = collapsed ? [.../* @__PURE__ */ new Set([...collapsedKeys.value, key])] : collapsedKeys.value.filter((k) => k !== key);
|
|
@@ -106,7 +136,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
106
136
|
}, [
|
|
107
137
|
renderSlot(_ctx.$slots, "header")
|
|
108
138
|
], 2)) : createCommentVNode("", true),
|
|
109
|
-
|
|
139
|
+
__props.searchable ? (openBlock(), createBlock(_sfc_main$1, {
|
|
140
|
+
key: 1,
|
|
141
|
+
modelValue: query.value,
|
|
142
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => query.value = $event),
|
|
143
|
+
size: "sm",
|
|
144
|
+
icon: "lucide:search",
|
|
145
|
+
class: "mb-2 shrink-0",
|
|
146
|
+
placeholder: __props.searchPlaceholder,
|
|
147
|
+
"aria-label": __props.searchPlaceholder
|
|
148
|
+
}, null, 8, ["modelValue", "placeholder", "aria-label"])) : createCommentVNode("", true),
|
|
149
|
+
createVNode(_sfc_main$2, {
|
|
110
150
|
groups: groups.value,
|
|
111
151
|
"pill-id": railPillId,
|
|
112
152
|
"item-active": itemActive,
|
|
@@ -132,14 +172,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
132
172
|
renderSlot(_ctx.$slots, "footer")
|
|
133
173
|
])) : createCommentVNode("", true)
|
|
134
174
|
], 16),
|
|
135
|
-
__props.responsive ? (openBlock(), createBlock(_sfc_main$
|
|
175
|
+
__props.responsive ? (openBlock(), createBlock(_sfc_main$3, {
|
|
136
176
|
key: 0,
|
|
137
177
|
open: __props.open,
|
|
138
178
|
direction: "left",
|
|
139
179
|
size: "sm",
|
|
140
180
|
"edge-open": __props.edgeOpen,
|
|
141
181
|
"edge-breakpoint": __props.mobileBreakpoint,
|
|
142
|
-
"onUpdate:open": _cache[
|
|
182
|
+
"onUpdate:open": _cache[2] || (_cache[2] = (v) => emit("update:open", v))
|
|
143
183
|
}, {
|
|
144
184
|
default: withCtx(() => [
|
|
145
185
|
createElementVNode("div", _hoisted_3, [
|
|
@@ -149,7 +189,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
149
189
|
}, [
|
|
150
190
|
renderSlot(_ctx.$slots, "header")
|
|
151
191
|
], 2)) : createCommentVNode("", true),
|
|
152
|
-
|
|
192
|
+
__props.searchable ? (openBlock(), createBlock(_sfc_main$1, {
|
|
193
|
+
key: 1,
|
|
194
|
+
modelValue: query.value,
|
|
195
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => query.value = $event),
|
|
196
|
+
size: "sm",
|
|
197
|
+
icon: "lucide:search",
|
|
198
|
+
class: "mb-2 shrink-0",
|
|
199
|
+
placeholder: __props.searchPlaceholder,
|
|
200
|
+
"aria-label": __props.searchPlaceholder
|
|
201
|
+
}, null, 8, ["modelValue", "placeholder", "aria-label"])) : createCommentVNode("", true),
|
|
202
|
+
createVNode(_sfc_main$2, {
|
|
153
203
|
groups: groups.value,
|
|
154
204
|
"pill-id": drawerPillId,
|
|
155
205
|
"item-active": itemActive,
|
|
@@ -2,7 +2,7 @@ import { defineComponent, computed, openBlock, createElementBlock, createElement
|
|
|
2
2
|
import { Motion } from "motion-v";
|
|
3
3
|
import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "reka-ui";
|
|
4
4
|
import { usePillTransition } from "../composables/usePillTransition.js";
|
|
5
|
-
import { _ as _sfc_main$3 } from "./LpBadge-
|
|
5
|
+
import { _ as _sfc_main$3 } from "./LpBadge-Fe0D1bYx.js";
|
|
6
6
|
import { _ as _sfc_main$4 } from "./LpContextMenu-B6WBLleS.js";
|
|
7
7
|
import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
|
|
8
8
|
import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
|
|
@@ -1,48 +1,18 @@
|
|
|
1
|
-
import { VariantProps } from 'tailwind-variants';
|
|
2
|
-
declare const badge: import('tailwind-variants').TVReturnType<{
|
|
3
|
-
tone: {
|
|
4
|
-
neutral: string;
|
|
5
|
-
brand: string;
|
|
6
|
-
action: string;
|
|
7
|
-
success: string;
|
|
8
|
-
warning: string;
|
|
9
|
-
danger: string;
|
|
10
|
-
outline: string;
|
|
11
|
-
};
|
|
12
|
-
}, undefined, "inline-flex items-center gap-1.5 rounded-pill px-2.5 py-0.5 text-xs font-medium", {
|
|
13
|
-
tone: {
|
|
14
|
-
neutral: string;
|
|
15
|
-
brand: string;
|
|
16
|
-
action: string;
|
|
17
|
-
success: string;
|
|
18
|
-
warning: string;
|
|
19
|
-
danger: string;
|
|
20
|
-
outline: string;
|
|
21
|
-
};
|
|
22
|
-
}, undefined, import('tailwind-variants').TVReturnType<{
|
|
23
|
-
tone: {
|
|
24
|
-
neutral: string;
|
|
25
|
-
brand: string;
|
|
26
|
-
action: string;
|
|
27
|
-
success: string;
|
|
28
|
-
warning: string;
|
|
29
|
-
danger: string;
|
|
30
|
-
outline: string;
|
|
31
|
-
};
|
|
32
|
-
}, undefined, "inline-flex items-center gap-1.5 rounded-pill px-2.5 py-0.5 text-xs font-medium", unknown, unknown, undefined>>;
|
|
33
|
-
type BadgeVariants = VariantProps<typeof badge>;
|
|
34
|
-
type __VLS_Props = {
|
|
35
|
-
tone?: BadgeVariants["tone"];
|
|
36
|
-
dot?: boolean;
|
|
37
|
-
};
|
|
38
|
-
declare var __VLS_1: {};
|
|
39
|
-
type __VLS_Slots = {} & {
|
|
40
|
-
default?: (props: typeof __VLS_1) => any;
|
|
41
|
-
};
|
|
42
|
-
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>;
|
|
43
|
-
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
44
1
|
declare const _default: typeof __VLS_export;
|
|
45
2
|
export default _default;
|
|
3
|
+
declare const __VLS_export: __VLS_WithSlots<import('vue').DefineComponent<{
|
|
4
|
+
tone?: "action" | "outline" | "danger" | "success" | "warning" | "neutral" | "brand" | undefined;
|
|
5
|
+
/** `sm` is the one that does not disturb a text-sm line it sits on. */
|
|
6
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
7
|
+
dot?: boolean;
|
|
8
|
+
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{
|
|
9
|
+
tone?: "action" | "outline" | "danger" | "success" | "warning" | "neutral" | "brand" | undefined;
|
|
10
|
+
/** `sm` is the one that does not disturb a text-sm line it sits on. */
|
|
11
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
12
|
+
dot?: boolean;
|
|
13
|
+
}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>, {
|
|
14
|
+
default?: (props: {}) => any;
|
|
15
|
+
}>;
|
|
46
16
|
type __VLS_WithSlots<T, S> = T & {
|
|
47
17
|
new (): {
|
|
48
18
|
$slots: S;
|
|
@@ -12,6 +12,21 @@ type __VLS_Props = {
|
|
|
12
12
|
* given it overrides the modelValue check. The consumer owns the routing.
|
|
13
13
|
*/
|
|
14
14
|
isActive?: (item: SidebarItem) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Put a filter field above the nav. A hundred-item sidebar is not read, it
|
|
17
|
+
* is searched: past a screenful, scanning costs more than typing, and every
|
|
18
|
+
* app that has one had built the same LpInput into the #header slot.
|
|
19
|
+
*
|
|
20
|
+
* Filtering is on `label` (and any `keywords` on the item), case- and
|
|
21
|
+
* accent-insensitive. Sections whose items all fail drop out rather than
|
|
22
|
+
* leaving a run of empty headings, and a collapsed section opens while a
|
|
23
|
+
* query is active — a hidden match is the same as no match.
|
|
24
|
+
*/
|
|
25
|
+
searchable?: boolean;
|
|
26
|
+
/** Placeholder for that field. */
|
|
27
|
+
searchPlaceholder?: string;
|
|
28
|
+
/** The query, when the app wants to own it (v-model:search). */
|
|
29
|
+
search?: string;
|
|
15
30
|
/** Show a skeleton placeholder instead of the items. */
|
|
16
31
|
loading?: boolean;
|
|
17
32
|
/** Skeleton row count while loading. */
|
|
@@ -75,42 +90,45 @@ type __VLS_Props = {
|
|
|
75
90
|
*/
|
|
76
91
|
autoCollapseAfter?: number;
|
|
77
92
|
};
|
|
78
|
-
declare var __VLS_1: {},
|
|
93
|
+
declare var __VLS_1: {}, __VLS_18: {
|
|
79
94
|
item: SidebarItem;
|
|
80
95
|
active: boolean;
|
|
81
|
-
},
|
|
96
|
+
}, __VLS_20: {}, __VLS_22: {}, __VLS_32: {}, __VLS_49: {
|
|
82
97
|
item: SidebarItem;
|
|
83
98
|
active: boolean;
|
|
84
|
-
},
|
|
99
|
+
}, __VLS_51: {}, __VLS_53: {};
|
|
85
100
|
type __VLS_Slots = {} & {
|
|
86
101
|
header?: (props: typeof __VLS_1) => any;
|
|
87
102
|
} & {
|
|
88
|
-
item?: (props: typeof
|
|
103
|
+
item?: (props: typeof __VLS_18) => any;
|
|
89
104
|
} & {
|
|
90
|
-
actions?: (props: typeof
|
|
105
|
+
actions?: (props: typeof __VLS_20) => any;
|
|
91
106
|
} & {
|
|
92
|
-
footer?: (props: typeof
|
|
107
|
+
footer?: (props: typeof __VLS_22) => any;
|
|
93
108
|
} & {
|
|
94
|
-
header?: (props: typeof
|
|
109
|
+
header?: (props: typeof __VLS_32) => any;
|
|
95
110
|
} & {
|
|
96
|
-
item?: (props: typeof
|
|
111
|
+
item?: (props: typeof __VLS_49) => any;
|
|
97
112
|
} & {
|
|
98
|
-
actions?: (props: typeof
|
|
113
|
+
actions?: (props: typeof __VLS_51) => any;
|
|
99
114
|
} & {
|
|
100
|
-
footer?: (props: typeof
|
|
115
|
+
footer?: (props: typeof __VLS_53) => any;
|
|
101
116
|
};
|
|
102
117
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
103
118
|
select: (item: SidebarItem) => any;
|
|
104
119
|
"update:modelValue": (id: string) => any;
|
|
105
120
|
"update:open": (value: boolean) => any;
|
|
106
121
|
"update:collapsed": (keys: string[]) => any;
|
|
122
|
+
"update:search": (value: string) => any;
|
|
107
123
|
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
108
124
|
onSelect?: ((item: SidebarItem) => any) | undefined;
|
|
109
125
|
"onUpdate:modelValue"?: ((id: string) => any) | undefined;
|
|
110
126
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
111
127
|
"onUpdate:collapsed"?: ((keys: string[]) => any) | undefined;
|
|
128
|
+
"onUpdate:search"?: ((value: string) => any) | undefined;
|
|
112
129
|
}>, {
|
|
113
130
|
variant: "rail" | "panel";
|
|
131
|
+
searchPlaceholder: string;
|
|
114
132
|
skeletonRows: number;
|
|
115
133
|
skeletonHeader: boolean;
|
|
116
134
|
responsive: boolean;
|