@star-ng/ui 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +162 -2
- package/fesm2022/star-ng-ui-accordion.mjs +376 -0
- package/fesm2022/star-ng-ui-accordion.mjs.map +1 -0
- package/fesm2022/star-ng-ui-autocomplete.mjs +786 -0
- package/fesm2022/star-ng-ui-autocomplete.mjs.map +1 -0
- package/fesm2022/star-ng-ui-avatar.mjs +154 -0
- package/fesm2022/star-ng-ui-avatar.mjs.map +1 -0
- package/fesm2022/star-ng-ui-badge.mjs +153 -0
- package/fesm2022/star-ng-ui-badge.mjs.map +1 -0
- package/fesm2022/star-ng-ui-breadcrumb.mjs +199 -0
- package/fesm2022/star-ng-ui-breadcrumb.mjs.map +1 -0
- package/fesm2022/star-ng-ui-button.mjs +282 -0
- package/fesm2022/star-ng-ui-button.mjs.map +1 -0
- package/fesm2022/star-ng-ui-card.mjs +112 -0
- package/fesm2022/star-ng-ui-card.mjs.map +1 -0
- package/fesm2022/star-ng-ui-chart.mjs +1904 -0
- package/fesm2022/star-ng-ui-chart.mjs.map +1 -0
- package/fesm2022/star-ng-ui-checkbox.mjs +345 -0
- package/fesm2022/star-ng-ui-checkbox.mjs.map +1 -0
- package/fesm2022/star-ng-ui-core.mjs +484 -0
- package/fesm2022/star-ng-ui-core.mjs.map +1 -0
- package/fesm2022/star-ng-ui-data-display.mjs +1870 -0
- package/fesm2022/star-ng-ui-data-display.mjs.map +1 -0
- package/fesm2022/star-ng-ui-date-picker.mjs +2786 -0
- package/fesm2022/star-ng-ui-date-picker.mjs.map +1 -0
- package/fesm2022/star-ng-ui-dialog.mjs +948 -0
- package/fesm2022/star-ng-ui-dialog.mjs.map +1 -0
- package/fesm2022/star-ng-ui-drawer.mjs +158 -0
- package/fesm2022/star-ng-ui-drawer.mjs.map +1 -0
- package/fesm2022/star-ng-ui-editor.mjs +416 -0
- package/fesm2022/star-ng-ui-editor.mjs.map +1 -0
- package/fesm2022/star-ng-ui-field.mjs +378 -0
- package/fesm2022/star-ng-ui-field.mjs.map +1 -0
- package/fesm2022/star-ng-ui-file-upload.mjs +762 -0
- package/fesm2022/star-ng-ui-file-upload.mjs.map +1 -0
- package/fesm2022/star-ng-ui-i18n-de.mjs +179 -0
- package/fesm2022/star-ng-ui-i18n-de.mjs.map +1 -0
- package/fesm2022/star-ng-ui-i18n-es.mjs +179 -0
- package/fesm2022/star-ng-ui-i18n-es.mjs.map +1 -0
- package/fesm2022/star-ng-ui-input-group.mjs +188 -0
- package/fesm2022/star-ng-ui-input-group.mjs.map +1 -0
- package/fesm2022/star-ng-ui-input-mask.mjs +434 -0
- package/fesm2022/star-ng-ui-input-mask.mjs.map +1 -0
- package/fesm2022/star-ng-ui-input-number.mjs +691 -0
- package/fesm2022/star-ng-ui-input-number.mjs.map +1 -0
- package/fesm2022/star-ng-ui-input-otp.mjs +343 -0
- package/fesm2022/star-ng-ui-input-otp.mjs.map +1 -0
- package/fesm2022/star-ng-ui-input-tags.mjs +616 -0
- package/fesm2022/star-ng-ui-input-tags.mjs.map +1 -0
- package/fesm2022/star-ng-ui-knob.mjs +514 -0
- package/fesm2022/star-ng-ui-knob.mjs.map +1 -0
- package/fesm2022/star-ng-ui-layout.mjs +608 -0
- package/fesm2022/star-ng-ui-layout.mjs.map +1 -0
- package/fesm2022/star-ng-ui-listbox.mjs +886 -0
- package/fesm2022/star-ng-ui-listbox.mjs.map +1 -0
- package/fesm2022/star-ng-ui-media.mjs +833 -0
- package/fesm2022/star-ng-ui-media.mjs.map +1 -0
- package/fesm2022/star-ng-ui-menu.mjs +1840 -0
- package/fesm2022/star-ng-ui-menu.mjs.map +1 -0
- package/fesm2022/star-ng-ui-message.mjs +191 -0
- package/fesm2022/star-ng-ui-message.mjs.map +1 -0
- package/fesm2022/star-ng-ui-paginator.mjs +387 -0
- package/fesm2022/star-ng-ui-paginator.mjs.map +1 -0
- package/fesm2022/star-ng-ui-panel.mjs +324 -0
- package/fesm2022/star-ng-ui-panel.mjs.map +1 -0
- package/fesm2022/star-ng-ui-password.mjs +517 -0
- package/fesm2022/star-ng-ui-password.mjs.map +1 -0
- package/fesm2022/star-ng-ui-popover.mjs +241 -0
- package/fesm2022/star-ng-ui-popover.mjs.map +1 -0
- package/fesm2022/star-ng-ui-progress-bar.mjs +183 -0
- package/fesm2022/star-ng-ui-progress-bar.mjs.map +1 -0
- package/fesm2022/star-ng-ui-radio.mjs +411 -0
- package/fesm2022/star-ng-ui-radio.mjs.map +1 -0
- package/fesm2022/star-ng-ui-rating.mjs +211 -0
- package/fesm2022/star-ng-ui-rating.mjs.map +1 -0
- package/fesm2022/star-ng-ui-select-button.mjs +613 -0
- package/fesm2022/star-ng-ui-select-button.mjs.map +1 -0
- package/fesm2022/star-ng-ui-select.mjs +2547 -0
- package/fesm2022/star-ng-ui-select.mjs.map +1 -0
- package/fesm2022/star-ng-ui-skeleton.mjs +160 -0
- package/fesm2022/star-ng-ui-skeleton.mjs.map +1 -0
- package/fesm2022/star-ng-ui-slider.mjs +552 -0
- package/fesm2022/star-ng-ui-slider.mjs.map +1 -0
- package/fesm2022/star-ng-ui-spinner.mjs +148 -0
- package/fesm2022/star-ng-ui-spinner.mjs.map +1 -0
- package/fesm2022/star-ng-ui-stepper.mjs +360 -0
- package/fesm2022/star-ng-ui-stepper.mjs.map +1 -0
- package/fesm2022/star-ng-ui-table.mjs +3531 -0
- package/fesm2022/star-ng-ui-table.mjs.map +1 -0
- package/fesm2022/star-ng-ui-tabs.mjs +464 -0
- package/fesm2022/star-ng-ui-tabs.mjs.map +1 -0
- package/fesm2022/star-ng-ui-tag.mjs +129 -0
- package/fesm2022/star-ng-ui-tag.mjs.map +1 -0
- package/fesm2022/star-ng-ui-theme-switch.mjs +105 -0
- package/fesm2022/star-ng-ui-theme-switch.mjs.map +1 -0
- package/fesm2022/star-ng-ui-theme.mjs +98 -0
- package/fesm2022/star-ng-ui-theme.mjs.map +1 -0
- package/fesm2022/star-ng-ui-toast.mjs +298 -0
- package/fesm2022/star-ng-ui-toast.mjs.map +1 -0
- package/fesm2022/star-ng-ui-toggle-switch.mjs +316 -0
- package/fesm2022/star-ng-ui-toggle-switch.mjs.map +1 -0
- package/fesm2022/star-ng-ui-tooltip.mjs +297 -0
- package/fesm2022/star-ng-ui-tooltip.mjs.map +1 -0
- package/fesm2022/star-ng-ui-transloco.mjs +40 -0
- package/fesm2022/star-ng-ui-transloco.mjs.map +1 -0
- package/fesm2022/star-ng-ui-tree.mjs +1446 -0
- package/fesm2022/star-ng-ui-tree.mjs.map +1 -0
- package/fesm2022/star-ng-ui-utility.mjs +2134 -0
- package/fesm2022/star-ng-ui-utility.mjs.map +1 -0
- package/fesm2022/star-ng-ui.mjs +51 -0
- package/package.json +285 -3
- package/styles/_base.scss +70 -0
- package/styles/_shared.scss +2 -0
- package/styles/_tokens.scss +190 -0
- package/styles/controls/_accordion.scss +75 -0
- package/styles/controls/_autocomplete.scss +44 -0
- package/styles/controls/_avatar.scss +39 -0
- package/styles/controls/_breadcrumb.scss +45 -0
- package/styles/controls/_button.scss +137 -0
- package/styles/controls/_card.scss +38 -0
- package/styles/controls/_chart.scss +214 -0
- package/styles/controls/_chip.scss +51 -0
- package/styles/controls/_choice.scss +153 -0
- package/styles/controls/_data-display.scss +124 -0
- package/styles/controls/_date-picker.scss +300 -0
- package/styles/controls/_dialog.scss +123 -0
- package/styles/controls/_drawer.scss +118 -0
- package/styles/controls/_editor.scss +74 -0
- package/styles/controls/_field.scss +92 -0
- package/styles/controls/_file-upload.scss +136 -0
- package/styles/controls/_input-group.scss +104 -0
- package/styles/controls/_input-mask.scss +46 -0
- package/styles/controls/_input-number.scss +125 -0
- package/styles/controls/_knob.scss +76 -0
- package/styles/controls/_layout.scss +182 -0
- package/styles/controls/_listbox.scss +38 -0
- package/styles/controls/_media.scss +222 -0
- package/styles/controls/_menu.scss +254 -0
- package/styles/controls/_message.scss +48 -0
- package/styles/controls/_org-chart.scss +128 -0
- package/styles/controls/_paginator.scss +59 -0
- package/styles/controls/_panel.scss +83 -0
- package/styles/controls/_popover.scss +40 -0
- package/styles/controls/_progress-bar.scss +74 -0
- package/styles/controls/_select-button.scss +61 -0
- package/styles/controls/_select.scss +216 -0
- package/styles/controls/_skeleton.scss +43 -0
- package/styles/controls/_slider.scss +163 -0
- package/styles/controls/_spinner.scss +34 -0
- package/styles/controls/_stepper.scss +109 -0
- package/styles/controls/_table.scss +523 -0
- package/styles/controls/_tabs.scss +93 -0
- package/styles/controls/_tag.scss +84 -0
- package/styles/controls/_toast.scss +141 -0
- package/styles/controls/_tooltip.scss +14 -0
- package/styles/controls/_tree.scss +113 -0
- package/styles/controls/_utility.scss +654 -0
- package/styles/star-ng.css +5807 -0
- package/styles/star-ng.min.css +1 -0
- package/styles/star-ng.scss +50 -0
- package/theme/star-theme-first-paint.js +1 -0
- package/types/star-ng-ui-accordion.d.ts +82 -0
- package/types/star-ng-ui-autocomplete.d.ts +171 -0
- package/types/star-ng-ui-avatar.d.ts +43 -0
- package/types/star-ng-ui-badge.d.ts +46 -0
- package/types/star-ng-ui-breadcrumb.d.ts +39 -0
- package/types/star-ng-ui-button.d.ts +79 -0
- package/types/star-ng-ui-card.d.ts +29 -0
- package/types/star-ng-ui-chart.d.ts +337 -0
- package/types/star-ng-ui-checkbox.d.ts +92 -0
- package/types/star-ng-ui-core.d.ts +373 -0
- package/types/star-ng-ui-data-display.d.ts +438 -0
- package/types/star-ng-ui-date-picker.d.ts +701 -0
- package/types/star-ng-ui-dialog.d.ts +254 -0
- package/types/star-ng-ui-drawer.d.ts +29 -0
- package/types/star-ng-ui-editor.d.ts +96 -0
- package/types/star-ng-ui-field.d.ts +146 -0
- package/types/star-ng-ui-file-upload.d.ts +192 -0
- package/types/star-ng-ui-i18n-de.d.ts +7 -0
- package/types/star-ng-ui-i18n-es.d.ts +7 -0
- package/types/star-ng-ui-input-group.d.ts +58 -0
- package/types/star-ng-ui-input-mask.d.ts +126 -0
- package/types/star-ng-ui-input-number.d.ts +193 -0
- package/types/star-ng-ui-input-otp.d.ts +86 -0
- package/types/star-ng-ui-input-tags.d.ts +159 -0
- package/types/star-ng-ui-knob.d.ts +121 -0
- package/types/star-ng-ui-layout.d.ts +154 -0
- package/types/star-ng-ui-listbox.d.ts +170 -0
- package/types/star-ng-ui-media.d.ts +161 -0
- package/types/star-ng-ui-menu.d.ts +332 -0
- package/types/star-ng-ui-message.d.ts +52 -0
- package/types/star-ng-ui-paginator.d.ts +85 -0
- package/types/star-ng-ui-panel.d.ts +65 -0
- package/types/star-ng-ui-password.d.ts +129 -0
- package/types/star-ng-ui-popover.d.ts +57 -0
- package/types/star-ng-ui-progress-bar.d.ts +49 -0
- package/types/star-ng-ui-radio.d.ts +116 -0
- package/types/star-ng-ui-rating.d.ts +52 -0
- package/types/star-ng-ui-select-button.d.ts +169 -0
- package/types/star-ng-ui-select.d.ts +563 -0
- package/types/star-ng-ui-skeleton.d.ts +47 -0
- package/types/star-ng-ui-slider.d.ts +145 -0
- package/types/star-ng-ui-spinner.d.ts +29 -0
- package/types/star-ng-ui-stepper.d.ts +89 -0
- package/types/star-ng-ui-table.d.ts +885 -0
- package/types/star-ng-ui-tabs.d.ts +109 -0
- package/types/star-ng-ui-tag.d.ts +35 -0
- package/types/star-ng-ui-theme-switch.d.ts +36 -0
- package/types/star-ng-ui-theme.d.ts +95 -0
- package/types/star-ng-ui-toast.d.ts +84 -0
- package/types/star-ng-ui-toggle-switch.d.ts +81 -0
- package/types/star-ng-ui-tooltip.d.ts +66 -0
- package/types/star-ng-ui-transloco.d.ts +14 -0
- package/types/star-ng-ui-tree.d.ts +343 -0
- package/types/star-ng-ui-utility.d.ts +533 -0
- package/types/star-ng-ui.d.ts +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"star-ng-ui-table.mjs","names":[],"sources":["../../../projects/star-ng/table/table-export.ts","../../../projects/star-ng/table/virtual-heights.ts","../../../projects/star-ng/table/table.ts"],"sourcesContent":["/**\n * File builders for `star-table` export. No third-party library: an `.xlsx` file is a ZIP of\n * small XML parts, written here without compression.\n */\n\n/** One exported cell: text, or a number that a spreadsheet can sum. */\nexport type StarExportCell = string | number;\n\nconst encoder = new TextEncoder();\n\nfunction escapeXml(text: string): string {\n return (\n text\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n // Characters that XML 1.0 does not allow.\n // eslint-disable-next-line no-control-regex\n .replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g, '')\n );\n}\n\nlet crcTable: Uint32Array | null = null;\n\nfunction crc32(bytes: Uint8Array): number {\n if (!crcTable) {\n crcTable = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n crcTable[n] = c >>> 0;\n }\n }\n let crc = 0xffffffff;\n for (const byte of bytes) crc = crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/** ZIP archive with stored (not compressed) entries. */\nfunction zip(files: readonly { readonly name: string; readonly text: string }[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n const central: Uint8Array[] = [];\n let offset = 0;\n for (const file of files) {\n const name = encoder.encode(file.name);\n const data = encoder.encode(file.text);\n const crc = crc32(data);\n const local = new DataView(new ArrayBuffer(30));\n local.setUint32(0, 0x04034b50, true);\n local.setUint16(4, 20, true); // version needed\n local.setUint16(6, 0x0800, true); // UTF-8 names\n local.setUint16(8, 0, true); // stored\n local.setUint32(14, crc, true);\n local.setUint32(18, data.length, true);\n local.setUint32(22, data.length, true);\n local.setUint16(26, name.length, true);\n const entry = new DataView(new ArrayBuffer(46));\n entry.setUint32(0, 0x02014b50, true);\n entry.setUint16(4, 20, true);\n entry.setUint16(6, 20, true);\n entry.setUint16(8, 0x0800, true);\n entry.setUint32(16, crc, true);\n entry.setUint32(20, data.length, true);\n entry.setUint32(24, data.length, true);\n entry.setUint16(28, name.length, true);\n entry.setUint32(42, offset, true);\n chunks.push(new Uint8Array(local.buffer), name, data);\n central.push(new Uint8Array(entry.buffer), name);\n offset += 30 + name.length + data.length;\n }\n const centralSize = central.reduce((size, part) => size + part.length, 0);\n const end = new DataView(new ArrayBuffer(22));\n end.setUint32(0, 0x06054b50, true);\n end.setUint16(8, files.length, true);\n end.setUint16(10, files.length, true);\n end.setUint32(12, centralSize, true);\n end.setUint32(16, offset, true);\n const parts = [...chunks, ...central, new Uint8Array(end.buffer)];\n const out = new Uint8Array(parts.reduce((size, part) => size + part.length, 0));\n let position = 0;\n for (const part of parts) {\n out.set(part, position);\n position += part.length;\n }\n return out;\n}\n\n/** Column letters of a 0-based column index: 0 → A, 26 → AA. */\nfunction columnName(index: number): string {\n let name = '';\n for (let n = index + 1; n > 0; n = Math.floor((n - 1) / 26)) {\n name = String.fromCharCode(65 + ((n - 1) % 26)) + name;\n }\n return name;\n}\n\n/**\n * Excel workbook (`.xlsx`) with one sheet: a bold header row, then the rows. Text cells are\n * inline strings, which a spreadsheet never reads as a formula; numbers stay numbers.\n */\nexport function buildXlsx(\n headers: readonly string[],\n rows: readonly (readonly StarExportCell[])[],\n sheetName = 'Sheet1',\n): Uint8Array {\n const cell = (value: StarExportCell, column: number, row: number, style = '') => {\n const ref = `${columnName(column)}${row}`;\n return typeof value === 'number' && Number.isFinite(value)\n ? `<c r=\"${ref}\"${style}><v>${value}</v></c>`\n : `<c r=\"${ref}\"${style} t=\"inlineStr\"><is><t xml:space=\"preserve\">${escapeXml(String(value))}</t></is></c>`;\n };\n const sheetRows = [\n `<row r=\"1\">${headers.map((header, i) => cell(header, i, 1, ' s=\"1\"')).join('')}</row>`,\n ...rows.map(\n (row, r) =>\n `<row r=\"${r + 2}\">${row.map((value, i) => cell(value, i, r + 2)).join('')}</row>`,\n ),\n ];\n const head = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\n const main = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';\n const rel = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';\n const pkg = 'http://schemas.openxmlformats.org/package/2006';\n const type = 'application/vnd.openxmlformats-officedocument.spreadsheetml';\n // Sheet names: 31 characters at most, none of \\ / ? * [ ] :\n const safeName = escapeXml(sheetName.replace(/[\\\\/?*[\\]:]/g, ' ').slice(0, 31) || 'Sheet1');\n return zip([\n {\n name: '[Content_Types].xml',\n text: `${head}<Types xmlns=\"${pkg}/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/xl/workbook.xml\" ContentType=\"${type}.sheet.main+xml\"/><Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"${type}.worksheet+xml\"/><Override PartName=\"/xl/styles.xml\" ContentType=\"${type}.styles+xml\"/></Types>`,\n },\n {\n name: '_rels/.rels',\n text: `${head}<Relationships xmlns=\"${pkg}/relationships\"><Relationship Id=\"rId1\" Type=\"${rel}/officeDocument\" Target=\"xl/workbook.xml\"/></Relationships>`,\n },\n {\n name: 'xl/workbook.xml',\n text: `${head}<workbook xmlns=\"${main}\" xmlns:r=\"${rel}\"><sheets><sheet name=\"${safeName}\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>`,\n },\n {\n name: 'xl/_rels/workbook.xml.rels',\n text: `${head}<Relationships xmlns=\"${pkg}/relationships\"><Relationship Id=\"rId1\" Type=\"${rel}/worksheet\" Target=\"worksheets/sheet1.xml\"/><Relationship Id=\"rId2\" Type=\"${rel}/styles\" Target=\"styles.xml\"/></Relationships>`,\n },\n {\n name: 'xl/styles.xml',\n text: `${head}<styleSheet xmlns=\"${main}\"><fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts><fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills><borders count=\"1\"><border/></borders><cellStyleXfs count=\"1\"><xf/></cellStyleXfs><cellXfs count=\"2\"><xf/><xf fontId=\"1\" applyFont=\"1\"/></cellXfs></styleSheet>`,\n },\n {\n name: 'xl/worksheets/sheet1.xml',\n text: `${head}<worksheet xmlns=\"${main}\"><sheetData>${sheetRows.join('')}</sheetData></worksheet>`,\n },\n ]);\n}\n\n/** A word longer than this has no room in a print column: it gets soft break points. */\nconst LONG_WORD = 20;\n/** Characters between two soft break points of a long word. */\nconst WORD_CHUNK = 12;\n\n/**\n * Escaped text for the print document. A word without spaces that is longer than `LONG_WORD`\n * (a web address, a code, a signature) gets `<wbr>` soft break points. The print engine then\n * wraps it inside its cell. Without them such a word sets the minimum width of its column, the\n * table gets wider than the paper, and the engine shrinks the whole page (all text smaller) to\n * make it fit. The CSS `overflow-wrap:anywhere` is no replacement: it lets every column shrink\n * to one character, and the table then splits the width by the longest cell text.\n */\nfunction printable(value: StarExportCell): string {\n return String(value)\n .split(/(\\s+)/)\n .map((word) => {\n const letters = Array.from(word);\n if (letters.length <= LONG_WORD) return escapeXml(word);\n const chunks: string[] = [];\n for (let start = 0; start < letters.length; start += WORD_CHUNK) {\n chunks.push(escapeXml(letters.slice(start, start + WORD_CHUNK).join('')));\n }\n return chunks.join('<wbr>');\n })\n .join('');\n}\n\n/** One step of the fit ladder: how a print table gives way when it is wider than the paper. */\nexport interface StarPrintFitStep {\n /** Text size in CSS pixels. The normal size is 12 px (9 pt). */\n readonly size: number;\n /** A cell of one short word may wrap too (at a hyphen). */\n readonly wrap: boolean;\n /** A word may break at any character. Last resort: it sets no minimum width on a column. */\n readonly anywhere: boolean;\n}\n\n/** The text size of the print document, in CSS pixels (9 pt). */\nconst PRINT_SIZE = 12;\n\n/**\n * What a table gives way to, in this order, until its minimum width fits the paper: first the\n * cells of one short word may wrap (the text keeps its size), then the text gets smaller\n * (11, 10, 9 and 8 px; 8 px is 6 pt, the floor), and last a word may break at any character.\n * Step 0 is the table as it is built: no rule changes, short words never wrap.\n */\nexport const PRINT_FIT_STEPS: readonly StarPrintFitStep[] = [\n { size: PRINT_SIZE, wrap: false, anywhere: false },\n { size: PRINT_SIZE, wrap: true, anywhere: false },\n { size: 11, wrap: true, anywhere: false },\n { size: 10, wrap: true, anywhere: false },\n { size: 9, wrap: true, anywhere: false },\n { size: 8, wrap: true, anywhere: false },\n { size: 8, wrap: true, anywhere: true },\n];\n\nconst round = (value: number) => Math.round(value * 100) / 100;\n\n/**\n * Style rules of one fit step. `scope` is the selector of the table (`table` in this file).\n * `columns` (minimum widths of the columns) is for the step that breaks words: it gives each\n * column a share of the width in proportion to its longest word.\n */\nfunction fitRules(step: StarPrintFitStep, scope: string, columns: readonly number[] = []): string {\n const scale = step.size / PRINT_SIZE;\n const total = columns.reduce((sum, width) => sum + width, 0);\n return (\n `${scope}{font-size:${step.size}px${step.anywhere && total ? ';table-layout:fixed' : ''}}` +\n // Padding follows the text size: at 6 pt, 4 px of padding would take a third of a column.\n `${scope} th,${scope} td{padding:${round(4 * scale)}px ${round(8 * scale)}px${\n step.anywhere ? ';overflow-wrap:anywhere' : ''\n }}` +\n (step.wrap ? `${scope} td.s{white-space:normal}` : '') +\n // Without this, a word-breaking table gives its width to the columns with the longest text\n // and leaves one character for the others. The shares add up to 100% at most, and the\n // padding is inside them, so the table does not grow beyond the page.\n (step.anywhere && total\n ? `${scope} th{box-sizing:border-box}` +\n columns\n .map(\n (width, index) =>\n `${scope} th:nth-child(${index + 1}){width:${Math.floor((width / total) * 10000) / 100}%}`,\n )\n .join('')\n : '')\n );\n}\n\n/**\n * Style sheet that makes the print table fit any paper. `widths[i]` is the minimum width in\n * pixels of the table at step `i` of `PRINT_FIT_STEPS`; `columns` are the minimum widths of its\n * columns at the last step that keeps words whole. Step `i` applies when the content width of\n * the page is less than the minimum width of every step before it. The query is a container\n * query on the wrapper of the table, so it is answered with the real width of the page, which\n * the print dialog (paper, margins, scale) decides after the document is built. A step that is\n * not narrower than a step before it is left out.\n */\nexport function printFitStyle(widths: readonly number[], columns: readonly number[] = []): string {\n let narrowest = widths[0] ?? 0;\n let css = '';\n for (let index = 1; index < widths.length && index < PRINT_FIT_STEPS.length; index++) {\n if (widths[index] >= narrowest) continue;\n css += `@container (width < ${narrowest}px){${fitRules(PRINT_FIT_STEPS[index], 'table', columns)}}`;\n narrowest = widths[index];\n }\n return css;\n}\n\n/** Widths measured by `fitPrintDocument`. */\nexport interface StarPrintFitMeasure {\n /** Minimum width of the table at each step of `PRINT_FIT_STEPS`. */\n readonly widths: readonly number[];\n /** Minimum width of each column at the last step that keeps words whole. */\n readonly columns: readonly number[];\n}\n\n/** A style sheet of the print document that can be changed and removed again. */\nexport interface StarPrintStyle {\n /** Replaces the rules of the sheet. */\n set(css: string): void;\n /** Takes the sheet out of the document. */\n remove(): void;\n}\n\n/**\n * Adds a style sheet to `doc`. The sheet is a constructed style sheet (`new CSSStyleSheet()`,\n * created in the realm of the document, then `adoptedStyleSheets`). A policy whose `style-src`\n * has no `'unsafe-inline'` blocks an inline `style` element, but it does not block a constructed\n * sheet. An environment without constructed style sheets (or one where they fail) gets a\n * `style` element instead: that is the only fallback, and a strict policy blocks it.\n */\nexport function addPrintStyle(doc: Document, css = ''): StarPrintStyle {\n const Sheet = doc.defaultView?.CSSStyleSheet;\n if (Sheet && 'adoptedStyleSheets' in doc && typeof Sheet.prototype.replaceSync === 'function') {\n try {\n const sheet = new Sheet();\n sheet.replaceSync(css);\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, sheet];\n return {\n set: (text) => sheet.replaceSync(text),\n remove: () => {\n doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter((other) => other !== sheet);\n },\n };\n } catch {\n // Fall through to the style element.\n }\n }\n const element = doc.createElement('style');\n element.textContent = css;\n doc.head.append(element);\n return {\n set: (text) => {\n element.textContent = text;\n },\n remove: () => element.remove(),\n };\n}\n\n/**\n * Adds the base style of the print document (see `buildPrintDocument`) to `doc`. The document\n * has no `style` element and no `style` attribute, so a Content-Security-Policy without\n * `'unsafe-inline'` in `style-src` does not unstyle it. Call it when the frame has loaded,\n * before `fitPrintDocument` measures the table.\n */\nexport function stylePrintDocument(doc: Document): void {\n addPrintStyle(doc, PRINT_STYLE);\n}\n\n/**\n * Measures the minimum width of the print table at each fit step, in the layout of `doc`, and\n * adds the style sheet of `printFitStyle` to it (a constructed style sheet, see\n * `addPrintStyle`). Call it when the frame has loaded and has its base style\n * (`stylePrintDocument`), before the print dialog opens. The widths are read in the real fonts\n * of the document, so the text of any font, wide or narrow, gets the steps it needs.\n */\nexport function fitPrintDocument(doc: Document): StarPrintFitMeasure {\n const table = doc.querySelector('table');\n if (!table) return { widths: [], columns: [] };\n // The probe sets the table to 1 px wide, and a table is never narrower than its minimum\n // width: the width that is read is the minimum width, whatever the size of the frame is.\n const probe = addPrintStyle(doc);\n const lastWhole = PRINT_FIT_STEPS.findIndex((step) => step.anywhere) - 1;\n let columns: number[] = [];\n const widths = PRINT_FIT_STEPS.map((step, index) => {\n probe.set(`table{width:1px}${fitRules(step, 'table')}`);\n if (index === lastWhole) {\n columns = Array.from(table.querySelectorAll('thead th'), (cell) =>\n Math.ceil(cell.getBoundingClientRect().width),\n );\n }\n return Math.ceil(table.getBoundingClientRect().width);\n });\n probe.remove();\n const css = printFitStyle(widths, columns);\n if (css) addPrintStyle(doc, css);\n return { widths, columns };\n}\n\n/** Alignment of a print column. `start` and `end` follow the direction of the document. */\nexport type StarPrintAlign = 'start' | 'center' | 'end';\n\n/**\n * Alignment of a print column. The column definition decides: an explicit `align` wins. Without\n * it a column in which every value is a number (and there is at least one) is `end`, and any\n * other column is `start`. The type of the printed text does not matter: a number that a\n * `format` function turned into a string still sits in a number column. `values` are the cell\n * values before formatting.\n */\nexport function printColumnAlign(\n align: StarPrintAlign | undefined,\n values: readonly unknown[],\n): StarPrintAlign {\n if (align) return align;\n return values.length > 0 && values.every((value) => typeof value === 'number') ? 'end' : 'start';\n}\n\n/** Language and direction of the print document. */\nexport interface StarPrintContext {\n readonly lang?: string;\n readonly dir?: 'ltr' | 'rtl';\n}\n\n/**\n * `lang` and `dir` for the print document: the nearest ancestor of `host` (the element itself\n * first) that has the attribute with a usable value, else the `<html>` element of `doc`. An\n * empty `lang` and a `dir` other than `ltr` or `rtl` (such as `auto`) are skipped.\n */\nexport function printContext(host: Element | null, doc: Document): StarPrintContext {\n const find = (name: 'lang' | 'dir', accept: (value: string) => boolean) => {\n for (let node = host; node; node = node.parentElement) {\n const value = node.getAttribute(name)?.trim();\n if (value && accept(value)) return value;\n }\n const root = doc.documentElement.getAttribute(name)?.trim();\n return root && accept(root) ? root : undefined;\n };\n const lang = find('lang', (value) => /^[A-Za-z0-9-]+$/.test(value));\n const dir = find('dir', (value) => /^(ltr|rtl)$/i.test(value))?.toLowerCase() as\n 'ltr' | 'rtl' | undefined;\n return { ...(lang ? { lang } : {}), ...(dir ? { dir } : {}) };\n}\n\n/** Options of `buildPrintDocument`. */\nexport interface StarPrintOptions extends StarPrintContext {\n /** Alignment of each column, in column order (see `printColumnAlign`). */\n readonly align?: readonly StarPrintAlign[];\n}\n\n/** Base style of the print document. It is added with `stylePrintDocument`, not inline. */\nexport const PRINT_STYLE = `body{font:12px/1.4 system-ui,sans-serif;color:#000;margin:16px}\nh1{font-size:16px;margin:0 0 12px;overflow-wrap:anywhere}\n.fit{container-type:inline-size}\ntable{width:100%;border-collapse:collapse}\nth,td{padding:4px 8px;border:1px solid #999;text-align:start;vertical-align:top;overflow-wrap:break-word}\nth{background:#eee}\nth.c,td.c{text-align:center}\nth.e,td.e{text-align:end}\ntd.s{white-space:nowrap}\nthead{display:table-header-group}\ntr{break-inside:avoid}`;\n\n/**\n * HTML document with one table, for the browser print dialog (\"Save as PDF\"). The markup has\n * no `style` element and no `style` attribute: the style is added to the loaded document by\n * `stylePrintDocument`, as a constructed style sheet, so that it works under a policy without\n * `'unsafe-inline'` in `style-src`. The table is built to print at the normal size. When the\n * paper is too narrow for it, call `fitPrintDocument` on the loaded document: the table then\n * wraps, shrinks or breaks words (see `PRINT_FIT_STEPS`) so that no column is cut off.\n *\n * `options.align` sets the alignment of each column (cells and header). `options.lang` and\n * `options.dir` go on the `html` element.\n */\nexport function buildPrintDocument(\n title: string,\n headers: readonly string[],\n rows: readonly (readonly StarExportCell[])[],\n options: StarPrintOptions = {},\n): string {\n const escape = (value: StarExportCell) => escapeXml(String(value));\n const alignClass = (align: StarPrintAlign) =>\n align === 'end' ? 'e' : align === 'center' ? 'c' : '';\n // A cell of one short word (a code, a number, a date, an address) is never wrapped: a break\n // inside \"INV-0001\" or \"2026-01-05\" would only make it hard to read.\n const cellClass = (value: StarExportCell, index: number) => {\n const text = String(value);\n const column = options.align?.[index];\n const classes = [\n // The column decides. Without a column alignment, a number cell is right-aligned.\n column ? alignClass(column) : typeof value === 'number' ? 'e' : '',\n // A number has no break point: it needs no rule.\n typeof value !== 'number' && text.length <= LONG_WORD && !/\\s/.test(text) ? 's' : '',\n ].filter(Boolean);\n return classes.length ? ` class=\"${classes.join(' ')}\"` : '';\n };\n // Without a column alignment, a column of numbers has its header on the right too.\n const numberColumn = (index: number) =>\n rows.length > 0 && rows.every((row) => typeof row[index] === 'number');\n const headerClass = (index: number) => {\n const align = options.align?.[index] ?? (numberColumn(index) ? 'end' : 'start');\n return alignClass(align) ? ` class=\"${alignClass(align)}\"` : '';\n };\n const attributes =\n (options.lang ? ` lang=\"${escapeXml(options.lang)}\"` : '') +\n (options.dir ? ` dir=\"${options.dir === 'rtl' ? 'rtl' : 'ltr'}\"` : '');\n return `<!doctype html><html${attributes}><head><meta charset=\"utf-8\"><title>${escape(title)}</title></head><body><h1>${escape(title)}</h1><div class=\"fit\"><table><thead><tr>${headers\n .map((header, index) => `<th scope=\"col\"${headerClass(index)}>${printable(header)}</th>`)\n .join('')}</tr></thead><tbody>${rows\n .map(\n (row) =>\n `<tr>${row.map((value, index) => `<td${cellClass(value, index)}>${printable(value)}</td>`).join('')}</tr>`,\n )\n .join('')}</tbody></table></div></body></html>`;\n}\n","/**\n * Pure helpers of the table virtual scroll with rows of different heights: a prefix-sum tree of\n * item heights, the rendered range, scroll anchoring and the list of items (group headings and\n * rows). They have no DOM access, so unit tests can check them without layout.\n */\n\n/**\n * Heights of a list of items in a Fenwick tree (binary indexed tree): the offset of an item and the\n * item at an offset take O(log n), a height change takes O(log n), and building takes O(n).\n */\nexport class HeightTree {\n private readonly heights: Float64Array;\n private readonly sums: Float64Array;\n /** Highest power of two that is not larger than the size, for the binary search. */\n private readonly topBit: number;\n\n constructor(heights: ArrayLike<number>) {\n const count = heights.length;\n this.heights = new Float64Array(count);\n this.sums = new Float64Array(count + 1);\n for (let i = 0; i < count; i++) {\n const height = Math.max(0, heights[i] || 0);\n this.heights[i] = height;\n this.sums[i + 1] += height;\n const parent = i + 1 + ((i + 1) & -(i + 1));\n if (parent <= count) this.sums[parent] += this.sums[i + 1];\n }\n let bit = 1;\n while (bit * 2 <= count) bit *= 2;\n this.topBit = count ? bit : 0;\n }\n\n get size(): number {\n return this.heights.length;\n }\n\n /** Height of all items. */\n get total(): number {\n return this.offsetOf(this.size);\n }\n\n get(index: number): number {\n return this.heights[index] ?? 0;\n }\n\n /** Sets the height of one item and returns the difference to the old height. */\n set(index: number, height: number): number {\n const delta = Math.max(0, height) - this.heights[index];\n if (!delta) return 0;\n this.heights[index] += delta;\n for (let i = index + 1; i <= this.size; i += i & -i) this.sums[i] += delta;\n return delta;\n }\n\n /** Sum of the heights of the items before `index`: the offset of the item from the top. */\n offsetOf(index: number): number {\n let sum = 0;\n for (let i = Math.min(index, this.size); i > 0; i -= i & -i) sum += this.sums[i];\n return sum;\n }\n\n /**\n * Index of the item at a pixel offset: an offset on a border belongs to the item that starts\n * there, and items without height are skipped. Clamped to the list; -1 for an empty list.\n */\n indexAt(offset: number): number {\n if (!this.size) return -1;\n let index = 0;\n let rest = Math.max(0, offset);\n for (let bit = this.topBit; bit > 0; bit >>= 1) {\n const next = index + bit;\n if (next <= this.size && this.sums[next] <= rest) {\n index = next;\n rest -= this.sums[next];\n }\n }\n return Math.min(index, this.size - 1);\n }\n}\n\n/** Rendered items `[start, end)`, the first item in view, and the heights of the spacer rows. */\nexport interface VariableRange {\n readonly start: number;\n readonly end: number;\n readonly first: number;\n readonly before: number;\n readonly after: number;\n}\n\n/**\n * Items to render for a scroll offset `top` (from the top of the first item) and a viewport\n * height: the items in view plus `buffer` items above and below.\n */\nexport function variableRange(\n tree: HeightTree,\n top: number,\n viewport: number,\n buffer: number,\n): VariableRange {\n const count = tree.size;\n if (!count) return { start: 0, end: 0, first: 0, before: 0, after: 0 };\n const from = Math.max(0, top);\n const first = tree.indexAt(from);\n // The last pixel line in view, so an item that starts just below the view is left out.\n const last = tree.indexAt(from + Math.max(1, viewport) - 1);\n const start = Math.max(0, first - buffer);\n const end = Math.min(count, last + 1 + buffer);\n return {\n start,\n end,\n first,\n before: tree.offsetOf(start),\n after: tree.total - tree.offsetOf(end),\n };\n}\n\n/** A measured height that differs from the height the tree had. */\nexport interface HeightChange {\n readonly index: number;\n readonly from: number;\n readonly to: number;\n}\n\n/**\n * Scroll offset change that keeps the anchor item (the first item in view) where it is on the\n * screen: the sum of the height changes of the items above it. Changes of the anchor item and of\n * the items below it move nothing above, so they do not count.\n */\nexport function anchorShift(changes: readonly HeightChange[], anchor: number): number {\n let shift = 0;\n for (const change of changes) if (change.index < anchor) shift += change.to - change.from;\n return shift;\n}\n\n/** The item at the top of the view, and how many of its pixels are above the top. */\nexport function anchorOf(\n tree: HeightTree,\n top: number,\n): { readonly index: number; readonly inside: number } | null {\n const index = tree.indexAt(top);\n if (index < 0) return null;\n return { index, inside: Math.max(0, top) - tree.offsetOf(index) };\n}\n\n/** One item of the virtual list: a group heading row, or a data row with its detail row. */\nexport type VirtualItem<T> =\n | {\n readonly kind: 'group';\n readonly key: string;\n readonly label: string;\n /** Rows of the group on the page, also when the group is closed. */\n readonly count: number;\n readonly collapsed: boolean;\n /** Position of the row among the body rows, from 0. */\n readonly aria: number;\n }\n | {\n readonly kind: 'row';\n readonly key: unknown;\n readonly row: T;\n /** Index of the row on the page. */\n readonly index: number;\n /** The row shows its detail row, which comes right after it. */\n readonly expanded: boolean;\n readonly aria: number;\n };\n\nexport interface VirtualLayoutOptions<T> {\n /** Group heading of a row, or null without groups. */\n readonly groupOf: ((row: T) => string) | null;\n readonly isCollapsed: (label: string) => boolean;\n readonly isExpanded: (row: T) => boolean;\n readonly keyOf: (row: T) => unknown;\n /** Measured or estimated height of an item. */\n readonly heightOf: (item: VirtualItem<T>) => number;\n}\n\nexport interface VirtualLayout<T> {\n readonly items: readonly VirtualItem<T>[];\n readonly tree: HeightTree;\n /** Number of body rows (headings, rows and detail rows), for `aria-rowcount`. */\n readonly bodyRows: number;\n readonly indexOfKey: ReadonlyMap<unknown, number>;\n}\n\n/** Key of a group heading item. The prefix keeps it apart from row keys. */\nexport function groupKey(label: string): string {\n return `\\u0000group\\u0000${label}`;\n}\n\n/**\n * Flattens the rows of the page into items: a heading before each group, then the rows of the\n * group unless it is closed (rows of a closed group take no space). `rows` must keep each group\n * together.\n */\nexport function buildVirtualLayout<T>(\n rows: readonly T[],\n options: VirtualLayoutOptions<T>,\n): VirtualLayout<T> {\n const items: VirtualItem<T>[] = [];\n const counts: number[] = [];\n let aria = 0;\n let label: string | null = null;\n let collapsed = false;\n rows.forEach((row, index) => {\n if (options.groupOf) {\n const group = options.groupOf(row);\n if (index === 0 || group !== label) {\n label = group;\n collapsed = options.isCollapsed(group);\n counts.push(0);\n items.push({\n kind: 'group',\n key: groupKey(group),\n label: group,\n count: 0,\n collapsed,\n aria,\n });\n aria++;\n }\n counts[counts.length - 1]++;\n if (collapsed) return;\n }\n const expanded = options.isExpanded(row);\n items.push({ kind: 'row', key: options.keyOf(row), row, index, expanded, aria });\n aria += expanded ? 2 : 1;\n });\n let group = 0;\n const indexOfKey = new Map<unknown, number>();\n const heights = new Float64Array(items.length);\n items.forEach((item, index) => {\n if (item.kind === 'group') items[index] = { ...item, count: counts[group++] };\n indexOfKey.set(item.key, index);\n heights[index] = options.heightOf(items[index]);\n });\n return { items, tree: new HeightTree(heights), bodyRows: aria, indexOfKey };\n}\n","import { DOCUMENT, NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n afterRenderEffect,\n ApplicationRef,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n contentChildren,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n isDevMode,\n model,\n output,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { StarButton } from '@star-ng/ui/button';\nimport { StarCheckbox } from '@star-ng/ui/checkbox';\nimport {\n compareValues,\n matchesFilter,\n readOption,\n STAR_UI_TEXT,\n starIsRtl,\n StarOptionKey,\n} from '@star-ng/ui/core';\nimport { StarPaginator } from '@star-ng/ui/paginator';\nimport { StarPopover } from '@star-ng/ui/popover';\nimport { StarMultiSelect } from '@star-ng/ui/select';\nimport { StarSkeleton } from '@star-ng/ui/skeleton';\nimport {\n buildPrintDocument,\n buildXlsx,\n fitPrintDocument,\n printColumnAlign,\n printContext,\n StarExportCell,\n stylePrintDocument,\n} from './table-export';\nimport {\n anchorOf,\n anchorShift,\n buildVirtualLayout,\n groupKey,\n HeightChange,\n variableRange,\n VirtualItem,\n VirtualLayout,\n} from './virtual-heights';\n\nexport interface StarColumn<T> {\n /** Unique column id; also the property read when `value` is not set. */\n readonly field: string;\n readonly header: string;\n /** Cell value accessor (default: `row[field]`). Used for display, sort and filter. */\n readonly value?: (row: T) => unknown;\n /** Display text (default: `String(value)`). */\n readonly format?: (row: T) => string;\n readonly sortable?: boolean;\n readonly width?: string;\n readonly align?: 'start' | 'center' | 'end';\n /**\n * Column filter, shown in a second header row.\n * - `'text'`: the display text contains the query (case- and accent-insensitive).\n * - `'select'`: the display text equals the choice.\n * - `'multiselect'`: the display text is one of the choices (value: text list).\n * - `'number'`: the cell value is in a range (value: `{ min, max }` numbers).\n * - `'date'`: the cell day is in a range (value: `{ min, max }` as `yyyy-mm-dd`).\n */\n readonly filter?: 'text' | 'select' | 'multiselect' | 'number' | 'date';\n /** Choices of a `'select'` or `'multiselect'` filter (default: the distinct display texts in `value`, sorted). */\n readonly filterOptions?: readonly string[];\n /** `false` leaves the column out of every export (CSV, Excel, print). */\n readonly exportable?: boolean;\n /**\n * Cell value in an export. Use it for a column with a custom cell template, where the\n * display text is not what the user sees. A number stays a number in Excel.\n */\n readonly exportValue?: (row: T) => string | number | null | undefined;\n /**\n * Keeps the column in view when the table scrolls sideways. Frozen columns come first.\n * The table measures the frozen columns to position the next one, so `width` is optional.\n */\n readonly frozen?: boolean;\n /** `false`: the user cannot hide the column in the Columns panel. */\n readonly hideable?: boolean;\n /**\n * The user can change the cell in place. The table does not change `value`: it emits\n * `cellEdit`, and the owner stores the new value.\n */\n readonly editable?: boolean | ((row: T) => boolean);\n /** Editor of an editable cell (default `'text'`). `'number'` emits a number or `null`. */\n readonly editor?: 'text' | 'number' | 'select';\n /** Choices of a `'select'` editor. */\n readonly editOptions?: readonly string[];\n /**\n * Footer cell: fixed text, or a function of the filtered rows (all pages), for a total or\n * an average. The table has a footer row when one column has a footer.\n */\n readonly footer?: string | ((rows: readonly T[]) => string);\n}\n\nexport interface StarCellEditEvent<T> {\n readonly row: T;\n readonly field: string;\n /** New value: text, or a number / `null` for the `'number'` editor. */\n readonly value: string | number | null;\n readonly previous: unknown;\n}\n\n/** Range of a `'number'` filter (numbers) or a `'date'` filter (`yyyy-mm-dd` text). */\nexport interface StarRangeFilter {\n readonly min?: number | string | null;\n readonly max?: number | string | null;\n}\n\n/** Text (`'text'`, `'select'`), text list (`'multiselect'`) or range (`'number'`, `'date'`). */\nexport type StarFilterValue = string | readonly string[] | StarRangeFilter;\n\n/** Column filter values by column `field`. An empty or missing value means \"no filter\". */\nexport type StarColumnFilters = Readonly<Record<string, StarFilterValue>>;\n\nfunction isRange(value: StarFilterValue | undefined): value is StarRangeFilter {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction hasBound(bound: number | string | null | undefined): bound is number | string {\n return bound !== null && bound !== undefined && bound !== '';\n}\n\nfunction isActiveFilter(value: StarFilterValue | undefined): value is StarFilterValue {\n if (isRange(value)) return hasBound(value.min) || hasBound(value.max);\n return !!value && value.length > 0;\n}\n\n/** Local calendar day of a cell value as `yyyy-mm-dd`, or `''` when it is not a date. */\nfunction dayKey(value: unknown): string {\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) return value.slice(0, 10);\n const date = value instanceof Date ? value : new Date(value as string | number);\n if (value === null || value === undefined || Number.isNaN(date.getTime())) return '';\n const pad = (part: number) => String(part).padStart(2, '0');\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n}\n\nexport interface StarExportOptions<T = unknown> {\n /** File name without extension (default `export`). */\n readonly fileName?: string;\n /** Export the selected rows only (default: all filtered rows, in the current sort order). */\n readonly selectionOnly?: boolean;\n /**\n * Rows to export instead of the table rows. Use it in lazy mode, where the table holds one\n * page: load all rows from the server and pass them here.\n */\n readonly rows?: readonly T[];\n /** Sheet name (Excel) or heading (print). Default: the table `ariaLabel`. */\n readonly title?: string;\n}\n\nexport interface StarCsvOptions<T = unknown> extends StarExportOptions<T> {\n /** Field separator (default `,`). */\n readonly separator?: string;\n}\n\n/** Rows rendered above and below the rows in view, so a fast scroll shows no gap. */\nconst VIRTUAL_BUFFER_ROWS = 5;\n/** Viewport height in pixels before the first scroll event gives the real height. */\nconst VIRTUAL_FALLBACK_VIEWPORT = 480;\n/** Smallest measured height change, in pixels, that updates the height of a row. */\nconst MEASURE_TOLERANCE = 0.1;\n/** Elements that take the focus with Tab, for keyboard moves between rendered rows. */\nconst FOCUSABLE =\n 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])';\n\n/** One line of the table body: a spacer, a group heading, or a row with its detail row. */\ntype BodyEntry<T> =\n | { readonly kind: 'spacer'; readonly key: string; readonly height: number }\n | {\n readonly kind: 'group';\n readonly key: string;\n readonly label: string;\n readonly count: number;\n /** `aria-rowindex`, or null without virtual scroll. */\n readonly aria: number | null;\n /** Index in the virtual list (`data-vi`), or null without virtual scroll. */\n readonly item: number | null;\n }\n | {\n readonly kind: 'row';\n readonly key: unknown;\n readonly row: T;\n readonly index: number;\n readonly aria: number | null;\n readonly item: number | null;\n };\n\n/** Smallest width, in pixels, that the user can give a column. */\nconst MIN_COLUMN_WIDTH = 48;\n/** `aria-valuemax` of a resize handle. The column width itself has no upper limit. */\nconst MAX_COLUMN_WIDTH_HINT = 2000;\n\nexport type StarSortOrder = 1 | -1;\n\nexport interface StarSortState {\n readonly field: string | null;\n readonly order: StarSortOrder;\n}\n\nexport interface StarLazyLoadEvent extends StarSortState {\n readonly first: number;\n readonly rows: number;\n readonly filter: string;\n readonly filters: StarColumnFilters;\n /** All sort columns in priority order (one entry without `multiSort`). */\n readonly sorts: readonly StarSortState[];\n}\n\n/** The user asked to move a row. The table does not change `value`: the owner moves the row. */\nexport interface StarRowReorderEvent<T> {\n readonly row: T;\n /** Index of the row in `value` now, and the index it must get. */\n readonly from: number;\n readonly to: number;\n}\n\n/** What `stateKey` stores in the browser. */\ninterface StarTableState {\n sortField?: string | null;\n sortOrder?: StarSortOrder;\n sortMeta?: readonly StarSortState[];\n filters?: StarColumnFilters;\n columnOrder?: readonly string[];\n hiddenColumns?: readonly string[];\n columnWidths?: Readonly<Record<string, number>>;\n rows?: number;\n collapsedGroups?: readonly string[];\n}\n\nexport interface StarCellContext<T> {\n readonly $implicit: T;\n readonly value: unknown;\n readonly index: number;\n}\n\n/** Custom cell: `<ng-template starCell=\"status\" let-row let-value=\"value\">…</ng-template>`. */\n@Directive({ selector: 'ng-template[starCell]' })\nexport class StarCellTemplate<T = unknown> {\n readonly starCell = input.required<string>();\n /** Optional: pass the table rows to type `let-row` in strict templates. */\n readonly starCellOf = input<readonly T[] | null>(null);\n readonly template = inject<TemplateRef<StarCellContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _dir: StarCellTemplate<T>,\n _ctx: unknown,\n ): _ctx is StarCellContext<T> {\n return true;\n }\n}\n\nexport interface StarRowContext<T> {\n readonly $implicit: T;\n readonly index: number;\n}\n\n/**\n * Detail content of an expanded row. When the table has this template, each row gets an\n * expand button: `<ng-template starRowExpansion let-row>…</ng-template>`.\n */\n@Directive({ selector: 'ng-template[starRowExpansion]' })\nexport class StarRowExpansionTemplate<T = unknown> {\n /** Optional: pass the table rows to type `let-row` in strict templates. */\n readonly starRowExpansionOf = input<readonly T[] | null>(null);\n readonly template = inject<TemplateRef<StarRowContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _dir: StarRowExpansionTemplate<T>,\n _ctx: unknown,\n ): _ctx is StarRowContext<T> {\n return true;\n }\n}\n\n/**\n * Data table (PrimeNG `p-table` essentials): typed columns, custom cell templates, sorting,\n * global filter, column filters, CSV / Excel / print export, client or lazy (server) pagination, single / multiple row selection with\n * checkboxes, row expansion, inline cell edit, column resize / reorder / hide / freeze, virtual scroll, row groups, multi-column sort,\n * footer row, row reorder, saved state, loading skeleton, empty state, sticky header and row click.\n *\n * ```html\n * <star-table [value]=\"rows()\" [columns]=\"columns\" dataKey=\"id\" selectionMode=\"multiple\"\n * [(selection)]=\"selected\" paginator [rows]=\"10\" [globalFilter]=\"query()\">\n * <ng-template starCell=\"status\" let-row><star-tag [value]=\"row.status\" /></ng-template>\n * </star-table>\n * ```\n */\n@Component({\n selector: 'star-table',\n imports: [\n NgTemplateOutlet,\n StarButton,\n StarCheckbox,\n StarMultiSelect,\n StarPaginator,\n StarPopover,\n StarSkeleton,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'star-table',\n '[class.star-table--striped]': 'striped()',\n '[class.star-table--sm]': \"size() === 'sm'\",\n '[class.star-table--sticky]': 'stickyHeader()',\n '[class.star-table--virtual]': 'virtualScroll()',\n '[class.star-table--variable]': 'variableHeights()',\n '[class.star-table--stack]': \"responsiveLayout() === 'stack'\",\n '[style.--star-table-row-height.px]': 'virtualScroll() ? virtualRowHeight() : null',\n // Virtual scroll: the focused row stays rendered, and Tab reaches rows out of the window.\n '(focusin)': 'onBodyFocusIn($event)',\n '(focusout)': 'onBodyFocusOut($event)',\n '(keydown)': 'onBodyKeydown($event)',\n },\n template: `\n <ng-content select=\"[starTableCaption]\" />\n @if (columnToggle()) {\n <div class=\"star-table__tools\">\n <star-button\n size=\"sm\"\n variant=\"secondary\"\n leadingIcon=\"ph-bold ph-columns\"\n (pressed)=\"columnsPanel.toggle($event)\"\n >\n {{ text.columns }}\n </star-button>\n <star-popover #columnsPanel [ariaLabel]=\"text.columns\">\n <ul class=\"star-table__columns\">\n @for (\n column of orderedColumns();\n track column.field;\n let first = $first;\n let last = $last\n ) {\n <li>\n <star-checkbox\n [checked]=\"!isHidden(column)\"\n [disabled]=\"!canHide(column)\"\n (checkedChange)=\"setColumnVisible(column, $event)\"\n >\n {{ column.header }}\n </star-checkbox>\n @if (reorderableColumns()) {\n <span class=\"star-table__columns-move\">\n <button\n type=\"button\"\n class=\"star-table__toggle\"\n [disabled]=\"first\"\n [attr.data-move]=\"moveKey(column, -1)\"\n [attr.aria-label]=\"text.moveColumnEarlier(column.header)\"\n (click)=\"moveColumnBy(column, -1)\"\n >\n <i class=\"ph-bold ph-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"star-table__toggle\"\n [disabled]=\"last\"\n [attr.data-move]=\"moveKey(column, 1)\"\n [attr.aria-label]=\"text.moveColumnLater(column.header)\"\n (click)=\"moveColumnBy(column, 1)\"\n >\n <i class=\"ph-bold ph-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </span>\n }\n </li>\n }\n </ul>\n </star-popover>\n </div>\n }\n <div\n #scroller\n class=\"star-table__scroll\"\n [attr.role]=\"scrollable() ? 'group' : null\"\n [attr.aria-label]=\"scrollable() ? ariaLabel() : null\"\n [attr.tabindex]=\"scrollable() ? 0 : null\"\n [style.max-height]=\"scrollHeight()\"\n (scroll)=\"onScroll($event)\"\n >\n <table\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.aria-rowcount]=\"ariaRowCount()\"\n >\n <thead>\n <tr [attr.aria-rowindex]=\"virtualScroll() ? 1 : null\">\n @if (reorderableRows()) {\n <th class=\"star-table__reorder\" scope=\"col\">\n <span class=\"star-sr-only\">{{ text.reorderRows }}</span>\n </th>\n }\n @if (expandable()) {\n <th class=\"star-table__expander\" scope=\"col\">\n <span class=\"star-sr-only\">{{ text.rowDetails }}</span>\n </th>\n }\n @if (selectionMode() === 'multiple') {\n <th class=\"star-table__select\" scope=\"col\">\n <star-checkbox\n [checked]=\"pageState() === true\"\n [indeterminate]=\"pageState() === 'mixed'\"\n [ariaLabel]=\"text.selectAllRows\"\n [disabled]=\"!pageRows().length\"\n (checkedChange)=\"togglePage($event)\"\n />\n </th>\n } @else if (selectionMode() === 'single') {\n <th class=\"star-table__select\" scope=\"col\">\n <span class=\"star-sr-only\">{{ text.selectRow }}</span>\n </th>\n }\n @for (column of visibleColumns(); track column.field) {\n <th\n scope=\"col\"\n [style.width]=\"widthOf(column)\"\n [style.min-width]=\"resizedWidth(column)\"\n [style.max-width]=\"resizedWidth(column)\"\n [style.inset-inline-start]=\"frozenOffset(column)\"\n [attr.data-field]=\"column.field\"\n [class]=\"'star-table__th star-table__cell--' + (column.align ?? 'start')\"\n [class.star-table__cell--frozen]=\"column.frozen\"\n [class.star-table__th--drop]=\"dropField() === column.field\"\n [attr.aria-sort]=\"ariaSort(column)\"\n [attr.draggable]=\"reorderableColumns() ? 'true' : null\"\n (dragstart)=\"onDragStart(column, $event)\"\n (dragover)=\"onDragOver(column, $event)\"\n (drop)=\"onDrop(column, $event)\"\n (dragend)=\"endDrag()\"\n >\n @if (column.sortable) {\n <button\n type=\"button\"\n class=\"star-table__sort\"\n [attr.title]=\"multiSort() ? text.sortMultiHint : null\"\n (click)=\"sortBy(column, $event)\"\n >\n {{ column.header }}\n <i [class]=\"sortIcon(column)\" aria-hidden=\"true\"></i>\n @if (sortRank(column); as rank) {\n <span class=\"star-table__sort-rank\">{{ rank }}</span>\n }\n </button>\n } @else {\n {{ column.header }}\n }\n @if (resizableColumns()) {\n <span\n class=\"star-table__resizer\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"text.resizeColumn(column.header)\"\n [attr.aria-valuenow]=\"resizeNow(column)\"\n [attr.aria-valuemin]=\"minColumnWidth\"\n [attr.aria-valuemax]=\"resizeMax(column)\"\n (pointerdown)=\"startResize(column, $event)\"\n (keydown)=\"onResizeKey(column, $event)\"\n ></span>\n }\n </th>\n }\n </tr>\n @if (hasColumnFilters()) {\n <tr class=\"star-table__filters\" [attr.aria-rowindex]=\"virtualScroll() ? 2 : null\">\n @if (reorderableRows()) {\n <td class=\"star-table__reorder\"></td>\n }\n @if (expandable()) {\n <td class=\"star-table__expander\"></td>\n }\n @if (selectionMode()) {\n <td class=\"star-table__select\"></td>\n }\n @for (column of visibleColumns(); track column.field) {\n <td\n [class.star-table__cell--frozen]=\"column.frozen\"\n [style.inset-inline-start]=\"frozenOffset(column)\"\n [attr.data-label]=\"column.filter ? column.header : null\"\n >\n @if (column.filter === 'select') {\n <select\n class=\"star-input star-input--sm star-table__filter\"\n [attr.aria-label]=\"text.filterBy(column.header)\"\n (change)=\"setFilter(column.field, $any($event.target).value)\"\n >\n <option value=\"\" [selected]=\"!filterValue(column.field)\">\n {{ text.filterAll }}\n </option>\n @for (option of filterChoices(column); track option) {\n <option [value]=\"option\" [selected]=\"option === filterValue(column.field)\">\n {{ option }}\n </option>\n }\n </select>\n } @else if (column.filter === 'text') {\n <input\n type=\"search\"\n class=\"star-input star-input--sm star-table__filter\"\n [attr.aria-label]=\"text.filterBy(column.header)\"\n [value]=\"filterValue(column.field)\"\n (input)=\"setFilter(column.field, $any($event.target).value)\"\n />\n } @else if (column.filter === 'multiselect') {\n <star-multi-select\n class=\"star-table__filter\"\n size=\"sm\"\n [options]=\"filterChoices(column)\"\n [value]=\"filterList(column.field)\"\n [placeholder]=\"text.filterAll\"\n [ariaLabel]=\"text.filterBy(column.header)\"\n (valueChange)=\"setFilter(column.field, $event)\"\n />\n } @else if (column.filter === 'number' || column.filter === 'date') {\n <span class=\"star-table__filter-range\">\n <input\n class=\"star-input star-input--sm star-table__filter\"\n [type]=\"column.filter\"\n [attr.aria-label]=\"text.filterMin(column.header)\"\n [attr.placeholder]=\"column.filter === 'number' ? text.filterMinShort : null\"\n [value]=\"filterBound(column.field, 'min')\"\n (input)=\"setBound(column, 'min', $any($event.target).value)\"\n />\n <input\n class=\"star-input star-input--sm star-table__filter\"\n [type]=\"column.filter\"\n [attr.aria-label]=\"text.filterMax(column.header)\"\n [attr.placeholder]=\"column.filter === 'number' ? text.filterMaxShort : null\"\n [value]=\"filterBound(column.field, 'max')\"\n (input)=\"setBound(column, 'max', $any($event.target).value)\"\n />\n </span>\n }\n </td>\n }\n </tr>\n }\n </thead>\n <tbody #body>\n @if (loading()) {\n @for (row of skeletonRows(); track row) {\n <tr class=\"star-table__row\">\n @if (reorderableRows()) {\n <td class=\"star-table__reorder\"></td>\n }\n @if (expandable()) {\n <td class=\"star-table__expander\"></td>\n }\n @if (selectionMode()) {\n <td class=\"star-table__select\"><star-skeleton size=\"1.25rem\" /></td>\n }\n @for (column of visibleColumns(); track column.field) {\n <td><star-skeleton height=\"0.875rem\" [width]=\"row % 2 ? '70%' : '90%'\" /></td>\n }\n </tr>\n }\n } @else {\n @for (entry of bodyEntries(); track entry.key) {\n @if (entry.kind === 'spacer') {\n <tr class=\"star-table__spacer\" aria-hidden=\"true\">\n <td [attr.colspan]=\"colspan()\" [style.height.px]=\"entry.height\"></td>\n </tr>\n } @else if (entry.kind === 'group') {\n @let group = entry;\n <tr\n class=\"star-table__group\"\n [attr.aria-rowindex]=\"group.aria\"\n [attr.data-vi]=\"group.item\"\n >\n <th [attr.colspan]=\"colspan()\" scope=\"colgroup\">\n <button\n type=\"button\"\n class=\"star-table__group-toggle\"\n [attr.aria-expanded]=\"!isGroupCollapsed(group.label)\"\n (click)=\"toggleGroup(group.label)\"\n >\n <i class=\"ph-bold ph-caret-down\" aria-hidden=\"true\"></i>\n {{ group.label }}\n <span class=\"star-table__group-count\">{{ group.count }}</span>\n </button>\n </th>\n </tr>\n } @else {\n @let row = entry.row;\n @let i = entry.index;\n <tr\n [attr.aria-rowindex]=\"entry.aria\"\n [attr.data-vi]=\"entry.item\"\n [hidden]=\"isRowCollapsed(row)\"\n class=\"star-table__row\"\n [class.star-table__row--alt]=\"i % 2 === 1\"\n [class.star-table__row--selected]=\"isSelected(row)\"\n [class.star-table__row--clickable]=\"clickable()\"\n [class.star-table__row--expanded]=\"expandable() && isExpanded(row)\"\n [attr.aria-selected]=\"selectionMode() ? isSelected(row) : null\"\n (click)=\"onRowClick(row, $event)\"\n >\n @if (reorderableRows()) {\n <td class=\"star-table__reorder\">\n <button\n type=\"button\"\n class=\"star-table__toggle\"\n [disabled]=\"!canMoveRow(row, -1)\"\n [attr.aria-label]=\"text.moveUp\"\n (click)=\"moveRow(row, -1)\"\n >\n <i class=\"ph-bold ph-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n class=\"star-table__toggle\"\n [disabled]=\"!canMoveRow(row, 1)\"\n [attr.aria-label]=\"text.moveDown\"\n (click)=\"moveRow(row, 1)\"\n >\n <i class=\"ph-bold ph-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </td>\n }\n @if (expandable()) {\n <td class=\"star-table__expander\">\n <button\n type=\"button\"\n class=\"star-table__toggle\"\n [attr.aria-expanded]=\"isExpanded(row)\"\n [attr.aria-controls]=\"isExpanded(row) ? detailId(i) : null\"\n [attr.aria-label]=\"isExpanded(row) ? text.collapseRow : text.expandRow\"\n (click)=\"toggleExpansion(row)\"\n >\n <i class=\"ph-bold ph-caret-right\" aria-hidden=\"true\"></i>\n </button>\n </td>\n }\n @if (selectionMode() === 'multiple') {\n <td class=\"star-table__select\">\n <star-checkbox\n [checked]=\"isSelected(row)\"\n [ariaLabel]=\"text.selectRow\"\n (checkedChange)=\"toggleRow(row)\"\n (click)=\"$event.stopPropagation()\"\n />\n </td>\n } @else if (selectionMode() === 'single') {\n <td class=\"star-table__select\">\n <input\n type=\"radio\"\n class=\"star-table__radio\"\n [name]=\"radioName\"\n [checked]=\"isSelected(row)\"\n [attr.aria-label]=\"text.selectRow\"\n (change)=\"selectOnly(row)\"\n (click)=\"$event.stopPropagation()\"\n />\n </td>\n }\n @for (column of visibleColumns(); track column.field) {\n <td\n [class]=\"'star-table__cell--' + (column.align ?? 'start')\"\n [class.star-table__cell--frozen]=\"column.frozen\"\n [style.inset-inline-start]=\"frozenOffset(column)\"\n [attr.data-label]=\"column.header\"\n >\n @if (isEditing(row, column)) {\n @if (column.editor === 'select') {\n <select\n class=\"star-input star-input--sm star-table__editor\"\n [attr.aria-label]=\"text.editCell(column.header)\"\n (change)=\"commitEdit(row, column, $any($event.target).value)\"\n (blur)=\"commitEdit(row, column, $any($event.target).value)\"\n (keydown.escape)=\"cancelEdit($event)\"\n >\n @for (option of column.editOptions ?? []; track option) {\n <option\n [value]=\"option\"\n [selected]=\"option === cellText(row, column)\"\n >\n {{ option }}\n </option>\n }\n </select>\n } @else {\n <input\n class=\"star-input star-input--sm star-table__editor\"\n [type]=\"column.editor === 'number' ? 'number' : 'text'\"\n [attr.aria-label]=\"text.editCell(column.header)\"\n [value]=\"editText(row, column)\"\n (blur)=\"commitEdit(row, column, $any($event.target).value)\"\n (keydown.enter)=\"commitEdit(row, column, $any($event.target).value)\"\n (keydown.escape)=\"cancelEdit($event)\"\n />\n }\n } @else if (isEditable(row, column)) {\n <button\n type=\"button\"\n class=\"star-table__edit\"\n [attr.data-edit]=\"editKey(row, column)\"\n (click)=\"startEdit(row, column)\"\n >\n <!-- The name is the action and the visible value (WCAG 2.5.3). -->\n <span class=\"star-sr-only\">{{ text.editCell(column.header) }}: </span>\n <span class=\"star-table__edit-value\">\n <ng-container\n *ngTemplateOutlet=\"\n cell;\n context: { $implicit: row, column, index: i }\n \"\n />\n </span>\n <i class=\"ph-bold ph-pencil-simple\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cell; context: { $implicit: row, column, index: i }\"\n />\n }\n </td>\n }\n </tr>\n @if (expansionTemplate(); as detail) {\n @if (isExpanded(row) && !isRowCollapsed(row)) {\n <tr\n class=\"star-table__expansion\"\n [id]=\"detailId(i)\"\n [attr.aria-rowindex]=\"entry.aria === null ? null : entry.aria + 1\"\n [attr.data-vi]=\"entry.item\"\n >\n <td [attr.colspan]=\"colspan()\">\n <ng-container\n *ngTemplateOutlet=\"detail; context: { $implicit: row, index: i }\"\n />\n </td>\n </tr>\n }\n }\n }\n } @empty {\n <tr>\n <td class=\"star-table__empty\" [attr.colspan]=\"colspan()\">\n <i class=\"ph-bold ph-tray\" aria-hidden=\"true\"></i>\n {{ emptyMessage() ?? text.noData }}\n </td>\n </tr>\n }\n }\n </tbody>\n @if (hasFooter()) {\n <tfoot>\n <tr\n class=\"star-table__footer\"\n [attr.aria-rowindex]=\"virtualScroll() ? ariaRowCount() : null\"\n >\n @if (reorderableRows()) {\n <td class=\"star-table__reorder\"></td>\n }\n @if (expandable()) {\n <td class=\"star-table__expander\"></td>\n }\n @if (selectionMode()) {\n <td class=\"star-table__select\"></td>\n }\n @for (column of visibleColumns(); track column.field) {\n <td\n [class]=\"'star-table__cell--' + (column.align ?? 'start')\"\n [attr.data-label]=\"footerText(column) ? column.header : null\"\n >\n {{ footerText(column) }}\n </td>\n }\n </tr>\n </tfoot>\n }\n </table>\n </div>\n <ng-template #cell let-row let-column=\"column\" let-i=\"index\">\n @if (cellTemplate(column.field); as custom) {\n <ng-container\n *ngTemplateOutlet=\"\n custom;\n context: { $implicit: row, value: cellValue(row, column), index: i }\n \"\n />\n } @else {\n {{ cellText(row, column) }}\n }\n </ng-template>\n @if (paginator()) {\n <star-paginator\n [ariaLabel]=\"ariaLabel() ? text.pagination + ': ' + ariaLabel() : null\"\n [totalRecords]=\"total()\"\n [(first)]=\"first\"\n [(rows)]=\"rows\"\n [rowsPerPageOptions]=\"rowsPerPageOptions()\"\n (pageChange)=\"emitLazy()\"\n />\n }\n `,\n})\nexport class StarTable<T> {\n protected readonly text = inject(STAR_UI_TEXT);\n private readonly document = inject(DOCUMENT);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n private readonly appRef = inject(ApplicationRef);\n\n readonly value = input.required<readonly T[]>();\n readonly columns = input.required<readonly StarColumn<T>[]>();\n /** Row identity for tracking and selection (default: the row object). */\n readonly dataKey = input<StarOptionKey<T> | null>(null);\n readonly loading = input(false, { transform: booleanAttribute });\n readonly emptyMessage = input<string | null>(null);\n readonly striped = input(false, { transform: booleanAttribute });\n readonly size = input<'sm' | 'md'>('md');\n readonly stickyHeader = input(false, { transform: booleanAttribute });\n readonly scrollHeight = input<string | null>(null);\n /**\n * Layout when the table is narrower than 40rem (a phone). `'scroll'`: the table scrolls\n * sideways. `'stack'`: each row is a block with one line per column, \"label: value\"; the\n * sortable headers stay as a row of buttons. With `virtualScroll`, `'stack'` turns on rows of\n * different heights.\n */\n readonly responsiveLayout = input<'scroll' | 'stack'>('scroll');\n /**\n * Renders only the rows in view (plus 5 above and below), for long lists. Needs\n * `scrollHeight`. Rows have one fixed height (`virtualRowHeight`, text on one line) unless\n * `virtualRowHeights` turns on rows of different heights.\n */\n readonly virtualScroll = input(false, { transform: booleanAttribute });\n /**\n * Row height in pixels with `virtualScroll`. With rows of different heights it is the\n * estimated height of a row that was not measured yet.\n */\n readonly virtualRowHeight = input(48);\n /**\n * Row heights with `virtualScroll`. `'auto'`: one fixed height, unless the table has row\n * expansion, `groupBy` or the stacked layout, which need rows of different heights.\n * `'variable'`: rows of different heights always, for cell text on more than one line. The\n * table measures each rendered row and keeps the heights.\n */\n readonly virtualRowHeights = input<'auto' | 'variable'>('auto');\n readonly ariaLabel = input<string | null>(null);\n\n readonly paginator = input(false, { transform: booleanAttribute });\n readonly first = model(0);\n readonly rows = model(10);\n readonly rowsPerPageOptions = input<readonly number[]>([10, 25, 50]);\n\n readonly sortField = model<string | null>(null);\n readonly sortOrder = model<StarSortOrder>(1);\n /** Case- and accent-insensitive text search over all columns. */\n readonly globalFilter = input('');\n /** Column filter values by column `field` (columns with `filter` set). Two-way. */\n readonly filters = model<StarColumnFilters>({});\n\n /** Server mode: the table only renders `value`; it emits `lazyLoad` for every change. */\n readonly lazy = input(false, { transform: booleanAttribute });\n /** Total rows on the server (lazy mode). */\n readonly totalRecords = input(0);\n\n readonly selectionMode = input<'single' | 'multiple' | null>(null);\n readonly selection = model<readonly T[]>([]);\n\n /**\n * Keys (`dataKey`) of the expanded rows. Two-way. Rows expand only when the table has an\n * `starRowExpansion` template.\n */\n readonly expandedKeys = model<readonly unknown[]>([]);\n /** `'single'`: opening a row closes the other rows. */\n readonly rowExpandMode = input<'single' | 'multiple'>('multiple');\n\n /** Shows a Columns button: the user can hide columns (and move them, with `reorderableColumns`). */\n readonly columnToggle = input(false, { transform: booleanAttribute });\n /** The user can move a column: drag its header, or use the Columns panel. */\n readonly reorderableColumns = input(false, { transform: booleanAttribute });\n /** The user can change a column width: drag the header edge, or use the arrow keys on it. */\n readonly resizableColumns = input(false, { transform: booleanAttribute });\n /** Column `field`s in display order. Columns not in the list keep their place after it. Two-way. */\n readonly columnOrder = model<readonly string[]>([]);\n /** `field`s of the hidden columns. Two-way. */\n readonly hiddenColumns = model<readonly string[]>([]);\n /** Column widths in pixels by `field`, set by the user. Two-way. */\n readonly columnWidths = model<Readonly<Record<string, number>>>({});\n\n /**\n * Sort by more than one column: Shift + click (or Shift + Enter) on a header adds it as the\n * next sort column. A plain click sorts by that column only.\n */\n readonly multiSort = input(false, { transform: booleanAttribute });\n /** Sort columns in priority order with `multiSort`. Two-way. */\n readonly sortMeta = model<readonly StarSortState[]>([]);\n /**\n * Group heading of a row (property name or function). Rows with the same heading show\n * together under it, in the order in which the headings first appear after sorting.\n * With `virtualScroll`, the rows of a closed group take no space.\n */\n readonly groupBy = input<StarOptionKey<T> | null>(null);\n /** Headings of the closed groups. Two-way. */\n readonly collapsedGroups = model<readonly string[]>([]);\n /**\n * Adds \"Move up\" / \"Move down\" buttons to each row. The buttons work while the table shows\n * `value` in its own order (no sort, no filter, no groups).\n */\n readonly reorderableRows = input(false, { transform: booleanAttribute });\n /**\n * Remembers sort, filters, column order, hidden columns, column widths, page size and\n * closed groups in the browser under this key, and restores them on the next visit.\n */\n readonly stateKey = input<string | null>(null);\n readonly stateStorage = input<'local' | 'session'>('local');\n\n readonly rowClick = output<T>();\n readonly rowReorder = output<StarRowReorderEvent<T>>();\n /** The user changed an editable cell (see `StarColumn.editable`). */\n readonly cellEdit = output<StarCellEditEvent<T>>();\n readonly lazyLoad = output<StarLazyLoadEvent>();\n\n /** The cell in edit mode: `<row key>|<field>` text, or `null`. */\n private readonly editing = signal<string | null>(null);\n private readonly cellTemplates = contentChildren(StarCellTemplate);\n private readonly expansion = contentChild(StarRowExpansionTemplate);\n protected readonly expansionTemplate = computed(\n () => (this.expansion()?.template as TemplateRef<StarRowContext<T>> | undefined) ?? null,\n );\n protected readonly expandable = computed(() => !!this.expansion());\n protected readonly radioName = `star-table-${Math.random().toString(36).slice(2)}`;\n protected readonly clickable = computed(() => this.selectionMode() === 'single');\n\n /** All columns in display order: frozen columns first, then `columnOrder`. */\n protected readonly orderedColumns = computed(() => {\n const order = this.columnOrder();\n const rank = (column: StarColumn<T>, index: number) => {\n const position = order.indexOf(column.field);\n return (column.frozen ? 0 : 1e6) + (position < 0 ? order.length + index : position);\n };\n return this.columns()\n .map((column, index) => ({ column, rank: rank(column, index) }))\n .sort((a, b) => a.rank - b.rank)\n .map(({ column }) => column);\n });\n\n protected readonly visibleColumns = computed(() => {\n const hidden = this.hiddenColumns();\n return this.orderedColumns().filter((column) => !hidden.includes(column.field));\n });\n\n protected readonly dragField = signal<string | null>(null);\n protected readonly dropField = signal<string | null>(null);\n private resizing = false;\n\n protected readonly hasColumnFilters = computed(() =>\n this.visibleColumns().some((column) => column.filter),\n );\n\n /** Columns that have a filter value now, with that value. */\n private readonly activeFilters = computed(() => {\n const filters = this.filters();\n return this.columns().flatMap((column) => {\n const query = filters[column.field];\n return column.filter && isActiveFilter(query) ? [{ column, query }] : [];\n });\n });\n\n private readonly filtered = computed(() => {\n if (this.lazy()) return this.value();\n const query = this.globalFilter();\n const active = this.activeFilters();\n if (!query && !active.length) return this.value();\n return this.value().filter(\n (row) =>\n (!query ||\n this.columns().some((column) => matchesFilter(this.cellText(row, column), query))) &&\n active.every(({ column, query: value }) => this.matchesColumnFilter(row, column, value)),\n );\n });\n\n /** Sort columns in priority order. */\n private readonly sorts = computed<readonly StarSortState[]>(() => {\n const meta = this.sortMeta();\n if (this.multiSort() && meta.length) return meta;\n const field = this.sortField();\n return field ? [{ field, order: this.sortOrder() }] : [];\n });\n\n private readonly sorted = computed(() => {\n let rows = this.filtered();\n if (this.lazy()) return rows;\n const sorts = this.sorts().flatMap((sort) => {\n const column = this.columns().find((c) => c.field === sort.field);\n return column ? [{ column, order: sort.order }] : [];\n });\n if (sorts.length) {\n rows = [...rows].sort((a, b) => {\n for (const { column, order } of sorts) {\n const result = compareValues(this.cellValue(a, column), this.cellValue(b, column));\n if (result) return order * result;\n }\n return 0;\n });\n }\n if (!this.groupBy()) return rows;\n // Keep each group together, in the order in which the groups first appear.\n const rank = new Map<string, number>();\n for (const row of rows) {\n const group = this.groupOf(row);\n if (!rank.has(group)) rank.set(group, rank.size);\n }\n return rows\n .map((row, index) => ({ row, index, rank: rank.get(this.groupOf(row)) ?? 0 }))\n .sort((a, b) => a.rank - b.rank || a.index - b.index)\n .map(({ row }) => row);\n });\n\n /** First row index of each group on the page, with the heading and the row count. */\n private readonly groupStarts = computed(() => {\n const starts = new Map<number, { label: string; count: number }>();\n if (!this.groupBy()) return starts;\n let current: { label: string; count: number } | null = null;\n this.pageRows().forEach((row, index) => {\n const label = this.groupOf(row);\n if (!current || current.label !== label) {\n current = { label, count: 0 };\n starts.set(index, current);\n }\n current.count++;\n });\n return starts;\n });\n\n protected readonly hasFooter = computed(() =>\n this.visibleColumns().some((column) => column.footer !== undefined),\n );\n\n /** Rows can move while the table shows `value` in its own order. */\n private readonly rowOrderIsOwn = computed(\n () =>\n !this.lazy() &&\n !this.sorts().length &&\n !this.globalFilter() &&\n !this.activeFilters().length &&\n !this.groupBy(),\n );\n private restoredKey: string | null = null;\n\n protected readonly total = computed(() =>\n this.lazy() ? this.totalRecords() : this.filtered().length,\n );\n\n protected readonly pageRows = computed(() => {\n const rows = this.sorted();\n if (this.lazy() || !this.paginator()) return rows;\n return rows.slice(this.first(), this.first() + this.rows());\n });\n\n private readonly scrollTop = signal(0);\n private readonly viewportHeight = signal(0);\n private readonly scroller = viewChild<ElementRef<HTMLElement>>('scroller');\n private readonly body = viewChild<ElementRef<HTMLElement>>('body');\n\n /**\n * Rows of different heights: on with `virtualRowHeights=\"variable\"`, and with the features that\n * cannot have one fixed height (row expansion, groups, stacked layout).\n */\n protected readonly variableHeights = computed(\n () =>\n this.virtualScroll() &&\n (this.virtualRowHeights() === 'variable' ||\n this.expandable() ||\n !!this.groupBy() ||\n this.responsiveLayout() === 'stack'),\n );\n\n /** Header rows: the column headings, and the filter row when there is one. */\n private readonly headerRows = computed(() => (this.hasColumnFilters() ? 2 : 1));\n\n /** `aria-rowcount` with virtual scroll: header, body (headings, rows, detail rows) and footer. */\n protected readonly ariaRowCount = computed(() => {\n if (!this.virtualScroll()) return null;\n const body = this.layout()?.bodyRows ?? this.pageRows().length;\n return this.headerRows() + body + (this.hasFooter() ? 1 : 0);\n });\n\n /** Expanded row keys, for a fast look-up per row. */\n private readonly expandedSet = computed(() => new Set(this.expandedKeys()));\n\n /**\n * Measured heights by row key (`dataKey` value, else the row object). A row with its detail\n * row open has its own entry, so closing it again needs no new measure. Group headings use\n * their item key. The maps are not signals: `measured` counts their changes.\n */\n private readonly rowHeights = new Map<unknown, number>();\n private readonly expandedHeights = new Map<unknown, number>();\n /** Counts up when a measured height changes the height tree. */\n private readonly measured = signal(0);\n /** Counts up when the measured heights are no longer valid (the table width changed). */\n private readonly heightEpoch = signal(0);\n /** Top of the table body in the scroll area (below the sticky header), in pixels. */\n private readonly bodyOffset = signal(0);\n\n /** Items (group headings and rows) and their heights, with rows of different heights. */\n private readonly layout = computed<VirtualLayout<T> | null>(() => {\n if (!this.variableHeights() || this.loading()) return null;\n const rows = this.pageRows();\n const grouped = !!this.groupBy();\n const collapsed = new Set(this.collapsedGroups());\n const expandable = this.expandable();\n const expanded = this.expandedSet();\n const estimate = Math.max(1, this.virtualRowHeight());\n this.heightEpoch();\n return untracked(() => {\n // Keys of rows that left the data would stay in the maps forever: drop them now and then.\n if (this.rowHeights.size + this.expandedHeights.size > 4 * rows.length + 1000) {\n this.rowHeights.clear();\n this.expandedHeights.clear();\n }\n return buildVirtualLayout(rows, {\n groupOf: grouped ? (row) => this.groupOf(row) : null,\n isCollapsed: (label) => collapsed.has(label),\n isExpanded: (row) => expandable && expanded.has(this.trackKey(row)),\n keyOf: (row) => this.trackKey(row),\n heightOf: (item) => this.estimateOf(item, estimate),\n });\n });\n });\n\n /** Measured height of an item, else the estimate (a row with its detail: two rows). */\n private estimateOf(item: VirtualItem<T>, estimate: number): number {\n if (item.kind === 'group') return this.rowHeights.get(item.key) ?? estimate;\n if (!item.expanded) return this.rowHeights.get(item.key) ?? estimate;\n return (\n this.expandedHeights.get(item.key) ?? (this.rowHeights.get(item.key) ?? estimate) + estimate\n );\n }\n\n /** Last layout and scroll offset of `variableWindow`, to keep the view on a layout change. */\n private anchorMemo: { layout: VirtualLayout<T>; rows: readonly T[]; top: number } | null = null;\n /** Scroll offset that the next render must apply (see `variableWindow`). */\n private pendingScroll: number | null = null;\n\n /** Rendered items with rows of different heights. */\n private readonly variableWindow = computed(() => {\n const layout = this.layout();\n if (!layout) return null;\n this.measured();\n const rows = this.pageRows();\n let top = Math.max(0, this.scrollTop() - this.bodyOffset());\n // The items changed but not the rows nor the scroll offset (a group closed, a row opened\n // from code, the width changed): keep the item at the top of the view where it was.\n const memo = this.anchorMemo;\n if (memo && memo.layout !== layout && memo.rows === rows && memo.top === top) {\n const anchor = anchorOf(memo.layout.tree, top);\n const key = anchor ? memo.layout.items[anchor.index]?.key : undefined;\n const index = anchor ? layout.indexOfKey.get(key) : undefined;\n if (anchor && index !== undefined) {\n const kept = layout.tree.offsetOf(index) + anchor.inside;\n if (Math.abs(kept - top) > 0.5) {\n top = kept;\n this.pendingScroll = kept + untracked(this.bodyOffset);\n }\n }\n }\n this.anchorMemo = { layout, rows, top };\n const viewport = this.viewportHeight() || VIRTUAL_FALLBACK_VIEWPORT;\n return { layout, ...variableRange(layout.tree, top, viewport, VIRTUAL_BUFFER_ROWS) };\n });\n\n /** Key of the row (or heading) that has the focus, kept rendered outside the window. */\n private readonly focusedKey = signal<{ readonly key: unknown } | null>(null);\n\n /** Index of the focused item in the virtual list, or -1. */\n private readonly focusedIndex = computed(() => {\n const focused = this.focusedKey();\n if (!focused || !this.virtualScroll()) return -1;\n const layout = this.layout();\n if (layout) return layout.indexOfKey.get(focused.key) ?? -1;\n return this.pageRows().findIndex((row) => Object.is(this.trackKey(row), focused.key));\n });\n\n /** The lines of the body: spacers, group headings and rows, in display order. */\n protected readonly bodyEntries = computed<readonly BodyEntry<T>[]>(() => {\n const rows = this.pageRows();\n if (!this.virtualScroll()) {\n const entries: BodyEntry<T>[] = [];\n const starts = this.groupStarts();\n rows.forEach((row, index) => {\n const group = starts.get(index);\n if (group) {\n entries.push({\n kind: 'group',\n key: groupKey(group.label),\n ...group,\n aria: null,\n item: null,\n });\n }\n entries.push({ kind: 'row', key: this.trackKey(row), row, index, aria: null, item: null });\n });\n return entries;\n }\n const header = this.headerRows();\n const focused = this.focusedIndex();\n const variable = this.variableWindow();\n if (variable) {\n const { layout } = variable;\n return this.windowEntries(\n variable,\n focused,\n layout.tree.total,\n (i) => layout.tree.offsetOf(i),\n (i) => {\n const item = layout.items[i];\n const aria = header + item.aria + 1;\n return item.kind === 'group'\n ? { kind: 'group', key: item.key, label: item.label, count: item.count, aria, item: i }\n : { kind: 'row', key: item.key, row: item.row, index: item.index, aria, item: i };\n },\n );\n }\n const height = Math.max(1, this.virtualRowHeight());\n const window = this.virtualWindow();\n return this.windowEntries(\n window,\n focused,\n rows.length * height,\n (i) => i * height,\n (i) => ({\n kind: 'row',\n key: this.trackKey(rows[i]),\n row: rows[i],\n index: i,\n aria: header + i + 1,\n item: i,\n }),\n );\n });\n\n /**\n * Entries of the window `[start, end)` and of the focused item outside it, with a spacer for\n * each gap, so the body keeps the full height.\n */\n private windowEntries(\n window: { readonly start: number; readonly end: number },\n focused: number,\n total: number,\n offsetOf: (index: number) => number,\n entryAt: (index: number) => BodyEntry<T>,\n ): BodyEntry<T>[] {\n const indexes: number[] = [];\n if (focused >= 0 && focused < window.start) indexes.push(focused);\n for (let i = window.start; i < window.end; i++) indexes.push(i);\n if (focused >= window.end) indexes.push(focused);\n const entries: BodyEntry<T>[] = [];\n let cursor = 0;\n let spacers = 0;\n const spacer = (height: number) => {\n if (height > 0.01) entries.push({ kind: 'spacer', key: `\\u0000spacer${spacers++}`, height });\n };\n for (const index of indexes) {\n spacer(offsetOf(index) - offsetOf(cursor));\n entries.push(entryAt(index));\n cursor = index + 1;\n }\n if (indexes.length) spacer(total - offsetOf(cursor));\n return entries;\n }\n\n /** First rendered row and the heights of the rows left out before and after the window. */\n protected readonly virtualWindow = computed(() => {\n const count = this.pageRows().length;\n if (!this.virtualScroll() || this.loading() || this.variableHeights())\n return { start: 0, end: count, before: 0, after: 0 };\n const height = Math.max(1, this.virtualRowHeight());\n const viewport = this.viewportHeight() || VIRTUAL_FALLBACK_VIEWPORT;\n const visible = Math.ceil(viewport / height);\n const first = Math.min(Math.floor(this.scrollTop() / height), Math.max(0, count - visible));\n const start = Math.max(0, first - VIRTUAL_BUFFER_ROWS);\n const end = Math.min(count, first + visible + VIRTUAL_BUFFER_ROWS);\n return { start, end, before: start * height, after: (count - end) * height };\n });\n\n protected onScroll(event: Event): void {\n if (!this.virtualScroll()) return;\n const viewport = event.target as HTMLElement;\n this.scrollTop.set(viewport.scrollTop);\n this.viewportHeight.set(viewport.clientHeight);\n }\n\n /** Rendered rows that the ResizeObserver watches (rows of different heights only). */\n private readonly observedRows = new Set<Element>();\n private rowObserver: ResizeObserver | null = null;\n\n /**\n * Measures the rendered items, stores their heights, and moves the scroll offset by the change\n * of the items above the first item in view, so the rows in view do not move (scroll\n * anchoring). Runs after a render and when the ResizeObserver reports a row size change.\n */\n private measureRendered(): void {\n const layout = untracked(this.layout);\n const scroller = this.scroller()?.nativeElement;\n const body = this.body()?.nativeElement;\n // A hidden table (display: none, a closed tab) has no layout: keep the heights it has.\n if (!layout || !scroller || !body || !scroller.isConnected || !scroller.clientHeight) return;\n if (this.pendingScroll !== null) {\n scroller.scrollTop = this.pendingScroll;\n this.pendingScroll = null;\n }\n const area = scroller.getBoundingClientRect();\n const offset =\n body.getBoundingClientRect().top - area.top - scroller.clientTop + scroller.scrollTop;\n const heights = new Map<number, number>();\n for (const row of Array.from(body.children) as HTMLElement[]) {\n const item = row.dataset['vi'];\n if (item === undefined) continue;\n heights.set(\n Number(item),\n (heights.get(Number(item)) ?? 0) + row.getBoundingClientRect().height,\n );\n }\n const { tree, items } = layout;\n const anchor = tree.indexAt(scroller.scrollTop - offset);\n const changes: HeightChange[] = [];\n for (const [index, height] of heights) {\n const item = items[index];\n if (!item || height <= 0) continue;\n const from = tree.get(index);\n if (Math.abs(height - from) < MEASURE_TOLERANCE) continue;\n tree.set(index, height);\n changes.push({ index, from, to: height });\n (item.kind === 'row' && item.expanded ? this.expandedHeights : this.rowHeights).set(\n item.key,\n height,\n );\n }\n const shift = anchorShift(changes, anchor);\n if (Math.abs(shift) >= 0.5) scroller.scrollTop += shift;\n this.bodyOffset.set(offset);\n this.viewportHeight.set(scroller.clientHeight);\n this.scrollTop.set(scroller.scrollTop);\n if (changes.length) this.measured.update((count) => count + 1);\n this.observeRows(body);\n }\n\n /** Watches the rendered rows and the body for size changes (content, fonts, images). */\n private observeRows(body: HTMLElement): void {\n if (typeof ResizeObserver === 'undefined') return;\n this.rowObserver ??= new ResizeObserver(() => this.measureRendered());\n const rows = new Set<Element>([\n body,\n ...Array.from(body.querySelectorAll(':scope > tr[data-vi]')),\n ]);\n for (const row of this.observedRows) {\n if (!rows.has(row)) {\n this.rowObserver.unobserve(row);\n this.observedRows.delete(row);\n }\n }\n for (const row of rows) {\n if (!this.observedRows.has(row)) {\n this.rowObserver.observe(row);\n this.observedRows.add(row);\n }\n }\n }\n\n /** Index in the virtual list of the item that holds an element, or -1. */\n private itemOf(element: Element | null): number {\n const row = element?.closest<HTMLElement>('tr[data-vi]');\n return row && this.body()?.nativeElement.contains(row) ? Number(row.dataset['vi']) : -1;\n }\n\n /** Key of an item of the virtual list. */\n private keyOfItem(index: number): unknown {\n const layout = this.layout();\n if (layout) return layout.items[index]?.key;\n const row = this.pageRows()[index];\n return row === undefined ? undefined : this.trackKey(row);\n }\n\n protected onBodyFocusIn(event: FocusEvent): void {\n if (!this.virtualScroll()) return;\n const index = this.itemOf(event.target as Element);\n if (index < 0) return;\n const key = this.keyOfItem(index);\n if (!Object.is(this.focusedKey()?.key, key)) this.focusedKey.set({ key });\n // The browser scrolled the focused element into view: render the rows around it now, so the\n // next Tab finds the next row.\n const scroller = this.scroller()?.nativeElement;\n if (scroller) {\n this.scrollTop.set(scroller.scrollTop);\n if (scroller.clientHeight) this.viewportHeight.set(scroller.clientHeight);\n }\n }\n\n protected onBodyFocusOut(event: FocusEvent): void {\n if (!this.virtualScroll()) return;\n const body = this.body()?.nativeElement;\n const next = event.relatedTarget as Node | null;\n if (!body || (next && body.contains(next))) return;\n // The focus left the body (not only the window of the browser): the row may leave the DOM.\n setTimeout(() => {\n if (!body.contains(this.document.activeElement)) this.focusedKey.set(null);\n });\n }\n\n /**\n * Tab and Shift + Tab from a row to a row that is not rendered (the focused row is kept\n * outside the window): scroll that row in, then focus its first (or last) control.\n */\n protected onBodyKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab' || !this.virtualScroll() || event.defaultPrevented) return;\n const body = this.body()?.nativeElement;\n const index = this.itemOf(event.target as Element);\n if (!body || index < 0) return;\n const step = event.shiftKey ? -1 : 1;\n const target = index + step;\n const count = this.layout()?.items.length ?? this.pageRows().length;\n if (target < 0 || target >= count || body.querySelector(`:scope > tr[data-vi=\"${target}\"]`)) {\n return;\n }\n const own = this.focusablesOf(body, index);\n const position = own.indexOf(event.target as HTMLElement);\n if (position < 0 || (step === 1 ? position < own.length - 1 : position > 0)) return;\n event.preventDefault();\n this.revealItem(target);\n afterNextRender(\n () => {\n // The first row after (or before) the focused one that has a control.\n for (let i = target; i >= 0 && i < count; i += step) {\n const controls = this.focusablesOf(body, i);\n if (!body.querySelector(`:scope > tr[data-vi=\"${i}\"]`)) break;\n if (controls.length) {\n (step === 1 ? controls[0] : controls[controls.length - 1]).focus();\n return;\n }\n }\n },\n { injector: this.injector },\n );\n // Render now, not at the next scheduled change detection: the row is rendered and focused\n // before this key event ends. On a slow device the next Tab can arrive before a scheduled\n // render, and it would then start from the old row, so one Tab would be lost or repeated.\n this.appRef.tick();\n }\n\n private focusablesOf(body: HTMLElement, index: number): HTMLElement[] {\n return Array.from(\n body.querySelectorAll<HTMLElement>(`:scope > tr[data-vi=\"${index}\"]`),\n ).flatMap((row) => Array.from(row.querySelectorAll<HTMLElement>(FOCUSABLE)));\n }\n\n /** Scrolls an item of the virtual list to the middle of the view. */\n private revealItem(index: number): void {\n const scroller = this.scroller()?.nativeElement;\n if (!scroller) return;\n const layout = this.layout();\n const offset = layout\n ? layout.tree.offsetOf(index)\n : index * Math.max(1, this.virtualRowHeight());\n scroller.scrollTop = Math.max(0, this.bodyOffset() + offset - scroller.clientHeight / 2);\n this.scrollTop.set(scroller.scrollTop);\n if (scroller.clientHeight) this.viewportHeight.set(scroller.clientHeight);\n }\n\n protected readonly skeletonRows = computed(() =>\n Array.from({ length: Math.min(this.rows(), 8) }, (_, i) => i),\n );\n protected readonly colspan = computed(\n () =>\n this.visibleColumns().length +\n (this.selectionMode() ? 1 : 0) +\n (this.expandable() ? 1 : 0) +\n (this.reorderableRows() ? 1 : 0),\n );\n\n /** Selection state of the rows on the current page, for the header checkbox. */\n protected readonly pageState = computed<boolean | 'mixed'>(() => {\n const rows = this.pageRows();\n const count = rows.filter((row) => this.isSelected(row)).length;\n if (!rows.length || count === 0) return false;\n return count === rows.length ? true : 'mixed';\n });\n\n constructor() {\n // A new filter goes back to page 1. Lazy tables also load the first page on init.\n effect(() => {\n this.globalFilter();\n this.filters();\n untracked(() => {\n this.first.set(0);\n this.emitLazy();\n });\n });\n afterRenderEffect({ read: () => this.measureFrozen() });\n // Rows of different heights: measure the rendered rows after each render of the body.\n afterRenderEffect(() => {\n this.bodyEntries();\n this.expandedKeys();\n if (this.variableHeights()) untracked(() => this.measureRendered());\n });\n const destroyRef = inject(DestroyRef);\n if (typeof ResizeObserver !== 'undefined') {\n let width: number | null = null;\n const observer = new ResizeObserver((entries) => {\n this.resized.update((count) => count + 1);\n // A new width wraps text differently (or stacks the rows): the measured heights are\n // estimates again. The rendered rows are measured again right away.\n const next = Math.round(entries[entries.length - 1].contentRect.width);\n if (width !== null && next !== width && untracked(this.variableHeights)) {\n this.rowHeights.clear();\n this.expandedHeights.clear();\n this.heightEpoch.update((count) => count + 1);\n }\n width = next;\n });\n observer.observe(this.host.nativeElement);\n destroyRef.onDestroy(() => observer.disconnect());\n }\n destroyRef.onDestroy(() => this.rowObserver?.disconnect());\n if (isDevMode()) {\n effect(() => {\n if (this.virtualScroll() && !this.scrollHeight()) {\n console.warn(\n 'star-table: virtualScroll needs scrollHeight. Without it the table does not scroll inside its own area, and rows after the first window are not rendered.',\n );\n }\n if (this.virtualRowHeights() === 'variable' && !this.virtualScroll()) {\n console.warn('star-table: virtualRowHeights has no effect without virtualScroll.');\n }\n });\n }\n // Saved state: restore once per key, then save every change.\n effect(() => {\n const key = this.stateKey();\n if (!key) return;\n if (this.restoredKey !== key) {\n this.restoredKey = key;\n untracked(() => this.restoreState(key));\n }\n const state: StarTableState = {\n sortField: this.sortField(),\n sortOrder: this.sortOrder(),\n sortMeta: this.sortMeta(),\n filters: this.filters(),\n columnOrder: this.columnOrder(),\n hiddenColumns: this.hiddenColumns(),\n columnWidths: this.columnWidths(),\n rows: this.rows(),\n collapsedGroups: this.collapsedGroups(),\n };\n try {\n this.storage()?.setItem(key, JSON.stringify(state));\n } catch {\n // Storage can be full or blocked: the table then works without saved state.\n }\n });\n }\n\n private storage(): Storage | null {\n const view = this.document.defaultView;\n try {\n return (\n (this.stateStorage() === 'session' ? view?.sessionStorage : view?.localStorage) ?? null\n );\n } catch {\n return null;\n }\n }\n\n private restoreState(key: string): void {\n let state: StarTableState;\n try {\n state = JSON.parse(this.storage()?.getItem(key) ?? 'null') as StarTableState;\n } catch {\n return;\n }\n if (!state || typeof state !== 'object') return;\n if (state.sortField !== undefined) this.sortField.set(state.sortField);\n if (state.sortOrder === 1 || state.sortOrder === -1) this.sortOrder.set(state.sortOrder);\n if (Array.isArray(state.sortMeta)) this.sortMeta.set(state.sortMeta);\n if (state.filters && typeof state.filters === 'object') this.filters.set(state.filters);\n if (Array.isArray(state.columnOrder)) this.columnOrder.set(state.columnOrder);\n if (Array.isArray(state.hiddenColumns)) this.hiddenColumns.set(state.hiddenColumns);\n if (state.columnWidths && typeof state.columnWidths === 'object') {\n this.columnWidths.set(state.columnWidths);\n }\n if (typeof state.rows === 'number' && state.rows > 0) this.rows.set(state.rows);\n if (Array.isArray(state.collapsedGroups)) this.collapsedGroups.set(state.collapsedGroups);\n }\n\n /** Removes the saved state of this table (`stateKey`). The current view does not change. */\n clearState(): void {\n const key = this.stateKey();\n if (key) this.storage()?.removeItem(key);\n }\n\n protected groupOf(row: T): string {\n const key = this.groupBy();\n const group = key ? readOption(row, key) : null;\n return group === null || group === undefined ? '' : String(group);\n }\n\n protected isGroupCollapsed(label: string): boolean {\n return this.collapsedGroups().includes(label);\n }\n\n protected isRowCollapsed(row: T): boolean {\n return !!this.groupBy() && this.isGroupCollapsed(this.groupOf(row));\n }\n\n protected toggleGroup(label: string): void {\n this.collapsedGroups.update((groups) =>\n groups.includes(label) ? groups.filter((group) => group !== label) : [...groups, label],\n );\n }\n\n protected footerText(column: StarColumn<T>): string {\n const footer = column.footer;\n if (footer === undefined) return '';\n return typeof footer === 'function' ? footer(this.sorted()) : footer;\n }\n\n protected canMoveRow(row: T, step: 1 | -1): boolean {\n if (!this.rowOrderIsOwn()) return false;\n const to = this.value().indexOf(row) + step;\n return to >= 0 && to < this.value().length;\n }\n\n protected moveRow(row: T, step: 1 | -1): void {\n if (!this.canMoveRow(row, step)) return;\n const from = this.value().indexOf(row);\n this.rowReorder.emit({ row, from, to: from + step });\n }\n\n protected trackKey(row: T): unknown {\n return readOption(row, this.dataKey());\n }\n\n protected cellTemplate(field: string): TemplateRef<StarCellContext<T>> | null {\n return this.cellTemplates().find((t) => t.starCell() === field)?.template ?? null;\n }\n\n protected cellValue(row: T, column: StarColumn<T>): unknown {\n return column.value\n ? column.value(row)\n : (row as Record<string, unknown> | null)?.[column.field];\n }\n\n protected cellText(row: T, column: StarColumn<T>): string {\n if (column.format) return column.format(row);\n const value = this.cellValue(row, column);\n return value === null || value === undefined ? '' : String(value);\n }\n\n protected isHidden(column: StarColumn<T>): boolean {\n return this.hiddenColumns().includes(column.field);\n }\n\n /** A column can hide unless it is locked or it is the last visible column. */\n protected canHide(column: StarColumn<T>): boolean {\n if (column.hideable === false) return false;\n return this.isHidden(column) || this.visibleColumns().length > 1;\n }\n\n protected setColumnVisible(column: StarColumn<T>, visible: boolean): void {\n this.hiddenColumns.update((hidden) =>\n visible ? hidden.filter((field) => field !== column.field) : [...hidden, column.field],\n );\n }\n\n /** Moves a column to the place of another column. */\n moveColumn(field: string, targetField: string): void {\n const fields = this.orderedColumns().map((column) => column.field);\n const from = fields.indexOf(field);\n const to = fields.indexOf(targetField);\n if (from < 0 || to < 0 || from === to) return;\n fields.splice(to, 0, ...fields.splice(from, 1));\n this.columnOrder.set(fields);\n }\n\n protected moveColumnBy(column: StarColumn<T>, delta: 1 | -1): void {\n const fields = this.orderedColumns().map((item) => item.field);\n const target = fields[fields.indexOf(column.field) + delta];\n if (!target) return;\n this.moveColumn(column.field, target);\n // The list in the Columns panel moves the button in the DOM, which drops the focus (and a\n // button at the end of the list becomes disabled). Keep the focus in the panel: on the same\n // button, or on the one for the other direction when that one is now disabled.\n this.focusMoveButton(column, delta);\n }\n\n /** Identifies a move button of the Columns panel, for `focusMoveButton`. */\n protected moveKey(column: StarColumn<T>, delta: 1 | -1): string {\n return `${this.radioName}|${column.field}|${delta}`;\n }\n\n private focusMoveButton(column: StarColumn<T>, delta: 1 | -1): void {\n afterNextRender(\n () => {\n // The panel is in the overlay container, not inside the table element.\n const button = (step: 1 | -1) =>\n this.document.querySelector<HTMLButtonElement>(\n `[data-move=\"${CSS.escape(this.moveKey(column, step))}\"]`,\n );\n const same = button(delta);\n (same && !same.disabled ? same : button(delta === 1 ? -1 : 1))?.focus();\n },\n { injector: this.injector },\n );\n }\n\n protected onDragStart(column: StarColumn<T>, event: DragEvent): void {\n if (this.resizing || !this.reorderableColumns()) {\n event.preventDefault();\n return;\n }\n this.dragField.set(column.field);\n event.dataTransfer?.setData('text/plain', column.field);\n if (event.dataTransfer) event.dataTransfer.effectAllowed = 'move';\n }\n\n protected onDragOver(column: StarColumn<T>, event: DragEvent): void {\n const field = this.dragField();\n if (!field || field === column.field) return;\n event.preventDefault();\n this.dropField.set(column.field);\n }\n\n protected onDrop(column: StarColumn<T>, event: DragEvent): void {\n const field = this.dragField();\n if (!field) return;\n event.preventDefault();\n this.moveColumn(field, column.field);\n this.endDrag();\n }\n\n protected endDrag(): void {\n this.dragField.set(null);\n this.dropField.set(null);\n }\n\n protected widthOf(column: StarColumn<T>): string | null {\n return this.resizedWidth(column) ?? column.width ?? null;\n }\n\n protected resizedWidth(column: StarColumn<T>): string | null {\n const width = this.columnWidths()[column.field];\n return width ? `${width}px` : null;\n }\n\n /** Rendered width in pixels of each frozen header cell, by column `field`. */\n private readonly frozenWidths = signal<Readonly<Record<string, number>>>({});\n /** Rendered width in pixels of each header cell, by column `field` (resizable tables only). */\n private readonly headerWidths = signal<Readonly<Record<string, number>>>({});\n /** The scroll area has content outside its box, so it must take the focus to scroll by key. */\n protected readonly scrollable = signal(false);\n protected readonly minColumnWidth = MIN_COLUMN_WIDTH;\n\n /** `aria-valuenow` of a resize handle: the width of the column in pixels. */\n protected resizeNow(column: StarColumn<T>): number | null {\n const width = this.columnWidths()[column.field] ?? this.headerWidths()[column.field];\n return width === undefined ? null : Math.round(width);\n }\n\n protected resizeMax(column: StarColumn<T>): number {\n return Math.max(MAX_COLUMN_WIDTH_HINT, this.resizeNow(column) ?? 0);\n }\n /** Counts up when the table element changes size, so the frozen columns are measured again. */\n private readonly resized = signal(0);\n\n /** Measures the frozen header cells after a render that can change their width. */\n private measureFrozen(): void {\n const frozen = this.visibleColumns().filter((column) => column.frozen);\n // Read what can change a width, so the effect runs again when it does.\n this.columnWidths();\n this.value();\n this.size();\n this.resized();\n const scroller = this.scroller()?.nativeElement;\n if (scroller) {\n this.scrollable.set(\n scroller.scrollWidth > scroller.clientWidth + 1 ||\n scroller.scrollHeight > scroller.clientHeight + 1,\n );\n }\n const resizable = this.resizableColumns();\n if (!frozen.length && !resizable) return;\n const widths: Record<string, number> = {};\n const all: Record<string, number> = {};\n for (const cell of this.host.nativeElement.querySelectorAll<HTMLElement>(\n 'thead th[data-field]',\n )) {\n const field = cell.dataset['field'];\n if (!field) continue;\n const width = cell.getBoundingClientRect().width;\n all[field] = width;\n if (frozen.some((column) => column.field === field)) widths[field] = width;\n }\n const sameWidths = (\n next: Readonly<Record<string, number>>,\n current: Readonly<Record<string, number>>,\n ) =>\n Object.keys(next).length === Object.keys(current).length &&\n Object.entries(next).every(\n ([field, width]) => Math.abs((current[field] ?? -1) - width) < 0.5,\n );\n if (!sameWidths(widths, untracked(this.frozenWidths))) this.frozenWidths.set(widths);\n if (resizable && !sameWidths(all, untracked(this.headerWidths))) this.headerWidths.set(all);\n }\n\n /**\n * Offset of a frozen column: the widths of the frozen columns before it. Uses the measured\n * widths; before the first measure (and where layout is not available) the declared widths.\n */\n protected frozenOffset(column: StarColumn<T>): string | null {\n if (!column.frozen) return null;\n const measured = this.frozenWidths();\n const before: string[] = [];\n let pixels = 0;\n let allMeasured = true;\n for (const item of this.visibleColumns()) {\n if (item === column) break;\n if (!item.frozen) continue;\n before.push(this.widthOf(item) ?? '0px');\n const width = measured[item.field];\n if (width) pixels += width;\n else allMeasured = false;\n }\n if (!before.length) return '0px';\n return allMeasured ? `${Math.round(pixels * 100) / 100}px` : `calc(${before.join(' + ')})`;\n }\n\n private setWidth(column: StarColumn<T>, width: number): void {\n const next = Math.max(MIN_COLUMN_WIDTH, Math.round(width));\n this.columnWidths.update((widths) => ({ ...widths, [column.field]: next }));\n }\n\n protected startResize(column: StarColumn<T>, event: PointerEvent): void {\n const handle = event.currentTarget as HTMLElement;\n const header = handle.closest('th');\n if (!header) return;\n event.preventDefault();\n event.stopPropagation();\n this.resizing = true;\n const direction = starIsRtl(header) ? -1 : 1;\n const startWidth = header.offsetWidth;\n const startX = event.clientX;\n handle.setPointerCapture?.(event.pointerId);\n const move = (moveEvent: PointerEvent) =>\n this.setWidth(column, startWidth + direction * (moveEvent.clientX - startX));\n const stop = () => {\n this.resizing = false;\n handle.removeEventListener('pointermove', move);\n handle.removeEventListener('pointerup', stop);\n handle.removeEventListener('pointercancel', stop);\n };\n handle.addEventListener('pointermove', move);\n handle.addEventListener('pointerup', stop);\n handle.addEventListener('pointercancel', stop);\n }\n\n protected onResizeKey(column: StarColumn<T>, event: KeyboardEvent): void {\n const step = event.key === 'ArrowRight' ? 16 : event.key === 'ArrowLeft' ? -16 : 0;\n if (!step) return;\n event.preventDefault();\n const header = (event.currentTarget as HTMLElement).closest('th');\n const direction = starIsRtl(header) ? -1 : 1;\n this.setWidth(\n column,\n (this.columnWidths()[column.field] ?? header?.offsetWidth ?? 0) + direction * step,\n );\n }\n\n protected editKey(row: T, column: StarColumn<T>): string {\n return `${String(this.trackKey(row))}|${column.field}`;\n }\n\n protected isEditable(row: T, column: StarColumn<T>): boolean {\n return typeof column.editable === 'function' ? column.editable(row) : !!column.editable;\n }\n\n protected isEditing(row: T, column: StarColumn<T>): boolean {\n return this.editing() === this.editKey(row, column);\n }\n\n /** Text in the editor: the raw value, so a formatted cell (date, currency) edits its data. */\n protected editText(row: T, column: StarColumn<T>): string {\n const value = this.cellValue(row, column);\n return value === null || value === undefined ? '' : String(value);\n }\n\n protected startEdit(row: T, column: StarColumn<T>): void {\n this.editing.set(this.editKey(row, column));\n this.focusAfterRender('.star-table__editor', true);\n }\n\n protected commitEdit(row: T, column: StarColumn<T>, text: string): void {\n // Enter removes the editor, which also fires `blur`: only the first event commits.\n if (!this.isEditing(row, column)) return;\n const previous = this.cellValue(row, column);\n const value = column.editor === 'number' ? (text.trim() === '' ? null : Number(text)) : text;\n this.closeEditor(row, column);\n if (typeof value === 'number' && Number.isNaN(value)) return;\n if (Object.is(value, previous) || (value === '' && (previous ?? '') === '')) return;\n this.cellEdit.emit({ row, field: column.field, value, previous });\n }\n\n protected cancelEdit(event: Event): void {\n event.stopPropagation();\n const key = this.editing();\n this.editing.set(null);\n if (key) this.focusAfterRender(`[data-edit=\"${CSS.escape(key)}\"]`);\n }\n\n private closeEditor(row: T, column: StarColumn<T>): void {\n const key = this.editKey(row, column);\n this.editing.set(null);\n this.focusAfterRender(`[data-edit=\"${CSS.escape(key)}\"]`);\n }\n\n private focusAfterRender(selector: string, select = false): void {\n afterNextRender(\n () => {\n const target = this.host.nativeElement.querySelector<HTMLElement>(selector);\n target?.focus();\n if (select && target instanceof HTMLInputElement && target.type === 'text') target.select();\n },\n { injector: this.injector },\n );\n }\n\n protected isExpanded(row: T): boolean {\n return this.expandedSet().has(this.trackKey(row));\n }\n\n protected detailId(index: number): string {\n return `${this.radioName}-detail-${index}`;\n }\n\n /** Opens or closes the detail of one row. */\n toggleExpansion(row: T): void {\n const key = this.trackKey(row);\n if (this.isExpanded(row)) {\n this.expandedKeys.update((keys) => keys.filter((expanded) => !Object.is(expanded, key)));\n } else {\n this.expandedKeys.update((keys) =>\n this.rowExpandMode() === 'single' ? [key] : [...keys, key],\n );\n }\n }\n\n /** Opens the detail of every row on the current page. */\n expandAll(): void {\n this.expandedKeys.set(this.pageRows().map((row) => this.trackKey(row)));\n }\n\n /** Closes every row detail. */\n collapseAll(): void {\n this.expandedKeys.set([]);\n }\n\n private matchesColumnFilter(row: T, column: StarColumn<T>, value: StarFilterValue): boolean {\n if (isRange(value)) {\n const raw = this.cellValue(row, column);\n if (column.filter === 'date') {\n const day = dayKey(raw);\n return (\n !!day &&\n (!hasBound(value.min) || day >= String(value.min)) &&\n (!hasBound(value.max) || day <= String(value.max))\n );\n }\n const amount = raw === null || raw === undefined || raw === '' ? NaN : Number(raw);\n return (\n !Number.isNaN(amount) &&\n (!hasBound(value.min) || amount >= Number(value.min)) &&\n (!hasBound(value.max) || amount <= Number(value.max))\n );\n }\n const text = this.cellText(row, column);\n if (typeof value !== 'string') return value.includes(text);\n return column.filter === 'select' ? text === value : matchesFilter(text, value);\n }\n\n protected filterValue(field: string): string {\n const value = this.filters()[field];\n return typeof value === 'string' ? value : '';\n }\n\n protected filterList(field: string): readonly string[] {\n const value = this.filters()[field];\n return Array.isArray(value) ? value : [];\n }\n\n protected filterBound(field: string, bound: 'min' | 'max'): string {\n const value = this.filters()[field];\n const side = isRange(value) ? value[bound] : null;\n return hasBound(side) ? String(side) : '';\n }\n\n protected setBound(column: StarColumn<T>, bound: 'min' | 'max', text: string): void {\n const current = this.filters()[column.field];\n const side = text === '' ? null : column.filter === 'number' ? Number(text) : text;\n this.setFilter(column.field, { ...(isRange(current) ? current : {}), [bound]: side });\n }\n\n protected filterChoices(column: StarColumn<T>): readonly string[] {\n if (column.filterOptions) return column.filterOptions;\n const texts = new Set(this.value().map((row) => this.cellText(row, column)));\n texts.delete('');\n return [...texts].sort((a, b) => compareValues(a, b));\n }\n\n protected setFilter(field: string, value: StarFilterValue): void {\n this.filters.update((filters) => ({ ...filters, [field]: value }));\n }\n\n /** Removes every column filter. */\n clearFilters(): void {\n this.filters.set({});\n }\n\n /** Columns and rows of an export: visible columns in display order, without `exportable: false`. */\n private exportData(options: StarExportOptions<T>): {\n readonly columns: readonly StarColumn<T>[];\n readonly rows: readonly T[];\n } {\n return {\n columns: this.visibleColumns().filter((column) => column.exportable !== false),\n rows: options.rows ?? (options.selectionOnly ? this.selection() : this.sorted()),\n };\n }\n\n /** Export text of a cell: `exportValue`, else the display text (`format` / `value`). */\n private exportText(row: T, column: StarColumn<T>): string {\n return column.exportValue ? String(column.exportValue(row) ?? '') : this.cellText(row, column);\n }\n\n /** A number cell stays a number in a spreadsheet when the column has no text format. */\n private exportCell(row: T, column: StarColumn<T>): StarExportCell {\n const custom = column.exportValue?.(row);\n if (typeof custom === 'number') return custom;\n const value = this.cellValue(row, column);\n return !column.exportValue && !column.format && typeof value === 'number'\n ? value\n : this.exportText(row, column);\n }\n\n /**\n * CSV text of the table: a header row, then the filtered rows in the current sort order\n * (all pages), or the selected rows, with the visible columns in display order. Cells use\n * the column `exportValue`, else the display text (`format` / `value`); custom cell\n * templates are not exported. In lazy mode only the loaded rows are available: pass all\n * rows with `options.rows`.\n *\n * Text that a spreadsheet would read as a formula (it starts with `=`, `+`, `-` or `@`)\n * gets a leading apostrophe, so exported user data cannot run as a formula.\n */\n toCsv(options: StarCsvOptions<T> = {}): string {\n const separator = options.separator ?? ',';\n const { columns, rows } = this.exportData(options);\n const escape = (text: string) =>\n text.includes(separator) || /[\"\\r\\n]/.test(text) ? `\"${text.replaceAll('\"', '\"\"')}\"` : text;\n const cell = (row: T, column: StarColumn<T>) => {\n const value = this.exportCell(row, column);\n const text = String(value);\n return escape(typeof value !== 'number' && /^[=+\\-@\\t\\r]/.test(text) ? `'${text}` : text);\n };\n return [\n columns.map((column) => escape(column.header)).join(separator),\n ...rows.map((row) => columns.map((column) => cell(row, column)).join(separator)),\n ].join('\\r\\n');\n }\n\n /** Downloads `toCsv()` as `<fileName>.csv` (UTF-8 with a byte order mark, for Excel). */\n exportCsv(options: StarCsvOptions<T> = {}): void {\n this.download(\n new Blob(['', this.toCsv(options)], { type: 'text/csv;charset=utf-8' }),\n `${options.fileName ?? 'export'}.csv`,\n );\n }\n\n /**\n * Excel workbook (`.xlsx`) bytes of the table: same columns and rows as `toCsv()`. Number\n * cells stay numbers; text cells are plain text, never formulas.\n */\n toXlsx(options: StarExportOptions<T> = {}): Uint8Array {\n const { columns, rows } = this.exportData(options);\n return buildXlsx(\n columns.map((column) => column.header),\n rows.map((row) => columns.map((column) => this.exportCell(row, column))),\n options.title ?? this.ariaLabel() ?? undefined,\n );\n }\n\n /** Downloads `toXlsx()` as `<fileName>.xlsx`. */\n exportExcel(options: StarExportOptions<T> = {}): void {\n const bytes = this.toXlsx(options);\n this.download(\n new Blob([bytes.buffer as ArrayBuffer], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n }),\n `${options.fileName ?? 'export'}.xlsx`,\n );\n }\n\n /**\n * Opens the browser print dialog with a plain table of the same columns and rows. The user\n * can print it or choose \"Save as PDF\". The table always fits the paper the user chooses: a\n * table that is too wide wraps its text, then gets smaller text (down to 6 pt), and last breaks\n * long words inside a cell. No column is cut off.\n */\n print(options: StarExportOptions<T> = {}): void {\n const { columns, rows } = this.exportData(options);\n const frame = this.document.createElement('iframe');\n frame.setAttribute('aria-hidden', 'true');\n frame.style.cssText = 'position:fixed;width:0;height:0;border:0;visibility:hidden';\n frame.srcdoc = buildPrintDocument(\n options.title ?? this.ariaLabel() ?? '',\n columns.map((column) => column.header),\n rows.map((row) => columns.map((column) => this.exportCell(row, column))),\n {\n // The column definition decides the alignment, not the type of the formatted text.\n align: columns.map((column) =>\n printColumnAlign(\n column.align,\n rows.map((row) => {\n const cell = this.exportCell(row, column);\n return typeof cell === 'number' ? cell : this.cellValue(row, column);\n }),\n ),\n ),\n ...printContext(this.host.nativeElement, this.document),\n },\n );\n frame.addEventListener('load', () => {\n const view = frame.contentWindow;\n if (!view) return;\n // The document has no style element and no style attribute, so that a policy without\n // 'unsafe-inline' in style-src does not unstyle it: the styles are constructed sheets.\n stylePrintDocument(view.document);\n // The paper is not known yet. The table gets the rules that wrap it, shrink its text or\n // break its words when the paper is too narrow, so that no column is cut off.\n fitPrintDocument(view.document);\n view.addEventListener('afterprint', () => frame.remove());\n view.focus();\n view.print();\n });\n this.document.body.append(frame);\n }\n\n private download(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob);\n const link = this.document.createElement('a');\n link.href = url;\n link.download = fileName;\n link.click();\n URL.revokeObjectURL(url);\n }\n\n /** Sorts by a column. With `multiSort`, `event.shiftKey` adds the column to the sort. */\n sortBy(column: StarColumn<T>, event?: MouseEvent | KeyboardEvent): void {\n const current = this.sorts().find((sort) => sort.field === column.field);\n const order: StarSortOrder = current ? (current.order === 1 ? -1 : 1) : 1;\n if (this.multiSort() && event?.shiftKey) {\n const sorts = this.sorts();\n this.sortMeta.set(\n current\n ? sorts.map((sort) => (sort.field === column.field ? { ...sort, order } : sort))\n : [...sorts, { field: column.field, order }],\n );\n } else {\n this.sortMeta.set(this.multiSort() ? [{ field: column.field, order }] : []);\n }\n // `sortField` / `sortOrder` always hold the first sort column.\n const first = this.multiSort() ? this.sortMeta()[0] : { field: column.field, order };\n this.sortField.set(first.field);\n this.sortOrder.set(first.order);\n this.first.set(0);\n this.emitLazy();\n }\n\n private sortOf(column: StarColumn<T>): StarSortState | undefined {\n return this.sorts().find((sort) => sort.field === column.field);\n }\n\n /** `aria-sort` goes on one column only: the first sort column. */\n protected ariaSort(column: StarColumn<T>): string | null {\n if (!column.sortable) return null;\n const first = this.sorts()[0];\n if (first?.field !== column.field) return 'none';\n return first.order === 1 ? 'ascending' : 'descending';\n }\n\n protected sortIcon(column: StarColumn<T>): string {\n const sort = this.sortOf(column);\n if (!sort) return 'ph-bold ph-arrows-down-up star-table__sort-idle';\n return sort.order === 1 ? 'ph-bold ph-sort-ascending' : 'ph-bold ph-sort-descending';\n }\n\n /** Position of a column in a sort by two or more columns, else `null`. */\n protected sortRank(column: StarColumn<T>): number | null {\n const sorts = this.sorts();\n if (sorts.length < 2) return null;\n const index = sorts.findIndex((sort) => sort.field === column.field);\n return index < 0 ? null : index + 1;\n }\n\n /** Keys of the selected rows: a look-up per row stays fast with 50,000 selected rows. */\n private readonly selectedKeys = computed(\n () => new Set(this.selection().map((row) => this.trackKey(row))),\n );\n\n protected isSelected(row: T): boolean {\n return this.selectedKeys().has(this.trackKey(row));\n }\n\n protected toggleRow(row: T): void {\n const key = this.trackKey(row);\n this.selection.update((selection) =>\n this.isSelected(row)\n ? selection.filter((selected) => !Object.is(this.trackKey(selected), key))\n : [...selection, row],\n );\n }\n\n protected selectOnly(row: T): void {\n this.selection.set([row]);\n }\n\n protected togglePage(checked: boolean): void {\n const page = this.pageRows();\n const keys = new Set(page.map((row) => this.trackKey(row)));\n this.selection.update((selection) => {\n const others = selection.filter((row) => !keys.has(this.trackKey(row)));\n return checked ? [...others, ...page] : others;\n });\n }\n\n protected onRowClick(row: T, event: MouseEvent): void {\n if ((event.target as HTMLElement).closest('button, a, input, select, textarea')) return;\n if (this.selectionMode() === 'single') this.selectOnly(row);\n this.rowClick.emit(row);\n }\n\n protected emitLazy(): void {\n if (!this.lazy()) return;\n this.lazyLoad.emit({\n first: this.first(),\n rows: this.rows(),\n field: this.sortField(),\n order: this.sortOrder(),\n filter: this.globalFilter(),\n filters: this.filters(),\n sorts: this.sorts(),\n });\n }\n}\n"],"mappings":"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"}
|