@lilydesignsystem/angular-data-grid 0.0.0-stage → 0.9.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/README.md +61 -2
- package/fesm2022/lilydesignsystem-angular-data-grid.mjs +3016 -0
- package/fesm2022/lilydesignsystem-angular-data-grid.mjs.map +1 -0
- package/package.json +47 -3
- package/types/lilydesignsystem-angular-data-grid.d.ts +811 -0
- package/types/lilydesignsystem-angular-data-grid.d.ts.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lilydesignsystem-angular-data-grid.mjs","names":[],"sources":["../../export-data.ts","../../cell-types.ts","../../data-grid.component.ts"],"sourcesContent":["// Table export for DataGrid: CSV, TSV and Excel (.xlsx), as pure functions.\n//\n// Nothing here knows about the grid. A table is a header row plus rows of\n// cell values, and every function turns one into text or bytes, so a consumer\n// who wants their own export button (or a server-side export) can call them\n// directly. DataGrid's own buttons are a thin layer on top.\n//\n// The .xlsx writer has no dependencies: a workbook is a ZIP of a few XML\n// parts, and the ZIP here only *stores* (no compression), which Excel,\n// LibreOffice, Numbers and Google Sheets all read. Entries carry a fixed\n// timestamp, so the same table always produces the same bytes.\n\nexport type ExportFormat = \"csv\" | \"tsv\" | \"xlsx\";\n\n/**\n * A live formula and the result it last computed. In an .xlsx the cell keeps the formula with the result cached\n * (a spreadsheet user keeps the live formula); CSV and TSV carry only the result.\n */\nexport type ExportFormula = { formula: string; result: unknown };\n\n/** Whether a cell value is an {@link ExportFormula}. */\nexport function isExportFormula(value: unknown): value is ExportFormula {\n return !!value && typeof value === \"object\" && !(value instanceof Date) && typeof (value as ExportFormula).formula === \"string\" && \"result\" in (value as object);\n}\n\n/** A header row and rows of cell values. A cell is a string, number, boolean, `Date`, an {@link ExportFormula}, or empty. */\nexport type ExportTable = {\n headers: string[];\n rows: unknown[][];\n};\n\nexport type DelimitedOptions = {\n /** Field separator. Default `\",\"` (use `\"\\t\"` for TSV). */\n delimiter?: string;\n /** Write the header row. Default true. */\n header?: boolean;\n /** Prefix a UTF-8 byte-order mark so Excel opens the file as UTF-8. Default false. */\n bom?: boolean;\n /** Defuse spreadsheet formulas: a string starting with `=`, `+`, `-`, `@`, tab or CR gets a leading `'`. Default true. */\n safe?: boolean;\n /** Line ending. Default `\"\\r\\n\"` (RFC 4180). */\n eol?: string;\n};\n\nexport type XlsxOptions = {\n /** Worksheet name (31 characters at most; `[]:*?/\\` are replaced). Default `\"Sheet1\"`. */\n sheetName?: string;\n /** Write the header row, in bold. Default true. */\n header?: boolean;\n};\n\nexport const MIME_TYPES: Record<ExportFormat, string> = {\n csv: \"text/csv;charset=utf-8\",\n tsv: \"text/tab-separated-values;charset=utf-8\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n};\n\n// ---------------------------------------------------------------------\n// Delimited text (CSV / TSV)\n// ---------------------------------------------------------------------\n\nconst FORMULA_START = /^[=+\\-@\\t\\r]/;\n\n/** One cell as text. Numbers and booleans are never treated as formulas; only strings are defused. */\nexport function cellText(value: unknown, safe = true): string {\n if (value === null || value === undefined) return \"\";\n if (isExportFormula(value)) return cellText(value.result, safe);\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return \"\";\n // A date at exactly UTC midnight is a civil date: write it without a time of day.\n const iso = value.toISOString();\n return iso.endsWith(\"T00:00:00.000Z\") ? iso.slice(0, 10) : iso;\n }\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"\";\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n const text = String(value);\n return safe && FORMULA_START.test(text) ? `'${text}` : text;\n}\n\nfunction quoteField(text: string, delimiter: string): string {\n return text.includes(delimiter) || /[\"\\r\\n]/.test(text) ? `\"${text.replace(/\"/g, '\"\"')}\"` : text;\n}\n\n/** CSV/TSV text for a table. Fields containing the delimiter, a quote or a line break are quoted. */\nexport function toDelimited(table: ExportTable, options: DelimitedOptions = {}): string {\n const { delimiter = \",\", header = true, bom = false, safe = true, eol = \"\\r\\n\" } = options;\n const lines: string[] = [];\n if (header) lines.push(table.headers.map((h) => quoteField(cellText(h, safe), delimiter)).join(delimiter));\n for (const row of table.rows) {\n lines.push(table.headers.map((_, i) => quoteField(cellText(row[i], safe), delimiter)).join(delimiter));\n }\n return (bom ? \"\" : \"\") + lines.join(eol) + (lines.length > 0 ? eol : \"\");\n}\n\nexport function toCsv(table: ExportTable, options: Omit<DelimitedOptions, \"delimiter\"> = {}): string {\n return toDelimited(table, { ...options, delimiter: \",\" });\n}\n\nexport function toTsv(table: ExportTable, options: Omit<DelimitedOptions, \"delimiter\"> = {}): string {\n return toDelimited(table, { ...options, delimiter: \"\\t\" });\n}\n\n// ---------------------------------------------------------------------\n// Excel (.xlsx)\n// ---------------------------------------------------------------------\n\nconst encoder = new TextEncoder();\n\n/** XML text with the characters XML 1.0 forbids removed. */\nfunction xmlEscape(text: string): string {\n return text\n .replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g, \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\n/** Column index (0-based) to a spreadsheet column name: 0 → A, 25 → Z, 26 → AA. */\nexport function columnName(index: number): string {\n let n = index;\n let name = \"\";\n do {\n name = String.fromCharCode(65 + (n % 26)) + name;\n n = Math.floor(n / 26) - 1;\n } while (n >= 0);\n return name;\n}\n\n/** Days since 1899-12-30 (Excel's day 0, with its 1900 leap-year quirk absorbed), with the time of day as a fraction. */\nfunction excelSerial(date: Date): number {\n return date.getTime() / 86_400_000 + 25_569;\n}\n\nfunction sheetNameFor(name: string): string {\n const cleaned = name.replace(/[[\\]:*?/\\\\]/g, \" \").replace(/\\s+/g, \" \").trim().slice(0, 31);\n return cleaned || \"Sheet1\";\n}\n\n// Cell styles: 0 default, 1 date, 2 date and time, 3 bold (headers).\nconst STYLES_XML =\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"yyyy\\\\-mm\\\\-dd\"/><numFmt numFmtId=\"165\" formatCode=\"yyyy\\\\-mm\\\\-dd\\\\ hh:mm:ss\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n \"</cellXfs>\" +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n \"</styleSheet>\";\n\n/** A formula cell: the expression (without its leading `=`) and the result it last computed, cached. */\nfunction formulaXml(ref: string, value: ExportFormula): string {\n const expression = xmlEscape(value.formula.replace(/^=/, \"\"));\n const result = value.result;\n if (typeof result === \"number\" && Number.isFinite(result)) return `<c r=\"${ref}\"><f>${expression}</f><v>${result}</v></c>`;\n if (typeof result === \"boolean\") return `<c r=\"${ref}\" t=\"b\"><f>${expression}</f><v>${result ? 1 : 0}</v></c>`;\n if (result instanceof Date && !Number.isNaN(result.getTime())) {\n const timeOfDay = result.getTime() % 86_400_000 !== 0;\n return `<c r=\"${ref}\" s=\"${timeOfDay ? 2 : 1}\"><f>${expression}</f><v>${excelSerial(result)}</v></c>`;\n }\n if (result === null || result === undefined) return `<c r=\"${ref}\"><f>${expression}</f></c>`;\n return `<c r=\"${ref}\" t=\"str\"><f>${expression}</f><v>${xmlEscape(String(result))}</v></c>`;\n}\n\nfunction cellXml(ref: string, value: unknown, headerStyle = false): string {\n if (value === null || value === undefined) return \"\";\n if (isExportFormula(value)) return formulaXml(ref, value);\n const s = headerStyle ? ' s=\"3\"' : \"\";\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) return \"\";\n const timeOfDay = value.getTime() % 86_400_000 !== 0;\n return `<c r=\"${ref}\" s=\"${timeOfDay ? 2 : 1}\"><v>${excelSerial(value)}</v></c>`;\n }\n if (typeof value === \"number\") return Number.isFinite(value) ? `<c r=\"${ref}\"${s}><v>${value}</v></c>` : \"\";\n if (typeof value === \"boolean\") return `<c r=\"${ref}\"${s} t=\"b\"><v>${value ? 1 : 0}</v></c>`;\n // A string is stored as text, so it is never read as a formula.\n return `<c r=\"${ref}\"${s} t=\"inlineStr\"><is><t xml:space=\"preserve\">${xmlEscape(String(value))}</t></is></c>`;\n}\n\nfunction sheetXml(table: ExportTable, header: boolean): string {\n const rows: string[] = [];\n let rowNumber = 0;\n if (header) {\n rowNumber += 1;\n rows.push(\n `<row r=\"${rowNumber}\">${table.headers.map((h, i) => cellXml(`${columnName(i)}${rowNumber}`, h, true)).join(\"\")}</row>`,\n );\n }\n for (const row of table.rows) {\n rowNumber += 1;\n const cells = table.headers.map((_, i) => cellXml(`${columnName(i)}${rowNumber}`, row[i])).join(\"\");\n rows.push(`<row r=\"${rowNumber}\">${cells}</row>`);\n }\n return (\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n (header && table.headers.length > 0 ? '<sheetViews><sheetView workbookViewId=\"0\"><pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/></sheetView></sheetViews>' : \"\") +\n `<sheetData>${rows.join(\"\")}</sheetData></worksheet>`\n );\n}\n\n/** An .xlsx workbook with one worksheet, as bytes. */\nexport function toXlsx(table: ExportTable, options: XlsxOptions = {}): Uint8Array {\n const { sheetName = \"Sheet1\", header = true } = options;\n const files: Record<string, string> = {\n \"[Content_Types].xml\":\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n \"</Types>\",\n \"_rels/.rels\":\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n \"</Relationships>\",\n \"xl/workbook.xml\":\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${xmlEscape(sheetNameFor(sheetName))}\" sheetId=\"1\" r:id=\"rId1\"/></sheets></workbook>`,\n \"xl/_rels/workbook.xml.rels\":\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n \"</Relationships>\",\n \"xl/styles.xml\": STYLES_XML,\n \"xl/worksheets/sheet1.xml\": sheetXml(table, header),\n };\n return zipStore(Object.entries(files).map(([name, text]) => ({ name, data: encoder.encode(text) })));\n}\n\n// ---------------------------------------------------------------------\n// ZIP (store only)\n// ---------------------------------------------------------------------\n\nlet crcTable: Uint32Array | undefined;\n\nexport function 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 (let i = 0; i < bytes.length; i++) crc = crcTable[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n// 1980-01-01 00:00:00, the ZIP epoch: a fixed stamp keeps the output reproducible.\nconst DOS_TIME = 0x0000;\nconst DOS_DATE = 0x0021;\n\n/** A ZIP archive holding `entries` uncompressed. */\nexport function zipStore(entries: { name: string; data: Uint8Array }[]): Uint8Array {\n const parts: Uint8Array[] = [];\n const central: Uint8Array[] = [];\n let offset = 0;\n for (const { name, data } of entries) {\n const nameBytes = encoder.encode(name);\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); // flags: UTF-8 names\n local.setUint16(8, 0, true); // method: stored\n local.setUint16(10, DOS_TIME, true);\n local.setUint16(12, DOS_DATE, true);\n local.setUint32(14, crc, true);\n local.setUint32(18, data.length, true);\n local.setUint32(22, data.length, true);\n local.setUint16(26, nameBytes.length, true);\n local.setUint16(28, 0, true);\n parts.push(new Uint8Array(local.buffer), nameBytes, data);\n\n const entry = new DataView(new ArrayBuffer(46));\n entry.setUint32(0, 0x02014b50, true);\n entry.setUint16(4, 20, true); // version made by\n entry.setUint16(6, 20, true); // version needed\n entry.setUint16(8, 0x0800, true);\n entry.setUint16(10, 0, true);\n entry.setUint16(12, DOS_TIME, true);\n entry.setUint16(14, DOS_DATE, 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, nameBytes.length, true);\n entry.setUint32(42, offset, true);\n central.push(new Uint8Array(entry.buffer), nameBytes);\n\n offset += 30 + nameBytes.length + data.length;\n }\n const centralSize = central.reduce((n, p) => n + p.length, 0);\n const end = new DataView(new ArrayBuffer(22));\n end.setUint32(0, 0x06054b50, true);\n end.setUint16(8, entries.length, true);\n end.setUint16(10, entries.length, true);\n end.setUint32(12, centralSize, true);\n end.setUint32(16, offset, true);\n const all = [...parts, ...central, new Uint8Array(end.buffer)];\n const out = new Uint8Array(all.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of all) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\n\n// ---------------------------------------------------------------------\n// Files\n// ---------------------------------------------------------------------\n\n/** The file for `table` in `format`, as a `Blob`. CSV and TSV carry a UTF-8 byte-order mark so Excel reads them as UTF-8. */\nexport function exportBlob(table: ExportTable, format: ExportFormat, options: { sheetName?: string; header?: boolean } = {}): Blob {\n if (format === \"xlsx\") return new Blob([toXlsx(table, options) as BlobPart], { type: MIME_TYPES.xlsx });\n const text = toDelimited(table, { delimiter: format === \"tsv\" ? \"\\t\" : \",\", header: options.header, bom: true });\n return new Blob([text], { type: MIME_TYPES[format] });\n}\n\n/** A filename with the format's extension, without doubling one the name already has. */\nexport function exportFilename(base: string, format: ExportFormat): string {\n const cleaned = base.replace(/[\\\\/:*?\"<>|\\u0000-\\u001F]/g, \"-\").trim() || \"export\";\n return cleaned.toLowerCase().endsWith(`.${format}`) ? cleaned : `${cleaned}.${format}`;\n}\n\n/** Saves a blob through a temporary link. Does nothing outside a browser. */\nexport function downloadBlob(blob: Blob, filename: string): void {\n if (typeof document === \"undefined\" || typeof URL === \"undefined\" || !URL.createObjectURL) return;\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n // Revoking at once can cancel the download in some browsers.\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n","// Cell types for DataGrid: a `column.type` is a named bundle of defaults for the\n// hooks a column already has (`format`, `compare`, `filterText`, `exportValue`,\n// `align`, `editor`). Nothing here is new machinery: `resolveColumn` fills in\n// what the column left out, and a column's own props always win.\n//\n// Values are plain data. Display is derived: no English, no default locale (with\n// no `locale` a value shows as stored), no HTML, no icons. See\n// spec/cell-types/index.md.\n\nexport type DataGridCellType =\n | \"text\"\n | \"number\"\n | \"link\"\n | \"date\"\n | \"time\"\n | \"time-zone\"\n | \"select\"\n | \"radio\"\n | \"person\"\n | \"file\"\n | \"rollup\"\n | \"formula\";\n\n/** A time of day and the zone it is stated in (an IANA zone id, or a bare offset such as `+01:00`). */\nexport type DataGridZonedTime = { time: string; timeZone: string };\n\n/** One person: the name is always shown as text; the avatar is the consumer's. */\nexport type DataGridPerson = { id: string; name?: string; email?: string; avatarUrl?: string };\n\n/** One file's metadata. The bytes live elsewhere; the grid never uploads. */\nexport type DataGridFile = { id: string; name: string; size?: number; type?: string; href?: string };\n\n/** What a rollup reduces its related values with. */\nexport type DataGridAggregate =\n | \"count\"\n | \"countUnique\"\n | \"sum\"\n | \"avg\"\n | \"median\"\n | \"min\"\n | \"max\"\n | \"range\"\n | \"percentTrue\"\n | \"percentEmpty\";\n\n/** What a formula engine hands back: a value, or an error message shown as text. */\nexport type DataGridFormulaResult = { value: unknown } | { error: string };\n\n/** What a formula engine is given. `rows` is every row, for references to other rows. */\nexport type DataGridFormulaContext = { row: Record<string, unknown>; rows: Record<string, unknown>[]; columnId: string };\n\n/** An option of a `select` or `radio` column. The label is displayed; the id is stored. */\nexport type DataGridOption = { id: string; label: string; disabled?: boolean; group?: string; [key: string]: unknown };\n\n/** A link value: an address, or an address with a label. */\nexport type DataGridLink = { href: string; label?: string; external?: boolean };\n\n/** The column facets a type can fill in. Structural so this module does not import the grid. */\nexport type TypedColumn = {\n id: string;\n type?: DataGridCellType;\n locale?: string;\n options?: DataGridOption[];\n sortBy?: \"label\" | \"order\";\n exportAs?: \"label\" | \"id\" | \"email\";\n numberFormat?: Intl.NumberFormatOptions;\n dateFormat?: Intl.DateTimeFormatOptions;\n timeFormat?: Intl.DateTimeFormatOptions;\n accessor?: (row: Record<string, unknown>) => unknown;\n format?: (value: unknown, row: Record<string, unknown>) => string;\n compare?: (a: unknown, b: unknown) => number;\n filterText?: (value: unknown, row: Record<string, unknown>) => string;\n exportValue?: (row: Record<string, unknown>) => unknown;\n align?: \"start\" | \"center\" | \"end\";\n editor?: string;\n parse?: (draft: string, row: Record<string, unknown>) => unknown;\n editable?: boolean;\n /** `time-zone`: the zones the editor offers, as `{ id, label }`. */\n timeZones?: DataGridOption[];\n /** `time-zone`: the date (ISO) used to order zoned times and to name a zone. Never computed here. */\n referenceDate?: string;\n /** `rollup`: how the related values are reduced. */\n aggregate?: DataGridAggregate;\n /** `rollup`: anything the named aggregates do not cover. */\n reduce?: (values: unknown[], row: Record<string, unknown>) => unknown;\n /** `rollup`: reads the related values. Defaults to the row's own array at the column id. */\n relation?: (row: Record<string, unknown>) => unknown[];\n /** `rollup` and `formula`: the type of the result, so it formats and sorts like one. */\n resultType?: \"number\" | \"date\" | \"text\";\n /** `formula`: evaluates an expression. Lily ships no engine and never evaluates a string itself. */\n evaluate?: (expression: string, context: DataGridFormulaContext) => DataGridFormulaResult;\n /** `person`: how many people show before \"+N\". */\n maxPeople?: number;\n /** `file`: formats a size in bytes for display. */\n formatSize?: (bytes: number) => string;\n /** Set by `resolveColumn` for a `formula`: the expression the row holds (the editor shows this, not the result). */\n source?: (row: Record<string, unknown>) => unknown;\n /** Set by `resolveColumn` for a `formula`: the error message for a row, or undefined. */\n errorOf?: (row: Record<string, unknown>) => string | undefined;\n};\n\nconst SAFE_SCHEME = /^(https?:|mailto:|tel:)/i;\nconst RELATIVE = /^(\\/(?!\\/)|\\.\\.?\\/|#|\\?)/;\n\n/** An address safe to put in an `href`: http(s), mailto, tel, or a relative one. Anything else (`javascript:`, `data:`) is null. */\nexport function safeHref(href: unknown): string | null {\n if (typeof href !== \"string\") return null;\n const text = href.trim();\n if (!text) return null;\n // Control characters are stripped by browsers when reading a scheme, so they cannot be allowed to hide one.\n // eslint-disable-next-line no-control-regex\n if (/[\\u0000-\\u001F\\u007F]/.test(text)) return null;\n return SAFE_SCHEME.test(text) || RELATIVE.test(text) ? text : null;\n}\n\n/** A link value as `{ href, label?, external? }`; a plain string is the address. */\nexport function linkParts(value: unknown): DataGridLink | null {\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value === \"string\") return { href: value };\n if (typeof value === \"object\" && typeof (value as DataGridLink).href === \"string\") return value as DataGridLink;\n return null;\n}\n\nexport function linkLabel(value: unknown): string {\n const link = linkParts(value);\n return link ? (link.label ?? link.href) : \"\";\n}\n\n/** A civil date `YYYY-MM-DD` that exists on the calendar. */\nexport function isCivilDate(text: unknown): text is string {\n if (typeof text !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(text)) return false;\n const [y, m, d] = text.split(\"-\").map(Number);\n const date = new Date(Date.UTC(y, m - 1, d));\n return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d;\n}\n\n/** A civil time `HH:mm` or `HH:mm:ss`, 24-hour. */\nexport function isCivilTime(text: unknown): text is string {\n if (typeof text !== \"string\") return false;\n const match = /^(\\d{2}):(\\d{2})(?::(\\d{2}))?$/.exec(text);\n return !!match && Number(match[1]) < 24 && Number(match[2]) < 60 && (match[3] === undefined || Number(match[3]) < 60);\n}\n\n/** A civil date as a `Date` at UTC midnight, or null. Typed, so an export writes a real spreadsheet date. */\nexport function civilDateToDate(text: unknown): Date | null {\n if (text instanceof Date) return Number.isNaN(text.getTime()) ? null : text;\n return isCivilDate(text) ? new Date(`${text}T00:00:00Z`) : null;\n}\n\nconst isEmpty = (value: unknown) => value === null || value === undefined || value === \"\";\n\nconst OFFSET = /^([+-])(\\d{2}):?(\\d{2})$/;\n\n/** The zone's offset from UTC, in minutes, at an instant. A bare offset (`+01:00`) is its own answer. Null when the zone is unknown. */\nfunction zoneOffsetMinutes(timeZone: string, instantMs: number): number | null {\n const bare = OFFSET.exec(timeZone);\n if (bare) return (bare[1] === \"-\" ? -1 : 1) * (Number(bare[2]) * 60 + Number(bare[3]));\n try {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hourCycle: \"h23\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n }).formatToParts(new Date(instantMs));\n const n = (type: string) => Number(parts.find((x) => x.type === type)?.value);\n const local = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\") % 24, n(\"minute\"), n(\"second\"));\n return (local - Math.floor(instantMs / 1000) * 1000) / 60000;\n } catch {\n return null;\n }\n}\n\n/** An IANA zone id the platform knows, or a bare offset such as `+01:00`. */\nexport function isValidTimeZone(timeZone: unknown): timeZone is string {\n return typeof timeZone === \"string\" && timeZone !== \"\" && zoneOffsetMinutes(timeZone, 0) !== null;\n}\n\n/** A zoned time: `{ time: \"HH:mm[:ss]\", timeZone }` with a real time and a known zone. */\nexport function isZonedTime(value: unknown): value is DataGridZonedTime {\n return !!value && typeof value === \"object\" && isCivilTime((value as DataGridZonedTime).time) && isValidTimeZone((value as DataGridZonedTime).timeZone);\n}\n\n/**\n * A zoned time as a number for ordering. With a `referenceDate` (ISO, supplied by the consumer: never computed here)\n * it is the UTC minute of that instant, so equal instants compare equal; without one it is the stated local time and\n * the zone is ignored.\n */\nexport function zonedMinutes(value: unknown, referenceDate?: string): number | null {\n if (!isZonedTime(value)) return null;\n const [h, m, sec] = value.time.split(\":\").map(Number);\n const local = h * 60 + m + (sec || 0) / 60;\n if (!referenceDate || !isCivilDate(referenceDate)) return local;\n const [y, mo, d] = referenceDate.split(\"-\").map(Number);\n const guess = Date.UTC(y, mo - 1, d, h, m, sec || 0);\n const offset = zoneOffsetMinutes(value.timeZone, guess);\n if (offset === null) return local;\n return guess / 60000 - offset;\n}\n\n/** A zoned time as the UTC time of day (`HH:mm`) at a reference date. Null without a valid reference date or value. */\nexport function zonedUtcTime(value: unknown, referenceDate?: string): string | null {\n if (!referenceDate || !isCivilDate(referenceDate)) return null;\n const minutes = zonedMinutes(value, referenceDate);\n if (minutes === null) return null;\n const day = ((Math.round(minutes) % 1440) + 1440) % 1440;\n return `${String(Math.floor(day / 60)).padStart(2, \"0\")}:${String(day % 60).padStart(2, \"0\")}`;\n}\n\n/** The zone as text: its short name (`BST`) when there is a locale and a reference date, else the zone id as given. */\nfunction zoneLabel(timeZone: string, locale: string | undefined, referenceDate: string | undefined): string {\n if (!locale || !referenceDate || !isCivilDate(referenceDate) || OFFSET.test(timeZone)) return timeZone;\n try {\n const parts = new Intl.DateTimeFormat(locale, { timeZone, timeZoneName: \"short\" }).formatToParts(new Date(`${referenceDate}T12:00:00Z`));\n return parts.find((x) => x.type === \"timeZoneName\")?.value ?? timeZone;\n } catch {\n return timeZone;\n }\n}\n\n/** The people in a value: one object or an array, each with an id. */\nexport function peopleOf(value: unknown): DataGridPerson[] {\n const list = Array.isArray(value) ? value : isEmpty(value) ? [] : [value];\n return list.filter((p): p is DataGridPerson => !!p && typeof p === \"object\" && typeof (p as DataGridPerson).id === \"string\");\n}\n\n/** A person's text: the name, or the id when there is none (never blank). */\nexport const personName = (person: DataGridPerson): string => (person.name ? person.name : person.id);\n\n/** The files in a value: an array of `{ id, name, … }`. */\nexport function filesOf(value: unknown): DataGridFile[] {\n return (Array.isArray(value) ? value : []).filter((f): f is DataGridFile => !!f && typeof f === \"object\" && typeof (f as DataGridFile).id === \"string\" && typeof (f as DataGridFile).name === \"string\");\n}\n\n/** Reduces related values to one result. An empty set is empty (null), not 0, except `count`. */\nexport function aggregateValues(kind: DataGridAggregate, values: unknown[]): unknown {\n const present = values.filter((v) => !isEmpty(v));\n const numbers = present.filter((v): v is number => typeof v === \"number\" && Number.isFinite(v));\n switch (kind) {\n case \"count\":\n return values.length;\n case \"countUnique\":\n return present.length === 0 ? null : new Set(present.map((v) => (typeof v === \"object\" ? JSON.stringify(v) : String(v)))).size;\n case \"sum\":\n return numbers.length === 0 ? null : numbers.reduce((a, b) => a + b, 0);\n case \"avg\":\n return numbers.length === 0 ? null : numbers.reduce((a, b) => a + b, 0) / numbers.length;\n case \"median\": {\n if (numbers.length === 0) return null;\n const sorted = numbers.slice().sort((a, b) => a - b);\n const mid = sorted.length >> 1;\n return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;\n }\n case \"min\":\n case \"max\": {\n const pool = numbers.length === present.length ? numbers : present.filter((v): v is string => typeof v === \"string\");\n if (pool.length === 0) return null;\n return (pool as (number | string)[]).reduce((a, b) => ((kind === \"min\" ? b < a : b > a) ? b : a));\n }\n case \"range\":\n return numbers.length === 0 ? null : Math.max(...numbers) - Math.min(...numbers);\n case \"percentTrue\": {\n const booleans = values.filter((v): v is boolean => typeof v === \"boolean\");\n return booleans.length === 0 ? null : (booleans.filter(Boolean).length / booleans.length) * 100;\n }\n case \"percentEmpty\":\n return values.length === 0 ? null : ((values.length - present.length) / values.length) * 100;\n }\n}\n\n/** Whether a (parsed) value is unacceptable for the column's type; the grid refuses the edit. Empty is always acceptable. */\nexport function isInvalidForType(column: TypedColumn, value: unknown): boolean {\n if (isEmpty(value)) return false;\n switch (column.type) {\n case \"number\":\n return typeof value !== \"number\" || !Number.isFinite(value);\n case \"link\":\n return safeHref(linkParts(value)?.href) === null;\n case \"date\":\n return !isCivilDate(value);\n case \"time\":\n return !isCivilTime(value);\n case \"time-zone\":\n return !isZonedTime(value);\n case \"select\":\n case \"radio\":\n return !(column.options ?? []).some((o) => o.id === value);\n case \"person\":\n return peopleOf(value).length === 0;\n default:\n return false;\n }\n}\n\nconst optionLabel = (column: TypedColumn, id: unknown): string => {\n const found = (column.options ?? []).find((o) => o.id === id);\n return found ? found.label : isEmpty(id) ? \"\" : String(id);\n};\n\n/** Formats a result by its declared type, so a rollup or formula of dates reads like a date. */\nfunction resultFormatter(column: TypedColumn, locale: string | undefined): (value: unknown) => string {\n const type = column.resultType ?? \"text\";\n if (type === \"number\") {\n const formatter = locale || column.numberFormat ? new Intl.NumberFormat(locale, column.numberFormat) : null;\n return (v) => (typeof v === \"number\" && Number.isFinite(v) ? (formatter ? formatter.format(v) : String(v)) : isEmpty(v) ? \"\" : String(v));\n }\n if (type === \"date\") {\n const formatter = locale || column.dateFormat ? new Intl.DateTimeFormat(locale, { dateStyle: \"medium\", ...column.dateFormat, timeZone: \"UTC\" }) : null;\n return (v) => {\n if (isEmpty(v)) return \"\";\n const date = civilDateToDate(v);\n return date ? (formatter ? formatter.format(date) : date.toISOString().slice(0, 10)) : String(v);\n };\n }\n return (v) => (isEmpty(v) ? \"\" : String(v));\n}\n\n/** Defaults a `type` gives its column. Anything the column sets itself replaces the matching default. */\nfunction typeDefaults(column: TypedColumn, gridLocale: string | undefined): Partial<TypedColumn> {\n const locale = column.locale ?? gridLocale;\n switch (column.type) {\n case \"text\":\n return {\n align: \"start\",\n editor: \"text\",\n ...(locale ? { compare: (a, b) => new Intl.Collator(locale).compare(String(a), String(b)) } : {}),\n };\n case \"number\": {\n const formatter = locale || column.numberFormat ? new Intl.NumberFormat(locale, column.numberFormat) : null;\n return {\n align: \"end\",\n editor: \"number\",\n ...(formatter ? { format: (v) => (typeof v === \"number\" && Number.isFinite(v) ? formatter.format(v) : \"\") } : {}),\n };\n }\n case \"link\":\n return {\n align: \"start\",\n editor: \"link\",\n format: (v) => linkLabel(v),\n filterText: (v) => {\n const link = linkParts(v);\n return link ? `${link.label ?? \"\"} ${link.href}`.trim() : \"\";\n },\n compare: (a, b) => {\n const x = linkLabel(a);\n const y = linkLabel(b);\n return locale ? new Intl.Collator(locale).compare(x, y) : x < y ? -1 : x > y ? 1 : 0;\n },\n exportValue: (row) => linkLabel(column.accessor ? column.accessor(row) : row[column.id]),\n parse: (draft, row) => {\n const previous = linkParts(column.accessor ? column.accessor(row) : row[column.id]);\n const href = draft.trim();\n if (!href) return null;\n return previous && typeof previous === \"object\" && (previous.label !== undefined || previous.external !== undefined)\n ? { ...previous, href }\n : href;\n },\n };\n case \"date\": {\n const formatter = locale || column.dateFormat\n ? new Intl.DateTimeFormat(locale, { dateStyle: \"medium\", ...column.dateFormat, timeZone: \"UTC\" })\n : null;\n return {\n align: \"start\",\n editor: \"date\",\n format: (v) => {\n if (isEmpty(v)) return \"\";\n const date = civilDateToDate(v);\n if (!date) return String(v);\n return formatter ? formatter.format(date) : date.toISOString().slice(0, 10);\n },\n exportValue: (row) => civilDateToDate(column.accessor ? column.accessor(row) : row[column.id]),\n };\n }\n case \"time\": {\n const formatter = locale || column.timeFormat\n ? new Intl.DateTimeFormat(locale, { timeStyle: \"short\", ...column.timeFormat, timeZone: \"UTC\" })\n : null;\n return {\n align: \"start\",\n editor: \"time\",\n format: (v) => {\n if (isEmpty(v)) return \"\";\n if (!isCivilTime(v)) return String(v);\n return formatter ? formatter.format(new Date(`1970-01-01T${v.length === 5 ? `${v}:00` : v}Z`)) : v;\n },\n };\n }\n case \"time-zone\": {\n const formatter = locale || column.timeFormat\n ? new Intl.DateTimeFormat(locale, { timeStyle: \"short\", ...column.timeFormat, timeZone: \"UTC\" })\n : null;\n const text = (v: unknown) => {\n if (isEmpty(v)) return \"\";\n if (!isZonedTime(v)) return String(v);\n const time = formatter ? formatter.format(new Date(`1970-01-01T${v.time.length === 5 ? `${v.time}:00` : v.time}Z`)) : v.time;\n return `${time} ${zoneLabel(v.timeZone, locale, column.referenceDate)}`;\n };\n return {\n align: \"start\",\n editor: \"time-zone\",\n format: text,\n compare: (a, b) => (zonedMinutes(a, column.referenceDate) ?? 0) - (zonedMinutes(b, column.referenceDate) ?? 0),\n exportValue: (row) => {\n const v = column.accessor ? column.accessor(row) : row[column.id];\n return isZonedTime(v) ? `${v.time} ${v.timeZone}` : null;\n },\n };\n }\n case \"person\": {\n const names = (v: unknown) => peopleOf(v).map(personName);\n const collator = locale ? new Intl.Collator(locale) : null;\n const order = (a: string, b: string) => (collator ? collator.compare(a, b) : a < b ? -1 : a > b ? 1 : 0);\n return {\n align: \"start\",\n editor: \"person\",\n format: (v) => names(v).join(\"; \"),\n filterText: (v) => peopleOf(v).map((p) => `${personName(p)} ${p.email ?? \"\"}`.trim()).join(\" \"),\n compare: (a, b) => {\n const x = names(a);\n const y = names(b);\n return order(x[0] ?? \"\", y[0] ?? \"\") || x.length - y.length;\n },\n exportValue: (row) => {\n const value = column.accessor ? column.accessor(row) : row[column.id];\n const parts = column.exportAs === \"email\" ? peopleOf(value).map((p) => p.email ?? \"\") : names(value);\n const joined = parts.join(\"; \");\n return joined.replace(/[;\\s]/g, \"\") === \"\" ? null : joined;\n },\n };\n }\n case \"file\": {\n const names = (v: unknown) => filesOf(v).map((f) => f.name);\n const collator = locale ? new Intl.Collator(locale) : null;\n const order = (a: string, b: string) => (collator ? collator.compare(a, b) : a < b ? -1 : a > b ? 1 : 0);\n return {\n align: \"start\",\n format: (v) => names(v).join(\"; \"),\n filterText: (v) => names(v).join(\" \"),\n compare: (a, b) => {\n const x = names(a);\n const y = names(b);\n return order(x[0] ?? \"\", y[0] ?? \"\") || x.length - y.length;\n },\n exportValue: (row) => {\n const joined = names(column.accessor ? column.accessor(row) : row[column.id]).join(\"; \");\n return joined === \"\" ? null : joined;\n },\n };\n }\n case \"select\":\n case \"radio\": {\n const order = new Map((column.options ?? []).map((o, i) => [o.id, i]));\n return {\n align: \"start\",\n editor: column.type === \"select\" ? \"select\" : \"radio\",\n format: (v) => optionLabel(column, v),\n filterText: (v) => optionLabel(column, v),\n compare:\n column.type === \"radio\" || column.sortBy === \"order\"\n ? (a, b) => (order.get(a as string) ?? Infinity) - (order.get(b as string) ?? Infinity)\n : (a, b) =>\n locale\n ? new Intl.Collator(locale).compare(optionLabel(column, a), optionLabel(column, b))\n : optionLabel(column, a) < optionLabel(column, b)\n ? -1\n : optionLabel(column, a) > optionLabel(column, b)\n ? 1\n : 0,\n exportValue: (row) => {\n const id = column.accessor ? column.accessor(row) : row[column.id];\n return column.exportAs === \"id\" ? (isEmpty(id) ? null : id) : isEmpty(id) ? null : optionLabel(column, id);\n },\n };\n }\n default:\n return {};\n }\n}\n\n/**\n * The column with its type's defaults filled in under its own props. A column with no `type` is returned as is.\n * `rows` is every row: a `formula` hands it to the consumer's engine for references to other rows. A rollup's and a\n * formula's results are computed once per row each time the columns are resolved (`rows` or `columns` changed),\n * never per comparison or keystroke.\n */\nexport function resolveColumn<T extends TypedColumn>(column: T, gridLocale?: string, rows: Record<string, unknown>[] = []): T {\n if (!column.type) return column;\n const defaults = typeDefaults(column, gridLocale) as Record<string, unknown>;\n const own = Object.fromEntries(Object.entries(column).filter(([, v]) => v !== undefined));\n const resolved = { ...defaults, ...own } as TypedColumn;\n const locale = column.locale ?? gridLocale;\n\n if (column.type === \"rollup\") {\n const relation = column.relation ?? (column.accessor ? (row: Record<string, unknown>) => column.accessor!(row) as unknown[] : (row: Record<string, unknown>) => row[column.id] as unknown[]);\n const cache = new WeakMap<object, unknown>();\n const format = resultFormatter(column, locale);\n resolved.accessor = (row: Record<string, unknown>) => {\n if (cache.has(row)) return cache.get(row);\n const related = relation(row);\n const values = Array.isArray(related) ? related : [];\n const result = column.reduce ? column.reduce(values, row) : aggregateValues(column.aggregate ?? \"count\", values);\n cache.set(row, result);\n return result;\n };\n resolved.editable = false;\n resolved.align = column.align ?? (column.resultType === \"number\" ? \"end\" : \"start\");\n if (column.format === undefined) resolved.format = (v: unknown) => format(v);\n if (column.exportValue === undefined) {\n resolved.exportValue = (row: Record<string, unknown>) => {\n const v = resolved.accessor!(row);\n return column.resultType === \"date\" ? civilDateToDate(v) : isEmpty(v) ? null : v;\n };\n }\n } else if (column.type === \"formula\") {\n const source = column.accessor ?? ((row: Record<string, unknown>) => row[column.id]);\n const cache = new WeakMap<object, DataGridFormulaResult>();\n const format = resultFormatter(column, locale);\n const result = (row: Record<string, unknown>): DataGridFormulaResult => {\n let found = cache.get(row);\n if (!found) {\n const expression = source(row);\n if (isEmpty(expression)) found = { value: null };\n else if (typeof column.evaluate !== \"function\") found = { value: expression };\n else {\n try {\n found = column.evaluate(String(expression), { row, rows, columnId: column.id });\n } catch (error) {\n found = { error: error instanceof Error ? error.message : String(error) };\n }\n }\n cache.set(row, found);\n }\n return found;\n };\n const valueOf = (row: Record<string, unknown>) => {\n const r = result(row);\n return \"error\" in r ? null : r.value;\n };\n resolved.source = source;\n resolved.errorOf = (row: Record<string, unknown>) => {\n const r = result(row);\n return \"error\" in r ? r.error : undefined;\n };\n resolved.accessor = valueOf;\n resolved.align = column.align ?? (column.resultType === \"number\" ? \"end\" : \"start\");\n if (column.format === undefined) {\n resolved.format = (v: unknown, row: Record<string, unknown>) => {\n const message = resolved.errorOf!(row);\n return message !== undefined ? message : format(v);\n };\n }\n if (column.exportValue === undefined) {\n resolved.exportValue = (row: Record<string, unknown>) => {\n const message = resolved.errorOf!(row);\n if (message !== undefined) return message;\n const v = valueOf(row);\n return column.resultType === \"date\" ? civilDateToDate(v) : isEmpty(v) ? null : v;\n };\n }\n if (column.filterText === undefined) {\n resolved.filterText = (v: unknown, row: Record<string, unknown>) =>\n resolved.format!(v, row);\n }\n }\n return resolved as unknown as T;\n}\n","// DataGrid (Angular helper). An Angular port of the canonical Svelte data grid; the contract is that\n// package's spec/index.md. Standalone component, OnPush, signals; it composes the headless\n// DataTable family (`lily-data-table`, `thead[lily-data-table-head]`, …) from\n// @lilydesignsystem/angular-headless.\n//\n// Angular idioms: `selected`, `filter`, `sort`, `columnOrder` and `page` are `model()`s (`[(selected)]`);\n// notifications are outputs; the Svelte snippets (`empty`, `footer`, a column's `cell`, `headerCell`,\n// `avatar`, `personEditor`) are `TemplateRef`s. The headless `lily-data-table` root renders a plain\n// `<table>` with no `role`, so the grid sets `role`, `aria-rowcount` and `aria-busy` on that inner table\n// after each render.\n\nimport {\n ChangeDetectionStrategy,\n Component,\n Directive,\n ElementRef,\n Injector,\n TemplateRef,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n untracked,\n viewChild,\n} from \"@angular/core\";\nimport { NgTemplateOutlet } from \"@angular/common\";\nimport {\n DataTable,\n DataTableBody,\n DataTableFoot,\n DataTableHead,\n DataTableRow,\n DataTableTD,\n DataTableTH,\n} from \"@lilydesignsystem/angular-headless\";\nimport { downloadBlob, exportBlob, exportFilename, type ExportFormat } from \"./export-data\";\nimport {\n filesOf,\n isInvalidForType,\n isZonedTime,\n linkParts,\n peopleOf,\n personName,\n resolveColumn,\n safeHref,\n zonedUtcTime,\n type DataGridCellType,\n type DataGridFile,\n type DataGridLink,\n type DataGridOption,\n type DataGridPerson,\n} from \"./cell-types\";\n\nexport type DataGridSortDirection = \"ascending\" | \"descending\" | \"none\";\n\nexport type DataGridSort = { columnId: string; direction: DataGridSortDirection };\n\nexport type DataGridSelectionMode = \"none\" | \"single\" | \"multiple\";\n\nexport type DataGridRow = Record<string, unknown>;\n\n/** What `exportHandler` and the `exportFile` output receive, before the file is saved. */\nexport type DataGridExport = {\n format: ExportFormat;\n /** The file name, with its extension. */\n filename: string;\n /** How many data rows (the header is not counted). */\n rowCount: number;\n /** The file. */\n blob: Blob;\n};\n\n/** What a column's `cell` template receives (as `$implicit`). */\nexport type DataGridCellContext = {\n value: unknown;\n formatted: string;\n row: DataGridRow;\n column: DataGridColumn;\n};\n\n/** What the `cellEdit` output carries after a cell edit is committed. */\nexport type DataGridCellEdit = {\n rowId: string;\n row: DataGridRow;\n columnId: string;\n /** The parsed new value (a number for the `\"number\"` editor, the text otherwise). */\n value: unknown;\n /** The cell's value before the edit. */\n previous: unknown;\n};\n\n/** What a person editor template receives (as `$implicit`). */\nexport type DataGridPersonEditorContext = { value: unknown; commit: (value: unknown) => void; cancel: () => void };\n\nexport type DataGridColumn = {\n /** Stable column identifier; also the default property read from each row. */\n id: string;\n /** Accessible + visible column header text. */\n header: string;\n /** Reads this column's raw value from a row. Defaults to `row[id]`. */\n accessor?: (row: DataGridRow) => unknown;\n /** Formats a raw value for display. Defaults to `String(value)` (`\"\"` for null/undefined). */\n format?: (value: unknown, row: DataGridRow) => string;\n /** Column participates in sorting. */\n sortable?: boolean;\n /** Orders two raw values when sorting. `null`/`undefined` always sort last, before `compare` is called. */\n compare?: (a: unknown, b: unknown) => number;\n /** Column participates in the text filter. Default true. */\n filterable?: boolean;\n /** Column can be resized (pointer + keyboard). */\n resizable?: boolean;\n /** Column can be reordered: Alt+ArrowLeft/Right on its focused header, or dragging the header onto another. */\n movable?: boolean;\n /** Pins the column: its header and cells get `data-pinned=\"start\"` / `\"end\"` for the consumer's sticky CSS. */\n pinned?: \"start\" | \"end\";\n /** Set `false` to leave the column out of an export. Default true. */\n exportable?: boolean;\n /** The value this column exports for a row. */\n exportValue?: (row: DataGridRow) => unknown;\n /** Column can be hidden via the column-visibility control. */\n hidable?: boolean;\n /** Initial pixel width, meaningful only when `resizable`. */\n width?: number;\n /** Custom cell content: a template receiving the cell context as `$implicit`. */\n cell?: TemplateRef<{ $implicit: DataGridCellContext }>;\n /** The header's content in place of the `header` text. `header` stays the accessible name. */\n headerCell?: TemplateRef<{ $implicit: DataGridColumn }>;\n /** Cells can be edited in place: F2 or Enter on a focused cell, a double click, or the button `labels.editCell` gates. */\n editable?: boolean;\n /** The editor's control. Default `\"text\"`; a `type` sets its own. */\n editor?: \"text\" | \"number\" | \"link\" | \"date\" | \"time\" | \"time-zone\" | \"select\" | \"radio\" | \"person\" | \"formula\";\n /** The kind of value in this column: a bundle of defaults for `format`, `compare`, `filterText`, `exportValue`, `align` and `editor`. */\n type?: DataGridCellType;\n /** BCP 47 locale for this column's formatting and collation. */\n locale?: string;\n /** `select` and `radio`: the choices. */\n options?: DataGridOption[];\n /** `time-zone`: the zones the editor's select offers. */\n timeZones?: DataGridOption[];\n /** `time-zone`: the date (ISO) that orders zoned times and names a zone. Never computed by the grid. */\n referenceDate?: string;\n /** `time-zone`: an export adds a second column holding the UTC time of day at `referenceDate`. */\n exportUtc?: boolean;\n /** `rollup`: how the related values are reduced. */\n aggregate?: \"count\" | \"countUnique\" | \"sum\" | \"avg\" | \"median\" | \"min\" | \"max\" | \"range\" | \"percentTrue\" | \"percentEmpty\";\n /** `rollup`: a reduction the named aggregates do not cover. */\n reduce?: (values: unknown[], row: DataGridRow) => unknown;\n /** `rollup`: reads the related values. */\n relation?: (row: DataGridRow) => unknown[];\n /** `rollup` and `formula`: the result's type. */\n resultType?: \"number\" | \"date\" | \"text\";\n /** `formula`: evaluates an expression. Lily ships no engine and never evaluates a string itself. */\n evaluate?: (expression: string, context: { row: DataGridRow; rows: DataGridRow[]; columnId: string }) => { value: unknown } | { error: string };\n /** `person`: how many people show before \"+N\". */\n maxPeople?: number;\n /** `person`: an avatar beside the name. Decorative. */\n avatar?: TemplateRef<{ $implicit: DataGridPerson }>;\n /** `person`: the editor template (`$implicit`: `{ value, commit, cancel }`). Without it a person cell is read-only. */\n personEditor?: TemplateRef<{ $implicit: DataGridPersonEditorContext }>;\n /** `file`: formats a size in bytes. */\n formatSize?: (bytes: number) => string;\n /** `file`: the `accept` of the file input. */\n accept?: string;\n /** `file`: whether the input takes several files. Default true. */\n multiple?: boolean;\n /** `select`: sort by option label (default) or by option order. */\n sortBy?: \"label\" | \"order\";\n /** `select`/`radio`: export the option's `\"label\"` or `\"id\"`. `person`: `\"email\"`. */\n exportAs?: \"label\" | \"id\" | \"email\";\n /** `number`: options for `Intl.NumberFormat`. */\n numberFormat?: Intl.NumberFormatOptions;\n /** `date`: options for `Intl.DateTimeFormat`. */\n dateFormat?: Intl.DateTimeFormatOptions;\n /** `time`: options for `Intl.DateTimeFormat`. */\n timeFormat?: Intl.DateTimeFormatOptions;\n /** The text the grid's filter matches for a value. */\n filterText?: (value: unknown, row: DataGridRow) => string;\n /** Turns the editor's text into the committed value. */\n parse?: (draft: string, row: DataGridRow) => unknown;\n /** Refuses a value: return a message and the cell stays in edit mode with `aria-invalid`. */\n validate?: (value: unknown, row: DataGridRow) => string | undefined;\n /** Set for a `formula` column: reads the expression a row holds. */\n source?: (row: DataGridRow) => unknown;\n /** Set for a `formula` column: the error message for a row, if any. */\n errorOf?: (row: DataGridRow) => string | undefined;\n /** Body cells of this column are `<th scope=\"row\" role=\"rowheader\">`. */\n rowHeader?: boolean;\n /** Horizontal alignment of the column's cells. */\n align?: \"start\" | \"center\" | \"end\";\n /** Extra class on each body cell of this column. */\n cellClass?: string | ((ctx: DataGridCellContext) => string);\n /** Extra attributes on each body cell of this column. */\n cellAttrs?: (ctx: DataGridCellContext) => Record<string, string>;\n};\n\n/**\n * Every field is optional, but its presence gates the control it names — no baked-in English fallback.\n * See the Svelte canonical's spec/index.md §5.\n */\nexport type DataGridLabels = {\n search?: string;\n columnVisibility?: string;\n columnVisibilityOption?: (header: string) => string;\n resizeHandle?: (header: string) => string;\n selectAll?: string;\n selectionColumn?: string;\n selectRow?: (rowLabel: string) => string;\n previousPage?: string;\n nextPage?: string;\n pageStatus?: (page: number, pageCount: number, rowCount: number) => string;\n pageAnnouncement?: (page: number, pageCount: number) => string;\n sortAnnouncement?: (header: string, direction: DataGridSortDirection) => string;\n filterAnnouncement?: (matchCount: number, totalCount: number) => string;\n selectionAnnouncement?: (selectedCount: number) => string;\n columnMoveAnnouncement?: (header: string, position: number, count: number) => string;\n editCell?: (header: string, rowLabel: string) => string;\n cellEditor?: (header: string) => string;\n editAnnouncement?: (header: string, value: string) => string;\n export?: string;\n exportCsv?: string;\n exportTsv?: string;\n exportExcel?: string;\n exportAnnouncement?: (format: ExportFormat, rowCount: number, filename: string) => string;\n invalidValue?: (header: string, type: string) => string;\n opensInNewTab?: (text: string) => string;\n radioGroup?: (header: string, rowLabel: string) => string;\n timeZone?: (header: string) => string;\n exportUtcHeader?: (header: string) => string;\n morePeople?: (count: number) => string;\n removeFile?: (name: string) => string;\n fileInput?: (header: string, rowLabel: string) => string;\n formulaEditor?: (header: string) => string;\n rollupDescription?: (header: string) => string;\n editCancelAnnouncement?: (header: string) => string;\n editError?: (header: string, message: string) => string;\n};\n\n/** What a footer template receives (as `$implicit`). */\nexport type DataGridFooterContext = { columns: DataGridColumn[]; rows: DataGridRow[] };\n\nexport type DataGridEntry = { row: DataGridRow; id: string };\n\ntype Editing = { rowId: string; columnId: string; draft: string; zone?: string; error?: string; invalid?: boolean };\n\ntype RenderItem = { kind: \"row\"; index: number } | { kind: \"spacer\"; rows: number; key: string };\n\n/** What counts as a widget inside a cell: something a person can operate. */\nconst WIDGET_SELECTOR = 'a[href], button, input, select, textarea, summary, [contenteditable=\"true\"]';\n\nconst MIN_COLUMN_WIDTH = 40;\nconst RESIZE_STEP = 16;\n\nlet uid = 0;\n/** Stable per-instance id prefix; SSR-safe (no Math.random / Date.now). */\nexport function nextDataGridId(): string {\n uid += 1;\n return `data-grid-${uid}`;\n}\n\n/** Default cell value reader: `row[column.id]`. */\nfunction defaultAccessor(column: DataGridColumn, row: DataGridRow): unknown {\n return column.accessor ? column.accessor(row) : row[column.id];\n}\n\n/** Default cell formatter: `String(value)`, `\"\"` for null/undefined. */\nfunction formatCell(column: DataGridColumn, row: DataGridRow): string {\n const value = defaultAccessor(column, row);\n if (column.format) return column.format(value, row);\n return value === null || value === undefined ? \"\" : String(value);\n}\n\n/** Sets a record of attributes on its host element (Angular cannot spread a dictionary in a template). */\n@Directive({ selector: \"[lilyDataGridAttrs]\", standalone: true })\nexport class DataGridAttrs {\n readonly lilyDataGridAttrs = input<Record<string, string> | undefined>(undefined);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private applied: string[] = [];\n\n constructor() {\n effect(() => {\n const next = this.lilyDataGridAttrs() ?? {};\n for (const name of this.applied) if (!(name in next)) this.host.nativeElement.removeAttribute(name);\n for (const [name, value] of Object.entries(next)) this.host.nativeElement.setAttribute(name, value);\n this.applied = Object.keys(next);\n });\n }\n}\n\n@Component({\n selector: \"lily-data-grid\",\n standalone: true,\n imports: [NgTemplateOutlet, DataGridAttrs, DataTable, DataTableBody, DataTableFoot, DataTableHead, DataTableRow, DataTableTD, DataTableTH],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div #rootEl class=\"data-grid {{ className() }}\">\n @if (labels().search || hidableColumns().length > 0 || hasExportButtons()) {\n <div class=\"data-grid-toolbar\">\n @if (labels().search; as searchLabel) {\n <input class=\"data-grid-search\" type=\"search\" [attr.aria-label]=\"searchLabel\" [value]=\"filter()\" (input)=\"onFilterInput($event)\" />\n }\n @if (hasExportButtons()) {\n <div class=\"data-grid-export\" role=\"group\" [attr.aria-label]=\"labels().export ?? null\">\n @if (labels().exportCsv; as csv) {\n <button type=\"button\" class=\"data-grid-export-button\" data-grid-export-format=\"csv\" [disabled]=\"exportEntries().length === 0\" (click)=\"runExport('csv')\">{{ csv }}</button>\n }\n @if (labels().exportTsv; as tsv) {\n <button type=\"button\" class=\"data-grid-export-button\" data-grid-export-format=\"tsv\" [disabled]=\"exportEntries().length === 0\" (click)=\"runExport('tsv')\">{{ tsv }}</button>\n }\n @if (labels().exportExcel; as excel) {\n <button type=\"button\" class=\"data-grid-export-button\" data-grid-export-format=\"xlsx\" [disabled]=\"exportEntries().length === 0\" (click)=\"runExport('xlsx')\">{{ excel }}</button>\n }\n </div>\n }\n @if (hidableColumns().length > 0 && labels().columnVisibility; as visibilityLabel) {\n <fieldset class=\"data-grid-column-visibility\">\n <legend>{{ visibilityLabel }}</legend>\n @for (column of hidableColumns(); track column.id) {\n <label>\n <input type=\"checkbox\" [checked]=\"!hiddenColumnIds().has(column.id)\" (change)=\"toggleColumnVisibility(column.id)\" />\n {{ labels().columnVisibilityOption?.(column.header) ?? column.header }}\n </label>\n }\n </fieldset>\n }\n </div>\n }\n\n @if (scroll()) {\n <!-- A scrollable region must be reachable by keyboard (WCAG 2.1.1); in grid mode a roving cell is already a tab stop. -->\n <div\n #scrollEl\n class=\"data-grid-scroll\"\n role=\"region\"\n [attr.aria-label]=\"label()\"\n [attr.tabindex]=\"isGrid() ? null : 0\"\n [attr.style]=\"scrollStyle()\"\n (scroll)=\"onScroll($event)\"\n >\n <ng-container *ngTemplateOutlet=\"tableTemplate\" />\n </div>\n } @else {\n <ng-container *ngTemplateOutlet=\"tableTemplate\" />\n }\n\n @if (pageSize()) {\n <div class=\"data-grid-pagination\">\n <button type=\"button\" class=\"data-grid-page-previous\" [disabled]=\"clampedPage() <= 1\" (click)=\"goToPage(clampedPage() - 1)\">{{ labels().previousPage }}</button>\n <span class=\"data-grid-page-status\">{{ labels().pageStatus?.(clampedPage(), pageCount(), sortedEntries().length) }}</span>\n <button type=\"button\" class=\"data-grid-page-next\" [disabled]=\"clampedPage() >= pageCount()\" (click)=\"goToPage(clampedPage() + 1)\">{{ labels().nextPage }}</button>\n </div>\n }\n\n <p class=\"data-grid-status\" aria-live=\"polite\">{{ statusMessage() }}</p>\n </div>\n\n <ng-template #tableTemplate>\n <lily-data-table\n [label]=\"label()\"\n [className]=\"''\"\n (keydown)=\"onGridKeydown($event)\"\n (focusin)=\"onGridFocusin($event)\"\n (focusout)=\"onGridFocusout($event)\"\n (click)=\"onGridClick($event)\"\n (dblclick)=\"onGridDblclick($event)\"\n >\n @if (caption()) {\n <caption>{{ caption() }}</caption>\n }\n <thead lily-data-table-head>\n <tr lily-data-table-row [attr.aria-rowindex]=\"indexed() ? 1 : null\">\n @if (hasSelection()) {\n <th\n lily-data-table-th\n data-row=\"-1\"\n data-col=\"0\"\n [attr.tabindex]=\"isGrid() ? (activeRow() === -1 && activeCol() === 0 ? 0 : -1) : null\"\n >\n @if (selectionMode() === 'multiple') {\n <input\n type=\"checkbox\"\n data-grid-own\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n [attr.aria-label]=\"labels().selectAll ?? null\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (click)=\"toggleSelectAll()\"\n />\n } @else {\n <span class=\"data-grid-selection-header-label\">{{ labels().selectionColumn }}</span>\n }\n </th>\n }\n @for (column of visibleColumns(); track column.id; let i = $index) {\n <th\n lily-data-table-th\n data-row=\"-1\"\n [attr.data-col]=\"colOffset() + i\"\n [attr.data-align]=\"column.align ?? null\"\n [attr.data-cell-type]=\"column.type ?? null\"\n [attr.data-pinned]=\"column.pinned ?? null\"\n [attr.tabindex]=\"isGrid() ? (activeRow() === -1 && activeCol() === colOffset() + i ? 0 : -1) : null\"\n [attr.aria-sort]=\"ariaSortFor(column)\"\n [attr.aria-describedby]=\"column.type === 'rollup' && labels().rollupDescription ? gridId + '-' + column.id + '-description' : null\"\n [attr.style]=\"cellStyle(column)\"\n [attr.draggable]=\"column.movable ? 'true' : null\"\n (dragstart)=\"onHeaderDragStart(column, $event)\"\n (dragover)=\"onHeaderDragOver($event)\"\n (drop)=\"onHeaderDrop(column.id, $event)\"\n >\n @if (column.sortable) {\n <button type=\"button\" class=\"data-grid-sort-button\" data-grid-own [attr.tabindex]=\"isGrid() ? -1 : null\" (click)=\"toggleSort(column)\">\n @if (column.headerCell; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: column }\" />\n } @else {<ng-container>{{ column.header }}</ng-container>}\n </button>\n } @else if (column.headerCell; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: column }\" />\n } @else {<ng-container>{{ column.header }}</ng-container>}\n @if (column.type === 'rollup' && labels().rollupDescription; as describe) {\n <span class=\"data-grid-visually-hidden\" [id]=\"gridId + '-' + column.id + '-description'\">{{ describe(column.header) }}</span>\n }\n @if (column.resizable) {\n <!-- WAI-ARIA \"window splitter\" pattern: role=\"separator\" plus tabindex/aria-valuenow is how a resize handle becomes focusable and operable. -->\n <span\n class=\"data-grid-resize-handle\"\n role=\"separator\"\n data-grid-own\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"labels().resizeHandle?.(column.header) ?? null\"\n [attr.aria-valuenow]=\"widthFor(column) ?? 120\"\n [attr.aria-valuemin]=\"minColumnWidth\"\n tabindex=\"0\"\n (keydown)=\"onResizeKeydown(column, $event)\"\n (pointerdown)=\"onResizePointerDown(column, $event)\"\n ></span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody lily-data-table-body>\n @for (item of renderItems(); track item.kind === 'row' ? pageEntries()[item.index].id : item.key) {\n @if (item.kind === 'spacer') {\n <tr class=\"data-grid-spacer\" aria-hidden=\"true\" [attr.style]=\"'height:' + item.rows * (virtualize()?.rowHeight ?? 0) + 'px'\">\n <td [attr.colspan]=\"lastCol() + 1\"></td>\n </tr>\n } @else {\n @let entry = pageEntries()[item.index];\n <tr\n lily-data-table-row\n [className]=\"rowClass()?.(entry.row) ?? ''\"\n [attr.aria-selected]=\"hasSelection() ? isSelected(entry.id) : null\"\n [attr.aria-rowindex]=\"indexed() ? pageStart() + item.index + 2 : null\"\n [lilyDataGridAttrs]=\"rowAttrs()?.(entry.row)\"\n >\n @if (hasSelection()) {\n <td\n lily-data-table-td\n [attr.role]=\"isGrid() ? 'gridcell' : 'cell'\"\n [attr.data-row]=\"item.index\"\n data-col=\"0\"\n [attr.tabindex]=\"isGrid() ? (activeRow() === item.index && activeCol() === 0 ? 0 : -1) : null\"\n >\n <input\n [type]=\"selectionMode() === 'single' ? 'radio' : 'checkbox'\"\n data-grid-own\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n [attr.aria-label]=\"labels().selectRow?.(rowLabelOf(entry)) ?? null\"\n [checked]=\"isSelected(entry.id)\"\n (click)=\"onRowSelectClick(pageStart() + item.index, $event)\"\n />\n </td>\n }\n @for (column of visibleColumns(); track column.id; let colIndex = $index) {\n @let ctx = cellFor(column, entry.row);\n @if (column.rowHeader) {\n <th\n lily-data-table-th\n scope=\"row\"\n role=\"rowheader\"\n [className]=\"cellClassOf(column, ctx)\"\n [attr.data-row]=\"item.index\"\n [attr.data-col]=\"colOffset() + colIndex\"\n [attr.data-align]=\"column.align ?? null\"\n [attr.data-cell-type]=\"column.type ?? null\"\n [attr.data-pinned]=\"column.pinned ?? null\"\n [attr.data-error]=\"column.errorOf?.(entry.row) !== undefined ? '' : null\"\n [attr.tabindex]=\"isGrid() ? (activeRow() === item.index && activeCol() === colOffset() + colIndex ? 0 : -1) : null\"\n [attr.style]=\"cellStyle(column)\"\n [lilyDataGridAttrs]=\"column.cellAttrs?.(ctx)\"\n >\n <ng-container *ngTemplateOutlet=\"cellBody; context: { entry: entry, column: column, ctx: ctx }\" />\n </th>\n } @else {\n <td\n lily-data-table-td\n [className]=\"cellClassOf(column, ctx)\"\n [attr.role]=\"isGrid() ? 'gridcell' : 'cell'\"\n [attr.data-row]=\"item.index\"\n [attr.data-col]=\"colOffset() + colIndex\"\n [attr.data-align]=\"column.align ?? null\"\n [attr.data-cell-type]=\"column.type ?? null\"\n [attr.data-pinned]=\"column.pinned ?? null\"\n [attr.data-editable]=\"isEditable(column) ? '' : null\"\n [attr.data-readonly]=\"column.type === 'rollup' ? '' : null\"\n [attr.aria-readonly]=\"column.type === 'rollup' ? 'true' : null\"\n [attr.data-error]=\"column.errorOf?.(entry.row) !== undefined ? '' : null\"\n [attr.data-editing]=\"isEditingCell(entry, column) ? '' : null\"\n [attr.tabindex]=\"isGrid() ? (activeRow() === item.index && activeCol() === colOffset() + colIndex ? 0 : -1) : null\"\n [attr.style]=\"cellStyle(column)\"\n [lilyDataGridAttrs]=\"column.cellAttrs?.(ctx)\"\n (dragover)=\"onFileDragOver(column, $event)\"\n (drop)=\"onFileDrop(entry, column, $event)\"\n >\n <ng-container *ngTemplateOutlet=\"cellBody; context: { entry: entry, column: column, ctx: ctx }\" />\n </td>\n }\n }\n </tr>\n }\n }\n @if (pageEntries().length === 0 && empty(); as emptyTemplate) {\n <tr lily-data-table-row className=\"data-grid-empty-row\">\n <td lily-data-table-td className=\"data-grid-empty\" [attr.colspan]=\"lastCol() + 1\" [attr.role]=\"isGrid() ? 'gridcell' : 'cell'\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate\" />\n </td>\n </tr>\n }\n </tbody>\n @if (footer(); as footerTemplate) {\n <tfoot lily-data-table-foot>\n <ng-container *ngTemplateOutlet=\"footerTemplate; context: { $implicit: footerContext() }\" />\n </tfoot>\n }\n </lily-data-table>\n </ng-template>\n\n <ng-template #cellBody let-entry=\"entry\" let-column=\"column\" let-ctx=\"ctx\">\n @if (isEditingCell(entry, column)) {\n @let editing = editingState()!;\n @if (column.editor === 'person' && column.personEditor) {\n <ng-container *ngTemplateOutlet=\"column.personEditor; context: { $implicit: personEditorContext(entry, column, ctx) }\" />\n } @else if (column.editor === 'time-zone') {\n <span\n class=\"data-grid-zoned-editor\"\n role=\"group\"\n [attr.aria-label]=\"labels().cellEditor?.(column.header) ?? column.header\"\n (focusout)=\"onZonedFocusout($event)\"\n >\n <input\n class=\"data-grid-cell-editor\"\n type=\"time\"\n step=\"1\"\n [attr.aria-label]=\"labels().cellEditor?.(column.header) ?? column.header\"\n [attr.aria-invalid]=\"editing.error || editing.invalid ? 'true' : null\"\n [attr.aria-describedby]=\"editing.error ? entry.id + '-' + column.id + '-error' : null\"\n [value]=\"editing.draft\"\n (input)=\"setDraft($event)\"\n (keydown)=\"onEditorKeydown($event)\"\n />\n <select\n class=\"data-grid-cell-editor data-grid-zone-editor\"\n [attr.aria-label]=\"labels().timeZone?.(column.header) ?? column.header\"\n (change)=\"setZone($event)\"\n (keydown)=\"onEditorKeydown($event)\"\n >\n @for (option of column.timeZones ?? []; track option.id) {\n <option [value]=\"option.id\" [selected]=\"option.id === editing.zone\">{{ option.label }}</option>\n }\n </select>\n </span>\n } @else if (column.editor === 'select') {\n <select\n class=\"data-grid-cell-editor\"\n [attr.aria-label]=\"labels().cellEditor?.(column.header) ?? column.header\"\n [attr.aria-invalid]=\"editing.error || editing.invalid ? 'true' : null\"\n [attr.aria-describedby]=\"editing.error ? entry.id + '-' + column.id + '-error' : null\"\n (change)=\"setDraft($event)\"\n (keydown)=\"onEditorKeydown($event)\"\n (blur)=\"onEditorBlur()\"\n >\n <option value=\"\" [selected]=\"editing.draft === ''\"></option>\n @for (option of ungroupedOptions(column); track option.id) {\n <option [value]=\"option.id\" [disabled]=\"option.disabled ?? false\" [selected]=\"option.id === editing.draft\">{{ option.label }}</option>\n }\n @for (group of groupsOf(column); track group) {\n <optgroup [label]=\"group\">\n @for (option of optionsInGroup(column, group); track option.id) {\n <option [value]=\"option.id\" [disabled]=\"option.disabled ?? false\" [selected]=\"option.id === editing.draft\">{{ option.label }}</option>\n }\n </optgroup>\n }\n </select>\n } @else {\n <input\n class=\"data-grid-cell-editor\"\n [type]=\"column.editor === 'number' ? 'number' : column.editor === 'date' ? 'date' : column.editor === 'time' ? 'time' : 'text'\"\n [attr.step]=\"column.editor === 'time' ? 1 : null\"\n [attr.inputmode]=\"column.editor === 'number' ? 'decimal' : null\"\n [attr.aria-label]=\"(column.type === 'formula' ? labels().formulaEditor?.(column.header) : undefined) ?? labels().cellEditor?.(column.header) ?? column.header\"\n [attr.aria-invalid]=\"editing.error || editing.invalid ? 'true' : null\"\n [attr.aria-describedby]=\"editing.error ? entry.id + '-' + column.id + '-error' : null\"\n [value]=\"editing.draft\"\n (input)=\"setDraft($event)\"\n (keydown)=\"onEditorKeydown($event)\"\n (blur)=\"onEditorBlur()\"\n />\n }\n @if (editing.error) {\n <span class=\"data-grid-cell-error\" [id]=\"entry.id + '-' + column.id + '-error'\">{{ editing.error }}</span>\n }\n } @else if (column.type === 'radio' && column.editable) {\n <fieldset class=\"data-grid-radio-group\" data-grid-own-group>\n <legend class=\"data-grid-radio-legend\">{{ labels().radioGroup?.(column.header, rowLabelOf(entry)) ?? column.header }}</legend>\n @for (option of column.options ?? []; track option.id) {\n <label class=\"data-grid-radio-option\">\n <input\n type=\"radio\"\n [name]=\"gridId + '-' + entry.id + '-' + column.id\"\n [value]=\"option.id\"\n [checked]=\"ctx.value === option.id\"\n [disabled]=\"option.disabled ?? false\"\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n (change)=\"commitValue(entry, column, option.id)\"\n />{{ option.label }}</label>\n }\n </fieldset>\n } @else {\n @if (column.cell; as cellTemplate) {\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: { $implicit: ctx }\" />\n } @else if (column.type === 'person') {\n @let people = peopleIn(ctx.value);\n @if (people.length > 0) {\n @let shown = shownPeople(column, ctx.value);\n <ul class=\"data-grid-people\">\n @for (person of shown; track person.id) {\n <li class=\"data-grid-person\">\n @if (column.avatar; as avatarTemplate) {\n <span class=\"data-grid-avatar\" aria-hidden=\"true\"><ng-container *ngTemplateOutlet=\"avatarTemplate; context: { $implicit: person }\" /></span>\n }\n <span class=\"data-grid-person-name\">{{ nameOf(person) }}</span>\n </li>\n }\n @if (shown.length < people.length && labels().morePeople; as more) {\n <li class=\"data-grid-people-more\">{{ more(people.length - shown.length) }}</li>\n }\n </ul>\n }\n } @else if (column.type === 'file') {\n @let files = filesIn(ctx.value);\n @if (files.length > 0) {\n <ul class=\"data-grid-files\">\n @for (file of files; track file.id) {\n <li class=\"data-grid-file\">\n @if (hrefOf(file.href); as fileHref) {\n <a class=\"data-grid-link\" [href]=\"fileHref\">{{ file.name }}</a>\n } @else {\n <span class=\"data-grid-file-name\">{{ file.name }}</span>\n }\n @if (file.size !== undefined && column.formatSize; as sizeText) {\n {{ ' ' }}<span class=\"data-grid-file-size\">{{ column.formatSize(file.size) }}</span>\n }\n @if (column.editable && labels().removeFile; as removeLabel) {\n <button\n type=\"button\"\n class=\"data-grid-file-remove\"\n data-grid-own\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n [attr.aria-label]=\"removeLabel(file.name)\"\n (click)=\"fileRemove.emit({ rowId: entry.id, row: entry.row, columnId: column.id, fileId: file.id })\"\n ></button>\n }\n </li>\n }\n </ul>\n }\n @if (column.editable) {\n <input\n type=\"file\"\n class=\"data-grid-file-input\"\n [attr.aria-label]=\"labels().fileInput?.(column.header, rowLabelOf(entry)) ?? column.header\"\n [multiple]=\"column.multiple !== false\"\n [attr.accept]=\"column.accept ?? null\"\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n (change)=\"onFileInput(entry, column, $event)\"\n />\n }\n } @else if (column.type === 'link') {\n @let link = linkIn(ctx.value);\n @if (link) {\n @if (hrefOf(link.href); as href) {\n <a class=\"data-grid-link\" [href]=\"href\" [attr.target]=\"link.external ? '_blank' : null\" [attr.rel]=\"link.external ? 'noopener noreferrer' : null\">{{ link.label ?? link.href }}@if (link.external && labels().opensInNewTab; as newTab) {{{ ' ' }}<span class=\"data-grid-visually-hidden\">{{ newTab(link.label ?? link.href) }}</span>}</a>\n } @else {\n <!-- An address with an unsafe scheme is shown as text, never as a link. -->\n <span class=\"data-grid-link data-grid-link-unsafe\">{{ link.label ?? link.href }}</span>\n }\n }\n } @else if (column.type === 'date' || column.type === 'time') {\n @if (ctx.formatted !== '') {\n <time [attr.datetime]=\"stringOf(ctx.value)\">{{ ctx.formatted }}</time>\n }\n } @else {<ng-container>{{ ctx.formatted }}</ng-container>}\n @if (isEditable(column) && column.type !== 'radio' && labels().editCell; as editLabel) {\n <button\n type=\"button\"\n class=\"data-grid-edit-button\"\n data-grid-own\n [attr.tabindex]=\"isGrid() ? -1 : null\"\n [attr.aria-label]=\"editLabel(column.header, rowLabelOf(entry))\"\n (click)=\"startEdit(entry, column)\"\n ></button>\n }\n }\n </ng-template>\n `,\n})\nexport class DataGrid {\n // ---- Inputs ----\n\n /** Accessible name for the grid, passed through to DataTable. */\n readonly label = input.required<string>();\n /** Optional visible caption. */\n readonly caption = input<string | undefined>(undefined);\n /** Column definitions. */\n readonly columns = input.required<DataGridColumn[]>();\n /** Row data. */\n readonly rows = input.required<DataGridRow[]>();\n /** BCP 47 locale for the typed columns' formatting and collation. Never defaulted: with none, values show as stored. */\n readonly locale = input<string | undefined>(undefined);\n /** Derives a stable id per row. Defaults to the row's index in `rows`. */\n readonly rowId = input<(row: DataGridRow, index: number) => string>((_row, index) => String(index));\n /** Row selection mode. */\n readonly selectionMode = input<DataGridSelectionMode>(\"none\");\n /** Rows per page. Unset disables pagination. */\n readonly pageSize = input<number | undefined>(undefined);\n /** If set, persist column widths / hidden columns / sort to localStorage. */\n readonly storageKey = input<string | undefined>(undefined);\n /** User-facing strings. */\n readonly labels = input<DataGridLabels>({});\n /** `\"grid\"` (default): roving-tabindex grid. `\"table\"`: a plain table with ordinary tab stops. */\n readonly mode = input<\"grid\" | \"table\">(\"grid\");\n /** Extra class on each body row. */\n readonly rowClass = input<((row: DataGridRow) => string) | undefined>(undefined);\n /** Extra attributes on each body row. */\n readonly rowAttrs = input<((row: DataGridRow) => Record<string, string>) | undefined>(undefined);\n /** Enter on a body cell with no widget, and a click outside any widget, emit `rowActivate` — only when this is true (Angular outputs cannot be tested for a listener). */\n readonly activateRows = input<boolean>(false);\n /** Shown in one row spanning every column when no row is to be shown. */\n readonly empty = input<TemplateRef<void> | undefined>(undefined);\n /** Rendered inside a `<tfoot>`: a template receiving `{ columns, rows }` as `$implicit`. */\n readonly footer = input<TemplateRef<{ $implicit: DataGridFooterContext }> | undefined>(undefined);\n /** Sets `aria-busy` on the table. */\n readonly busy = input<boolean>(false);\n /** Wrap the table in a scrollable `data-grid-scroll` region. Default true. */\n readonly scroll = input<boolean>(true);\n /** The file name without its extension. Default `\"data-grid\"`. */\n readonly exportFilename = input<string>(\"data-grid\");\n /** What an export holds: `\"view\"` (default) or `\"selected\"`. */\n readonly exportScope = input<\"view\" | \"selected\">(\"view\");\n /** `.xlsx` only: a `formula` column keeps the live expression with the result cached. */\n readonly exportFormulas = input<boolean>(false);\n /** Called with the file before it is saved. Return `false` to keep the grid from saving it. */\n readonly exportHandler = input<((file: DataGridExport) => boolean | void) | undefined>(undefined);\n /** Renders only the rows in view, in a scroll region of `height` px (needs `scroll`). */\n readonly virtualize = input<{ rowHeight: number; height: number; overscan?: number } | undefined>(undefined);\n /** Extra CSS class on the root. */\n readonly className = input<string>(\"\");\n\n // ---- Two-way models ----\n\n /** Selected row ids. Two-way bindable: `[(selected)]`. */\n readonly selected = model<string[]>([]);\n /** Text filter. Two-way bindable: `[(filter)]`. */\n readonly filter = model<string>(\"\");\n /** Current sort. Two-way bindable: `[(sort)]`. */\n readonly sort = model<DataGridSort>({ columnId: \"\", direction: \"none\" });\n /** Column ids in display order. Two-way bindable: `[(columnOrder)]`; columns it does not name follow in their `columns` order. */\n readonly columnOrder = model<string[]>([]);\n /** Current 1-indexed page. Two-way bindable: `[(page)]`. */\n readonly page = model<number>(1);\n\n // ---- Outputs ----\n\n readonly cellEdit = output<DataGridCellEdit>();\n readonly filesSelected = output<{ rowId: string; row: DataGridRow; columnId: string; files: File[] }>();\n readonly fileRemove = output<{ rowId: string; row: DataGridRow; columnId: string; fileId: string }>();\n readonly rowActivate = output<{ row: DataGridRow; id: string }>();\n readonly exportFile = output<DataGridExport>();\n\n // ---- State ----\n\n protected readonly gridId = nextDataGridId();\n protected readonly minColumnWidth = MIN_COLUMN_WIDTH;\n private readonly rootRef = viewChild.required<ElementRef<HTMLDivElement>>(\"rootEl\");\n private readonly scrollRef = viewChild<ElementRef<HTMLDivElement>>(\"scrollEl\");\n private readonly injector = inject(Injector);\n\n protected readonly statusMessage = signal(\"\");\n protected readonly hiddenColumnIds = signal<ReadonlySet<string>>(new Set());\n private readonly columnWidths = signal<Record<string, number>>({});\n private readonly focusedRow = signal(-1); // -1 = header row\n private readonly focusedCol = signal(0);\n private lastSelectedIndex = -1;\n protected readonly editingState = signal<Editing | null>(null);\n private readonly scrollTop = signal(0);\n private draggingColumnId: string | null = null;\n\n // ---- Derived data ----\n\n /** Each column with its type's defaults filled in under its own props. */\n protected readonly resolvedColumns = computed(() => this.columns().map((c) => resolveColumn(c, this.locale(), this.rows())) as DataGridColumn[]);\n protected readonly isGrid = computed(() => this.mode() === \"grid\");\n protected readonly hasSelection = computed(() => this.selectionMode() !== \"none\");\n protected readonly colOffset = computed(() => (this.hasSelection() ? 1 : 0));\n\n /** Columns in display order: those named in `columnOrder` first, the rest after in their own order. */\n private readonly orderedColumns = computed(() => {\n const order = this.columnOrder();\n const columns = this.resolvedColumns();\n if (order.length === 0) return columns;\n const rank = (id: string) => {\n const i = order.indexOf(id);\n return i === -1 ? order.length : i;\n };\n return columns\n .map((c, i) => ({ c, i }))\n .sort((a, b) => rank(a.c.id) - rank(b.c.id) || a.i - b.i)\n .map((x) => x.c);\n });\n protected readonly visibleColumns = computed(() => this.orderedColumns().filter((c) => !this.hiddenColumnIds().has(c.id)));\n protected readonly hidableColumns = computed(() => this.resolvedColumns().filter((c) => c.hidable));\n\n private readonly entries = computed<DataGridEntry[]>(() => {\n const rowId = this.rowId();\n return this.rows().map((row, index) => ({ row, id: rowId(row, index) }));\n });\n\n /** Each cell's value and formatted text, read once per row object and column (reset when the columns change). */\n private readonly cellCache = computed(() => {\n this.resolvedColumns();\n return new WeakMap<DataGridRow, Map<string, DataGridCellContext>>();\n });\n\n protected cellFor(column: DataGridColumn, row: DataGridRow): DataGridCellContext {\n const cache = this.cellCache();\n let perRow = cache.get(row);\n if (!perRow) {\n perRow = new Map();\n cache.set(row, perRow);\n }\n let ctx = perRow.get(column.id);\n if (!ctx) {\n ctx = { value: defaultAccessor(column, row), formatted: formatCell(column, row), row, column };\n perRow.set(column.id, ctx);\n }\n return ctx;\n }\n\n /** Lowercased search text per row, built once per rows/columns change. */\n private readonly searchIndex = computed(() => {\n const filterable = this.resolvedColumns().filter((c) => c.filterable !== false);\n return this.entries().map((entry) =>\n filterable.map((column) =>\n (column.filterText ? column.filterText(this.cellFor(column, entry.row).value, entry.row) : this.cellFor(column, entry.row).formatted).toLowerCase(),\n ),\n );\n });\n\n private readonly filteredEntries = computed(() => {\n const text = this.filter().trim().toLowerCase();\n if (!text) return this.entries();\n const index = this.searchIndex();\n return this.entries().filter((_entry, i) => index[i].some((value) => value.includes(text)));\n });\n\n protected readonly sortedEntries = computed(() => {\n const sort = this.sort();\n const filtered = this.filteredEntries();\n if (sort.direction === \"none\" || !sort.columnId) return filtered;\n const column = this.resolvedColumns().find((c) => c.id === sort.columnId);\n if (!column) return filtered;\n const dir = sort.direction === \"ascending\" ? 1 : -1;\n const compare = column.compare;\n // Read each sort key once (n accessor calls), not twice per comparison.\n const keyed = filtered.map((entry) => ({ entry, key: this.cellFor(column, entry.row).value }));\n keyed.sort((a, b) => {\n const av = a.key;\n const bv = b.key;\n if (av === bv) return 0;\n // Missing values sort last in both directions.\n if (av === null || av === undefined) return 1;\n if (bv === null || bv === undefined) return -1;\n if (compare) return compare(av, bv) * dir;\n return (av as never) > (bv as never) ? dir : -dir;\n });\n return keyed.map((k) => k.entry);\n });\n\n protected readonly pageCount = computed(() => {\n const size = this.pageSize();\n return size ? Math.max(1, Math.ceil(this.sortedEntries().length / size)) : 1;\n });\n protected readonly clampedPage = computed(() => Math.min(Math.max(this.page(), 1), this.pageCount()));\n protected readonly pageStart = computed(() => {\n const size = this.pageSize();\n return size ? (this.clampedPage() - 1) * size : 0;\n });\n protected readonly pageEntries = computed(() => {\n const size = this.pageSize();\n return size ? this.sortedEntries().slice(this.pageStart(), this.pageStart() + size) : this.sortedEntries();\n });\n protected readonly lastCol = computed(() => this.colOffset() + this.visibleColumns().length - 1);\n\n // The roving position clamped to the cells that exist now.\n protected readonly activeRow = computed(() => Math.max(-1, Math.min(this.focusedRow(), this.pageEntries().length - 1)));\n protected readonly activeCol = computed(() => Math.max(0, Math.min(this.focusedCol(), this.lastCol())));\n\n protected readonly indexed = computed(() => !!this.pageSize() || !!this.virtualize());\n private readonly rowCount = computed(() =>\n this.pageSize() ? this.sortedEntries().length + 1 : this.virtualize() ? this.pageEntries().length + 1 : undefined,\n );\n\n protected readonly renderItems = computed<RenderItem[]>(() => {\n const total = this.pageEntries().length;\n const v = this.virtualize();\n if (!v) return this.pageEntries().map((_, index) => ({ kind: \"row\", index }) as RenderItem);\n const overscan = v.overscan ?? 3;\n const top = this.scrollTop();\n const start = Math.max(0, Math.floor(top / v.rowHeight) - overscan);\n const end = Math.min(total, Math.ceil((top + v.height) / v.rowHeight) + overscan);\n const indices = new Set<number>();\n for (let i = start; i < end; i++) indices.add(i);\n const active = this.activeRow();\n if (active >= 0 && active < total) indices.add(active);\n const items: RenderItem[] = [];\n let previous = -1;\n for (const index of [...indices].sort((a, b) => a - b)) {\n if (index - previous > 1) items.push({ kind: \"spacer\", rows: index - previous - 1, key: `spacer-${previous}` });\n items.push({ kind: \"row\", index });\n previous = index;\n }\n if (total - 1 - previous > 0) items.push({ kind: \"spacer\", rows: total - 1 - previous, key: `spacer-${previous}` });\n return items;\n });\n\n protected readonly scrollStyle = computed(() => {\n const v = this.virtualize();\n return v ? `height:${v.height}px;overflow:auto` : null;\n });\n\n private readonly selectedSet = computed(() => new Set(this.selected()));\n protected readonly allSelected = computed(() => this.sortedEntries().length > 0 && this.sortedEntries().every((e) => this.selectedSet().has(e.id)));\n protected readonly someSelected = computed(() => !this.allSelected() && this.sortedEntries().some((e) => this.selectedSet().has(e.id)));\n\n protected readonly footerContext = computed<DataGridFooterContext>(() => ({\n columns: this.visibleColumns(),\n rows: this.pageEntries().map((e) => e.row),\n }));\n\n protected readonly exportColumns = computed(() => this.visibleColumns().filter((c) => c.exportable !== false));\n protected readonly exportEntries = computed(() =>\n this.exportScope() === \"selected\" ? this.sortedEntries().filter((e) => this.selectedSet().has(e.id)) : this.sortedEntries(),\n );\n protected readonly hasExportButtons = computed(() => {\n const l = this.labels();\n return !!(l.exportCsv || l.exportTsv || l.exportExcel);\n });\n\n constructor() {\n // The headless `lily-data-table` root renders a plain <table>: give it the grid's role and counts.\n effect(() => {\n const root = this.rootRef().nativeElement;\n const grid = this.isGrid();\n const count = this.rowCount();\n const busy = this.busy();\n this.sortedEntries();\n this.pageEntries();\n this.visibleColumns();\n this.scroll();\n afterNextRender(\n () => {\n const table = root.querySelector<HTMLElement>(\"table.data-table\");\n if (!table) return;\n table.setAttribute(\"role\", grid ? \"grid\" : \"table\");\n if (grid && count !== undefined) table.setAttribute(\"aria-rowcount\", String(count));\n else table.removeAttribute(\"aria-rowcount\");\n if (busy) table.setAttribute(\"aria-busy\", \"true\");\n else table.removeAttribute(\"aria-busy\");\n },\n { injector: this.injector },\n );\n });\n\n // Widgets in body cells are not tab stops, so Tab leaves the grid in one step. Re-run whenever what is on screen changes.\n effect(() => {\n this.pageEntries();\n this.visibleColumns();\n this.isGrid();\n this.scrollTop();\n this.editingState();\n afterNextRender(() => this.normaliseWidgets(), { injector: this.injector });\n });\n\n // Persistence (view state only: widths, hidden columns, sort — never rows/selection).\n let restored = false;\n effect(() => {\n const key = this.storageKey();\n if (!key || restored) return;\n restored = true;\n untracked(() => this.restoreView(key));\n });\n effect(() => {\n const key = this.storageKey();\n const snapshot = { columnWidths: this.columnWidths(), hiddenColumnIds: [...this.hiddenColumnIds()], sort: this.sort() };\n if (!key || typeof localStorage === \"undefined\") return;\n try {\n localStorage.setItem(key, JSON.stringify(snapshot));\n } catch {\n // ignore quota / privacy errors\n }\n });\n }\n\n // ---- Announcements ----\n\n private announce(message: string | undefined): void {\n if (message) this.statusMessage.set(message);\n }\n\n // ---- Sorting ----\n\n protected ariaSortFor(column: DataGridColumn): DataGridSortDirection | null {\n if (!column.sortable) return null;\n return this.sort().columnId === column.id ? this.sort().direction : \"none\";\n }\n\n protected toggleSort(column: DataGridColumn): void {\n if (!column.sortable) return;\n const current = this.sort();\n const next: DataGridSort =\n current.columnId !== column.id\n ? { columnId: column.id, direction: \"ascending\" }\n : current.direction === \"ascending\"\n ? { columnId: column.id, direction: \"descending\" }\n : current.direction === \"descending\"\n ? { columnId: \"\", direction: \"none\" }\n : { columnId: column.id, direction: \"ascending\" };\n this.sort.set(next);\n this.announce(this.labels().sortAnnouncement?.(column.header, next.direction));\n }\n\n // ---- Filtering ----\n\n protected onFilterInput(event: Event): void {\n this.filter.set((event.target as HTMLInputElement).value);\n this.page.set(1);\n this.announce(this.labels().filterAnnouncement?.(this.filteredEntries().length, this.rows().length));\n }\n\n // ---- Selection ----\n\n protected isSelected(id: string): boolean {\n return this.selectedSet().has(id);\n }\n\n private setSelected(next: string[]): void {\n this.selected.set(next);\n this.announce(this.labels().selectionAnnouncement?.(next.length));\n }\n\n protected onRowSelectClick(index: number, event: Event): void {\n const e = event as MouseEvent;\n this.toggleRow(index, e);\n }\n\n /** `index` is the row's position in the sorted entries, not on the current page. */\n private toggleRow(index: number, event?: { shiftKey?: boolean; ctrlKey?: boolean; metaKey?: boolean }): void {\n const sorted = this.sortedEntries();\n const id = sorted[index].id;\n const selected = this.selected();\n const mode = this.selectionMode();\n if (mode === \"single\") {\n this.setSelected(this.isSelected(id) ? [] : [id]);\n } else if (mode === \"multiple\") {\n if (event?.shiftKey && this.lastSelectedIndex >= 0) {\n const [start, end] = this.lastSelectedIndex < index ? [this.lastSelectedIndex, index] : [index, this.lastSelectedIndex];\n const range = sorted.slice(start, end + 1).map((e) => e.id);\n this.setSelected([...new Set([...selected, ...range])]);\n } else if (event?.ctrlKey || event?.metaKey) {\n this.setSelected(this.isSelected(id) ? selected.filter((x) => x !== id) : [...selected, id]);\n } else {\n this.setSelected(this.isSelected(id) && selected.length === 1 ? [] : [id]);\n }\n }\n this.lastSelectedIndex = index;\n }\n\n protected toggleSelectAll(): void {\n if (this.allSelected()) this.setSelected([]);\n else this.setSelected(this.sortedEntries().map((e) => e.id));\n }\n\n // ---- Column resize ----\n\n protected widthFor(column: DataGridColumn): number | undefined {\n return this.columnWidths()[column.id] ?? column.width;\n }\n\n /** Inline style of a column's cells: its width, and its alignment where one is set. */\n protected cellStyle(column: DataGridColumn): string | null {\n const parts: string[] = [];\n const width = this.widthFor(column);\n if (width) parts.push(`width:${width}px`);\n if (column.align) parts.push(`text-align:${column.align}`);\n return parts.length > 0 ? parts.join(\";\") : null;\n }\n\n private setWidth(column: DataGridColumn, width: number): void {\n this.columnWidths.update((current) => ({ ...current, [column.id]: Math.max(MIN_COLUMN_WIDTH, width) }));\n }\n\n protected onResizeKeydown(column: DataGridColumn, event: Event): void {\n const e = event as KeyboardEvent;\n // The resize handle is its own tab stop outside the grid's roving-tabindex system — every key here must stop.\n e.stopPropagation();\n const current = this.widthFor(column) ?? 120;\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n this.setWidth(column, current + RESIZE_STEP);\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n this.setWidth(column, current - RESIZE_STEP);\n }\n }\n\n protected onResizePointerDown(column: DataGridColumn, event: Event): void {\n const e = event as PointerEvent;\n e.preventDefault();\n const startX = e.clientX;\n const target = e.target as HTMLElement;\n const startWidth = this.widthFor(column) ?? target.closest(\"th\")?.getBoundingClientRect().width ?? 120;\n target.setPointerCapture?.(e.pointerId);\n const onMove = (moveEvent: PointerEvent): void => this.setWidth(column, startWidth + (moveEvent.clientX - startX));\n const onUp = (): void => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n }\n\n // ---- Column visibility, pagination ----\n\n protected toggleColumnVisibility(columnId: string): void {\n this.hiddenColumnIds.update((current) => {\n const next = new Set(current);\n if (next.has(columnId)) next.delete(columnId);\n else next.add(columnId);\n return next;\n });\n }\n\n protected goToPage(next: number): void {\n const target = Math.min(Math.max(next, 1), this.pageCount());\n if (target === this.clampedPage()) return;\n this.page.set(target);\n this.announce(this.labels().pageAnnouncement?.(target, this.pageCount()));\n }\n\n // ---- Column reorder ----\n\n /** Move `columnId` to sit at `toVisibleIndex` among the visible columns. Returns whether it moved. */\n private moveColumn(columnId: string, toVisibleIndex: number): boolean {\n const ids = this.visibleColumns().map((c) => c.id);\n const from = ids.indexOf(columnId);\n const to = Math.min(Math.max(toVisibleIndex, 0), ids.length - 1);\n if (from === -1 || from === to) return false;\n ids.splice(to, 0, ...ids.splice(from, 1));\n // Hidden columns keep their places in the full order; visible ones are re-sequenced around them.\n const visibleSet = new Set(ids);\n let next = 0;\n this.columnOrder.set(this.orderedColumns().map((c) => (visibleSet.has(c.id) ? ids[next++] : c.id)));\n const column = this.resolvedColumns().find((c) => c.id === columnId)!;\n this.announce(this.labels().columnMoveAnnouncement?.(column.header, to + 1, ids.length));\n return true;\n }\n\n protected onHeaderDragStart(column: DataGridColumn, event: Event): void {\n if (!column.movable) return;\n this.draggingColumnId = column.id;\n (event as DragEvent).dataTransfer?.setData(\"text/plain\", column.id);\n }\n\n protected onHeaderDragOver(event: Event): void {\n if (this.draggingColumnId) event.preventDefault();\n }\n\n protected onHeaderDrop(targetId: string, event: Event): void {\n event.preventDefault();\n const id = this.draggingColumnId;\n this.draggingColumnId = null;\n if (!id || id === targetId) return;\n const to = this.visibleColumns().findIndex((c) => c.id === targetId);\n if (to >= 0) this.moveColumn(id, to);\n }\n\n // ---- Windowing ----\n\n protected onScroll(event: Event): void {\n if (this.virtualize()) this.scrollTop.set((event.currentTarget as HTMLElement).scrollTop);\n }\n\n /** Bring a body row into the scroll region. */\n private revealRow(index: number): void {\n const v = this.virtualize();\n if (!v || index < 0) return;\n const top = index * v.rowHeight;\n const current = this.scrollTop();\n let next = current;\n if (top < current) next = top;\n else if (top + v.rowHeight > current + v.height) next = top + v.rowHeight - v.height;\n if (next === current) return;\n this.scrollTop.set(next);\n const el = this.scrollRef()?.nativeElement;\n if (el) el.scrollTop = next;\n }\n\n // ---- Focus ----\n\n private focusActiveCell(): void {\n afterNextRender(\n () => {\n this.rootRef().nativeElement\n .querySelector<HTMLElement>('.data-table-th[tabindex=\"0\"], .data-table-td[tabindex=\"0\"]')\n ?.focus({ preventScroll: true });\n },\n { injector: this.injector },\n );\n }\n\n private moveFocus(row: number, col: number): void {\n const nextRow = Math.min(Math.max(row, -1), this.pageEntries().length - 1);\n this.focusedRow.set(nextRow);\n this.focusedCol.set(Math.min(Math.max(col, 0), this.lastCol()));\n this.revealRow(nextRow);\n this.focusActiveCell();\n }\n\n // ---- Export ----\n\n /** One cell for an export: typed values stay typed, everything else is the text the grid shows. */\n private exportCell(column: DataGridColumn, row: DataGridRow): unknown {\n if (column.exportValue) return column.exportValue(row);\n const ctx = this.cellFor(column, row);\n const value = ctx.value;\n if (value === null || value === undefined) return null;\n if (typeof value === \"number\" || typeof value === \"boolean\" || value instanceof Date) return value;\n return ctx.formatted;\n }\n\n private hasUtcColumn(c: DataGridColumn): boolean {\n return c.type === \"time-zone\" && !!c.exportUtc && !!c.referenceDate && !!this.labels().exportUtcHeader;\n }\n\n protected runExport(format: ExportFormat): void {\n const live = (c: DataGridColumn) => format === \"xlsx\" && this.exportFormulas() && c.type === \"formula\" && !!c.source;\n const headers: string[] = [];\n for (const c of this.exportColumns()) {\n headers.push(c.header);\n if (this.hasUtcColumn(c)) headers.push(this.labels().exportUtcHeader!(c.header));\n }\n const rows = this.exportEntries().map((entry) => {\n const cells: unknown[] = [];\n for (const c of this.exportColumns()) {\n const expression = live(c) ? c.source!(entry.row) : undefined;\n cells.push(\n typeof expression === \"string\" && expression !== \"\" && !c.errorOf?.(entry.row)\n ? { formula: expression, result: this.exportCell(c, entry.row) }\n : this.exportCell(c, entry.row),\n );\n if (this.hasUtcColumn(c)) cells.push(zonedUtcTime(this.cellFor(c, entry.row).value, c.referenceDate));\n }\n return cells;\n });\n const table = { headers, rows };\n const name = this.exportFilename();\n const filename = exportFilename(name, format);\n const blob = exportBlob(table, format, { sheetName: name });\n const file: DataGridExport = { format, filename, rowCount: rows.length, blob };\n this.exportFile.emit(file);\n if (this.exportHandler()?.(file) === false) return;\n downloadBlob(blob, filename);\n this.announce(this.labels().exportAnnouncement?.(format, rows.length, filename));\n }\n\n // ---- Files ----\n\n /** Files dropped on an editable file cell: the same report as the file input. The grid uploads nothing. */\n protected onFileDragOver(column: DataGridColumn, event: Event): void {\n if (column.type !== \"file\" || !column.editable) return;\n if (Array.from((event as DragEvent).dataTransfer?.types ?? []).includes(\"Files\")) event.preventDefault();\n }\n\n protected onFileDrop(entry: DataGridEntry, column: DataGridColumn, event: Event): void {\n if (column.type !== \"file\" || !column.editable) return;\n const dropped = Array.from((event as DragEvent).dataTransfer?.files ?? []);\n if (dropped.length === 0) return;\n event.preventDefault();\n const files = column.multiple === false ? dropped.slice(0, 1) : dropped;\n this.filesSelected.emit({ rowId: entry.id, row: entry.row, columnId: column.id, files });\n }\n\n protected onFileInput(entry: DataGridEntry, column: DataGridColumn, event: Event): void {\n const input = event.target as HTMLInputElement;\n const chosen = Array.from(input.files ?? []);\n if (chosen.length > 0) this.filesSelected.emit({ rowId: entry.id, row: entry.row, columnId: column.id, files: chosen });\n input.value = \"\";\n }\n\n // ---- Cell editing ----\n\n /** A cell the person can edit through the grid's edit model (not a rollup, a file cell with its own widgets, or a person cell with no editor). */\n protected isEditable(column: DataGridColumn): boolean {\n if (!column.editable) return false;\n if (column.type === \"rollup\" || column.type === \"file\") return false;\n if (column.type === \"person\" && !column.personEditor) return false;\n return true;\n }\n\n protected isEditingCell(entry: DataGridEntry, column: DataGridColumn): boolean {\n const e = this.editingState();\n return !!e && e.rowId === entry.id && e.columnId === column.id;\n }\n\n protected startEdit(entry: DataGridEntry, column: DataGridColumn): void {\n if (!this.isEditable(column)) return;\n // A formula's editor shows the expression the row holds, not the result.\n const raw = column.type === \"formula\" && column.source ? column.source(entry.row) : defaultAccessor(column, entry.row);\n if (column.type === \"time-zone\") {\n const zoned = isZonedTime(raw) ? raw : null;\n this.editingState.set({ rowId: entry.id, columnId: column.id, draft: zoned?.time ?? \"\", zone: zoned?.timeZone ?? column.timeZones?.[0]?.id ?? \"\" });\n } else {\n const text = column.type === \"link\" ? (linkParts(raw)?.href ?? \"\") : raw === null || raw === undefined ? \"\" : String(raw);\n this.editingState.set({ rowId: entry.id, columnId: column.id, draft: text });\n }\n afterNextRender(\n () => {\n const editor = this.rootRef().nativeElement.querySelector<HTMLInputElement | HTMLSelectElement>(\".data-grid-cell-editor\");\n editor?.focus();\n if (editor instanceof HTMLInputElement && editor.type === \"text\") editor.select();\n },\n { injector: this.injector },\n );\n }\n\n private parseDraft(column: DataGridColumn, row: DataGridRow, draft: string, zone?: string): unknown {\n if (column.parse) return column.parse(draft, row);\n if (column.type === \"time-zone\") return draft === \"\" ? null : { time: draft, timeZone: zone ?? \"\" };\n if (column.editor === \"number\") return draft.trim() === \"\" ? null : Number(draft);\n if (column.editor === \"date\" || column.editor === \"time\" || column.editor === \"select\") return draft === \"\" ? null : draft;\n return draft;\n }\n\n /** Two link values with the same address and label are the same edit. */\n private isStructurallyEqual(a: unknown, b: unknown): boolean {\n return typeof a === \"object\" && typeof b === \"object\" && a !== null && b !== null && JSON.stringify(a) === JSON.stringify(b);\n }\n\n /** Validate and report one new value for a cell. Returns false (and keeps editing, if the editor is open) when it is refused. */\n protected commitValue(entry: DataGridEntry, column: DataGridColumn, value: unknown): boolean {\n const message = column.validate?.(value, entry.row);\n const invalidType = isInvalidForType(column, value);\n if (message || invalidType) {\n const text = message ?? this.labels().invalidValue?.(column.header, column.type ?? \"\") ?? \"\";\n const current = this.editingState();\n if (current) this.editingState.set({ ...current, error: text || undefined, invalid: true });\n this.announce(this.labels().editError?.(column.header, text));\n return false;\n }\n const previous = column.type === \"formula\" && column.source ? column.source(entry.row) : defaultAccessor(column, entry.row);\n this.editingState.set(null);\n if (value !== previous && !this.isStructurallyEqual(value, previous)) {\n this.cellEdit.emit({ rowId: entry.id, row: entry.row, columnId: column.id, value, previous });\n this.announce(this.labels().editAnnouncement?.(column.header, column.format ? column.format(value, entry.row) : String(value ?? \"\")));\n }\n return true;\n }\n\n private commitEdit(): void {\n const current = this.editingState();\n if (!current) return;\n const entry = this.entries().find((e) => e.id === current.rowId);\n const column = this.resolvedColumns().find((c) => c.id === current.columnId);\n if (!entry || !column) {\n this.editingState.set(null);\n return;\n }\n if (this.commitValue(entry, column, this.parseDraft(column, entry.row, current.draft, current.zone))) this.focusActiveCell();\n }\n\n private cancelEdit(): void {\n const current = this.editingState();\n if (!current) return;\n this.editingState.set(null);\n const column = this.resolvedColumns().find((c) => c.id === current.columnId);\n if (column) this.announce(this.labels().editCancelAnnouncement?.(column.header));\n this.focusActiveCell();\n }\n\n protected onEditorKeydown(event: Event): void {\n const e = event as KeyboardEvent;\n // The editor owns its keys; none may reach the grid's own handler.\n e.stopPropagation();\n // While an input method is composing, Enter picks the candidate and Escape cancels the composition:\n // neither commits nor cancels the edit. Some browsers report the confirming Enter with `isComposing`\n // already false, but keyCode 229.\n if (e.isComposing || e.keyCode === 229) return;\n if (e.key === \"Enter\") {\n e.preventDefault();\n this.commitEdit();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n this.cancelEdit();\n }\n }\n\n protected onEditorBlur(): void {\n if (this.editingState()) this.commitEdit();\n }\n\n /** Focus leaving the time-zone editor's pair (not moving between its two controls) commits. */\n protected onZonedFocusout(event: Event): void {\n const e = event as FocusEvent;\n if (this.editingState() && !(e.currentTarget as HTMLElement).contains(e.relatedTarget as Node | null)) this.commitEdit();\n }\n\n protected setDraft(event: Event): void {\n const current = this.editingState();\n if (current) this.editingState.set({ ...current, draft: (event.target as HTMLInputElement | HTMLSelectElement).value, error: undefined, invalid: false });\n }\n\n protected setZone(event: Event): void {\n const current = this.editingState();\n if (current) this.editingState.set({ ...current, zone: (event.target as HTMLSelectElement).value, error: undefined, invalid: false });\n }\n\n protected personEditorContext(entry: DataGridEntry, column: DataGridColumn, ctx: DataGridCellContext): DataGridPersonEditorContext {\n return { value: ctx.value, commit: (v: unknown) => void this.commitValue(entry, column, v), cancel: () => this.cancelEdit() };\n }\n\n // ---- Keyboard (WAI-ARIA APG Grid pattern) ----\n\n private activateFocusedCell(): void {\n if (this.activeCol() === 0 && this.hasSelection()) {\n if (this.activeRow() === -1) {\n if (this.selectionMode() === \"multiple\") this.toggleSelectAll();\n } else {\n this.toggleRow(this.pageStart() + this.activeRow());\n }\n return;\n }\n const column = this.visibleColumns()[this.activeCol() - this.colOffset()];\n if (!column) return;\n if (this.activeRow() === -1) this.toggleSort(column);\n }\n\n /** The widgets a consumer put in a body cell (never the grid's own controls). */\n private widgetsIn(cell: Element): HTMLElement[] {\n return Array.from(cell.querySelectorAll<HTMLElement>(WIDGET_SELECTOR)).filter((el) => !el.closest(\"[data-grid-own]\"));\n }\n\n private setWidgetTabindex(cell: Element, value: \"0\" | \"-1\"): void {\n for (const widget of this.widgetsIn(cell)) widget.setAttribute(\"tabindex\", value);\n }\n\n private normaliseWidgets(): void {\n if (!this.isGrid()) return;\n for (const cell of this.rootRef().nativeElement.querySelectorAll(\".data-table-body [data-row][data-col]\")) {\n if (cell.getAttribute(\"data-grid-entered\") === \"true\") continue;\n this.setWidgetTabindex(cell, \"-1\");\n }\n }\n\n /** Focus the first widget of a cell; its widgets are tab stops while focus stays inside it. */\n private enterCell(cell: HTMLElement): boolean {\n const first = this.widgetsIn(cell)[0];\n if (!first) return false;\n cell.setAttribute(\"data-grid-entered\", \"true\");\n this.setWidgetTabindex(cell, \"0\");\n first.focus();\n return true;\n }\n\n private leaveCell(cell: Element): void {\n if (cell.getAttribute(\"data-grid-entered\") !== \"true\") return;\n cell.removeAttribute(\"data-grid-entered\");\n this.setWidgetTabindex(cell, \"-1\");\n }\n\n /** Pointer or programmatic focus on a cell moves the roving position to it. */\n protected onGridFocusin(event: Event): void {\n if (!this.isGrid()) return;\n const target = event.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-row][data-col]\");\n if (!cell) return;\n this.focusedRow.set(Number(cell.dataset[\"row\"]));\n this.focusedCol.set(Number(cell.dataset[\"col\"]));\n // Focus arriving on a widget (a click, or Tab inside the cell) makes the cell's widgets tab stops.\n if (target !== cell && !target.closest(\"[data-grid-own]\") && cell.closest(\".data-table-body\")) {\n cell.setAttribute(\"data-grid-entered\", \"true\");\n this.setWidgetTabindex(cell, \"0\");\n }\n }\n\n protected onGridFocusout(event: Event): void {\n if (!this.isGrid()) return;\n const e = event as FocusEvent;\n const cell = (e.target as HTMLElement).closest<HTMLElement>(\"[data-row][data-col]\");\n if (!cell) return;\n const next = e.relatedTarget as Node | null;\n if (next && cell.contains(next)) return;\n this.leaveCell(cell);\n }\n\n /** A click on a body cell, outside any widget, activates its row. */\n protected onGridClick(event: Event): void {\n if (!this.activateRows()) return;\n const target = event.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-row][data-col]\");\n if (!cell || cell.closest(\".data-table-head\")) return;\n if (target.closest(WIDGET_SELECTOR) || target.closest(\"[data-grid-own]\")) return;\n const entry = this.pageEntries()[Number(cell.dataset[\"row\"])];\n if (entry) this.rowActivate.emit({ row: entry.row, id: entry.id });\n }\n\n /** A double click on an editable body cell starts editing it. */\n protected onGridDblclick(event: Event): void {\n const target = event.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-row][data-col]\");\n if (!cell || cell.closest(\".data-table-head\") || target.closest(\"input, button, select, textarea\")) return;\n const entry = this.pageEntries()[Number(cell.dataset[\"row\"])];\n const column = this.visibleColumns()[Number(cell.dataset[\"col\"]) - this.colOffset()];\n if (entry && column && this.isEditable(column)) this.startEdit(entry, column);\n }\n\n protected onGridKeydown(event: Event): void {\n if (!this.isGrid()) return;\n const e = event as KeyboardEvent;\n const target = e.target as HTMLElement;\n const cell = target.closest<HTMLElement>(\"[data-row][data-col]\");\n if (!cell) return;\n // A key pressed on a widget inside a cell belongs to the widget: the caret moves in a field, a select\n // opens, a link follows. Only Escape is the grid's, and it hands focus back to the cell.\n if (target !== cell && !target.closest(\"[data-grid-own]\")) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n cell.focus({ preventScroll: true });\n }\n return;\n }\n const activeRow = this.activeRow();\n const activeCol = this.activeCol();\n const colOffset = this.colOffset();\n if (e.altKey && activeRow === -1 && (e.key === \"ArrowRight\" || e.key === \"ArrowLeft\")) {\n const column = this.visibleColumns()[activeCol - colOffset];\n if (column?.movable) {\n e.preventDefault();\n const delta = e.key === \"ArrowRight\" ? 1 : -1;\n if (this.moveColumn(column.id, activeCol - colOffset + delta)) this.moveFocus(-1, activeCol + delta);\n return;\n }\n }\n const size = this.pageSize();\n switch (e.key) {\n case \"ArrowRight\":\n e.preventDefault();\n this.moveFocus(activeRow, activeCol + 1);\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n this.moveFocus(activeRow, activeCol - 1);\n break;\n case \"ArrowDown\":\n e.preventDefault();\n this.moveFocus(activeRow + 1, activeCol);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n this.moveFocus(activeRow - 1, activeCol);\n break;\n case \"Home\":\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) this.moveFocus(-1, 0);\n else this.moveFocus(activeRow, 0);\n break;\n case \"End\":\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) this.moveFocus(this.pageEntries().length - 1, this.lastCol());\n else this.moveFocus(activeRow, this.lastCol());\n break;\n case \"PageDown\":\n e.preventDefault();\n this.moveFocus(activeRow + (size ?? 10), activeCol);\n break;\n case \"PageUp\":\n e.preventDefault();\n this.moveFocus(activeRow - (size ?? 10), activeCol);\n break;\n case \"F2\": {\n const entry = this.pageEntries()[Number(cell.dataset[\"row\"])];\n const column = this.visibleColumns()[Number(cell.dataset[\"col\"]) - colOffset];\n if (target === cell && entry && column && this.isEditable(column)) {\n e.preventDefault();\n this.startEdit(entry, column);\n }\n break;\n }\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (e.key === \"Enter\" && target === cell && cell.closest(\".data-table-body\")) {\n const entry = this.pageEntries()[Number(cell.dataset[\"row\"])];\n const column = this.visibleColumns()[Number(cell.dataset[\"col\"]) - colOffset];\n if (entry && column && this.isEditable(column)) {\n this.startEdit(entry, column);\n break;\n }\n }\n if (target === cell && cell.closest(\".data-table-body\") && !cell.querySelector(\"[data-grid-own]\")) {\n // A cell with a widget in it is entered; one without activates its row.\n if (this.enterCell(cell)) break;\n if (e.key === \"Enter\" && this.activateRows()) {\n const entry = this.pageEntries()[Number(cell.dataset[\"row\"])];\n if (entry) this.rowActivate.emit({ row: entry.row, id: entry.id });\n break;\n }\n }\n this.activateFocusedCell();\n break;\n }\n }\n\n // ---- Persistence ----\n\n private restoreView(key: string): void {\n try {\n const raw = localStorage.getItem(key);\n if (raw) {\n const saved = JSON.parse(raw) as { columnWidths?: Record<string, number>; hiddenColumnIds?: string[]; sort?: DataGridSort };\n if (saved.columnWidths) this.columnWidths.set(saved.columnWidths);\n if (saved.hiddenColumnIds) this.hiddenColumnIds.set(new Set(saved.hiddenColumnIds));\n if (saved.sort) this.sort.set(saved.sort);\n }\n } catch {\n // ignore quota / privacy / parse errors\n }\n }\n\n // ---- Template helpers ----\n\n protected rowLabelOf(entry: DataGridEntry): string {\n const first = this.visibleColumns()[0];\n return first ? this.cellFor(first, entry.row).formatted : entry.id;\n }\n\n protected cellClassOf(column: DataGridColumn, ctx: DataGridCellContext): string {\n const extra = typeof column.cellClass === \"function\" ? column.cellClass(ctx) : column.cellClass;\n return extra ?? \"\";\n }\n\n protected peopleIn(value: unknown): DataGridPerson[] {\n return peopleOf(value);\n }\n\n protected shownPeople(column: DataGridColumn, value: unknown): DataGridPerson[] {\n const people = peopleOf(value);\n return column.maxPeople !== undefined ? people.slice(0, Math.max(0, column.maxPeople)) : people;\n }\n\n protected nameOf(person: DataGridPerson): string {\n return personName(person);\n }\n\n protected filesIn(value: unknown): DataGridFile[] {\n return filesOf(value);\n }\n\n protected linkIn(value: unknown): DataGridLink | null {\n return linkParts(value);\n }\n\n protected hrefOf(href: string | undefined): string | null {\n return href === undefined ? null : safeHref(href);\n }\n\n protected stringOf(value: unknown): string {\n return String(value);\n }\n\n protected ungroupedOptions(column: DataGridColumn): DataGridOption[] {\n return (column.options ?? []).filter((o) => !o.group);\n }\n\n protected groupsOf(column: DataGridColumn): string[] {\n return [...new Set((column.options ?? []).filter((o) => o.group).map((o) => o.group as string))];\n }\n\n protected optionsInGroup(column: DataGridColumn, group: string): DataGridOption[] {\n return (column.options ?? []).filter((o) => o.group === group);\n }\n}\n\nexport default DataGrid;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lilydesignsystem/angular-data-grid",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": "=26"
|
|
6
|
+
},
|
|
7
|
+
"description": "Lily Design System Angular interactive data grid composing the headless DataTable family: sort, filter, selection, pagination, resize, reorder, cell editing, virtualization, export to CSV, TSV and Excel, and twelve cell types. Headless, SSR-safe, no CSS.",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@lilydesignsystem/angular-headless": "^0.5.0",
|
|
10
|
+
"tslib": "^2.3.0"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@angular/common": ">=20.0.0 <23.0.0",
|
|
14
|
+
"@angular/core": ">=20.0.0 <23.0.0"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"keywords": [
|
|
18
|
+
"lily",
|
|
19
|
+
"design",
|
|
20
|
+
"system",
|
|
21
|
+
"angular",
|
|
22
|
+
"data",
|
|
23
|
+
"grid",
|
|
24
|
+
"table",
|
|
25
|
+
"headless"
|
|
26
|
+
],
|
|
27
|
+
"author": "Joel Parker Henderson <joel@joelparkerhenderson.com>",
|
|
28
|
+
"license": "MIT OR Apache-2.0 OR GPL-2.0-only OR GPL-3.0-only OR BSD-3-Clause",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/LilyDesignSystem/lily-design-system.git",
|
|
32
|
+
"directory": "lily-design-system-angular-data-grid"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://lilydesignsystem.com/",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/LilyDesignSystem/lily-design-system/issues"
|
|
37
|
+
},
|
|
38
|
+
"module": "fesm2022/lilydesignsystem-angular-data-grid.mjs",
|
|
39
|
+
"typings": "types/lilydesignsystem-angular-data-grid.d.ts",
|
|
40
|
+
"exports": {
|
|
41
|
+
"./package.json": {
|
|
42
|
+
"default": "./package.json"
|
|
43
|
+
},
|
|
44
|
+
".": {
|
|
45
|
+
"types": "./types/lilydesignsystem-angular-data-grid.d.ts",
|
|
46
|
+
"default": "./fesm2022/lilydesignsystem-angular-data-grid.mjs"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"type": "module"
|
|
6
50
|
}
|