@leavepulse/ui 0.33.1 → 0.35.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/{LpCommandPalette-CEY-pajO.css → LpCommandPalette-BERCHiev.css} +4 -4
- package/dist/assets/{LpTable-Ckoi05Am.css → LpTable-DfSwPCJ-.css} +21 -8
- package/dist/chunks/LpModalNav-B7W9VAne.js +142 -0
- package/dist/component-names.d.ts +1 -1
- package/dist/components/LpCommandPalette.vue.d.ts +62 -0
- package/dist/components/LpCommandPalette.vue.js +237 -56
- package/dist/components/LpModalNav.vue.d.ts +74 -0
- package/dist/components/LpModalNav.vue.js +4 -0
- package/dist/components/LpTable.vue.js +7 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +72 -70
- package/package.json +1 -1
- package/src/component-names.ts +1 -0
- package/src/components/LpCommandPalette.vue +369 -21
- package/src/components/LpModalNav.vue +177 -0
- package/src/components/LpTable.vue +22 -2
- package/src/index.ts +2 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
2
|
/* Each result eases in; honours reduced motion. */
|
|
3
|
-
.lp-cmd-item[data-v-
|
|
4
|
-
animation: lp-cmd-in-
|
|
3
|
+
.lp-cmd-item[data-v-d0e03a58] {
|
|
4
|
+
animation: lp-cmd-in-d0e03a58 140ms ease-out both;
|
|
5
5
|
}
|
|
6
|
-
@keyframes lp-cmd-in-
|
|
6
|
+
@keyframes lp-cmd-in-d0e03a58 {
|
|
7
7
|
from {
|
|
8
8
|
opacity: 0;
|
|
9
9
|
transform: translateY(3px);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
@media (prefers-reduced-motion: reduce) {
|
|
13
|
-
.lp-cmd-item[data-v-
|
|
13
|
+
.lp-cmd-item[data-v-d0e03a58] {
|
|
14
14
|
animation: none;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -11,21 +11,34 @@
|
|
|
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-1fada8e7],
|
|
15
|
+
.lp-row-leave-active[data-v-1fada8e7] {
|
|
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-1fada8e7] {
|
|
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-1fada8e7],
|
|
24
|
+
.lp-row-leave-to[data-v-1fada8e7] {
|
|
25
25
|
opacity: 0;
|
|
26
26
|
transform: translateX(-0.5rem);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/*
|
|
30
|
+
* The empty-state row leaves at once, without the fade. It and the first real
|
|
31
|
+
* rows would otherwise share the table for the length of the animation, and a
|
|
32
|
+
* row of blank height sits above them — the table jumps once on every load.
|
|
33
|
+
*
|
|
34
|
+
* `position: absolute` is what a list would use here, but a positioned `<tr>`
|
|
35
|
+
* drops out of the table layout entirely. Nothing sits below this row to be
|
|
36
|
+
* dragged around, so simply not animating its exit costs nothing.
|
|
37
|
+
*/
|
|
38
|
+
.lp-row-empty.lp-row-leave-active[data-v-1fada8e7] {
|
|
39
|
+
display: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
/*
|
|
30
43
|
* The leaving row stays in the flow. Taking it out with `position: absolute` is
|
|
31
44
|
* the usual trick for a list, but a `<tr>` positioned that way loses the table's
|
|
@@ -37,9 +50,9 @@
|
|
|
37
50
|
/* A filter that redraws the list is information, not decoration: with motion
|
|
38
51
|
turned down the rows change without animating rather than not changing. */
|
|
39
52
|
@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-
|
|
53
|
+
.lp-row-enter-active[data-v-1fada8e7],
|
|
54
|
+
.lp-row-leave-active[data-v-1fada8e7],
|
|
55
|
+
.lp-row-move[data-v-1fada8e7] {
|
|
43
56
|
transition: none;
|
|
44
57
|
}
|
|
45
58
|
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { defineComponent, ref, computed, openBlock, createBlock, createSlots, withCtx, createElementVNode, renderSlot, normalizeProps, guardReactiveProps, createCommentVNode, normalizeClass, createVNode, createTextVNode, toDisplayString } from "vue";
|
|
2
|
+
import { _ as _sfc_main$3 } from "./LpButton-5VXXCjwF.js";
|
|
3
|
+
import { _ as _sfc_main$4 } from "./LpIcon-CCnX5_2j.js";
|
|
4
|
+
import { _ as _sfc_main$1 } from "./LpModal-DAqXzsm-.js";
|
|
5
|
+
import { _ as _sfc_main$2 } from "./LpSidebar-DcYavim2.js";
|
|
6
|
+
const _hoisted_1 = { class: "flex items-center gap-2" };
|
|
7
|
+
const _hoisted_2 = { class: "flex min-h-0 flex-1 gap-4" };
|
|
8
|
+
const _hoisted_3 = { class: "flex min-h-0 min-w-0 flex-1 flex-col" };
|
|
9
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
10
|
+
__name: "LpModalNav",
|
|
11
|
+
props: {
|
|
12
|
+
open: { type: Boolean },
|
|
13
|
+
modelValue: {},
|
|
14
|
+
items: {},
|
|
15
|
+
sections: {},
|
|
16
|
+
title: {},
|
|
17
|
+
description: {},
|
|
18
|
+
size: { default: "2xl" },
|
|
19
|
+
width: {},
|
|
20
|
+
navWidth: { default: "13rem" },
|
|
21
|
+
searchable: { type: Boolean },
|
|
22
|
+
searchPlaceholder: {},
|
|
23
|
+
loading: { type: Boolean },
|
|
24
|
+
mobileBreakpoint: { default: "lg" },
|
|
25
|
+
navLabel: { default: "Sections" },
|
|
26
|
+
fillBody: { type: Boolean, default: true }
|
|
27
|
+
},
|
|
28
|
+
emits: ["update:open", "update:modelValue"],
|
|
29
|
+
setup(__props, { emit: __emit }) {
|
|
30
|
+
const props = __props;
|
|
31
|
+
const emit = __emit;
|
|
32
|
+
const navOpen = ref(false);
|
|
33
|
+
const active = computed({
|
|
34
|
+
get: () => props.modelValue ?? "",
|
|
35
|
+
set: (v) => emit("update:modelValue", v)
|
|
36
|
+
});
|
|
37
|
+
const hasNav = computed(
|
|
38
|
+
() => Boolean(props.items?.length || props.sections?.length)
|
|
39
|
+
);
|
|
40
|
+
const TRIGGER_VISIBILITY = {
|
|
41
|
+
sm: "sm:hidden",
|
|
42
|
+
md: "md:hidden",
|
|
43
|
+
lg: "lg:hidden",
|
|
44
|
+
xl: "xl:hidden"
|
|
45
|
+
};
|
|
46
|
+
const triggerClass = computed(() => TRIGGER_VISIBILITY[props.mobileBreakpoint]);
|
|
47
|
+
return (_ctx, _cache) => {
|
|
48
|
+
return openBlock(), createBlock(_sfc_main$1, {
|
|
49
|
+
open: __props.open,
|
|
50
|
+
title: __props.title,
|
|
51
|
+
description: __props.description,
|
|
52
|
+
size: __props.size,
|
|
53
|
+
width: __props.width,
|
|
54
|
+
"fill-body": __props.fillBody,
|
|
55
|
+
"onUpdate:open": _cache[3] || (_cache[3] = ($event) => emit("update:open", $event))
|
|
56
|
+
}, createSlots({
|
|
57
|
+
title: withCtx(() => [
|
|
58
|
+
createElementVNode("div", _hoisted_1, [
|
|
59
|
+
hasNav.value ? (openBlock(), createBlock(_sfc_main$3, {
|
|
60
|
+
key: 0,
|
|
61
|
+
variant: "ghost",
|
|
62
|
+
size: "sm",
|
|
63
|
+
square: "",
|
|
64
|
+
"aria-label": __props.navLabel,
|
|
65
|
+
class: normalizeClass(triggerClass.value),
|
|
66
|
+
onClick: _cache[0] || (_cache[0] = ($event) => navOpen.value = true)
|
|
67
|
+
}, {
|
|
68
|
+
default: withCtx(() => [
|
|
69
|
+
createVNode(_sfc_main$4, {
|
|
70
|
+
name: "lucide:menu",
|
|
71
|
+
size: 18
|
|
72
|
+
})
|
|
73
|
+
]),
|
|
74
|
+
_: 1
|
|
75
|
+
}, 8, ["aria-label", "class"])) : createCommentVNode("", true),
|
|
76
|
+
renderSlot(_ctx.$slots, "title", {}, () => [
|
|
77
|
+
createTextVNode(toDisplayString(__props.title), 1)
|
|
78
|
+
])
|
|
79
|
+
])
|
|
80
|
+
]),
|
|
81
|
+
default: withCtx(() => [
|
|
82
|
+
createElementVNode("div", _hoisted_2, [
|
|
83
|
+
hasNav.value ? (openBlock(), createBlock(_sfc_main$2, {
|
|
84
|
+
key: 0,
|
|
85
|
+
modelValue: active.value,
|
|
86
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => active.value = $event),
|
|
87
|
+
open: navOpen.value,
|
|
88
|
+
"onUpdate:open": _cache[2] || (_cache[2] = ($event) => navOpen.value = $event),
|
|
89
|
+
variant: "panel",
|
|
90
|
+
items: __props.items,
|
|
91
|
+
sections: __props.sections,
|
|
92
|
+
width: __props.navWidth,
|
|
93
|
+
searchable: __props.searchable,
|
|
94
|
+
"search-placeholder": __props.searchPlaceholder,
|
|
95
|
+
loading: __props.loading,
|
|
96
|
+
responsive: "",
|
|
97
|
+
"mobile-breakpoint": __props.mobileBreakpoint,
|
|
98
|
+
class: "shrink-0"
|
|
99
|
+
}, createSlots({ _: 2 }, [
|
|
100
|
+
_ctx.$slots.navHeader ? {
|
|
101
|
+
name: "header",
|
|
102
|
+
fn: withCtx(() => [
|
|
103
|
+
renderSlot(_ctx.$slots, "navHeader")
|
|
104
|
+
]),
|
|
105
|
+
key: "0"
|
|
106
|
+
} : void 0,
|
|
107
|
+
_ctx.$slots.navItem ? {
|
|
108
|
+
name: "item",
|
|
109
|
+
fn: withCtx((slotProps) => [
|
|
110
|
+
renderSlot(_ctx.$slots, "navItem", normalizeProps(guardReactiveProps(slotProps)))
|
|
111
|
+
]),
|
|
112
|
+
key: "1"
|
|
113
|
+
} : void 0,
|
|
114
|
+
_ctx.$slots.navFooter ? {
|
|
115
|
+
name: "footer",
|
|
116
|
+
fn: withCtx(() => [
|
|
117
|
+
renderSlot(_ctx.$slots, "navFooter")
|
|
118
|
+
]),
|
|
119
|
+
key: "2"
|
|
120
|
+
} : void 0
|
|
121
|
+
]), 1032, ["modelValue", "open", "items", "sections", "width", "searchable", "search-placeholder", "loading", "mobile-breakpoint"])) : createCommentVNode("", true),
|
|
122
|
+
createElementVNode("div", _hoisted_3, [
|
|
123
|
+
renderSlot(_ctx.$slots, "default")
|
|
124
|
+
])
|
|
125
|
+
])
|
|
126
|
+
]),
|
|
127
|
+
_: 2
|
|
128
|
+
}, [
|
|
129
|
+
_ctx.$slots.footer ? {
|
|
130
|
+
name: "footer",
|
|
131
|
+
fn: withCtx(() => [
|
|
132
|
+
renderSlot(_ctx.$slots, "footer")
|
|
133
|
+
]),
|
|
134
|
+
key: "0"
|
|
135
|
+
} : void 0
|
|
136
|
+
]), 1032, ["open", "title", "description", "size", "width", "fill-body"]);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
export {
|
|
141
|
+
_sfc_main as _
|
|
142
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpActionBar", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpColorPicker", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpDropzone", "LpEmptyState", "LpFileTree", "LpFileTreeNode", "LpFormField", "LpIcon", "LpImageEditor", "LpInfraNode", "LpInput", "LpLaneNode", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpMediaGallery", "LpModal", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRollingText", "LpScrollArea", "LpSection", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpTilt", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar", "LpWaypointEdge"];
|
|
1
|
+
export declare const COMPONENT_NAMES: readonly ["LayoutCanvas", "LayoutNode", "LpActionBar", "LpAddressInput", "LpAlert", "LpAppShell", "LpAutocomplete", "LpAvatar", "LpBadge", "LpBreadcrumbs", "LpButton", "LpCalendar", "LpCard", "LpChart", "LpCheckbox", "LpCodeBlock", "LpColorPicker", "LpCommandPalette", "LpConfirmDialog", "LpContextMenu", "LpDatePicker", "LpDisclosure", "LpDivider", "LpDrawer", "LpDropdownMenu", "LpDropzone", "LpEmptyState", "LpFileTree", "LpFileTreeNode", "LpFormField", "LpIcon", "LpImageEditor", "LpInfraNode", "LpInput", "LpLaneNode", "LpLightbox", "LpLink", "LpLogViewer", "LpMapPicker", "LpMediaGallery", "LpModal", "LpModalNav", "LpNotificationBell", "LpNumberField", "LpNumberFlow", "LpOtpInput", "LpPagination", "LpPasswordInput", "LpPhoneInput", "LpPie", "LpPopover", "LpProgress", "LpRadio", "LpRadioGroup", "LpRollingText", "LpScrollArea", "LpSection", "LpSegmented", "LpSelect", "LpServiceNode", "LpShift", "LpShortcutsDialog", "LpSidebar", "LpSidebarNav", "LpSkeleton", "LpSlider", "LpSparkline", "LpStat", "LpStepper", "LpSwitch", "LpTable", "LpTableOfContents", "LpTabs", "LpTextarea", "LpThemeSwitcher", "LpTilt", "LpToaster", "LpTooltip", "LpTopologyCanvas", "LpUptimeBar", "LpWaypointEdge"];
|
|
@@ -17,8 +17,35 @@ export interface Command {
|
|
|
17
17
|
* decommission, …) that shouldn't clutter the palette but stay reachable.
|
|
18
18
|
*/
|
|
19
19
|
hidden?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Picking this opens a mode instead of closing: a nested list, either given
|
|
22
|
+
* outright or fetched from the query typed inside it. This is what keeps a
|
|
23
|
+
* palette from flattening "restart <service>" into one row per service —
|
|
24
|
+
* and what lets the second step search a list too big to enumerate.
|
|
25
|
+
*
|
|
26
|
+
* `onSelect` still runs when the mode opens, so a command can both act and
|
|
27
|
+
* drill in.
|
|
28
|
+
*/
|
|
29
|
+
children?: Command[] | ((query: string) => Command[] | Promise<Command[]>);
|
|
30
|
+
/** Placeholder while inside this command's mode. */
|
|
31
|
+
childPlaceholder?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Keep the palette open after this runs. For a command that toggles
|
|
34
|
+
* something the user may want to toggle again (a theme, a filter) without
|
|
35
|
+
* reopening and retyping.
|
|
36
|
+
*/
|
|
37
|
+
keepOpen?: boolean;
|
|
20
38
|
onSelect?: () => void;
|
|
21
39
|
}
|
|
40
|
+
/** Footer hints and the mode chip, spelled out so an app can translate them. */
|
|
41
|
+
export interface PaletteLabels {
|
|
42
|
+
navigate: string;
|
|
43
|
+
select: string;
|
|
44
|
+
close: string;
|
|
45
|
+
/** Hint for leaving a mode, shown only while inside one. */
|
|
46
|
+
back: string;
|
|
47
|
+
searching: string;
|
|
48
|
+
}
|
|
22
49
|
type __VLS_Props = {
|
|
23
50
|
open?: boolean;
|
|
24
51
|
commands: Command[];
|
|
@@ -26,17 +53,52 @@ type __VLS_Props = {
|
|
|
26
53
|
emptyText?: string;
|
|
27
54
|
/** Bind a global ⌘K / Ctrl-K toggle. */
|
|
28
55
|
hotkey?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Commands fetched from the typed query — what reaches the things too many
|
|
58
|
+
* (or too remote) to hand over as a list: people, files, tickets. Called
|
|
59
|
+
* debounced, never for a query shorter than `minChars`, and only its
|
|
60
|
+
* newest call counts: an earlier one that lands late is dropped, so a slow
|
|
61
|
+
* response can't overwrite a fresher list.
|
|
62
|
+
*
|
|
63
|
+
* Results join the static commands, so a palette can do both.
|
|
64
|
+
*/
|
|
65
|
+
search?: (query: string, signal: AbortSignal) => Command[] | Promise<Command[]>;
|
|
66
|
+
/** Wait after the last keystroke before `search` runs. */
|
|
67
|
+
debounce?: number;
|
|
68
|
+
/** Shortest query `search` runs for. */
|
|
69
|
+
minChars?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Ids of recently picked commands, newest first — bind it to storage and
|
|
72
|
+
* the palette opens on what this person actually uses. It only reorders
|
|
73
|
+
* commands already in the list; an id that no longer resolves is skipped,
|
|
74
|
+
* so a stored history never resurrects a command that has gone away.
|
|
75
|
+
*/
|
|
76
|
+
recent?: string[];
|
|
77
|
+
/** How many recent commands to surface. */
|
|
78
|
+
recentLimit?: number;
|
|
79
|
+
/** Headings the palette adds itself. */
|
|
80
|
+
recentLabel?: string;
|
|
81
|
+
resultsLabel?: string;
|
|
82
|
+
/** Footer hints and the mode chip, spelled out for translation. */
|
|
83
|
+
labels?: Partial<PaletteLabels>;
|
|
29
84
|
};
|
|
30
85
|
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
31
86
|
select: (command: Command) => any;
|
|
32
87
|
"update:open": (value: boolean) => any;
|
|
88
|
+
run: (id: string, command: Command) => any;
|
|
33
89
|
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
34
90
|
onSelect?: ((command: Command) => any) | undefined;
|
|
35
91
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
92
|
+
onRun?: ((id: string, command: Command) => any) | undefined;
|
|
36
93
|
}>, {
|
|
37
94
|
placeholder: string;
|
|
38
95
|
emptyText: string;
|
|
96
|
+
minChars: number;
|
|
97
|
+
debounce: number;
|
|
98
|
+
recentLimit: number;
|
|
39
99
|
hotkey: boolean;
|
|
100
|
+
recentLabel: string;
|
|
101
|
+
resultsLabel: string;
|
|
40
102
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
41
103
|
declare const _default: typeof __VLS_export;
|
|
42
104
|
export default _default;
|