@indielayer/ui
Version:
Indielayer UI Components with Tailwind CSS build for Vue 3
425 lines (424 loc) • 16 kB
JavaScript
import { defineComponent as oe, mergeModels as D, useModel as ie, ref as ue, computed as m, watch as de, useSlots as ce, openBlock as s, createElementBlock as i, mergeProps as W, unref as p, renderSlot as g, createElementVNode as h, normalizeStyle as K, normalizeClass as k, createVNode as v, withCtx as u, createBlock as d, withModifiers as L, createCommentVNode as y, Fragment as b, renderList as $, createTextVNode as j, toDisplayString as q } from "vue";
import { useTheme as fe } from "../../composables/useTheme.js";
import { useVirtualList as pe } from "../../composables/useVirtualList.js";
import ge from "./TableHead.vue.js";
import O from "./TableHeader.vue.js";
import ve from "./TableBody.js";
import E from "./TableRow.vue.js";
import w from "./TableCell.vue.js";
import ye from "../spinner/Spinner.vue.js";
import me from "../skeleton/Skeleton.vue.js";
import he from "../icon/Icon.vue.js";
import G from "../checkbox/Checkbox.vue.js";
import { chevronDownIcon as ke } from "../../common/icons.js";
const be = { key: 1 }, we = ["colspan"], Se = { key: 2 }, $e = ["colspan"], Ce = ["onClick"], Be = ["colspan"], Fe = { key: 0 }, Le = {
headers: {
type: Array,
default: () => []
},
items: {
type: Array,
default: () => []
},
sort: {
type: Array,
default: () => []
},
loading: Boolean,
loadingSkeleton: Boolean,
loadingLines: {
type: [Number, String],
default: 3
},
error: Boolean,
dense: Boolean,
fixed: Boolean,
striped: Boolean,
pointer: Boolean,
scrollable: {
type: Boolean,
default: !0
},
stickyHeader: {
type: Boolean,
default: !0
},
expandable: Boolean,
virtualList: Boolean,
virtualListOffsetTop: Number,
virtualListOffsetBottom: Number,
virtualListItemHeight: {
type: Number,
default: 54
},
virtualListOverscan: {
type: Number,
default: 10
},
keyProp: String,
selectable: Boolean,
singleSelect: Boolean,
autoClearSelected: {
type: Boolean,
default: !0
},
toFn: Function,
hrefFn: Function,
hrefTarget: String
}, Ae = { name: "XTable" }, De = /* @__PURE__ */ oe({
...Ae,
props: /* @__PURE__ */ D({
...Le,
items: {
type: Array,
default: () => []
},
toFn: Function,
hrefFn: Function,
hrefTarget: String
}, {
selected: {},
selectedModifiers: {}
}),
emits: /* @__PURE__ */ D(["update:sort", "click-row"], ["update:selected"]),
setup(c, { emit: J }) {
const l = c, r = ie(c, "selected"), C = ue(/* @__PURE__ */ new Map()), B = m(() => l.items), { list: Q, containerProps: U, wrapperProps: Y } = pe(
B,
{
disabled: !l.virtualList,
itemHeight: l.virtualListItemHeight || 54,
topOffset: l.virtualListOffsetTop || 0,
bottomOffset: l.virtualListOffsetBottom || 0,
overscan: l.virtualListOverscan
}
);
function f(e, n) {
if (!l.keyProp || !e || typeof e != "object" || e === null)
return n;
const t = e[l.keyProp];
return t == null ? (console.warn(`[XTable] keyProp "${l.keyProp}" is undefined/null for item at index ${n}. Falling back to index.`), n) : typeof t != "string" && typeof t != "number" ? (console.warn(`[XTable] keyProp "${l.keyProp}" must be a string or number, got ${typeof t}. Falling back to index.`), n) : t;
}
function F(e) {
return e.index;
}
const M = J;
function Z(e, n) {
if (e)
for (let t = 0; t < n.length; t++) {
const { 0: a, 1: o } = n[t].split(",");
if (e === a)
return parseInt(o) > 0 ? 1 : -1;
}
}
function _(e) {
const n = l.sort.slice(0);
let t = !1;
for (let a = 0; a < n.length; a++) {
const { 0: o, 1: S } = n[a].split(",");
if (o === e.value) {
if (t = !0, S === "-1") {
n.splice(a, 1, `${e.value},1`);
break;
} else if (S === "1") {
n.splice(a, 1);
break;
}
}
}
t || n.push(`${e.value},-1`), M("update:sort", n);
}
const A = /* @__PURE__ */ new Map();
function ee(e, n) {
if (!n || !e)
return "";
let t;
return Array.isArray(n) ? t = n : A.has(n) ? t = A.get(n) : (t = n.match(/([^[.\]])+/g), t && A.set(n, t)), !t || t.length === 0 ? "" : t.reduce((o, S) => o == null || typeof o != "object" ? null : o[S], e) ?? "";
}
const x = m(() => l.selectable ? B.value.map((e, n) => f(e, n)) : []), V = m(() => !l.selectable || l.singleSelect ? /* @__PURE__ */ new Set() : Array.isArray(r.value) ? new Set(r.value) : /* @__PURE__ */ new Set()), z = m(() => {
if (!l.selectable || l.singleSelect || !Array.isArray(r.value) || r.value.length === 0)
return !1;
const e = x.value.length;
return e === 0 ? !1 : r.value.length === e;
}), T = m(() => {
if (!l.selectable || l.singleSelect || !Array.isArray(r.value) || r.value.length === 0)
return !1;
const e = x.value.length;
return e === 0 ? !1 : r.value.length > 0 && r.value.length !== e;
});
function R(e) {
return l.selectable ? l.singleSelect ? r.value === e : V.value.has(e) : !1;
}
function N(e) {
l.selectable && (l.singleSelect ? r.value = r.value === e ? void 0 : e : (Array.isArray(r.value) || (r.value = []), V.value.has(e) ? r.value = r.value.filter((n) => n !== e) : r.value = [...r.value, e]));
}
function X() {
!l.selectable || l.singleSelect || (z.value || T.value ? r.value = [] : r.value = x.value);
}
function te(e) {
if (!l.expandable)
return;
const n = f(e.data, F(e));
C.value.set(n, !C.value.get(n));
}
function P(e) {
if (!l.expandable)
return !1;
const n = f(e.data, F(e));
return C.value.get(n) ?? !1;
}
function le(e, n) {
const t = F(n);
if (l.selectable && l.singleSelect) {
const a = f(e, t);
N(a);
}
M("click-row", e, t);
}
const H = m(() => {
let e = l.headers.length;
return l.selectable && !l.singleSelect && e++, l.expandable && e++, e;
});
de(B, (e) => {
const n = /* @__PURE__ */ new Set();
e.forEach((t, a) => {
n.add(f(t, a));
}), l.expandable && C.value.forEach((t, a) => {
n.has(a) || C.value.delete(a);
}), l.selectable && l.autoClearSelected && (l.singleSelect ? n.has(r.value) || (r.value = void 0) : Array.isArray(r.value) && r.value.length > 0 && (r.value = r.value.filter((t) => n.has(t))));
}, { immediate: !0 });
const ne = ce(), ae = m(() => Object.keys(ne).some((e) => e.startsWith("footer-"))), { styles: re, classes: I, className: se } = fe("Table", {}, l);
return (e, n) => (s(), i("div", W({
class: [p(se), p(I).wrapper]
}, p(U)), [
g(e.$slots, "title"),
g(e.$slots, "actions"),
h("div", W(p(Y), {
class: ["relative", {
"!h-auto": l.loading
}]
}), [
h("table", {
style: K(p(re)),
class: k(p(I).table)
}, [
v(ge, { "sticky-header": e.stickyHeader }, {
default: u(() => [
l.selectable && !l.singleSelect ? (s(), d(O, {
key: 0,
width: "40",
class: "!pl-3.5 !pr-0.5 !py-2.5 cursor-pointer",
onClick: X
}, {
default: u(() => [
v(G, {
"model-value": z.value || T.value,
indeterminate: T.value,
"hide-footer": "",
"aria-label": "Select all rows",
"skip-form-registry": "",
onClick: L(X, ["prevent", "stop"])
}, null, 8, ["model-value", "indeterminate"])
]),
_: 1
})) : y("", !0),
e.expandable ? (s(), d(O, {
key: 1,
width: "48",
class: "!p-0"
})) : y("", !0),
(s(!0), i(b, null, $(e.headers, (t, a) => (s(), d(O, {
key: a,
"text-align": t.align,
sort: Z(t.value, e.sort),
sortable: t.sortable,
width: t.width,
tooltip: t.tooltip,
onClick: (o) => t.sortable ? _(t) : null
}, {
default: u(() => [
g(e.$slots, `header-${t.value}`, { header: t }, () => [
j(q(t.text), 1)
])
]),
_: 2
}, 1032, ["text-align", "sort", "sortable", "width", "tooltip", "onClick"]))), 128))
]),
_: 3
}, 8, ["sticky-header"]),
v(p(ve), null, {
default: u(() => [
e.loading ? (s(!0), i(b, { key: 0 }, $(Number(e.loadingLines), (t, a) => (s(), d(E, {
key: a,
striped: e.striped
}, {
default: u(() => [
(s(!0), i(b, null, $(e.headers, (o, S) => (s(), d(w, {
key: S,
"text-align": o.align,
width: o.width,
dense: e.dense,
fixed: e.fixed
}, {
default: u(() => [
g(e.$slots, `loading-${o.value}`, { item: t }, () => [
v(me, {
class: k(["max-w-[60%]", {
"mx-auto": o.align === "center",
"ml-auto": o.align === "right"
}]),
shape: o.skeletonShape || "line"
}, null, 8, ["shape", "class"])
])
]),
_: 2
}, 1032, ["text-align", "width", "dense", "fixed"]))), 128))
]),
_: 2
}, 1032, ["striped"]))), 128)) : e.error ? (s(), i("tr", be, [
h("td", { colspan: H.value }, [
g(e.$slots, "error")
], 8, we)
])) : !B.value || B.value.length === 0 ? (s(), i("tr", Se, [
h("td", { colspan: H.value }, [
g(e.$slots, "empty")
], 8, $e)
])) : (s(!0), i(b, { key: 3 }, $(p(Q), (t) => (s(), i(b, {
key: f(t.data, t.index)
}, [
v(E, {
pointer: e.pointer || !!c.toFn || !!c.hrefFn,
striped: e.striped,
selected: R(f(t.data, t.index)),
"single-select": e.singleSelect,
onClick: (a) => le(t.data, t)
}, {
default: u(() => [
l.selectable && !e.singleSelect ? (s(), d(w, {
key: 0,
width: "40",
class: "!pl-3.5 !pr-0.5 cursor-pointer",
onClick: L((a) => N(f(t.data, t.index)), ["stop"])
}, {
default: u(() => [
v(G, {
"model-value": R(f(t.data, t.index)),
"hide-footer": "",
"aria-label": `Select row ${F(t) + 1}`,
"skip-form-registry": "",
onClick: L((a) => N(f(t.data, t.index)), ["prevent", "stop"])
}, null, 8, ["model-value", "aria-label", "onClick"])
]),
_: 2
}, 1032, ["onClick"])) : y("", !0),
e.expandable ? (s(), d(w, {
key: 1,
width: "48",
class: "!p-1"
}, {
default: u(() => [
h("button", {
type: "button",
class: k(["px-3 p-2", [e.dense ? "p-0.5" : "px-3 py-2"]]),
onClick: L((a) => te(t), ["stop"])
}, [
v(he, {
icon: p(ke),
size: e.dense ? "xs" : "md",
class: k(["transition-transform", {
"rotate-180": P(t)
}])
}, null, 8, ["icon", "size", "class"])
], 10, Ce)
]),
_: 2
}, 1024)) : y("", !0),
(s(!0), i(b, null, $(e.headers, (a, o) => (s(), d(w, {
key: o,
"text-align": a.align,
truncate: a.truncate,
width: a.width,
dense: e.dense,
style: K([l.virtualList ? {
height: `${l.virtualListItemHeight}px`,
maxHeight: `${l.virtualListItemHeight}px`,
overflow: "hidden",
whiteSpace: "nowrap"
} : {}]),
href: c.hrefFn ? c.hrefFn(t.data) : void 0,
to: c.toFn ? c.toFn(t.data) : void 0,
target: c.hrefFn ? c.hrefTarget : void 0
}, {
default: u(() => [
g(e.$slots, `item-${a.value}`, {
item: t.data
}, () => [
j(q(ee(t.data, a.value)), 1)
])
]),
_: 2
}, 1032, ["text-align", "truncate", "width", "dense", "style", "href", "to", "target"]))), 128))
]),
_: 2
}, 1032, ["pointer", "striped", "selected", "single-select", "onClick"]),
e.expandable ? (s(), i("tr", {
key: 0,
class: k({ hidden: !P(t) })
}, [
h("td", { colspan: H.value }, [
h("div", {
class: k(["overflow-hidden transition-opacity", [P(t) ? "" : "opacity-0 max-h-0"]])
}, [
g(e.$slots, "expanded-row", {
item: t.data
})
], 2)
], 8, Be)
], 2)) : y("", !0)
], 64))), 128))
]),
_: 3
}),
g(e.$slots, "footer", {}, () => [
ae.value && !e.loading ? (s(), i("tfoot", Fe, [
v(E, null, {
default: u(() => [
l.selectable && !l.singleSelect ? (s(), d(w, {
key: 0,
width: "40",
class: "!pl-3.5 !pr-0.5"
})) : y("", !0),
e.expandable ? (s(), d(w, {
key: 1,
width: "48",
class: "!p-0"
})) : y("", !0),
(s(!0), i(b, null, $(e.headers, (t, a) => (s(), d(w, {
key: a,
"text-align": t.align,
width: t.width,
dense: e.dense
}, {
default: u(() => [
g(e.$slots, `footer-${t.value}`, { header: t })
]),
_: 2
}, 1032, ["text-align", "width", "dense"]))), 128))
]),
_: 3
})
])) : y("", !0)
])
], 6),
e.loading ? (s(), i("div", {
key: 0,
class: k(p(I).loadingWrapper)
}, [
v(ye, { size: "lg" })
], 2)) : y("", !0)
], 16)
], 16));
}
});
export {
De as default
};