@leavepulse/ui 0.36.1 → 0.37.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-BERCHiev.css → LpCommandPalette-B-g1fa8r.css} +4 -4
- package/dist/assets/{LpTable-DfSwPCJ-.css → LpTable-BbOFmZfc.css} +9 -9
- package/dist/components/LpCommandPalette.vue.js +14 -30
- package/dist/components/LpTable.vue.d.ts +41 -4
- package/dist/components/LpTable.vue.js +235 -139
- package/dist/composables/useAsyncTask.d.ts +18 -0
- package/dist/composables/useAsyncTask.js +36 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -0
- package/package.json +1 -1
- package/src/components/LpCommandPalette.vue +14 -35
- package/src/components/LpTable.vue +181 -17
- package/src/composables/useAsyncTask.ts +50 -0
- 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-dbc1130a] {
|
|
4
|
+
animation: lp-cmd-in-dbc1130a 140ms ease-out both;
|
|
5
5
|
}
|
|
6
|
-
@keyframes lp-cmd-in-
|
|
6
|
+
@keyframes lp-cmd-in-dbc1130a {
|
|
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-dbc1130a] {
|
|
14
14
|
animation: none;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -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-63738e53],
|
|
15
|
+
.lp-row-leave-active[data-v-63738e53] {
|
|
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-63738e53] {
|
|
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-63738e53],
|
|
24
|
+
.lp-row-leave-to[data-v-63738e53] {
|
|
25
25
|
opacity: 0;
|
|
26
26
|
transform: translateX(-0.5rem);
|
|
27
27
|
}
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* drops out of the table layout entirely. Nothing sits below this row to be
|
|
36
36
|
* dragged around, so simply not animating its exit costs nothing.
|
|
37
37
|
*/
|
|
38
|
-
.lp-row-empty.lp-row-leave-active[data-v-
|
|
38
|
+
.lp-row-empty.lp-row-leave-active[data-v-63738e53] {
|
|
39
39
|
display: none;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
/* A filter that redraws the list is information, not decoration: with motion
|
|
51
51
|
turned down the rows change without animating rather than not changing. */
|
|
52
52
|
@media (prefers-reduced-motion: reduce) {
|
|
53
|
-
.lp-row-enter-active[data-v-
|
|
54
|
-
.lp-row-leave-active[data-v-
|
|
55
|
-
.lp-row-move[data-v-
|
|
53
|
+
.lp-row-enter-active[data-v-63738e53],
|
|
54
|
+
.lp-row-leave-active[data-v-63738e53],
|
|
55
|
+
.lp-row-move[data-v-63738e53] {
|
|
56
56
|
transition: none;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { defineComponent, computed, ref, shallowRef,
|
|
1
|
+
import { defineComponent, computed, ref, shallowRef, watch, nextTick, openBlock, createBlock, unref, withCtx, createVNode, withModifiers, createTextVNode, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, toDisplayString, withDirectives, withKeys, vModelText, normalizeClass } from "vue";
|
|
2
2
|
import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription } from "reka-ui";
|
|
3
3
|
import { _ as _sfc_main$1 } from "../chunks/LpIcon-CCnX5_2j.js";
|
|
4
4
|
import { _ as _sfc_main$2 } from "../chunks/LpScrollArea-D8xyKXcF.js";
|
|
5
|
+
import { useAsyncTask } from "../composables/useAsyncTask.js";
|
|
5
6
|
import { useHotkeys } from "../composables/useHotkeys.js";
|
|
6
7
|
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
|
|
7
|
-
import '../assets/LpCommandPalette-
|
|
8
|
+
import '../assets/LpCommandPalette-B-g1fa8r.css';const _hoisted_1 = { class: "flex shrink-0 items-center gap-2.5 border-b border-line px-4" };
|
|
8
9
|
const _hoisted_2 = ["title", "onClick"];
|
|
9
10
|
const _hoisted_3 = ["placeholder", "onKeydown"];
|
|
10
11
|
const _hoisted_4 = {
|
|
@@ -102,10 +103,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
102
103
|
return true;
|
|
103
104
|
}
|
|
104
105
|
const found = shallowRef([]);
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
let controller;
|
|
108
|
-
let token = 0;
|
|
106
|
+
const task = useAsyncTask();
|
|
107
|
+
const searching = task.pending;
|
|
109
108
|
function fetcher() {
|
|
110
109
|
const current = mode.value;
|
|
111
110
|
if (current) {
|
|
@@ -114,12 +113,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
114
113
|
return props.search ?? null;
|
|
115
114
|
}
|
|
116
115
|
function cancel() {
|
|
117
|
-
|
|
118
|
-
timer = void 0;
|
|
119
|
-
controller?.abort();
|
|
120
|
-
controller = void 0;
|
|
121
|
-
token += 1;
|
|
122
|
-
searching.value = false;
|
|
116
|
+
task.cancel();
|
|
123
117
|
}
|
|
124
118
|
function refresh() {
|
|
125
119
|
cancel();
|
|
@@ -129,22 +123,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
129
123
|
const q = query.value.trim();
|
|
130
124
|
const inMode = mode.value !== null;
|
|
131
125
|
if (!inMode && q.length < Math.max(1, props.minChars)) return;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const hits = await run2(q, controller.signal);
|
|
138
|
-
if (mine !== token) return;
|
|
139
|
-
found.value = hits;
|
|
140
|
-
} catch {
|
|
141
|
-
if (mine === token) found.value = [];
|
|
142
|
-
} finally {
|
|
143
|
-
if (mine === token) searching.value = false;
|
|
144
|
-
}
|
|
145
|
-
}, props.debounce);
|
|
126
|
+
task.run((signal) => run2(q, signal), {
|
|
127
|
+
delay: props.debounce,
|
|
128
|
+
apply: (hits) => found.value = hits,
|
|
129
|
+
fail: () => found.value = []
|
|
130
|
+
});
|
|
146
131
|
}
|
|
147
|
-
onBeforeUnmount(cancel);
|
|
148
132
|
const source = computed(() => mode.value ? modeItems.value : props.commands);
|
|
149
133
|
const ranked = computed(() => {
|
|
150
134
|
const q = query.value.trim().toLowerCase();
|
|
@@ -333,7 +317,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
333
317
|
_: 1
|
|
334
318
|
}),
|
|
335
319
|
createElementVNode("div", _hoisted_1, [
|
|
336
|
-
!searching
|
|
320
|
+
!unref(searching) ? (openBlock(), createBlock(_sfc_main$1, {
|
|
337
321
|
key: 0,
|
|
338
322
|
name: "lucide:search",
|
|
339
323
|
size: 18,
|
|
@@ -391,7 +375,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
391
375
|
"content-class": "p-2"
|
|
392
376
|
}, {
|
|
393
377
|
default: withCtx(() => [
|
|
394
|
-
flat.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(searching
|
|
378
|
+
flat.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(unref(searching) ? text.value.searching : __props.emptyText), 1)) : createCommentVNode("", true),
|
|
395
379
|
(openBlock(true), createElementBlock(Fragment, null, renderList(grouped.value, (group) => {
|
|
396
380
|
return openBlock(), createElementBlock(Fragment, {
|
|
397
381
|
key: group.name
|
|
@@ -481,7 +465,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
481
465
|
};
|
|
482
466
|
}
|
|
483
467
|
});
|
|
484
|
-
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
468
|
+
const LpCommandPalette = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-dbc1130a"]]);
|
|
485
469
|
export {
|
|
486
470
|
LpCommandPalette as default
|
|
487
471
|
};
|
|
@@ -26,10 +26,47 @@ export interface SortState {
|
|
|
26
26
|
key: string;
|
|
27
27
|
dir: "asc" | "desc";
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* What a server-backed table asks for. `hidden` mirrors the header filter: the
|
|
31
|
+
* values unticked per column, so a value the server has never sent before shows
|
|
32
|
+
* up instead of being silently excluded.
|
|
33
|
+
*/
|
|
34
|
+
export interface TableQuery {
|
|
35
|
+
page: number;
|
|
36
|
+
pageSize: number;
|
|
37
|
+
sort: SortState | null;
|
|
38
|
+
hidden: Record<string, unknown[]>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* One page of a server-backed table. `facets` are the distinct values of the
|
|
42
|
+
* filterable columns across the whole result — one page cannot know them, and a
|
|
43
|
+
* filter built from twenty-five rows would offer whatever happened to be on it.
|
|
44
|
+
*/
|
|
45
|
+
export interface TablePage<Row> {
|
|
46
|
+
rows: Row[];
|
|
47
|
+
total: number;
|
|
48
|
+
facets?: Record<string, unknown[]>;
|
|
49
|
+
}
|
|
50
|
+
declare const _default: typeof __VLS_export;
|
|
51
|
+
export default _default;
|
|
29
52
|
declare const __VLS_export: <T extends Record<string, unknown>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
30
53
|
props: import('vue').PublicProps & __VLS_PrettifyLocal<{
|
|
31
54
|
columns: TableColumn<T>[];
|
|
32
|
-
rows
|
|
55
|
+
/** The rows, for a table that holds its data. Ignored when `load` is set. */
|
|
56
|
+
rows?: T[];
|
|
57
|
+
/**
|
|
58
|
+
* Fetch the rows instead of being handed them: paging, sorting and the
|
|
59
|
+
* header filters then happen on the server. Debounced and abortable, the
|
|
60
|
+
* same way as the command palette's `search` — a stale page never lands
|
|
61
|
+
* over a fresher one.
|
|
62
|
+
*/
|
|
63
|
+
load?: (query: TableQuery, signal: AbortSignal) => TablePage<T> | Promise<TablePage<T>>;
|
|
64
|
+
/** Rows per page with `load`. */
|
|
65
|
+
pageSize?: number;
|
|
66
|
+
/** Wait after a sort or filter change before `load` runs. */
|
|
67
|
+
debounce?: number;
|
|
68
|
+
loadingLabel?: string;
|
|
69
|
+
errorLabel?: string;
|
|
33
70
|
/** Stable id per row — required for selection; falls back to index otherwise. */
|
|
34
71
|
rowKey?: keyof T | ((row: T) => string | number);
|
|
35
72
|
emptyLabel?: string;
|
|
@@ -62,7 +99,9 @@ declare const __VLS_export: <T extends Record<string, unknown>>(__VLS_props: Non
|
|
|
62
99
|
}> & (typeof globalThis extends {
|
|
63
100
|
__VLS_PROPS_FALLBACK: infer P;
|
|
64
101
|
} ? P : {});
|
|
65
|
-
expose: (exposed: {
|
|
102
|
+
expose: (exposed: import('vue').ShallowUnwrapRef<{
|
|
103
|
+
reload: () => void;
|
|
104
|
+
}>) => void;
|
|
66
105
|
attrs: any;
|
|
67
106
|
slots: {
|
|
68
107
|
[x: `cell-${string}`]: ((props: {
|
|
@@ -78,8 +117,6 @@ declare const __VLS_export: <T extends Record<string, unknown>>(__VLS_props: Non
|
|
|
78
117
|
}>) => import('vue').VNode & {
|
|
79
118
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
80
119
|
};
|
|
81
|
-
declare const _default: typeof __VLS_export;
|
|
82
|
-
export default _default;
|
|
83
120
|
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
84
121
|
[K in keyof T]: T[K];
|
|
85
122
|
} : {
|