UNPKG

@trimble-oss/moduswebcomponents

Version:

Modus Web Components is a modern, accessible UI library built with Stencil JS that provides reusable web components following Trimble's Modus design system. This updated version focuses on improved flexibility, enhanced theming options, comprehensive cust

1,000 lines (999 loc) 45.1 kB
/* eslint-disable @typescript-eslint/no-base-to-string */ import { h, Host, } from "@stencil/core"; import { convertTablePropsToClasses } from "./modus-wc-table.tailwind"; import { inheritAriaAttributes } from "../utils"; import { createModusTable, transformColumns, } from "./modus-wc-table.core"; export class ModusWcTable { constructor() { this.inheritedAttributes = {}; this.table = null; this.tanStackColumns = []; /** Enable cell editing. Either a boolean (all rows) or a predicate per row. */ this.editable = false; /** Custom CSS class to apply to the inner div. */ this.customClass = ''; /** The density of the table, used to save space or increase readability. */ this.density = 'comfortable'; /** Enable hover effect on table rows. */ this.hover = true; /** The current page number in pagination (1-based index). */ this.currentPage = 1; /** Enable pagination for the table. */ this.paginated = false; /** Available options for the number of rows per page. */ this.pageSizeOptions = [5, 10, 15]; /** Show/hide the page size selector in pagination. */ this.showPageSizeSelector = true; /** Enable sorting functionality for sortable columns. */ this.sortable = true; /** Row selection mode: 'none' for no selection, 'single' for single row, 'multi' for multiple rows. */ this.selectable = 'none'; /** Zebra striped tables differentiate rows by styling them in an alternating fashion. */ this.zebra = false; /** Currently editing cell coordinates */ this.activeEditor = null; /** Internal state for column sorting. */ this.sorting = []; /** Internal state for pagination. */ this.internalPagination = { pageIndex: 0, pageSize: 5, }; /** Internal state for row selection. */ this.internalRowSelection = {}; // Handle sorting changes from TanStack this.handleSortingChange = (updater) => { // Get the new sorting state const newSorting = typeof updater === 'function' ? updater(this.sorting) : updater; // Update the component state - this should trigger a re-render this.sorting = [...newSorting]; // Create a new array to ensure Stencil detects the change if (this.table) { // Tell TanStack the new sorting so it can recompute row model this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { state: Object.assign(Object.assign({}, prev.state), { sorting: newSorting }) }))); // Trigger row-model recomputation void this.table.getSortedRowModel().rows; } // Emit event this.sortChange.emit(newSorting); // Update the component state to ensure UI updates this.sorting = [...newSorting]; }; // Handle pagination changes from TanStack this.handlePaginationChange = (updater) => { // Get the new pagination state const newPagination = typeof updater === 'function' ? updater(this.internalPagination) : updater; // Update the component state this.internalPagination = newPagination; // Force a row model recalculation for immediate display if (this.table) { this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { state: Object.assign(Object.assign({}, prev.state), { pagination: newPagination }) }))); } // Emit event this.paginationChange.emit({ currentPage: newPagination.pageIndex + 1, pageSize: newPagination.pageSize, }); this.internalPagination = newPagination; }; // NEW: handle row-selection changes coming from TanStack this.handleRowSelectionChange = (updater) => { const newSelection = typeof updater === 'function' ? updater(this.internalRowSelection) : updater; // If uncontrolled, update internal state (do NOT call setRowSelection again – would recurse) if (!this.selectedRowIds) { this.internalRowSelection = Object.assign({}, newSelection); } const selectedRowIds = Object.keys(newSelection).filter((id) => newSelection[id]); const selectedRows = []; if (this.table) { selectedRowIds.forEach((id) => { const row = this.table.getRow(id); if (row) selectedRows.push(row.original); }); } if (this.table) { this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { state: Object.assign(Object.assign({}, prev.state), { rowSelection: newSelection }) }))); } this.rowSelectionChange.emit({ selectedRows, selectedRowIds }); }; this.handleRowClick = (rowObj, index) => { if (this.selectable !== 'none' && this.table) { this.toggleRowSelection(rowObj); } this.rowClick.emit({ row: rowObj.original, index }); }; this.handleHeaderClick = (columnId) => { const column = this.columns.find((col) => col.id === columnId); if (!(column === null || column === void 0 ? void 0 : column.sortable) || !this.sortable || !this.table) return; // Get the current sorting state from the component const currentColumnSort = this.sorting.find((sort) => sort.id === columnId); // Determine the new sorting state let newSorting = []; if (!currentColumnSort) { // Not sorted yet, sort ascending newSorting = [{ id: columnId, desc: false }]; } else if (!currentColumnSort.desc) { // Currently ascending, change to descending newSorting = [{ id: columnId, desc: true }]; } // If already descending, clear sorting (empty array) try { // Update TanStack table with the new sorting state this.table.setSorting(newSorting); // Recalculate row model to apply sorting immediately void this.table.getSortedRowModel().rows; // Update the component state to ensure UI updates this.sorting = [...newSorting]; // Emit the event this.sortChange.emit(newSorting); } catch (error) { console.error('Error applying sorting:', error); } }; } handleCurrentPageChange(newValue) { if (!this.table) return; if (this.internalPagination.pageIndex !== newValue - 1) { this.internalPagination = Object.assign(Object.assign({}, this.internalPagination), { pageIndex: newValue - 1 }); // This will trigger onPaginationChange callback this.table.setPagination(this.internalPagination); } } handleDataChange(newData) { if (this.table) { this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { data: [...newData] }))); } else if (newData && this.columns) { // If table doesn't exist yet but we have both data and columns, initialize this.initializeTable(); } } handleColumnsChange(newColumns) { if (this.table) { this.tanStackColumns = transformColumns(newColumns, this.sortable); this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { columns: this.tanStackColumns }))); } else if (newColumns && this.data) { // If table doesn't exist yet but we have both columns and data, initialize this.initializeTable(); } } handleSortableChange(newSortable) { if (this.table) { this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { enableSorting: newSortable, columns: transformColumns(this.columns, newSortable), state: Object.assign(Object.assign({}, prev.state), { sorting: [] }) }))); } } handlePaginatedChange(newPaginated) { if (this.table) { this.table.setOptions((prev) => (Object.assign(Object.assign({}, prev), { manualPagination: !newPaginated }))); } } handleSelectedRowIdsChange(newIds) { if (!this.table) return; if (Array.isArray(newIds)) { const selection = {}; newIds.forEach((id) => (selection[id] = true)); this.internalRowSelection = selection; this.table.setRowSelection(selection); } } componentWillLoad() { var _a, _b; if (!this.columns) { console.error('ModusWcTable: columns is required.'); } if (!this.data) { console.error('ModusWcTable: data is required.'); } this.internalPagination = { pageIndex: this.currentPage - 1, pageSize: this.pageSizeOptions[0], }; // Initialize row selection from selectedRowIds prop const rowSelection = Object.fromEntries((_b = (_a = this.selectedRowIds) === null || _a === void 0 ? void 0 : _a.map((id) => [id, true])) !== null && _b !== void 0 ? _b : []); if (rowSelection && Object.keys(rowSelection).length > 0) { this.internalRowSelection = rowSelection; } this.inheritedAttributes = inheritAriaAttributes(this.el); this.initializeTable(); } disconnectedCallback() { // Clean up global listener on component disconnect if (this.globalClickHandler) { document.removeEventListener('click', this.globalClickHandler, true); this.globalClickHandler = undefined; } // Clear active editor reference this.activeEditorElement = undefined; } initializeTable() { if (!this.columns || !this.data) return; // First, make a copy of the data to avoid any reference issues const dataForTable = [...this.data]; // Transform columns (selection column rendered manually in DOM) this.tanStackColumns = transformColumns(this.columns, this.sortable); // Create the table with callbacks to handle state changes this.table = createModusTable({ data: dataForTable, // Use the copied data columns: this.tanStackColumns, rowSelection: this.internalRowSelection, enableRowSelection: this.selectable !== 'none', pagination: this.internalPagination, enableSorting: this.sortable, manualPagination: !this.paginated, manualSorting: false, // Let TanStack handle sorting internally onSortingChange: this.handleSortingChange, onPaginationChange: this.handlePaginationChange, onRowSelectionChange: this.handleRowSelectionChange, getRowId: (orig, idx) => orig && orig['id'] !== undefined && orig['id'] !== null ? String(orig['id']) : String(idx), }); // If we already have a sorting state, apply it immediately if (this.sorting.length > 0 && this.table) { this.table.setSorting([...this.sorting]); } } getClasses() { const classList = ['modus-wc-table']; const propClasses = convertTablePropsToClasses({ density: this.density, zebra: this.zebra, hover: this.hover, }); if (propClasses) classList.push(propClasses); if (this.customClass) classList.push(this.customClass); return classList.join(' '); } toggleRowSelection(rowObj) { var _a, _b; const idStr = String(rowObj.id); const isSelected = !!this.internalRowSelection[idStr]; if (this.selectable === 'single') { /* istanbul ignore next */ (_a = this.table) === null || _a === void 0 ? void 0 : _a.setRowSelection({ [idStr]: !isSelected, }); } else { // Multi-select: toggle via TanStack then mirror into reactive state so // row highlight updates synchronously. (_b = rowObj.toggleSelected) === null || _b === void 0 ? void 0 : _b.call(rowObj); } } getTotalPages() { if (!this.data || !this.data.length) return 1; return this.internalPagination.pageSize <= 0 ? 1 : Math.ceil(this.data.length / this.internalPagination.pageSize); } handlePageChange(newPage) { const totalPages = this.getTotalPages(); if (newPage < 1 || newPage > totalPages || !this.table) return; const newPageIndex = newPage - 1; // Setting pagination will trigger the onPaginationChange callback this.table.setPagination(Object.assign(Object.assign({}, this.internalPagination), { pageIndex: newPageIndex })); } handlePageSizeOptionChange(event) { if (!this.table) return; const select = event.detail .srcElement; const newPageSize = parseInt(select.value, 10); // Setting pagination will trigger the onPaginationChange callback this.table.setPagination({ pageSize: newPageSize, pageIndex: 0, }); } renderCell(column, row) { var _a; const value = row[column.accessor]; if (column.cellRenderer) { return column.cellRenderer(value, row); } return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : ''; } getPaginationSize() { switch (this.density) { case 'compact': return 'sm'; case 'relaxed': return 'lg'; default: return 'md'; } } renderPageSizeSelector() { var _a; if (!this.showPageSizeSelector) return null; const paginationSize = this.getPaginationSize(); const options = (_a = this.pageSizeOptions) === null || _a === void 0 ? void 0 : _a.map((size) => ({ value: size.toString(), label: size.toString(), })); return (h("div", { class: "page-size-selector" }, h("span", null, "Show"), h("modus-wc-select", { "aria-label": "Select page size", bordered: true, size: paginationSize, onInputChange: (e) => this.handlePageSizeOptionChange(e), options: options }))); } renderPaginationInfo() { if (!this.data || !this.data.length) return null; const startItem = Math.min(this.internalPagination.pageIndex * this.internalPagination.pageSize + 1, this.data.length); const endItem = Math.min((this.internalPagination.pageIndex + 1) * this.internalPagination.pageSize, this.data.length); return (h("div", { class: "pagination-info" }, "Showing ", startItem, " to ", endItem, " of ", this.data.length, " entries")); } /* ---------- Editing helpers ---------- */ isRowEditable(row) { if (typeof this.editable === 'function') return this.editable(row); return Boolean(this.editable); } /** * Validate that the row index and column ID are valid * @param rowIndex The row index to validate * @param colId The column ID to validate * @returns true if both row index and column ID are valid */ validateRowAndColumn(rowIndex, colId) { var _a, _b; // Check valid row index if (rowIndex < 0 || rowIndex >= (((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0)) { return false; } // Check valid column ID const columnExists = ((_b = this.columns) === null || _b === void 0 ? void 0 : _b.some((col) => col.id === colId)) || false; return columnExists; } enterEdit(rowIndex, colId) { // Validate row and column first if (!this.validateRowAndColumn(rowIndex, colId)) { return; } const row = this.data[rowIndex]; if (!this.isRowEditable(row)) return; this.activeEditor = { rowIndex, colId }; this.cellEditStart.emit({ rowIndex, colId }); } commitEdit(rowIndex, colId, newValue) { var _a; // Validate row and column first if (!this.validateRowAndColumn(rowIndex, colId)) { return; } // Update data array immutably const newData = [...this.data]; const updatedRow = Object.assign(Object.assign({}, newData[rowIndex]), { [colId]: newValue }); newData[rowIndex] = updatedRow; this.data = newData; // Push into TanStack so internal model stays in sync (_a = this.table) === null || _a === void 0 ? void 0 : _a.setOptions((prev) => (Object.assign(Object.assign({}, prev), { data: newData }))); this.cellEditCommit.emit({ rowIndex, colId, newValue, updatedRow }); // Simply clear editor state – Stencil will re-render cell normally this.activeEditor = null; } setupEditorCell(el, cellNode, column, row, handleCommit) { el.innerHTML = ''; const isNode = typeof cellNode !== 'string' && 'tagName' in cellNode; if (isNode) { el.appendChild(cellNode); if (column.editorTemplate && column.editorSetup) { column.editorSetup(cellNode, row, handleCommit); } // Store reference to active editor element this.activeEditorElement = el; // Create and keep global click handler active if (!this.globalClickHandler) { this.globalClickHandler = (event) => { // Only process clicks when we have an active editor if (!this.activeEditor || !this.activeEditorElement) { return; } const target = event.target; const outsideTable = !this.el.contains(target); // Check if click is outside table if (outsideTable) { this.activeEditor = null; this.activeEditorElement = undefined; } }; // Register once and keep it active document.addEventListener('click', this.globalClickHandler, true); } } else { el.textContent = String(cellNode); } } render() { var _a, _b, _c; // Derive rows straight from TanStack's row model so that any sorting/pagination // is reflected automatically const rows = this.table ? this.paginated ? this.table.getPaginationRowModel().rows : this.table.getRowModel().rows : []; const displayData = rows.map((r) => r.original); const totalPages = this.getTotalPages(); return (h(Host, { key: '1cf7f9c0b22b23d76fe433dc69b7c12e3c36263c' }, h("div", { key: '896c63170c7ef798d3b2d5cf9978cceadb40529a', class: "table-container" }, h("div", Object.assign({ key: 'd551fb0d5e4ca7de9d01381e4ff80606b2dc4580', class: "modus-wc-overflow-x-auto" }, this.inheritedAttributes), h("table", { key: '504170d756594e6dc8da783d5414a96310382ce3', class: this.getClasses() }, this.caption && (h("caption", { key: '43703be78071edfa608ae23c8b71724486eb82c3', class: "modus-wc-sr-only" }, this.caption)), h("thead", { key: '733bce82284aba8b72df8131e01279649995ccf7' }, h("tr", { key: 'aeaa9d8214f7022d324ac16c5aaa88666fc6c0a8' }, this.selectable !== 'none' && (h("th", { key: '2178d4040efaef874635add286fa1a9219c648e8', class: "selection-column", style: { width: '48px' } }, this.selectable === 'multi' && this.table && (h("modus-wc-checkbox", { key: '8ae882271283a269561e369bab88586230dcd707', "aria-label": "Select all rows", size: "sm", value: this.table.getIsAllRowsSelected(), indeterminate: this.table.getIsSomeRowsSelected() && !this.table.getIsAllRowsSelected(), onInputChange: () => { var _a; /* istanbul ignore next */ return (_a = this.table) === null || _a === void 0 ? void 0 : _a.toggleAllRowsSelected(); } })))), (_a = this.columns) === null || _a === void 0 ? void 0 : _a.map((column) => { var _a; const tanCol = (_a = this.table) === null || _a === void 0 ? void 0 : _a.getColumn(column.id); const sortStatus = tanCol === null || tanCol === void 0 ? void 0 : tanCol.getIsSorted(); // 'asc' | 'desc' | false const isAsc = sortStatus === 'asc'; const isDesc = sortStatus === 'desc'; return (h("th", { class: { [column.className || '']: !!column.className, sortable: Boolean(column.sortable && this.sortable), sorted: !!sortStatus, asc: !!isAsc, desc: !!isDesc, }, style: { width: column.width }, onClick: () => this.handleHeaderClick(column.id), role: column.sortable && this.sortable ? 'button' : undefined, tabIndex: column.sortable && this.sortable ? 0 : undefined, "aria-sort": isAsc ? 'ascending' : isDesc ? 'descending' : undefined }, column.header, column.sortable && this.sortable && (h("span", { class: "sort-icon", "aria-hidden": "true" }, isAsc ? (h("modus-wc-icon", { name: "sort_alpha_down", size: "xs" })) : isDesc ? (h("modus-wc-icon", { name: "sort_alpha_up", size: "xs" })) : (h("modus-wc-icon", { name: "sort_alpha_down", size: "xs", style: { opacity: '0.5' } })))))); }))), h("tbody", { key: '92c266aeeecb4e742f2e600d61c249f83f63bad0' }, displayData.length > 0 ? (rows.map((rowObj, index) => { var _a, _b, _c, _d, _e; const row = rowObj.original; return (h("tr", { key: (_a = rowObj.id) !== null && _a !== void 0 ? _a : `row-${index}`, class: { selected: !!this.internalRowSelection[String(rowObj.id)] || ((_b = rowObj.getIsSelected) === null || _b === void 0 ? void 0 : _b.call(rowObj)), }, onClick: () => this.handleRowClick(rowObj, index) }, this.selectable !== 'none' && (h("td", { class: "selection-column", style: { width: '48px' } }, h("modus-wc-checkbox", { "aria-label": "Select row", size: "sm", value: (_d = (_c = rowObj.getIsSelected) === null || _c === void 0 ? void 0 : _c.call(rowObj)) !== null && _d !== void 0 ? _d : false }))), /* istanbul ignore next */ (_e = this.columns) === null || _e === void 0 ? void 0 : _e.map((column) => { var _a, _b, _c; const editing = ((_a = this.activeEditor) === null || _a === void 0 ? void 0 : _a.rowIndex) === index && this.activeEditor.colId === column.id; const cellDisplay = this.renderCell(column, row); /* istanbul ignore next */ const handleCommit = (newVal) => this.commitEdit(index, column.id, newVal); let cellNode; if (editing) { if (column.editorTemplate) { const htmlStr = column.editorTemplate.replace(/\$\{value\}/g, /* istanbul ignore next */ String((_b = row[column.accessor]) !== null && _b !== void 0 ? _b : '')); const wrapper = document.createElement('div'); wrapper.innerHTML = htmlStr; cellNode = wrapper.firstElementChild; // allow users to wire events / data (_c = column.editorSetup) === null || _c === void 0 ? void 0 : _c.call(column, cellNode, row, handleCommit); } else if (column.customEditorRenderer) { cellNode = column.customEditorRenderer(row[column.accessor], handleCommit, row); } else { cellNode = cellDisplay; } } else { cellNode = cellDisplay; } return (h("td", { class: { [column.className || '']: !!column.className, editing, }, "data-col": column.id, onDblClick: (e) => { var _a, _b, _c; // Don't enter edit mode if already editing this cell if (((_a = this.activeEditor) === null || _a === void 0 ? void 0 : _a.rowIndex) === index && ((_b = this.activeEditor) === null || _b === void 0 ? void 0 : _b.colId) === column.id) { return; } // Don't enter edit mode if clicking inside an active editor if ((_c = this.activeEditorElement) === null || _c === void 0 ? void 0 : _c.contains(e.target)) { return; } this.enterEdit(index, column.id); }, ref: (el) => { if (!el) return; this.setupEditorCell(el, cellNode, column, row, handleCommit); } })); }))); })) : (h("tr", null, h("td", { colSpan: (((_b = this.columns) === null || _b === void 0 ? void 0 : _b.length) || 1) + (this.selectable !== 'none' ? 1 : 0), class: "no-data-message" }, "No data available")))))), this.paginated && ((_c = this.data) === null || _c === void 0 ? void 0 : _c.length) > 0 && (h("div", { key: 'aaa5bfe16cb2433f3adec73e2740625aa7afa678', class: "pagination-container" }, this.renderPageSizeSelector(), this.renderPaginationInfo(), h("div", { key: '2f12609eebdc7e3bcd5ea9f24fe99eae6d51ab0f', class: "pagination-controls" }, h("modus-wc-pagination", { key: '5d4782ec737bc3ec3547f0f40280c91e03bc1614', count: totalPages, page: this.internalPagination.pageIndex + 1, size: this.getPaginationSize(), onPageChange: (e) => this.handlePageChange(Number(e.detail.newPage)) }))))))); } static get is() { return "modus-wc-table"; } static get originalStyleUrls() { return { "$": ["modus-wc-table.scss"] }; } static get styleUrls() { return { "$": ["modus-wc-table.css"] }; } static get properties() { return { "editable": { "type": "boolean", "attribute": "editable", "mutable": false, "complexType": { "original": "boolean | ((row: Record<string, unknown>) => boolean)", "resolved": "((row: Record<string, unknown>) => boolean) | boolean | undefined", "references": { "Record": { "location": "global", "id": "global::Record" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Enable cell editing. Either a boolean (all rows) or a predicate per row." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "columns": { "type": "unknown", "attribute": "columns", "mutable": false, "complexType": { "original": "ITableColumn[]", "resolved": "ITableColumn[]", "references": { "ITableColumn": { "location": "local", "path": "/home/runner/work/modus-wc-2.0/modus-wc-2.0/src/components/modus-wc-table/modus-wc-table.tsx", "id": "src/components/modus-wc-table/modus-wc-table.tsx::ITableColumn" } } }, "required": true, "optional": false, "docs": { "tags": [], "text": "An array of column definitions." }, "getter": false, "setter": false }, "customClass": { "type": "string", "attribute": "custom-class", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Custom CSS class to apply to the inner div." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "''" }, "data": { "type": "unknown", "attribute": "data", "mutable": false, "complexType": { "original": "Record<string, unknown>[]", "resolved": "Record<string, unknown>[]", "references": { "Record": { "location": "global", "id": "global::Record" } } }, "required": true, "optional": false, "docs": { "tags": [], "text": "An array of data objects." }, "getter": false, "setter": false }, "density": { "type": "string", "attribute": "density", "mutable": false, "complexType": { "original": "Density", "resolved": "\"comfortable\" | \"compact\" | \"relaxed\" | undefined", "references": { "Density": { "location": "import", "path": "../types", "id": "src/components/types.ts::Density" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The density of the table, used to save space or increase readability." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "'comfortable'" }, "hover": { "type": "boolean", "attribute": "hover", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Enable hover effect on table rows." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "true" }, "currentPage": { "type": "number", "attribute": "current-page", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The current page number in pagination (1-based index)." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "1" }, "paginated": { "type": "boolean", "attribute": "paginated", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Enable pagination for the table." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "pageSizeOptions": { "type": "unknown", "attribute": "page-size-options", "mutable": false, "complexType": { "original": "number[]", "resolved": "number[]", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Available options for the number of rows per page." }, "getter": false, "setter": false, "defaultValue": "[5, 10, 15]" }, "showPageSizeSelector": { "type": "boolean", "attribute": "show-page-size-selector", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Show/hide the page size selector in pagination." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "true" }, "sortable": { "type": "boolean", "attribute": "sortable", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Enable sorting functionality for sortable columns." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "true" }, "selectable": { "type": "string", "attribute": "selectable", "mutable": false, "complexType": { "original": "'none' | 'single' | 'multi'", "resolved": "\"multi\" | \"none\" | \"single\" | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Row selection mode: 'none' for no selection, 'single' for single row, 'multi' for multiple rows." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "'none'" }, "selectedRowIds": { "type": "unknown", "attribute": "selected-row-ids", "mutable": false, "complexType": { "original": "string[]", "resolved": "string[] | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Array of selected row IDs. Used for controlled selection state." }, "getter": false, "setter": false }, "zebra": { "type": "boolean", "attribute": "zebra", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Zebra striped tables differentiate rows by styling them in an alternating fashion." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "caption": { "type": "string", "attribute": "caption", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Accessibility caption for the table (visually hidden but available to screen readers)." }, "getter": false, "setter": false, "reflect": false } }; } static get states() { return { "activeEditor": {}, "sorting": {}, "internalPagination": {}, "internalRowSelection": {} }; } static get events() { return [{ "method": "cellEditStart", "name": "cellEditStart", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when cell editing starts." }, "complexType": { "original": "{\n rowIndex: number;\n colId: string;\n }", "resolved": "{ rowIndex: number; colId: string; }", "references": {} } }, { "method": "cellEditCommit", "name": "cellEditCommit", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when cell editing is committed with the new value." }, "complexType": { "original": "{\n rowIndex: number;\n colId: string;\n newValue: unknown;\n updatedRow: Record<string, unknown>;\n }", "resolved": "{ rowIndex: number; colId: string; newValue: unknown; updatedRow: Record<string, unknown>; }", "references": { "Record": { "location": "global", "id": "global::Record" } } } }, { "method": "rowClick", "name": "rowClick", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when a row is clicked." }, "complexType": { "original": "{\n row: Record<string, unknown>;\n index: number;\n }", "resolved": "{ row: Record<string, unknown>; index: number; }", "references": { "Record": { "location": "global", "id": "global::Record" } } } }, { "method": "sortChange", "name": "sortChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when sorting changes with the new sorting state." }, "complexType": { "original": "SortingState", "resolved": "ColumnSort[]", "references": { "SortingState": { "location": "import", "path": "@tanstack/table-core", "id": "node_modules::SortingState" } } } }, { "method": "paginationChange", "name": "paginationChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when pagination changes with the new pagination state." }, "complexType": { "original": "IPaginationChangeEventDetail", "resolved": "IPaginationChangeEventDetail", "references": { "IPaginationChangeEventDetail": { "location": "local", "path": "/home/runner/work/modus-wc-2.0/modus-wc-2.0/src/components/modus-wc-table/modus-wc-table.tsx", "id": "src/components/modus-wc-table/modus-wc-table.tsx::IPaginationChangeEventDetail" } } } }, { "method": "rowSelectionChange", "name": "rowSelectionChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emits when row selection changes with the selected rows and their IDs." }, "complexType": { "original": "{\n selectedRows: Record<string, unknown>[];\n selectedRowIds: string[];\n }", "resolved": "{ selectedRows: Record<string, unknown>[]; selectedRowIds: string[]; }", "references": { "Record": { "location": "global", "id": "global::Record" } } } }]; } static get elementRef() { return "el"; } static get watchers() { return [{ "propName": "currentPage", "methodName": "handleCurrentPageChange" }, { "propName": "data", "methodName": "handleDataChange" }, { "propName": "columns", "methodName": "handleColumnsChange" }, { "propName": "sortable", "methodName": "handleSortableChange" }, { "propName": "paginated", "methodName": "handlePaginatedChange" }, { "propName": "selectedRowIds", "methodName": "handleSelectedRowIdsChange" }]; } }