dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
614 lines (613 loc) • 24.3 kB
JavaScript
var I = Object.defineProperty, L = Object.defineProperties;
var A = Object.getOwnPropertyDescriptors;
var B = Object.getOwnPropertySymbols;
var O = Object.prototype.hasOwnProperty, E = Object.prototype.propertyIsEnumerable;
var _ = (d, t, e) => t in d ? I(d, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : d[t] = e, m = (d, t) => {
for (var e in t || (t = {}))
O.call(t, e) && _(d, e, t[e]);
if (B)
for (var e of B(t))
E.call(t, e) && _(d, e, t[e]);
return d;
}, y = (d, t) => L(d, A(t));
import { TableController as H, flexRender as C } from "../../node_modules/@tanstack/lit-table/build/lib/index.js";
import { clsx as f } from "../../node_modules/clsx/dist/clsx.js";
import "../../node_modules/@lit/reactive-element/reactive-element.js";
import { nothing as z } from "../../node_modules/lit-html/lit-html.js";
import "../../node_modules/lit-element/lit-element.js";
import { property as a } from "../../node_modules/@lit/reactive-element/decorators/property.js";
import { state as $ } from "../../node_modules/@lit/reactive-element/decorators/state.js";
import { ifDefined as u } from "../../node_modules/lit-html/directives/if-defined.js";
import { repeat as S } from "../../node_modules/lit-html/directives/repeat.js";
import { html as p, unsafeStatic as P } from "../../node_modules/lit-html/static.js";
import { DdsElement as M } from "../../internal/dds-hu-element.js";
import "../../localization/localization.js";
import D from "../checkbox/checkbox.component.js";
import N from "../icons/arrows/arrows-arrow-down-s-line/arrows-arrow-down-s-line.component.js";
import U from "../icons/arrows/arrows-arrow-up-s-line/arrows-arrow-up-s-line.component.js";
import j from "../pager/pager.component.js";
import K from "../skeleton/skeleton.component.js";
import F from "../spinner/spinner.component.js";
import q from "./datatable.scss.js";
import { renderCellContent as G } from "./utils/cell-renderer.js";
import { t as c } from "../../node_modules/i18next/dist/esm/i18next.js";
import { getPaginationRowModel as V, getSortedRowModel as X, getCoreRowModel as J } from "../../node_modules/@tanstack/table-core/build/lib/index.js";
import { unsafeCSS as Q } from "../../node_modules/@lit/reactive-element/css-tag.js";
var W = Object.defineProperty, i = (d, t, e, l) => {
for (var r = void 0, n = d.length - 1, s; n >= 0; n--)
(s = d[n]) && (r = s(t, e, r) || r);
return r && W(t, e, r), r;
};
const k = "__multiSelect__", w = class w extends M {
constructor() {
super(...arguments), this.tableController = new H(this), this.stickyOffsets = /* @__PURE__ */ new Map(), this.data = [], this.columns = [], this.rowKey = "id", this.enableRowSelection = !1, this.stickySelectionColumn = !1, this.enableSorting = !1, this.manualSorting = !1, this.manualPagination = !1, this.autoResetPageIndex = !1, this.enableRowClick = !1, this.loading = !1, this.enableStripedRows = !1, this.loadingType = "spinner", this.loadingVariant = "neutral", this.loadingSize = "lg", this.disableHeaderOnEmpty = "true", this.showPagerOnEmpty = !1, this.pager = !1, this.showPageSizeOptions = "true", this.showPageIndex = "true", this.showPageCount = "true", this.showFirstButton = "true", this.showPreviousButton = "true", this.showNextButton = "true", this.showLastButton = "true", this.showPageNumbers = "false", this.siblingCount = 1, this.sortButtonTestId = "datatable-sort-button", this.pageSizeOptions = [10, 25, 50, 100], this._sorting = [], this._rowSelection = {}, this._pagination = {
pageIndex: 0,
pageSize: 10
}, this._columnSizing = {}, this.ariaLabel = null, this._statusMessage = "", this.debug = !1, this.columnsMemo = () => {
const t = this.columns.map((e) => !e.size && !e.minSize && !e.maxSize ? y(m({}, e), { minSize: 0 }) : e);
return [
...this.enableRowSelection && this.columns[0] && this.columns[0].id !== k ? [
y(m({
id: k,
accessorKey: k,
enableSorting: !1,
size: 50,
maxSize: 50
}, this.stickySelectionColumn ? { sticky: "left" } : {}), {
header: ({ table: e }) => p`<dap-ds-checkbox
isIndeterminate=${e.getIsSomeRowsSelected()}
-change=${e.getToggleAllRowsSelectedHandler()}
.checked="${e.getIsAllRowsSelected()}"
.indeterminate="${e.getIsSomeRowsSelected()}"
?disabled="${this.disableHeaderOnEmpty === "true" && this.isTableEmpty}"></dap-ds-checkbox>`,
cell: ({ row: e }) => p`<dap-ds-checkbox
-change="${e.getToggleSelectedHandler()}"
.checked="${e.getIsSelected()}"
?disabled="${!e.getCanSelect()}"
.indeterminate="${e.getIsSomeSelected()}"></dap-ds-checkbox>`
})
] : [],
...t
];
}, this.renderColgroup = (t) => {
const e = this.columnsMemo(), l = this.columnSizing || this._columnSizing;
return p`
<colgroup>
${S(
e,
(r, n) => r.id || `col-${n}`,
(r) => {
const n = r;
let s;
return l && n.id && l[n.id] ? s = `${l[n.id]}px` : n.size ? s = `${n.size}px` : s = "auto", p`<col style="width: ${s};" />`;
}
)}
</colgroup>
`;
}, this.renderHeader = (t) => p`
<thead part="header">
${S(
t.getHeaderGroups(),
(e) => e.id,
(e) => p`
<tr
part="header-row"
class=${f("data-table-header-row", {
"data-table-header-row--striped": this.enableStripedRows
})}>
${S(
e.headers,
(l) => l.id,
(l) => this.renderHeaderCell(l)
)}
</tr>
`
)}
</thead>
`, this.renderSkeletonRows = (t, e) => p`
${S(
Array.from({ length: t }, (l, r) => r),
(l) => l,
(l) => p`
<tr class="data-table-row">
${S(
Array.from({ length: e }, (r, n) => n),
(r) => r,
(r) => p`<td class="data-table-cell">
<dap-ds-skeleton></dap-ds-skeleton>
</td>`
)}
</tr>
`
)}
`, this.renderBody = (t) => {
var e, l;
return p`
${this.loading ? p`<tbody part="body">
${this.loadingType === "spinner" ? p`
<tr>
<td
colspan="${this.columnsMemo().length}"
class="data-table-cell">
<div part="loading" class="data-table-placeholder">
<slot name="loading">
<dap-ds-spinner
size=${this.loadingSize}
variant=${this.loadingVariant}
.staticSize=${this.loadingStaticSize}
.text=${this.loadingText}></dap-ds-spinner>
</slot>
</div>
</td>
</tr>
` : p`
${this.renderSkeletonRows(
(e = this._pagination.pageSize) != null ? e : 10,
this.columnsMemo().length
)}
`}
</tbody>` : p`
<tbody part="body">
${this.isTableEmpty ? p`<tr class="data-table-row data-table-row--empty">
<td
colspan="${this.columnsMemo().length}"
class="data-table-cell">
<div part="empty" class="data-table-placeholder">
<slot name="empty">
<span
>${(l = this.emptyText) != null ? l : c("datatable.noData")}</span
>
</slot>
</div>
</td>
</tr>` : t.getRowModel().rows.map(
(r, n) => p`
<tr
part="row"
role=${this.enableRowClick ? "button" : "row"}
tabindex=${this.enableRowClick ? 0 : -1}
aria-selected=${r.getIsSelected()}
aria-rowindex=${n + 2}
class=${f("data-table-row", {
"data-table-row--selected": r.getIsSelected(),
"data-table-row--clickable": this.enableRowClick,
"data-table-row--striped": this.enableStripedRows
})}
=${() => this.handleRowClick(r)}
=${(s) => this.handleRowKeydown(s, r)}>
${r.getVisibleCells().map((s) => {
const g = s.column.columnDef, h = this.stickyOffsets.get(s.column.id), b = [
g.textAlign && `text-align: ${g.textAlign};`,
this.getStickyStyle(s.column.id)
].filter(Boolean).join(" ") || void 0;
return p`
<td
part="cell"
class=${f(
"data-table-cell",
h && `data-table-cell--sticky-${h.side}`
)}
style="${u(b)}">
${this.renderCell(s)}
</td>
`;
})}
</tr>
`
)}
</tbody>
`}
`;
};
}
/** @ignore */
get isTableEmpty() {
return this.manualPagination && this.rowCount !== void 0 ? this.rowCount === 0 : !this.data || this.data.length === 0;
}
/** @ignore */
get shouldDisableHeaderActions() {
return this.disableHeaderOnEmpty === "true" && this.isTableEmpty;
}
firstUpdated(t) {
super.firstUpdated(t), this.sorting && (this._sorting = this.sorting), this.rowSelection && (this._rowSelection = this.rowSelection), this.pagination ? this._pagination = this.pagination : this.pageSizeOptions && this.pageSizeOptions.length > 0 && (this._pagination = y(m({}, this._pagination), {
pageSize: this.pageSizeOptions[0]
}));
}
updated(t) {
super.updated(t), t.has("pagination") && (this._pagination = this.pagination), t.has("sorting") && (this._sorting = this.sorting), (t.has("rowSelection") || t.has("rowselection")) && (this._rowSelection = this.rowSelection), t.has("data") && this.requestUpdate();
}
/**
* Cleanup resize observer
*/
disconnectedCallback() {
super.disconnectedCallback(), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = void 0);
}
// Walks the visible leaf columns from each edge inward, giving every pinned
// column its offset (the summed width of the already-seen pinned columns on
// that side). getSize() resolves to the column's `size`, so a pinned column
// without a size contributes 0 and the next one on that side would overlap it.
computeStickyOffsets(t) {
const e = /* @__PURE__ */ new Map(), l = t.getVisibleLeafColumns();
let r = 0;
for (let s = l.length - 1; s >= 0; s--) {
const g = l[s];
g.columnDef.sticky === "right" && (e.set(g.id, { side: "right", offset: r }), r += g.getSize());
}
let n = 0;
for (const s of l)
s.columnDef.sticky === "left" && (e.set(s.id, { side: "left", offset: n }), n += s.getSize());
this.stickyOffsets = e;
}
// Inline sticky positioning for a pinned column. z-index lifts the cell above
// the row cells scrolling under it (needed for a left-pinned column, whose
// siblings paint after it). The opaque background and edge divider come from
// the `--sticky-*` classes in the stylesheet.
getStickyStyle(t) {
const e = this.stickyOffsets.get(t);
if (e)
return `position: sticky; ${e.side}: ${e.offset}px; z-index: 1;`;
}
renderHeaderCell(t, e = !1) {
var v;
const l = t.column.columnDef, r = t.column.getCanSort(), n = t.column.getIsSorted(), s = t.column.getNextSortingOrder(), g = (v = l.disableDefaultSorting) != null ? v : !1, h = this.stickyOffsets.get(t.column.id), b = [this.getHeaderCellStyle(t), this.getStickyStyle(t.column.id)].filter(Boolean).join(" ") || void 0, x = l.headerTextAlign ? `justify-content: ${l.headerTextAlign};` : void 0, R = this.getSortIcon(n), T = this.getSortTitle(r, s);
return p`
<th
colspan="${t.colSpan}"
rowspan="${t.rowSpan}"
part="header-cell"
class=${f(
"data-table-header-cell",
h && `data-table-header-cell--sticky-${h.side}`
)}
scope="col"
aria-sort=${r && !this.shouldDisableHeaderActions ? this.getAriaSortValue(n) : "none"}
style="${u(b)}">
${this.renderHeaderCellContent(
t,
l,
r,
g,
T,
x,
R
)}
</th>
`;
}
renderHeaderCellContent(t, e, l, r, n, s, g) {
if (!l)
return C(e.header, t.getContext());
const h = r || this.shouldDisableHeaderActions ? "div" : "dap-ds-button", b = !r && !this.shouldDisableHeaderActions ? t.column.getToggleSortingHandler() : null, x = l && !this.shouldDisableHeaderActions ? "pointer" : "not-allowed";
return p`<${P(h)}
class="data-table-header-cell__controller"
variant="clean"
data-testid="${this.sortButtonTestId}-${t.column.id}"
title=${u(n)}
="${b}"
style="cursor: ${x}">
<span
part="content"
class="data-table-header-cell__content"
style="${u(s)}">
${C(e.header, t.getContext())}
${g}
</span>
</${P(h)}>`;
}
getHeaderCellStyle(t) {
const e = t.column.columnDef;
if (!(!e.size && !e.maxSize && !e.headerTextAlign))
return `
${e.size ? `width: ${e.size}px;` : ""}
${e.maxSize ? `max-width: ${e.maxSize}px;` : ""}
${e.headerTextAlign ? `text-align: ${e.headerTextAlign};` : ""}
`;
}
// Replace this union type with a type alias.
getSortIcon(t) {
return t === "asc" ? p`<dap-ds-icon-arrow-up-s-line
size="16"></dap-ds-icon-arrow-up-s-line>` : t === "desc" ? p`<dap-ds-icon-arrow-down-s-line
size="16"></dap-ds-icon-arrow-down-s-line>` : null;
}
getSortTitle(t, e) {
if (t)
return e === "asc" ? c("datatable.sortAscending") : e === "desc" ? c("datatable.sortDescending") : c("datatable.clearSort");
}
getAriaSortValue(t) {
return t === "asc" ? "ascending" : t === "desc" ? "descending" : "none";
}
/**
* Render cell content with support for multiple formats
* Supports: primitives, styled objects, HTMLElements, HTML strings,
* render callbacks, and Lit templates
*/
renderCell(t) {
const e = t.column.columnDef.cell, l = t.getContext(), r = typeof e == "function" ? e(l) : e, n = G(r);
return typeof n == "string" || typeof n == "number" || typeof n == "boolean" || n === null || n === void 0 || n instanceof HTMLElement ? n : C(e, l);
}
handleRowClick(t) {
this.enableRowClick && this.emit("dds-row-click", { row: t });
}
handleRowKeydown(t, e) {
if (t.key === "Enter" || t.key === " ") {
if (t.composedPath().some((n) => n instanceof HTMLElement ? !!(["BUTTON", "A", "INPUT", "SELECT", "TEXTAREA"].includes(
n.tagName
) || n.getAttribute("role") === "button" || n.tagName.toLowerCase().includes("button") || n.tagName.toLowerCase().includes("btn")) : !1))
return;
t.preventDefault(), this.handleRowClick(e);
}
}
render() {
var e, l, r, n;
const t = this.tableController.table(y(m({
data: this.data,
columns: this.columnsMemo(),
filterFns: {},
state: {
sorting: this._sorting,
rowSelection: this._rowSelection,
pagination: this._pagination
},
manualSorting: this.manualSorting,
enableSorting: this.enableSorting,
enableRowSelection: this.enableRowSelection,
manualPagination: this.manualPagination,
autoResetPageIndex: this.autoResetPageIndex,
onSortingChange: (s) => {
typeof s == "function" ? this._sorting = s(this._sorting) : this._sorting = s, this.emit("dds-sorting-change", { sorting: this._sorting });
},
getCoreRowModel: J()
}, !this.manualSorting && {
getSortedRowModel: X()
}), {
getPaginationRowModel: V(),
onPaginationChange: (s) => {
typeof s == "function" ? this._pagination = s(this._pagination) : this._pagination = s, this.emit("dds-pagination-change", {
pagination: {
pageIndex: this._pagination.pageIndex,
pageSize: this._pagination.pageSize
}
});
},
onRowSelectionChange: (s) => {
typeof s == "function" ? this._rowSelection = s(this._rowSelection) : this._rowSelection = s, this.emit("dds-selection-change", { selection: this._rowSelection });
},
getRowId: (s) => s[this.rowKey],
rowCount: (e = this.rowCount) != null ? e : this.data ? this.data.length : 0,
debugTable: this.debug,
debugHeaders: this.debug,
debugColumns: this.debug
}));
return this.computeStickyOffsets(t), p`
<div class="data-table-container">
<table
part="base"
role="table"
aria-label=${u(
(l = this.ariaLabel) != null ? l : c("datatable.tableDescription")
)}
aria-describedby=${u(this.ariaDescribedBy)}
aria-rowcount=${(r = this.rowCount) != null ? r : this.data ? this.data.length : 0}
class=${f("data-table", {
"data-table--loading": this.loading
})}>
${this.caption ? p`<caption class="visually-hidden">
${this.caption}
</caption>` : z}
${this.renderColgroup(t)} ${this.renderHeader(t)}
${this.renderBody(t)}
</table>
</div>
${this._statusMessage ? p`<div
aria-live="polite"
aria-atomic="true"
class="visually-hidden"
id="table-status">
${this._statusMessage}
</div>` : z}
${this.pager && !this.isTableEmpty || this.pager && this.showPagerOnEmpty && this.isTableEmpty ? p`<dap-ds-pager
class="data-table-pager"
part="pager"
.disabled=${this.isTableEmpty}
.manualPagination=${this.manualPagination}
.pageIndex=${t.getState().pagination.pageIndex}
.pageSize=${t.getState().pagination.pageSize}
.totalRows=${(n = this.rowCount) != null ? n : this.data ? this.data.length : 0}
.pageSizeOptions=${this.pageSizeOptions}
.showPageSizeOptions=${this.showPageSizeOptions}
.showPageIndex=${this.showPageIndex}
.showPageCount=${this.showPageCount}
.showFirstButton=${this.showFirstButton}
.showPreviousButton=${this.showPreviousButton}
.showNextButton=${this.showNextButton}
.showLastButton=${this.showLastButton}
.showPageNumbers=${this.showPageNumbers}
.siblingCount=${this.siblingCount}
.firstButtonLabel=${this.firstButtonLabel}
.previousButtonLabel=${this.previousButtonLabel}
.nextButtonLabel=${this.nextButtonLabel}
.lastButtonLabel=${this.lastButtonLabel}
.pageStateText=${this.pageStateText}
exportparts="base:pager-base, first:pager-first, previous:pager-previous, next:pager-next, last:pager-last, page-size:pager-page-size-select, page-size-select-base:page-size-select-base, page-size-select-trigger:page-size-select-trigger, pager-button-first-base:pager-button-first-base, pager-button-first-content:pager-button-first-content, pager-button-previous-base:pager-button-previous-base, pager-button-previous-content:pager-button-previous-content, pager-button-next-base:pager-button-next-base, pager-button-next-content:pager-button-next-content, pager-button-last-base:pager-button-last-base, pager-button-last-content:pager-button-last-content, page-numbers:pager-page-numbers, page-number:pager-page-number, page-number-active:pager-page-number-active, page-number-base:pager-page-number-base, page-number-content:pager-page-number-content, page-info:pager-page-info"
-pagination-change=${(s) => {
s.preventDefault(), s.stopPropagation(), s.detail.action === "pageSize" ? t.setPageSize(s.detail.pagination.pageSize) : t.setPageIndex(s.detail.pagination.pageIndex);
}}>
<slot name="first-button-label" slot="first-button-label">
${this.firstButtonLabel || c("pager.first")}
</slot>
<slot name="previous-button-label" slot="previous-button-label">
${this.previousButtonLabel || c("pager.previous")}
</slot>
<slot name="next-button-label" slot="next-button-label">
${this.nextButtonLabel || c("pager.next")}
</slot>
<slot name="last-button-label" slot="last-button-label">
${this.lastButtonLabel || c("pager.last")}
</slot>
</dap-ds-pager>` : z}
`;
}
};
w.tagName = "dap-ds-datatable", w.dependencies = {
"dap-ds-checkbox": D,
"dap-ds-icon-arrow-up-s-line": U,
"dap-ds-icon-arrow-down-s-line": N,
"dap-ds-skeleton": K,
"dap-ds-spinner": F,
"dap-ds-pager": j
}, w.styles = Q(q);
let o = w;
i([
a({ attribute: !1 })
], o.prototype, "data");
i([
a({ attribute: !1 })
], o.prototype, "columns");
i([
a()
], o.prototype, "rowKey");
i([
a({ type: Boolean })
], o.prototype, "enableRowSelection");
i([
a({ type: Boolean })
], o.prototype, "stickySelectionColumn");
i([
a({ type: Boolean })
], o.prototype, "enableSorting");
i([
a({ type: Boolean })
], o.prototype, "manualSorting");
i([
a({ type: Boolean })
], o.prototype, "manualPagination");
i([
a({ type: Boolean })
], o.prototype, "autoResetPageIndex");
i([
a({ type: Boolean })
], o.prototype, "enableRowClick");
i([
a({ type: Boolean })
], o.prototype, "loading");
i([
a({ type: Boolean })
], o.prototype, "enableStripedRows");
i([
a({ type: Number })
], o.prototype, "rowCount");
i([
a({ type: String })
], o.prototype, "caption");
i([
a({ type: String })
], o.prototype, "loadingType");
i([
a({ type: String, reflect: !0 })
], o.prototype, "loadingVariant");
i([
a({ type: String, reflect: !0 })
], o.prototype, "loadingSize");
i([
a({ type: Number })
], o.prototype, "loadingStaticSize");
i([
a({ type: String })
], o.prototype, "loadingText");
i([
a({ type: String })
], o.prototype, "emptyText");
i([
a({ type: String })
], o.prototype, "disableHeaderOnEmpty");
i([
a({ type: Boolean })
], o.prototype, "showPagerOnEmpty");
i([
a({ type: Boolean })
], o.prototype, "pager");
i([
a({ type: String })
], o.prototype, "showPageSizeOptions");
i([
a({ type: String })
], o.prototype, "showPageIndex");
i([
a({ type: String })
], o.prototype, "showPageCount");
i([
a({ type: String })
], o.prototype, "showFirstButton");
i([
a({ type: String })
], o.prototype, "showPreviousButton");
i([
a({ type: String })
], o.prototype, "showNextButton");
i([
a({ type: String })
], o.prototype, "showLastButton");
i([
a({ type: String })
], o.prototype, "showPageNumbers");
i([
a({ type: Number })
], o.prototype, "siblingCount");
i([
a({ type: String })
], o.prototype, "firstButtonLabel");
i([
a({ type: String })
], o.prototype, "previousButtonLabel");
i([
a({ type: String })
], o.prototype, "nextButtonLabel");
i([
a({ type: String })
], o.prototype, "lastButtonLabel");
i([
a()
], o.prototype, "sortButtonTestId");
i([
a({ attribute: !1 })
], o.prototype, "pageStateText");
i([
a({ type: Array })
], o.prototype, "pageSizeOptions");
i([
a({ type: Array })
], o.prototype, "sorting");
i([
$()
], o.prototype, "_sorting");
i([
a({ type: Object })
], o.prototype, "rowSelection");
i([
$()
], o.prototype, "_rowSelection");
i([
a({ type: Object })
], o.prototype, "pagination");
i([
$()
], o.prototype, "_pagination");
i([
a({ type: Object })
], o.prototype, "columnSizing");
i([
$()
], o.prototype, "_columnSizing");
i([
a({ type: String })
], o.prototype, "ariaLabel");
i([
$()
], o.prototype, "_statusMessage");
i([
a({ type: Boolean })
], o.prototype, "debug");
export {
o as default
};
//# sourceMappingURL=datatable.component.js.map