@leavepulse/ui 0.29.3 → 0.29.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/assets/LpChart-CzgCGaAA.css +8 -0
- package/dist/assets/{LpTable-B9Iko3XD.css → LpTable-Bz3uJNa3.css} +8 -8
- package/dist/chunks/{LpAppShell-CGX0DlIW.js → LpAppShell-BJk3b-u4.js} +1 -1
- package/dist/chunks/{LpAvatar-CzCE5cXg.js → LpAvatar-D3l4nabg.js} +1 -1
- package/dist/chunks/{LpCard-DSefTGEH.js → LpCard-D0M2ZCnB.js} +1 -1
- package/dist/chunks/{LpContextMenu-D0mzXqA7.js → LpContextMenu-B6WBLleS.js} +55 -8
- package/dist/chunks/{LpFileTree-BaV7f0O7.js → LpFileTree-DfFqY__1.js} +1 -1
- package/dist/chunks/{LpFileTreeNode-BzpBa7R7.js → LpFileTreeNode-COchUMNn.js} +1 -1
- package/dist/chunks/{LpLogViewer-CKmEQYnm.js → LpLogViewer-CVaGfTF_.js} +1 -1
- package/dist/chunks/{LpNotificationBell-Dvu-b6Vn.js → LpNotificationBell-CTsIcPqX.js} +1 -1
- package/dist/chunks/{LpPie-BkjWlfSw.js → LpPie-BL1vTDSM.js} +1 -1
- package/dist/chunks/{LpSidebar-CWehDCxN.js → LpSidebar-C_Mr-JPI.js} +1 -1
- package/dist/chunks/{LpSidebarNav-5RGNr2D3.js → LpSidebarNav-D6v12-36.js} +1 -1
- package/dist/chunks/{LpThemeSwitcher-Dj4VcTu7.js → LpThemeSwitcher-r1te9nB2.js} +1 -1
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpAvatar.vue.js +1 -1
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.js +814 -2
- package/dist/components/LpContextMenu.vue.d.ts +7 -0
- package/dist/components/LpContextMenu.vue.js +1 -1
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpTable.vue.d.ts +19 -0
- package/dist/components/LpTable.vue.js +233 -143
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/index.js +124 -124
- package/package.json +1 -1
- package/src/components/LpChart.vue +337 -63
- package/src/components/LpContextMenu.vue +49 -0
- package/src/components/LpTable.vue +166 -23
- package/dist/chunks/LpChart-UiU4RhXP.js +0 -672
|
@@ -9,6 +9,13 @@ export interface ContextMenuItemDef {
|
|
|
9
9
|
onSelect?: () => void;
|
|
10
10
|
/** Nested submenu. When present, onSelect is ignored. */
|
|
11
11
|
children?: ContextMenuItemDef[];
|
|
12
|
+
/**
|
|
13
|
+
* Renders as a tick-box rather than a plain item, and the menu stays open on
|
|
14
|
+
* select. For the lists where the point is to set several at once — which
|
|
15
|
+
* columns to show, which values to filter by — and closing after each one
|
|
16
|
+
* would mean reopening the menu for every tick.
|
|
17
|
+
*/
|
|
18
|
+
checked?: boolean;
|
|
12
19
|
}
|
|
13
20
|
type __VLS_Props = {
|
|
14
21
|
items: ContextMenuItemDef[];
|
|
@@ -6,6 +6,21 @@ export interface TableColumn<Row> {
|
|
|
6
6
|
width?: string;
|
|
7
7
|
/** Allow clicking the header to sort by this column. */
|
|
8
8
|
sortable?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Offer "show only these values" in the header's menu, built from the values
|
|
11
|
+
* actually present in the rows. For a column that holds a small vocabulary —
|
|
12
|
+
* a type, a state, a site — where the question is "just the mains leads,
|
|
13
|
+
* please". Pointless on a column of unique values, so it is opt-in.
|
|
14
|
+
*/
|
|
15
|
+
filterable?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* How a raw cell value reads in that filter list. `power_ac` is the stored
|
|
18
|
+
* vocabulary; the menu should say what the column itself says.
|
|
19
|
+
*/
|
|
20
|
+
valueLabel?: (value: unknown) => string;
|
|
21
|
+
/** Keep this column out of the show/hide list — an actions column has no
|
|
22
|
+
* name to offer and nothing to gain from being hidden. */
|
|
23
|
+
alwaysVisible?: boolean;
|
|
9
24
|
}
|
|
10
25
|
export interface SortState {
|
|
11
26
|
key: string;
|
|
@@ -36,6 +51,10 @@ declare const __VLS_export: <T extends Record<string, unknown>>(__VLS_props: Non
|
|
|
36
51
|
sortAscLabel?: string;
|
|
37
52
|
sortDescLabel?: string;
|
|
38
53
|
sortClearLabel?: string;
|
|
54
|
+
/** Wording for the value filter and the column chooser. */
|
|
55
|
+
filterLabel?: string;
|
|
56
|
+
showAllLabel?: string;
|
|
57
|
+
columnsLabel?: string;
|
|
39
58
|
} & {
|
|
40
59
|
"onUpdate:selected"?: ((value: (string | number)[]) => any) | undefined;
|
|
41
60
|
"onUpdate:sort"?: ((value: SortState | null) => any) | undefined;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineComponent, ref, computed, watch, onBeforeUnmount, openBlock, createBlock, withCtx, createElementVNode, normalizeClass, createElementBlock,
|
|
2
|
-
import { _ as _sfc_main$
|
|
3
|
-
import { _ as _sfc_main$
|
|
1
|
+
import { defineComponent, ref, computed, watch, onBeforeUnmount, openBlock, createBlock, withCtx, createVNode, createElementVNode, normalizeClass, createElementBlock, createCommentVNode, Fragment, renderList, normalizeStyle, createTextVNode, toDisplayString, TransitionGroup, unref, mergeProps, withModifiers, renderSlot } from "vue";
|
|
2
|
+
import { _ as _sfc_main$3 } from "../chunks/LpCheckbox-BO0zuuPh.js";
|
|
3
|
+
import { _ as _sfc_main$2 } from "../chunks/LpContextMenu-B6WBLleS.js";
|
|
4
4
|
import { _ as _sfc_main$4 } from "../chunks/LpIcon-CCnX5_2j.js";
|
|
5
5
|
import { _ as _sfc_main$1 } from "../chunks/LpScrollArea-D8xyKXcF.js";
|
|
6
6
|
import { useRovingFocus } from "../composables/useRovingFocus.js";
|
|
7
7
|
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
|
|
8
|
-
import '../assets/LpTable-
|
|
8
|
+
import '../assets/LpTable-Bz3uJNa3.css';const _hoisted_1 = { class: "w-full border-collapse text-sm" };
|
|
9
9
|
const _hoisted_2 = { class: "border-b border-line bg-surface-soft" };
|
|
10
10
|
const _hoisted_3 = {
|
|
11
11
|
key: 0,
|
|
@@ -31,7 +31,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
31
31
|
rowMenu: {},
|
|
32
32
|
sortAscLabel: { default: "Sort ascending" },
|
|
33
33
|
sortDescLabel: { default: "Sort descending" },
|
|
34
|
-
sortClearLabel: { default: "Clear sorting" }
|
|
34
|
+
sortClearLabel: { default: "Clear sorting" },
|
|
35
|
+
filterLabel: { default: "Show only" },
|
|
36
|
+
showAllLabel: { default: "Show all" },
|
|
37
|
+
columnsLabel: { default: "Columns" }
|
|
35
38
|
},
|
|
36
39
|
emits: ["update:selected", "update:sort", "rowClick"],
|
|
37
40
|
setup(__props, { emit: __emit }) {
|
|
@@ -52,13 +55,51 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
52
55
|
}
|
|
53
56
|
const ownSort = ref(null);
|
|
54
57
|
const activeSort = computed(() => props.sort ?? ownSort.value);
|
|
58
|
+
const hiddenValues = ref({});
|
|
59
|
+
const hiddenColumns = ref(/* @__PURE__ */ new Set());
|
|
60
|
+
const visibleColumns = computed(
|
|
61
|
+
() => props.columns.filter((c) => !hiddenColumns.value.has(c.key))
|
|
62
|
+
);
|
|
63
|
+
function valuesOf(col) {
|
|
64
|
+
const seen = [];
|
|
65
|
+
for (const row of props.rows) {
|
|
66
|
+
const v = row[col.key];
|
|
67
|
+
if (!seen.includes(v)) seen.push(v);
|
|
68
|
+
}
|
|
69
|
+
return seen;
|
|
70
|
+
}
|
|
71
|
+
function isValueHidden(key, value) {
|
|
72
|
+
return hiddenValues.value[key]?.has(value) ?? false;
|
|
73
|
+
}
|
|
74
|
+
function toggleValue(key, value) {
|
|
75
|
+
const next = new Set(hiddenValues.value[key] ?? []);
|
|
76
|
+
if (next.has(value)) next.delete(value);
|
|
77
|
+
else next.add(value);
|
|
78
|
+
hiddenValues.value = { ...hiddenValues.value, [key]: next };
|
|
79
|
+
}
|
|
80
|
+
function showAllValues(key) {
|
|
81
|
+
hiddenValues.value = { ...hiddenValues.value, [key]: /* @__PURE__ */ new Set() };
|
|
82
|
+
}
|
|
83
|
+
function toggleColumn(key) {
|
|
84
|
+
const next = new Set(hiddenColumns.value);
|
|
85
|
+
if (next.has(key)) next.delete(key);
|
|
86
|
+
else next.add(key);
|
|
87
|
+
hiddenColumns.value = next;
|
|
88
|
+
}
|
|
89
|
+
const filteredRows = computed(() => {
|
|
90
|
+
const active = Object.entries(hiddenValues.value).filter(([, set]) => set.size);
|
|
91
|
+
if (!active.length) return props.rows;
|
|
92
|
+
return props.rows.filter(
|
|
93
|
+
(row) => active.every(([key, hidden]) => !hidden.has(row[key]))
|
|
94
|
+
);
|
|
95
|
+
});
|
|
55
96
|
const displayRows = computed(() => {
|
|
56
97
|
const s = activeSort.value;
|
|
57
|
-
if (!s) return
|
|
98
|
+
if (!s) return filteredRows.value;
|
|
58
99
|
const col = props.columns.find((c) => c.key === s.key);
|
|
59
|
-
if (!col?.sortable) return
|
|
100
|
+
if (!col?.sortable) return filteredRows.value;
|
|
60
101
|
const factor = s.dir === "asc" ? 1 : -1;
|
|
61
|
-
return [...
|
|
102
|
+
return [...filteredRows.value].sort((a, b) => compare(a[s.key], b[s.key]) * factor);
|
|
62
103
|
});
|
|
63
104
|
function compare(a, b) {
|
|
64
105
|
if (a == null && b == null) return 0;
|
|
@@ -83,31 +124,73 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
83
124
|
return s.dir === "asc" ? "lucide:arrow-up" : "lucide:arrow-down";
|
|
84
125
|
}
|
|
85
126
|
function headerMenu(col) {
|
|
86
|
-
if (!col.sortable) return [];
|
|
87
127
|
const s = activeSort.value;
|
|
88
128
|
const set = (next) => () => {
|
|
89
129
|
ownSort.value = next;
|
|
90
130
|
emit("update:sort", next);
|
|
91
131
|
};
|
|
132
|
+
const items = [];
|
|
133
|
+
if (col.sortable) {
|
|
134
|
+
items.push(
|
|
135
|
+
{
|
|
136
|
+
label: props.sortAscLabel,
|
|
137
|
+
icon: "lucide:arrow-up",
|
|
138
|
+
disabled: s?.key === col.key && s.dir === "asc",
|
|
139
|
+
onSelect: set({ key: col.key, dir: "asc" })
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
label: props.sortDescLabel,
|
|
143
|
+
icon: "lucide:arrow-down",
|
|
144
|
+
disabled: s?.key === col.key && s.dir === "desc",
|
|
145
|
+
onSelect: set({ key: col.key, dir: "desc" })
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: props.sortClearLabel,
|
|
149
|
+
icon: "lucide:x",
|
|
150
|
+
disabled: !s,
|
|
151
|
+
onSelect: set(null)
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
if (col.filterable) {
|
|
156
|
+
const hidden = hiddenValues.value[col.key];
|
|
157
|
+
items.push({
|
|
158
|
+
label: props.filterLabel,
|
|
159
|
+
icon: "lucide:filter",
|
|
160
|
+
separatorBefore: items.length > 0,
|
|
161
|
+
children: [
|
|
162
|
+
...valuesOf(col).map((value) => ({
|
|
163
|
+
label: col.valueLabel?.(value) ?? String(value ?? "—"),
|
|
164
|
+
checked: !isValueHidden(col.key, value),
|
|
165
|
+
onSelect: () => toggleValue(col.key, value)
|
|
166
|
+
})),
|
|
167
|
+
{
|
|
168
|
+
label: props.showAllLabel,
|
|
169
|
+
icon: "lucide:list",
|
|
170
|
+
separatorBefore: true,
|
|
171
|
+
disabled: !hidden?.size,
|
|
172
|
+
onSelect: () => showAllValues(col.key)
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return items;
|
|
178
|
+
}
|
|
179
|
+
function tableMenu() {
|
|
180
|
+
const offered = props.columns.filter((c) => !c.alwaysVisible && c.label);
|
|
181
|
+
if (!offered.length) return [];
|
|
92
182
|
return [
|
|
93
183
|
{
|
|
94
|
-
label: props.
|
|
95
|
-
icon: "lucide:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
label: props.sortClearLabel,
|
|
107
|
-
icon: "lucide:x",
|
|
108
|
-
separatorBefore: true,
|
|
109
|
-
disabled: !s,
|
|
110
|
-
onSelect: set(null)
|
|
184
|
+
label: props.columnsLabel,
|
|
185
|
+
icon: "lucide:columns-3",
|
|
186
|
+
children: offered.map((col) => ({
|
|
187
|
+
label: col.label,
|
|
188
|
+
checked: !hiddenColumns.value.has(col.key),
|
|
189
|
+
// The last visible column cannot be hidden: a table with no columns is
|
|
190
|
+
// a blank card the operator has no way back from.
|
|
191
|
+
disabled: !hiddenColumns.value.has(col.key) && visibleColumns.value.length <= 1,
|
|
192
|
+
onSelect: () => toggleColumn(col.key)
|
|
193
|
+
}))
|
|
111
194
|
}
|
|
112
195
|
];
|
|
113
196
|
}
|
|
@@ -190,130 +273,137 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
190
273
|
"bar-inset-top": barInsetTop.value
|
|
191
274
|
}, {
|
|
192
275
|
default: withCtx(() => [
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
createElementVNode("button", {
|
|
220
|
-
type: "button",
|
|
221
|
-
class: normalizeClass(["group/sort -mx-1 inline-flex items-center gap-1 rounded px-1 outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring", [
|
|
222
|
-
col.align === "right" ? "flex-row-reverse" : "",
|
|
223
|
-
activeSort.value?.key === col.key ? "text-ink" : ""
|
|
224
|
-
]]),
|
|
225
|
-
onClick: ($event) => toggleSort(col)
|
|
226
|
-
}, [
|
|
227
|
-
createTextVNode(toDisplayString(col.label) + " ", 1),
|
|
228
|
-
createVNode(_sfc_main$4, {
|
|
229
|
-
name: sortIcon(col),
|
|
230
|
-
size: 13,
|
|
231
|
-
class: normalizeClass([
|
|
232
|
-
"shrink-0 transition-[transform,opacity] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)]",
|
|
233
|
-
activeSort.value?.key === col.key ? "opacity-100" : "opacity-40 group-hover/sort:opacity-70"
|
|
234
|
-
])
|
|
235
|
-
}, null, 8, ["name", "class"])
|
|
236
|
-
], 10, _hoisted_5)
|
|
237
|
-
]),
|
|
238
|
-
_: 2
|
|
239
|
-
}, 1032, ["items"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
240
|
-
createTextVNode(toDisplayString(col.label), 1)
|
|
241
|
-
], 64))
|
|
242
|
-
], 14, _hoisted_4);
|
|
243
|
-
}), 128))
|
|
244
|
-
])
|
|
245
|
-
], 2),
|
|
246
|
-
createVNode(TransitionGroup, {
|
|
247
|
-
tag: "tbody",
|
|
248
|
-
name: "lp-row",
|
|
249
|
-
ref: (el) => unref(roving).setContainer(el?.$el ?? null)
|
|
250
|
-
}, {
|
|
251
|
-
default: withCtx(() => [
|
|
252
|
-
displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_6, [
|
|
253
|
-
createElementVNode("td", {
|
|
254
|
-
colspan: colSpan.value,
|
|
255
|
-
class: "px-4 py-10 text-center text-muted"
|
|
256
|
-
}, [
|
|
257
|
-
createVNode(_sfc_main$4, {
|
|
258
|
-
name: __props.emptyIcon,
|
|
259
|
-
size: 22,
|
|
260
|
-
class: "mx-auto mb-2 opacity-60"
|
|
261
|
-
}, null, 8, ["name"]),
|
|
262
|
-
createElementVNode("div", null, toDisplayString(__props.emptyLabel), 1)
|
|
263
|
-
], 8, _hoisted_7)
|
|
264
|
-
])) : createCommentVNode("", true),
|
|
265
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(displayRows.value, (row, index) => {
|
|
266
|
-
return openBlock(), createBlock(_sfc_main$3, {
|
|
267
|
-
key: keyFor(row, index),
|
|
268
|
-
items: menuFor(row)
|
|
269
|
-
}, {
|
|
270
|
-
default: withCtx(() => [
|
|
271
|
-
createElementVNode("tr", mergeProps({
|
|
272
|
-
class: ["group border-b border-line/60 outline-none transition-colors last:border-0 hover:bg-surface-soft/60 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring data-[active]:bg-surface-soft/40", selectedSet.value.has(keyFor(row, index)) ? "bg-brand-soft/40" : ""]
|
|
273
|
-
}, { ref_for: true }, unref(roving).itemProps(String(keyFor(row, index))), {
|
|
274
|
-
onClick: ($event) => emit("rowClick", row),
|
|
275
|
-
onKeydown: onRowKeydown
|
|
276
|
-
}), [
|
|
277
|
-
__props.selectable ? (openBlock(), createElementBlock("td", {
|
|
276
|
+
createVNode(_sfc_main$2, {
|
|
277
|
+
items: tableMenu()
|
|
278
|
+
}, {
|
|
279
|
+
default: withCtx(() => [
|
|
280
|
+
createElementVNode("table", _hoisted_1, [
|
|
281
|
+
createElementVNode("thead", {
|
|
282
|
+
ref_key: "headEl",
|
|
283
|
+
ref: headEl,
|
|
284
|
+
class: normalizeClass(__props.stickyHeader ? "sticky top-0 z-10" : "")
|
|
285
|
+
}, [
|
|
286
|
+
createElementVNode("tr", _hoisted_2, [
|
|
287
|
+
__props.selectable ? (openBlock(), createElementBlock("th", _hoisted_3, [
|
|
288
|
+
createVNode(_sfc_main$3, {
|
|
289
|
+
"model-value": allChecked.value,
|
|
290
|
+
indeterminate: someChecked.value,
|
|
291
|
+
"onUpdate:modelValue": toggleAll
|
|
292
|
+
}, null, 8, ["model-value", "indeterminate"])
|
|
293
|
+
])) : createCommentVNode("", true),
|
|
294
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(visibleColumns.value, (col) => {
|
|
295
|
+
return openBlock(), createElementBlock("th", {
|
|
296
|
+
key: col.key,
|
|
297
|
+
style: normalizeStyle(col.width ? { width: col.width } : void 0),
|
|
298
|
+
class: normalizeClass(["px-4 py-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted", alignClass(col.align)]),
|
|
299
|
+
"aria-sort": activeSort.value?.key === col.key ? activeSort.value.dir === "asc" ? "ascending" : "descending" : void 0
|
|
300
|
+
}, [
|
|
301
|
+
col.sortable ? (openBlock(), createBlock(_sfc_main$2, {
|
|
278
302
|
key: 0,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
items: headerMenu(col)
|
|
304
|
+
}, {
|
|
305
|
+
default: withCtx(() => [
|
|
306
|
+
createElementVNode("button", {
|
|
307
|
+
type: "button",
|
|
308
|
+
class: normalizeClass(["group/sort -mx-1 inline-flex items-center gap-1 rounded px-1 outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring", [
|
|
309
|
+
col.align === "right" ? "flex-row-reverse" : "",
|
|
310
|
+
activeSort.value?.key === col.key ? "text-ink" : ""
|
|
311
|
+
]]),
|
|
312
|
+
onClick: ($event) => toggleSort(col)
|
|
313
|
+
}, [
|
|
314
|
+
createTextVNode(toDisplayString(col.label) + " ", 1),
|
|
315
|
+
createVNode(_sfc_main$4, {
|
|
316
|
+
name: sortIcon(col),
|
|
317
|
+
size: 13,
|
|
318
|
+
class: normalizeClass([
|
|
319
|
+
"shrink-0 transition-[transform,opacity] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)]",
|
|
320
|
+
activeSort.value?.key === col.key ? "opacity-100" : "opacity-40 group-hover/sort:opacity-70"
|
|
321
|
+
])
|
|
322
|
+
}, null, 8, ["name", "class"])
|
|
323
|
+
], 10, _hoisted_5)
|
|
324
|
+
]),
|
|
325
|
+
_: 2
|
|
326
|
+
}, 1032, ["items"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
327
|
+
createTextVNode(toDisplayString(col.label), 1)
|
|
328
|
+
], 64))
|
|
329
|
+
], 14, _hoisted_4);
|
|
330
|
+
}), 128))
|
|
331
|
+
])
|
|
332
|
+
], 2),
|
|
333
|
+
createVNode(TransitionGroup, {
|
|
334
|
+
tag: "tbody",
|
|
335
|
+
name: "lp-row",
|
|
336
|
+
ref: (el) => unref(roving).setContainer(el?.$el ?? null)
|
|
337
|
+
}, {
|
|
338
|
+
default: withCtx(() => [
|
|
339
|
+
displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_6, [
|
|
340
|
+
createElementVNode("td", {
|
|
341
|
+
colspan: colSpan.value,
|
|
342
|
+
class: "px-4 py-10 text-center text-muted"
|
|
343
|
+
}, [
|
|
344
|
+
createVNode(_sfc_main$4, {
|
|
345
|
+
name: __props.emptyIcon,
|
|
346
|
+
size: 22,
|
|
347
|
+
class: "mx-auto mb-2 opacity-60"
|
|
348
|
+
}, null, 8, ["name"]),
|
|
349
|
+
createElementVNode("div", null, toDisplayString(__props.emptyLabel), 1)
|
|
350
|
+
], 8, _hoisted_7)
|
|
351
|
+
])) : createCommentVNode("", true),
|
|
352
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(displayRows.value, (row, index) => {
|
|
353
|
+
return openBlock(), createBlock(_sfc_main$2, {
|
|
354
|
+
key: keyFor(row, index),
|
|
355
|
+
items: menuFor(row)
|
|
356
|
+
}, {
|
|
357
|
+
default: withCtx(() => [
|
|
358
|
+
createElementVNode("tr", mergeProps({
|
|
359
|
+
class: ["group border-b border-line/60 outline-none transition-colors last:border-0 hover:bg-surface-soft/60 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring data-[active]:bg-surface-soft/40", selectedSet.value.has(keyFor(row, index)) ? "bg-brand-soft/40" : ""]
|
|
360
|
+
}, { ref_for: true }, unref(roving).itemProps(String(keyFor(row, index))), {
|
|
361
|
+
onClick: ($event) => emit("rowClick", row),
|
|
362
|
+
onKeydown: onRowKeydown
|
|
363
|
+
}), [
|
|
364
|
+
__props.selectable ? (openBlock(), createElementBlock("td", {
|
|
365
|
+
key: 0,
|
|
366
|
+
class: "w-px px-4 py-3",
|
|
367
|
+
onClick: _cache[0] || (_cache[0] = withModifiers(() => {
|
|
368
|
+
}, ["stop"]))
|
|
369
|
+
}, [
|
|
370
|
+
createVNode(_sfc_main$3, {
|
|
371
|
+
"model-value": selectedSet.value.has(keyFor(row, index)),
|
|
372
|
+
"onUpdate:modelValue": (v) => toggleRow(keyFor(row, index), v)
|
|
373
|
+
}, null, 8, ["model-value", "onUpdate:modelValue"])
|
|
374
|
+
])) : createCommentVNode("", true),
|
|
375
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(visibleColumns.value, (col) => {
|
|
376
|
+
return openBlock(), createElementBlock("td", {
|
|
377
|
+
key: col.key,
|
|
378
|
+
class: normalizeClass(["px-4 py-3 text-ink", alignClass(col.align)])
|
|
379
|
+
}, [
|
|
380
|
+
renderSlot(_ctx.$slots, `cell-${col.key}`, {
|
|
381
|
+
row,
|
|
382
|
+
value: row[col.key]
|
|
383
|
+
}, () => [
|
|
384
|
+
createTextVNode(toDisplayString(row[col.key]), 1)
|
|
385
|
+
], true)
|
|
386
|
+
], 2);
|
|
387
|
+
}), 128))
|
|
388
|
+
], 16, _hoisted_8)
|
|
389
|
+
]),
|
|
390
|
+
_: 2
|
|
391
|
+
}, 1032, ["items"]);
|
|
392
|
+
}), 128))
|
|
393
|
+
]),
|
|
394
|
+
_: 3
|
|
395
|
+
}, 512)
|
|
396
|
+
])
|
|
397
|
+
]),
|
|
398
|
+
_: 3
|
|
399
|
+
}, 8, ["items"])
|
|
310
400
|
]),
|
|
311
401
|
_: 3
|
|
312
402
|
}, 8, ["bar-inset-top"]);
|
|
313
403
|
};
|
|
314
404
|
}
|
|
315
405
|
});
|
|
316
|
-
const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
406
|
+
const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f9c874a7"]]);
|
|
317
407
|
export {
|
|
318
408
|
LpTable as default
|
|
319
409
|
};
|