@star-ng/ui 0.0.0-stage → 0.1.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.
Files changed (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -2
  3. package/fesm2022/star-ng-ui-accordion.mjs +376 -0
  4. package/fesm2022/star-ng-ui-accordion.mjs.map +1 -0
  5. package/fesm2022/star-ng-ui-autocomplete.mjs +782 -0
  6. package/fesm2022/star-ng-ui-autocomplete.mjs.map +1 -0
  7. package/fesm2022/star-ng-ui-avatar.mjs +154 -0
  8. package/fesm2022/star-ng-ui-avatar.mjs.map +1 -0
  9. package/fesm2022/star-ng-ui-badge.mjs +153 -0
  10. package/fesm2022/star-ng-ui-badge.mjs.map +1 -0
  11. package/fesm2022/star-ng-ui-breadcrumb.mjs +199 -0
  12. package/fesm2022/star-ng-ui-breadcrumb.mjs.map +1 -0
  13. package/fesm2022/star-ng-ui-button.mjs +282 -0
  14. package/fesm2022/star-ng-ui-button.mjs.map +1 -0
  15. package/fesm2022/star-ng-ui-card.mjs +112 -0
  16. package/fesm2022/star-ng-ui-card.mjs.map +1 -0
  17. package/fesm2022/star-ng-ui-chart.mjs +1904 -0
  18. package/fesm2022/star-ng-ui-chart.mjs.map +1 -0
  19. package/fesm2022/star-ng-ui-checkbox.mjs +345 -0
  20. package/fesm2022/star-ng-ui-checkbox.mjs.map +1 -0
  21. package/fesm2022/star-ng-ui-core.mjs +392 -0
  22. package/fesm2022/star-ng-ui-core.mjs.map +1 -0
  23. package/fesm2022/star-ng-ui-data-display.mjs +1556 -0
  24. package/fesm2022/star-ng-ui-data-display.mjs.map +1 -0
  25. package/fesm2022/star-ng-ui-date-picker.mjs +2786 -0
  26. package/fesm2022/star-ng-ui-date-picker.mjs.map +1 -0
  27. package/fesm2022/star-ng-ui-dialog.mjs +948 -0
  28. package/fesm2022/star-ng-ui-dialog.mjs.map +1 -0
  29. package/fesm2022/star-ng-ui-drawer.mjs +158 -0
  30. package/fesm2022/star-ng-ui-drawer.mjs.map +1 -0
  31. package/fesm2022/star-ng-ui-editor.mjs +416 -0
  32. package/fesm2022/star-ng-ui-editor.mjs.map +1 -0
  33. package/fesm2022/star-ng-ui-field.mjs +378 -0
  34. package/fesm2022/star-ng-ui-field.mjs.map +1 -0
  35. package/fesm2022/star-ng-ui-file-upload.mjs +762 -0
  36. package/fesm2022/star-ng-ui-file-upload.mjs.map +1 -0
  37. package/fesm2022/star-ng-ui-i18n-de.mjs +179 -0
  38. package/fesm2022/star-ng-ui-i18n-de.mjs.map +1 -0
  39. package/fesm2022/star-ng-ui-i18n-es.mjs +179 -0
  40. package/fesm2022/star-ng-ui-i18n-es.mjs.map +1 -0
  41. package/fesm2022/star-ng-ui-input-group.mjs +188 -0
  42. package/fesm2022/star-ng-ui-input-group.mjs.map +1 -0
  43. package/fesm2022/star-ng-ui-input-mask.mjs +434 -0
  44. package/fesm2022/star-ng-ui-input-mask.mjs.map +1 -0
  45. package/fesm2022/star-ng-ui-input-number.mjs +691 -0
  46. package/fesm2022/star-ng-ui-input-number.mjs.map +1 -0
  47. package/fesm2022/star-ng-ui-input-otp.mjs +343 -0
  48. package/fesm2022/star-ng-ui-input-otp.mjs.map +1 -0
  49. package/fesm2022/star-ng-ui-input-tags.mjs +616 -0
  50. package/fesm2022/star-ng-ui-input-tags.mjs.map +1 -0
  51. package/fesm2022/star-ng-ui-knob.mjs +514 -0
  52. package/fesm2022/star-ng-ui-knob.mjs.map +1 -0
  53. package/fesm2022/star-ng-ui-layout.mjs +608 -0
  54. package/fesm2022/star-ng-ui-layout.mjs.map +1 -0
  55. package/fesm2022/star-ng-ui-listbox.mjs +978 -0
  56. package/fesm2022/star-ng-ui-listbox.mjs.map +1 -0
  57. package/fesm2022/star-ng-ui-media.mjs +833 -0
  58. package/fesm2022/star-ng-ui-media.mjs.map +1 -0
  59. package/fesm2022/star-ng-ui-menu.mjs +1840 -0
  60. package/fesm2022/star-ng-ui-menu.mjs.map +1 -0
  61. package/fesm2022/star-ng-ui-message.mjs +191 -0
  62. package/fesm2022/star-ng-ui-message.mjs.map +1 -0
  63. package/fesm2022/star-ng-ui-paginator.mjs +387 -0
  64. package/fesm2022/star-ng-ui-paginator.mjs.map +1 -0
  65. package/fesm2022/star-ng-ui-panel.mjs +324 -0
  66. package/fesm2022/star-ng-ui-panel.mjs.map +1 -0
  67. package/fesm2022/star-ng-ui-password.mjs +517 -0
  68. package/fesm2022/star-ng-ui-password.mjs.map +1 -0
  69. package/fesm2022/star-ng-ui-popover.mjs +241 -0
  70. package/fesm2022/star-ng-ui-popover.mjs.map +1 -0
  71. package/fesm2022/star-ng-ui-progress-bar.mjs +183 -0
  72. package/fesm2022/star-ng-ui-progress-bar.mjs.map +1 -0
  73. package/fesm2022/star-ng-ui-radio.mjs +411 -0
  74. package/fesm2022/star-ng-ui-radio.mjs.map +1 -0
  75. package/fesm2022/star-ng-ui-rating.mjs +211 -0
  76. package/fesm2022/star-ng-ui-rating.mjs.map +1 -0
  77. package/fesm2022/star-ng-ui-select-button.mjs +613 -0
  78. package/fesm2022/star-ng-ui-select-button.mjs.map +1 -0
  79. package/fesm2022/star-ng-ui-select.mjs +2523 -0
  80. package/fesm2022/star-ng-ui-select.mjs.map +1 -0
  81. package/fesm2022/star-ng-ui-skeleton.mjs +160 -0
  82. package/fesm2022/star-ng-ui-skeleton.mjs.map +1 -0
  83. package/fesm2022/star-ng-ui-slider.mjs +552 -0
  84. package/fesm2022/star-ng-ui-slider.mjs.map +1 -0
  85. package/fesm2022/star-ng-ui-spinner.mjs +148 -0
  86. package/fesm2022/star-ng-ui-spinner.mjs.map +1 -0
  87. package/fesm2022/star-ng-ui-stepper.mjs +360 -0
  88. package/fesm2022/star-ng-ui-stepper.mjs.map +1 -0
  89. package/fesm2022/star-ng-ui-table.mjs +3477 -0
  90. package/fesm2022/star-ng-ui-table.mjs.map +1 -0
  91. package/fesm2022/star-ng-ui-tabs.mjs +464 -0
  92. package/fesm2022/star-ng-ui-tabs.mjs.map +1 -0
  93. package/fesm2022/star-ng-ui-tag.mjs +129 -0
  94. package/fesm2022/star-ng-ui-tag.mjs.map +1 -0
  95. package/fesm2022/star-ng-ui-theme-switch.mjs +105 -0
  96. package/fesm2022/star-ng-ui-theme-switch.mjs.map +1 -0
  97. package/fesm2022/star-ng-ui-theme.mjs +98 -0
  98. package/fesm2022/star-ng-ui-theme.mjs.map +1 -0
  99. package/fesm2022/star-ng-ui-toast.mjs +298 -0
  100. package/fesm2022/star-ng-ui-toast.mjs.map +1 -0
  101. package/fesm2022/star-ng-ui-toggle-switch.mjs +316 -0
  102. package/fesm2022/star-ng-ui-toggle-switch.mjs.map +1 -0
  103. package/fesm2022/star-ng-ui-tooltip.mjs +297 -0
  104. package/fesm2022/star-ng-ui-tooltip.mjs.map +1 -0
  105. package/fesm2022/star-ng-ui-transloco.mjs +40 -0
  106. package/fesm2022/star-ng-ui-transloco.mjs.map +1 -0
  107. package/fesm2022/star-ng-ui-tree.mjs +1446 -0
  108. package/fesm2022/star-ng-ui-tree.mjs.map +1 -0
  109. package/fesm2022/star-ng-ui-utility.mjs +2134 -0
  110. package/fesm2022/star-ng-ui-utility.mjs.map +1 -0
  111. package/fesm2022/star-ng-ui.mjs +51 -0
  112. package/package.json +281 -3
  113. package/styles/_base.scss +70 -0
  114. package/styles/_shared.scss +2 -0
  115. package/styles/_tokens.scss +190 -0
  116. package/styles/controls/_accordion.scss +75 -0
  117. package/styles/controls/_autocomplete.scss +44 -0
  118. package/styles/controls/_avatar.scss +39 -0
  119. package/styles/controls/_breadcrumb.scss +45 -0
  120. package/styles/controls/_button.scss +137 -0
  121. package/styles/controls/_card.scss +38 -0
  122. package/styles/controls/_chart.scss +214 -0
  123. package/styles/controls/_chip.scss +51 -0
  124. package/styles/controls/_choice.scss +153 -0
  125. package/styles/controls/_data-display.scss +118 -0
  126. package/styles/controls/_date-picker.scss +300 -0
  127. package/styles/controls/_dialog.scss +123 -0
  128. package/styles/controls/_drawer.scss +118 -0
  129. package/styles/controls/_editor.scss +74 -0
  130. package/styles/controls/_field.scss +92 -0
  131. package/styles/controls/_file-upload.scss +136 -0
  132. package/styles/controls/_input-group.scss +104 -0
  133. package/styles/controls/_input-mask.scss +46 -0
  134. package/styles/controls/_input-number.scss +125 -0
  135. package/styles/controls/_knob.scss +76 -0
  136. package/styles/controls/_layout.scss +182 -0
  137. package/styles/controls/_listbox.scss +38 -0
  138. package/styles/controls/_media.scss +222 -0
  139. package/styles/controls/_menu.scss +254 -0
  140. package/styles/controls/_message.scss +48 -0
  141. package/styles/controls/_org-chart.scss +128 -0
  142. package/styles/controls/_paginator.scss +59 -0
  143. package/styles/controls/_panel.scss +83 -0
  144. package/styles/controls/_popover.scss +40 -0
  145. package/styles/controls/_progress-bar.scss +74 -0
  146. package/styles/controls/_select-button.scss +61 -0
  147. package/styles/controls/_select.scss +216 -0
  148. package/styles/controls/_skeleton.scss +43 -0
  149. package/styles/controls/_slider.scss +163 -0
  150. package/styles/controls/_spinner.scss +34 -0
  151. package/styles/controls/_stepper.scss +109 -0
  152. package/styles/controls/_table.scss +523 -0
  153. package/styles/controls/_tabs.scss +93 -0
  154. package/styles/controls/_tag.scss +84 -0
  155. package/styles/controls/_toast.scss +141 -0
  156. package/styles/controls/_tooltip.scss +14 -0
  157. package/styles/controls/_tree.scss +113 -0
  158. package/styles/controls/_utility.scss +654 -0
  159. package/styles/star-ng.css +5803 -0
  160. package/styles/star-ng.min.css +1 -0
  161. package/styles/star-ng.scss +50 -0
  162. package/theme/star-theme-first-paint.js +1 -0
  163. package/types/star-ng-ui-accordion.d.ts +82 -0
  164. package/types/star-ng-ui-autocomplete.d.ts +171 -0
  165. package/types/star-ng-ui-avatar.d.ts +43 -0
  166. package/types/star-ng-ui-badge.d.ts +46 -0
  167. package/types/star-ng-ui-breadcrumb.d.ts +39 -0
  168. package/types/star-ng-ui-button.d.ts +79 -0
  169. package/types/star-ng-ui-card.d.ts +29 -0
  170. package/types/star-ng-ui-chart.d.ts +337 -0
  171. package/types/star-ng-ui-checkbox.d.ts +92 -0
  172. package/types/star-ng-ui-core.d.ts +310 -0
  173. package/types/star-ng-ui-data-display.d.ts +339 -0
  174. package/types/star-ng-ui-date-picker.d.ts +701 -0
  175. package/types/star-ng-ui-dialog.d.ts +254 -0
  176. package/types/star-ng-ui-drawer.d.ts +29 -0
  177. package/types/star-ng-ui-editor.d.ts +96 -0
  178. package/types/star-ng-ui-field.d.ts +146 -0
  179. package/types/star-ng-ui-file-upload.d.ts +192 -0
  180. package/types/star-ng-ui-i18n-de.d.ts +7 -0
  181. package/types/star-ng-ui-i18n-es.d.ts +7 -0
  182. package/types/star-ng-ui-input-group.d.ts +58 -0
  183. package/types/star-ng-ui-input-mask.d.ts +126 -0
  184. package/types/star-ng-ui-input-number.d.ts +193 -0
  185. package/types/star-ng-ui-input-otp.d.ts +86 -0
  186. package/types/star-ng-ui-input-tags.d.ts +159 -0
  187. package/types/star-ng-ui-knob.d.ts +121 -0
  188. package/types/star-ng-ui-layout.d.ts +154 -0
  189. package/types/star-ng-ui-listbox.d.ts +197 -0
  190. package/types/star-ng-ui-media.d.ts +161 -0
  191. package/types/star-ng-ui-menu.d.ts +332 -0
  192. package/types/star-ng-ui-message.d.ts +52 -0
  193. package/types/star-ng-ui-paginator.d.ts +85 -0
  194. package/types/star-ng-ui-panel.d.ts +65 -0
  195. package/types/star-ng-ui-password.d.ts +129 -0
  196. package/types/star-ng-ui-popover.d.ts +57 -0
  197. package/types/star-ng-ui-progress-bar.d.ts +49 -0
  198. package/types/star-ng-ui-radio.d.ts +116 -0
  199. package/types/star-ng-ui-rating.d.ts +52 -0
  200. package/types/star-ng-ui-select-button.d.ts +169 -0
  201. package/types/star-ng-ui-select.d.ts +540 -0
  202. package/types/star-ng-ui-skeleton.d.ts +47 -0
  203. package/types/star-ng-ui-slider.d.ts +145 -0
  204. package/types/star-ng-ui-spinner.d.ts +29 -0
  205. package/types/star-ng-ui-stepper.d.ts +89 -0
  206. package/types/star-ng-ui-table.d.ts +829 -0
  207. package/types/star-ng-ui-tabs.d.ts +109 -0
  208. package/types/star-ng-ui-tag.d.ts +35 -0
  209. package/types/star-ng-ui-theme-switch.d.ts +36 -0
  210. package/types/star-ng-ui-theme.d.ts +95 -0
  211. package/types/star-ng-ui-toast.d.ts +84 -0
  212. package/types/star-ng-ui-toggle-switch.d.ts +81 -0
  213. package/types/star-ng-ui-tooltip.d.ts +66 -0
  214. package/types/star-ng-ui-transloco.d.ts +14 -0
  215. package/types/star-ng-ui-tree.d.ts +310 -0
  216. package/types/star-ng-ui-utility.d.ts +533 -0
  217. package/types/star-ng-ui.d.ts +51 -0
@@ -0,0 +1,3477 @@
1
+ import { DOCUMENT, NgTemplateOutlet } from "@angular/common";
2
+ import * as i0 from "@angular/core";
3
+ import { ApplicationRef, ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, Injector, TemplateRef, afterNextRender, afterRenderEffect, booleanAttribute, computed, contentChild, contentChildren, effect, inject, input, isDevMode, model, output, signal, untracked, viewChild } from "@angular/core";
4
+ import { StarButton } from "@star-ng/ui/button";
5
+ import { StarCheckbox } from "@star-ng/ui/checkbox";
6
+ import { STAR_UI_TEXT, compareValues, matchesFilter, readOption, starIsRtl } from "@star-ng/ui/core";
7
+ import { StarPaginator } from "@star-ng/ui/paginator";
8
+ import { StarPopover } from "@star-ng/ui/popover";
9
+ import { StarMultiSelect } from "@star-ng/ui/select";
10
+ import { StarSkeleton } from "@star-ng/ui/skeleton";
11
+ const encoder = new TextEncoder();
12
+ function escapeXml(text) {
13
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, "");
14
+ }
15
+ let crcTable = null;
16
+ function crc32(bytes) {
17
+ if (!crcTable) {
18
+ crcTable = /* @__PURE__ */ new Uint32Array(256);
19
+ for (let n = 0; n < 256; n++) {
20
+ let c = n;
21
+ for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
22
+ crcTable[n] = c >>> 0;
23
+ }
24
+ }
25
+ let crc = 4294967295;
26
+ for (const byte of bytes) crc = crcTable[(crc ^ byte) & 255] ^ crc >>> 8;
27
+ return (crc ^ 4294967295) >>> 0;
28
+ }
29
+ function zip(files) {
30
+ const chunks = [];
31
+ const central = [];
32
+ let offset = 0;
33
+ for (const file of files) {
34
+ const name = encoder.encode(file.name);
35
+ const data = encoder.encode(file.text);
36
+ const crc = crc32(data);
37
+ const local = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(30));
38
+ local.setUint32(0, 67324752, true);
39
+ local.setUint16(4, 20, true);
40
+ local.setUint16(6, 2048, true);
41
+ local.setUint16(8, 0, true);
42
+ local.setUint32(14, crc, true);
43
+ local.setUint32(18, data.length, true);
44
+ local.setUint32(22, data.length, true);
45
+ local.setUint16(26, name.length, true);
46
+ const entry = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(46));
47
+ entry.setUint32(0, 33639248, true);
48
+ entry.setUint16(4, 20, true);
49
+ entry.setUint16(6, 20, true);
50
+ entry.setUint16(8, 2048, true);
51
+ entry.setUint32(16, crc, true);
52
+ entry.setUint32(20, data.length, true);
53
+ entry.setUint32(24, data.length, true);
54
+ entry.setUint16(28, name.length, true);
55
+ entry.setUint32(42, offset, true);
56
+ chunks.push(new Uint8Array(local.buffer), name, data);
57
+ central.push(new Uint8Array(entry.buffer), name);
58
+ offset += 30 + name.length + data.length;
59
+ }
60
+ const centralSize = central.reduce((size, part) => size + part.length, 0);
61
+ const end = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(22));
62
+ end.setUint32(0, 101010256, true);
63
+ end.setUint16(8, files.length, true);
64
+ end.setUint16(10, files.length, true);
65
+ end.setUint32(12, centralSize, true);
66
+ end.setUint32(16, offset, true);
67
+ const parts = [
68
+ ...chunks,
69
+ ...central,
70
+ new Uint8Array(end.buffer)
71
+ ];
72
+ const out = new Uint8Array(parts.reduce((size, part) => size + part.length, 0));
73
+ let position = 0;
74
+ for (const part of parts) {
75
+ out.set(part, position);
76
+ position += part.length;
77
+ }
78
+ return out;
79
+ }
80
+ function columnName(index) {
81
+ let name = "";
82
+ for (let n = index + 1; n > 0; n = Math.floor((n - 1) / 26)) name = String.fromCharCode(65 + (n - 1) % 26) + name;
83
+ return name;
84
+ }
85
+ function buildXlsx(headers, rows, sheetName = "Sheet1") {
86
+ const cell = (value, column, row, style = "") => {
87
+ const ref = `${columnName(column)}${row}`;
88
+ return typeof value === "number" && Number.isFinite(value) ? `<c r="${ref}"${style}><v>${value}</v></c>` : `<c r="${ref}"${style} t="inlineStr"><is><t xml:space="preserve">${escapeXml(String(value))}</t></is></c>`;
89
+ };
90
+ const sheetRows = [`<row r="1">${headers.map((header, i) => cell(header, i, 1, " s=\"1\"")).join("")}</row>`, ...rows.map((row, r) => `<row r="${r + 2}">${row.map((value, i) => cell(value, i, r + 2)).join("")}</row>`)];
91
+ const head = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
92
+ const main = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
93
+ const rel = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
94
+ const pkg = "http://schemas.openxmlformats.org/package/2006";
95
+ const type = "application/vnd.openxmlformats-officedocument.spreadsheetml";
96
+ const safeName = escapeXml(sheetName.replace(/[\\/?*[\]:]/g, " ").slice(0, 31) || "Sheet1");
97
+ return zip([
98
+ {
99
+ name: "[Content_Types].xml",
100
+ text: `${head}<Types xmlns="${pkg}/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="${type}.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="${type}.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="${type}.styles+xml"/></Types>`
101
+ },
102
+ {
103
+ name: "_rels/.rels",
104
+ text: `${head}<Relationships xmlns="${pkg}/relationships"><Relationship Id="rId1" Type="${rel}/officeDocument" Target="xl/workbook.xml"/></Relationships>`
105
+ },
106
+ {
107
+ name: "xl/workbook.xml",
108
+ text: `${head}<workbook xmlns="${main}" xmlns:r="${rel}"><sheets><sheet name="${safeName}" sheetId="1" r:id="rId1"/></sheets></workbook>`
109
+ },
110
+ {
111
+ name: "xl/_rels/workbook.xml.rels",
112
+ text: `${head}<Relationships xmlns="${pkg}/relationships"><Relationship Id="rId1" Type="${rel}/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="${rel}/styles" Target="styles.xml"/></Relationships>`
113
+ },
114
+ {
115
+ name: "xl/styles.xml",
116
+ text: `${head}<styleSheet xmlns="${main}"><fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><b/><sz val="11"/><name val="Calibri"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="1"><border/></borders><cellStyleXfs count="1"><xf/></cellStyleXfs><cellXfs count="2"><xf/><xf fontId="1" applyFont="1"/></cellXfs></styleSheet>`
117
+ },
118
+ {
119
+ name: "xl/worksheets/sheet1.xml",
120
+ text: `${head}<worksheet xmlns="${main}"><sheetData>${sheetRows.join("")}</sheetData></worksheet>`
121
+ }
122
+ ]);
123
+ }
124
+ const LONG_WORD = 20;
125
+ const WORD_CHUNK = 12;
126
+ function printable(value) {
127
+ return String(value).split(/(\s+)/).map((word) => {
128
+ const letters = Array.from(word);
129
+ if (letters.length <= LONG_WORD) return escapeXml(word);
130
+ const chunks = [];
131
+ for (let start = 0; start < letters.length; start += WORD_CHUNK) chunks.push(escapeXml(letters.slice(start, start + WORD_CHUNK).join("")));
132
+ return chunks.join("<wbr>");
133
+ }).join("");
134
+ }
135
+ const PRINT_SIZE = 12;
136
+ const PRINT_FIT_STEPS = [
137
+ {
138
+ size: PRINT_SIZE,
139
+ wrap: false,
140
+ anywhere: false
141
+ },
142
+ {
143
+ size: PRINT_SIZE,
144
+ wrap: true,
145
+ anywhere: false
146
+ },
147
+ {
148
+ size: 11,
149
+ wrap: true,
150
+ anywhere: false
151
+ },
152
+ {
153
+ size: 10,
154
+ wrap: true,
155
+ anywhere: false
156
+ },
157
+ {
158
+ size: 9,
159
+ wrap: true,
160
+ anywhere: false
161
+ },
162
+ {
163
+ size: 8,
164
+ wrap: true,
165
+ anywhere: false
166
+ },
167
+ {
168
+ size: 8,
169
+ wrap: true,
170
+ anywhere: true
171
+ }
172
+ ];
173
+ const round = (value) => Math.round(value * 100) / 100;
174
+ function fitRules(step, scope, columns = []) {
175
+ const scale = step.size / PRINT_SIZE;
176
+ const total = columns.reduce((sum, width) => sum + width, 0);
177
+ return `${scope}{font-size:${step.size}px${step.anywhere && total ? ";table-layout:fixed" : ""}}${scope} th,${scope} td{padding:${round(4 * scale)}px ${round(8 * scale)}px${step.anywhere ? ";overflow-wrap:anywhere" : ""}}` + (step.wrap ? `${scope} td.s{white-space:normal}` : "") + (step.anywhere && total ? `${scope} th{box-sizing:border-box}` + columns.map((width, index) => `${scope} th:nth-child(${index + 1}){width:${Math.floor(width / total * 1e4) / 100}%}`).join("") : "");
178
+ }
179
+ function printFitStyle(widths, columns = []) {
180
+ let narrowest = widths[0] ?? 0;
181
+ let css = "";
182
+ for (let index = 1; index < widths.length && index < PRINT_FIT_STEPS.length; index++) {
183
+ if (widths[index] >= narrowest) continue;
184
+ css += `@container (width < ${narrowest}px){${fitRules(PRINT_FIT_STEPS[index], "table", columns)}}`;
185
+ narrowest = widths[index];
186
+ }
187
+ return css;
188
+ }
189
+ function fitPrintDocument(doc) {
190
+ const table = doc.querySelector("table");
191
+ if (!table) return {
192
+ widths: [],
193
+ columns: []
194
+ };
195
+ const probe = doc.createElement("style");
196
+ doc.head.append(probe);
197
+ const lastWhole = PRINT_FIT_STEPS.findIndex((step) => step.anywhere) - 1;
198
+ let columns = [];
199
+ const widths = PRINT_FIT_STEPS.map((step, index) => {
200
+ probe.textContent = `table{width:1px}${fitRules(step, "table")}`;
201
+ if (index === lastWhole) columns = Array.from(table.querySelectorAll("thead th"), (cell) => Math.ceil(cell.getBoundingClientRect().width));
202
+ return Math.ceil(table.getBoundingClientRect().width);
203
+ });
204
+ probe.remove();
205
+ const css = printFitStyle(widths, columns);
206
+ if (css) {
207
+ const style = doc.createElement("style");
208
+ style.textContent = css;
209
+ doc.head.append(style);
210
+ }
211
+ return {
212
+ widths,
213
+ columns
214
+ };
215
+ }
216
+ function buildPrintDocument(title, headers, rows) {
217
+ const escape = (value) => escapeXml(String(value));
218
+ const cellClass = (value) => {
219
+ const text = String(value);
220
+ const classes = [typeof value === "number" ? "n" : "", typeof value !== "number" && text.length <= LONG_WORD && !/\s/.test(text) ? "s" : ""].filter(Boolean);
221
+ return classes.length ? ` class="${classes.join(" ")}"` : "";
222
+ };
223
+ const numberColumn = (index) => rows.length > 0 && rows.every((row) => typeof row[index] === "number");
224
+ return `<!doctype html><html><head><meta charset="utf-8"><title>${escape(title)}</title><style>
225
+ body{font:12px/1.4 system-ui,sans-serif;color:#000;margin:16px}
226
+ h1{font-size:16px;margin:0 0 12px;overflow-wrap:anywhere}
227
+ .fit{container-type:inline-size}
228
+ table{width:100%;border-collapse:collapse}
229
+ th,td{padding:4px 8px;border:1px solid #999;text-align:left;vertical-align:top;overflow-wrap:break-word}
230
+ th{background:#eee}
231
+ th.n,td.n{text-align:right}
232
+ td.s{white-space:nowrap}
233
+ thead{display:table-header-group}
234
+ tr{break-inside:avoid}
235
+ </style></head><body><h1>${escape(title)}</h1><div class="fit"><table><thead><tr>${headers.map((header, index) => `<th scope="col"${numberColumn(index) ? " class=\"n\"" : ""}>${printable(header)}</th>`).join("")}</tr></thead><tbody>${rows.map((row) => `<tr>${row.map((value) => `<td${cellClass(value)}>${printable(value)}</td>`).join("")}</tr>`).join("")}</tbody></table></div></body></html>`;
236
+ }
237
+ var HeightTree = class {
238
+ heights;
239
+ sums;
240
+ topBit;
241
+ constructor(heights) {
242
+ const count = heights.length;
243
+ this.heights = new Float64Array(count);
244
+ this.sums = new Float64Array(count + 1);
245
+ for (let i = 0; i < count; i++) {
246
+ const height = Math.max(0, heights[i] || 0);
247
+ this.heights[i] = height;
248
+ this.sums[i + 1] += height;
249
+ const parent = i + 1 + (i + 1 & -(i + 1));
250
+ if (parent <= count) this.sums[parent] += this.sums[i + 1];
251
+ }
252
+ let bit = 1;
253
+ while (bit * 2 <= count) bit *= 2;
254
+ this.topBit = count ? bit : 0;
255
+ }
256
+ get size() {
257
+ return this.heights.length;
258
+ }
259
+ get total() {
260
+ return this.offsetOf(this.size);
261
+ }
262
+ get(index) {
263
+ return this.heights[index] ?? 0;
264
+ }
265
+ set(index, height) {
266
+ const delta = Math.max(0, height) - this.heights[index];
267
+ if (!delta) return 0;
268
+ this.heights[index] += delta;
269
+ for (let i = index + 1; i <= this.size; i += i & -i) this.sums[i] += delta;
270
+ return delta;
271
+ }
272
+ offsetOf(index) {
273
+ let sum = 0;
274
+ for (let i = Math.min(index, this.size); i > 0; i -= i & -i) sum += this.sums[i];
275
+ return sum;
276
+ }
277
+ indexAt(offset) {
278
+ if (!this.size) return -1;
279
+ let index = 0;
280
+ let rest = Math.max(0, offset);
281
+ for (let bit = this.topBit; bit > 0; bit >>= 1) {
282
+ const next = index + bit;
283
+ if (next <= this.size && this.sums[next] <= rest) {
284
+ index = next;
285
+ rest -= this.sums[next];
286
+ }
287
+ }
288
+ return Math.min(index, this.size - 1);
289
+ }
290
+ };
291
+ function variableRange(tree, top, viewport, buffer) {
292
+ const count = tree.size;
293
+ if (!count) return {
294
+ start: 0,
295
+ end: 0,
296
+ first: 0,
297
+ before: 0,
298
+ after: 0
299
+ };
300
+ const from = Math.max(0, top);
301
+ const first = tree.indexAt(from);
302
+ const last = tree.indexAt(from + Math.max(1, viewport) - 1);
303
+ const start = Math.max(0, first - buffer);
304
+ const end = Math.min(count, last + 1 + buffer);
305
+ return {
306
+ start,
307
+ end,
308
+ first,
309
+ before: tree.offsetOf(start),
310
+ after: tree.total - tree.offsetOf(end)
311
+ };
312
+ }
313
+ function anchorShift(changes, anchor) {
314
+ let shift = 0;
315
+ for (const change of changes) if (change.index < anchor) shift += change.to - change.from;
316
+ return shift;
317
+ }
318
+ function anchorOf(tree, top) {
319
+ const index = tree.indexAt(top);
320
+ if (index < 0) return null;
321
+ return {
322
+ index,
323
+ inside: Math.max(0, top) - tree.offsetOf(index)
324
+ };
325
+ }
326
+ function groupKey(label) {
327
+ return `\u0000group\u0000${label}`;
328
+ }
329
+ function buildVirtualLayout(rows, options) {
330
+ const items = [];
331
+ const counts = [];
332
+ let aria = 0;
333
+ let label = null;
334
+ let collapsed = false;
335
+ rows.forEach((row, index) => {
336
+ if (options.groupOf) {
337
+ const group = options.groupOf(row);
338
+ if (index === 0 || group !== label) {
339
+ label = group;
340
+ collapsed = options.isCollapsed(group);
341
+ counts.push(0);
342
+ items.push({
343
+ kind: "group",
344
+ key: groupKey(group),
345
+ label: group,
346
+ count: 0,
347
+ collapsed,
348
+ aria
349
+ });
350
+ aria++;
351
+ }
352
+ counts[counts.length - 1]++;
353
+ if (collapsed) return;
354
+ }
355
+ const expanded = options.isExpanded(row);
356
+ items.push({
357
+ kind: "row",
358
+ key: options.keyOf(row),
359
+ row,
360
+ index,
361
+ expanded,
362
+ aria
363
+ });
364
+ aria += expanded ? 2 : 1;
365
+ });
366
+ let group = 0;
367
+ const indexOfKey = /* @__PURE__ */ new Map();
368
+ const heights = new Float64Array(items.length);
369
+ items.forEach((item, index) => {
370
+ if (item.kind === "group") items[index] = {
371
+ ...item,
372
+ count: counts[group++]
373
+ };
374
+ indexOfKey.set(item.key, index);
375
+ heights[index] = options.heightOf(items[index]);
376
+ });
377
+ return {
378
+ items,
379
+ tree: new HeightTree(heights),
380
+ bodyRows: aria,
381
+ indexOfKey
382
+ };
383
+ }
384
+ function isRange(value) {
385
+ return typeof value === "object" && value !== null && !Array.isArray(value);
386
+ }
387
+ function hasBound(bound) {
388
+ return bound !== null && bound !== void 0 && bound !== "";
389
+ }
390
+ function isActiveFilter(value) {
391
+ if (isRange(value)) return hasBound(value.min) || hasBound(value.max);
392
+ return !!value && value.length > 0;
393
+ }
394
+ function dayKey(value) {
395
+ if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value)) return value.slice(0, 10);
396
+ const date = value instanceof Date ? value : new Date(value);
397
+ if (value === null || value === void 0 || Number.isNaN(date.getTime())) return "";
398
+ const pad = (part) => String(part).padStart(2, "0");
399
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
400
+ }
401
+ const VIRTUAL_BUFFER_ROWS = 5;
402
+ const VIRTUAL_FALLBACK_VIEWPORT = 480;
403
+ const MEASURE_TOLERANCE = .1;
404
+ const FOCUSABLE = "button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])";
405
+ const MIN_COLUMN_WIDTH = 48;
406
+ const MAX_COLUMN_WIDTH_HINT = 2e3;
407
+ var StarCellTemplate = class StarCellTemplate {
408
+ starCell = input.required(...ngDevMode ? [{ debugName: "starCell" }] : /* istanbul ignore next */ []);
409
+ starCellOf = input(null, ...ngDevMode ? [{ debugName: "starCellOf" }] : /* istanbul ignore next */ []);
410
+ template = inject(TemplateRef);
411
+ static ngTemplateContextGuard(_dir, _ctx) {
412
+ return true;
413
+ }
414
+ static ɵfac = i0.ɵɵngDeclareFactory({
415
+ minVersion: "12.0.0",
416
+ version: "22.2.6",
417
+ ngImport: i0,
418
+ type: StarCellTemplate,
419
+ deps: [],
420
+ target: i0.ɵɵFactoryTarget.Directive
421
+ });
422
+ static ɵdir = i0.ɵɵngDeclareDirective({
423
+ minVersion: "17.1.0",
424
+ version: "22.2.6",
425
+ type: StarCellTemplate,
426
+ isStandalone: true,
427
+ selector: "ng-template[starCell]",
428
+ inputs: {
429
+ starCell: {
430
+ classPropertyName: "starCell",
431
+ publicName: "starCell",
432
+ isSignal: true,
433
+ isRequired: true,
434
+ transformFunction: null
435
+ },
436
+ starCellOf: {
437
+ classPropertyName: "starCellOf",
438
+ publicName: "starCellOf",
439
+ isSignal: true,
440
+ isRequired: false,
441
+ transformFunction: null
442
+ }
443
+ },
444
+ ngImport: i0
445
+ });
446
+ };
447
+ i0.ɵɵngDeclareClassMetadata({
448
+ minVersion: "12.0.0",
449
+ version: "22.2.6",
450
+ ngImport: i0,
451
+ type: StarCellTemplate,
452
+ decorators: [{
453
+ type: Directive,
454
+ args: [{ selector: "ng-template[starCell]" }]
455
+ }],
456
+ propDecorators: {
457
+ starCell: [{
458
+ type: i0.Input,
459
+ args: [{
460
+ isSignal: true,
461
+ alias: "starCell",
462
+ required: true
463
+ }]
464
+ }],
465
+ starCellOf: [{
466
+ type: i0.Input,
467
+ args: [{
468
+ isSignal: true,
469
+ alias: "starCellOf",
470
+ required: false
471
+ }]
472
+ }]
473
+ }
474
+ });
475
+ var StarRowExpansionTemplate = class StarRowExpansionTemplate {
476
+ starRowExpansionOf = input(null, ...ngDevMode ? [{ debugName: "starRowExpansionOf" }] : /* istanbul ignore next */ []);
477
+ template = inject(TemplateRef);
478
+ static ngTemplateContextGuard(_dir, _ctx) {
479
+ return true;
480
+ }
481
+ static ɵfac = i0.ɵɵngDeclareFactory({
482
+ minVersion: "12.0.0",
483
+ version: "22.2.6",
484
+ ngImport: i0,
485
+ type: StarRowExpansionTemplate,
486
+ deps: [],
487
+ target: i0.ɵɵFactoryTarget.Directive
488
+ });
489
+ static ɵdir = i0.ɵɵngDeclareDirective({
490
+ minVersion: "17.1.0",
491
+ version: "22.2.6",
492
+ type: StarRowExpansionTemplate,
493
+ isStandalone: true,
494
+ selector: "ng-template[starRowExpansion]",
495
+ inputs: { starRowExpansionOf: {
496
+ classPropertyName: "starRowExpansionOf",
497
+ publicName: "starRowExpansionOf",
498
+ isSignal: true,
499
+ isRequired: false,
500
+ transformFunction: null
501
+ } },
502
+ ngImport: i0
503
+ });
504
+ };
505
+ i0.ɵɵngDeclareClassMetadata({
506
+ minVersion: "12.0.0",
507
+ version: "22.2.6",
508
+ ngImport: i0,
509
+ type: StarRowExpansionTemplate,
510
+ decorators: [{
511
+ type: Directive,
512
+ args: [{ selector: "ng-template[starRowExpansion]" }]
513
+ }],
514
+ propDecorators: { starRowExpansionOf: [{
515
+ type: i0.Input,
516
+ args: [{
517
+ isSignal: true,
518
+ alias: "starRowExpansionOf",
519
+ required: false
520
+ }]
521
+ }] }
522
+ });
523
+ var StarTable = class StarTable {
524
+ text = inject(STAR_UI_TEXT);
525
+ document = inject(DOCUMENT);
526
+ host = inject(ElementRef);
527
+ injector = inject(Injector);
528
+ appRef = inject(ApplicationRef);
529
+ value = input.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
530
+ columns = input.required(...ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []);
531
+ dataKey = input(null, ...ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []);
532
+ loading = input(false, {
533
+ ...ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {},
534
+ transform: booleanAttribute
535
+ });
536
+ emptyMessage = input(null, ...ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []);
537
+ striped = input(false, {
538
+ ...ngDevMode ? { debugName: "striped" } : /* istanbul ignore next */ {},
539
+ transform: booleanAttribute
540
+ });
541
+ size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
542
+ stickyHeader = input(false, {
543
+ ...ngDevMode ? { debugName: "stickyHeader" } : /* istanbul ignore next */ {},
544
+ transform: booleanAttribute
545
+ });
546
+ scrollHeight = input(null, ...ngDevMode ? [{ debugName: "scrollHeight" }] : /* istanbul ignore next */ []);
547
+ responsiveLayout = input("scroll", ...ngDevMode ? [{ debugName: "responsiveLayout" }] : /* istanbul ignore next */ []);
548
+ virtualScroll = input(false, {
549
+ ...ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {},
550
+ transform: booleanAttribute
551
+ });
552
+ virtualRowHeight = input(48, ...ngDevMode ? [{ debugName: "virtualRowHeight" }] : /* istanbul ignore next */ []);
553
+ virtualRowHeights = input("auto", ...ngDevMode ? [{ debugName: "virtualRowHeights" }] : /* istanbul ignore next */ []);
554
+ ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
555
+ paginator = input(false, {
556
+ ...ngDevMode ? { debugName: "paginator" } : /* istanbul ignore next */ {},
557
+ transform: booleanAttribute
558
+ });
559
+ first = model(0, ...ngDevMode ? [{ debugName: "first" }] : /* istanbul ignore next */ []);
560
+ rows = model(10, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
561
+ rowsPerPageOptions = input([
562
+ 10,
563
+ 25,
564
+ 50
565
+ ], ...ngDevMode ? [{ debugName: "rowsPerPageOptions" }] : /* istanbul ignore next */ []);
566
+ sortField = model(null, ...ngDevMode ? [{ debugName: "sortField" }] : /* istanbul ignore next */ []);
567
+ sortOrder = model(1, ...ngDevMode ? [{ debugName: "sortOrder" }] : /* istanbul ignore next */ []);
568
+ globalFilter = input("", ...ngDevMode ? [{ debugName: "globalFilter" }] : /* istanbul ignore next */ []);
569
+ filters = model({}, ...ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []);
570
+ lazy = input(false, {
571
+ ...ngDevMode ? { debugName: "lazy" } : /* istanbul ignore next */ {},
572
+ transform: booleanAttribute
573
+ });
574
+ totalRecords = input(0, ...ngDevMode ? [{ debugName: "totalRecords" }] : /* istanbul ignore next */ []);
575
+ selectionMode = input(null, ...ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []);
576
+ selection = model([], ...ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []);
577
+ expandedKeys = model([], ...ngDevMode ? [{ debugName: "expandedKeys" }] : /* istanbul ignore next */ []);
578
+ rowExpandMode = input("multiple", ...ngDevMode ? [{ debugName: "rowExpandMode" }] : /* istanbul ignore next */ []);
579
+ columnToggle = input(false, {
580
+ ...ngDevMode ? { debugName: "columnToggle" } : /* istanbul ignore next */ {},
581
+ transform: booleanAttribute
582
+ });
583
+ reorderableColumns = input(false, {
584
+ ...ngDevMode ? { debugName: "reorderableColumns" } : /* istanbul ignore next */ {},
585
+ transform: booleanAttribute
586
+ });
587
+ resizableColumns = input(false, {
588
+ ...ngDevMode ? { debugName: "resizableColumns" } : /* istanbul ignore next */ {},
589
+ transform: booleanAttribute
590
+ });
591
+ columnOrder = model([], ...ngDevMode ? [{ debugName: "columnOrder" }] : /* istanbul ignore next */ []);
592
+ hiddenColumns = model([], ...ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []);
593
+ columnWidths = model({}, ...ngDevMode ? [{ debugName: "columnWidths" }] : /* istanbul ignore next */ []);
594
+ multiSort = input(false, {
595
+ ...ngDevMode ? { debugName: "multiSort" } : /* istanbul ignore next */ {},
596
+ transform: booleanAttribute
597
+ });
598
+ sortMeta = model([], ...ngDevMode ? [{ debugName: "sortMeta" }] : /* istanbul ignore next */ []);
599
+ groupBy = input(null, ...ngDevMode ? [{ debugName: "groupBy" }] : /* istanbul ignore next */ []);
600
+ collapsedGroups = model([], ...ngDevMode ? [{ debugName: "collapsedGroups" }] : /* istanbul ignore next */ []);
601
+ reorderableRows = input(false, {
602
+ ...ngDevMode ? { debugName: "reorderableRows" } : /* istanbul ignore next */ {},
603
+ transform: booleanAttribute
604
+ });
605
+ stateKey = input(null, ...ngDevMode ? [{ debugName: "stateKey" }] : /* istanbul ignore next */ []);
606
+ stateStorage = input("local", ...ngDevMode ? [{ debugName: "stateStorage" }] : /* istanbul ignore next */ []);
607
+ rowClick = output();
608
+ rowReorder = output();
609
+ cellEdit = output();
610
+ lazyLoad = output();
611
+ editing = signal(null, ...ngDevMode ? [{ debugName: "editing" }] : /* istanbul ignore next */ []);
612
+ cellTemplates = contentChildren(StarCellTemplate, ...ngDevMode ? [{ debugName: "cellTemplates" }] : /* istanbul ignore next */ []);
613
+ expansion = contentChild(StarRowExpansionTemplate, ...ngDevMode ? [{ debugName: "expansion" }] : /* istanbul ignore next */ []);
614
+ expansionTemplate = computed(() => this.expansion()?.template ?? null, ...ngDevMode ? [{ debugName: "expansionTemplate" }] : /* istanbul ignore next */ []);
615
+ expandable = computed(() => !!this.expansion(), ...ngDevMode ? [{ debugName: "expandable" }] : /* istanbul ignore next */ []);
616
+ radioName = `star-table-${Math.random().toString(36).slice(2)}`;
617
+ clickable = computed(() => this.selectionMode() === "single", ...ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []);
618
+ orderedColumns = computed(() => {
619
+ const order = this.columnOrder();
620
+ const rank = (column, index) => {
621
+ const position = order.indexOf(column.field);
622
+ return (column.frozen ? 0 : 1e6) + (position < 0 ? order.length + index : position);
623
+ };
624
+ return this.columns().map((column, index) => ({
625
+ column,
626
+ rank: rank(column, index)
627
+ })).sort((a, b) => a.rank - b.rank).map(({ column }) => column);
628
+ }, ...ngDevMode ? [{ debugName: "orderedColumns" }] : /* istanbul ignore next */ []);
629
+ visibleColumns = computed(() => {
630
+ const hidden = this.hiddenColumns();
631
+ return this.orderedColumns().filter((column) => !hidden.includes(column.field));
632
+ }, ...ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []);
633
+ dragField = signal(null, ...ngDevMode ? [{ debugName: "dragField" }] : /* istanbul ignore next */ []);
634
+ dropField = signal(null, ...ngDevMode ? [{ debugName: "dropField" }] : /* istanbul ignore next */ []);
635
+ resizing = false;
636
+ hasColumnFilters = computed(() => this.visibleColumns().some((column) => column.filter), ...ngDevMode ? [{ debugName: "hasColumnFilters" }] : /* istanbul ignore next */ []);
637
+ activeFilters = computed(() => {
638
+ const filters = this.filters();
639
+ return this.columns().flatMap((column) => {
640
+ const query = filters[column.field];
641
+ return column.filter && isActiveFilter(query) ? [{
642
+ column,
643
+ query
644
+ }] : [];
645
+ });
646
+ }, ...ngDevMode ? [{ debugName: "activeFilters" }] : /* istanbul ignore next */ []);
647
+ filtered = computed(() => {
648
+ if (this.lazy()) return this.value();
649
+ const query = this.globalFilter();
650
+ const active = this.activeFilters();
651
+ if (!query && !active.length) return this.value();
652
+ return this.value().filter((row) => (!query || this.columns().some((column) => matchesFilter(this.cellText(row, column), query))) && active.every(({ column, query: value }) => this.matchesColumnFilter(row, column, value)));
653
+ }, ...ngDevMode ? [{ debugName: "filtered" }] : /* istanbul ignore next */ []);
654
+ sorts = computed(() => {
655
+ const meta = this.sortMeta();
656
+ if (this.multiSort() && meta.length) return meta;
657
+ const field = this.sortField();
658
+ return field ? [{
659
+ field,
660
+ order: this.sortOrder()
661
+ }] : [];
662
+ }, ...ngDevMode ? [{ debugName: "sorts" }] : /* istanbul ignore next */ []);
663
+ sorted = computed(() => {
664
+ let rows = this.filtered();
665
+ if (this.lazy()) return rows;
666
+ const sorts = this.sorts().flatMap((sort) => {
667
+ const column = this.columns().find((c) => c.field === sort.field);
668
+ return column ? [{
669
+ column,
670
+ order: sort.order
671
+ }] : [];
672
+ });
673
+ if (sorts.length) rows = [...rows].sort((a, b) => {
674
+ for (const { column, order } of sorts) {
675
+ const result = compareValues(this.cellValue(a, column), this.cellValue(b, column));
676
+ if (result) return order * result;
677
+ }
678
+ return 0;
679
+ });
680
+ if (!this.groupBy()) return rows;
681
+ const rank = /* @__PURE__ */ new Map();
682
+ for (const row of rows) {
683
+ const group = this.groupOf(row);
684
+ if (!rank.has(group)) rank.set(group, rank.size);
685
+ }
686
+ return rows.map((row, index) => ({
687
+ row,
688
+ index,
689
+ rank: rank.get(this.groupOf(row)) ?? 0
690
+ })).sort((a, b) => a.rank - b.rank || a.index - b.index).map(({ row }) => row);
691
+ }, ...ngDevMode ? [{ debugName: "sorted" }] : /* istanbul ignore next */ []);
692
+ groupStarts = computed(() => {
693
+ const starts = /* @__PURE__ */ new Map();
694
+ if (!this.groupBy()) return starts;
695
+ let current = null;
696
+ this.pageRows().forEach((row, index) => {
697
+ const label = this.groupOf(row);
698
+ if (!current || current.label !== label) {
699
+ current = {
700
+ label,
701
+ count: 0
702
+ };
703
+ starts.set(index, current);
704
+ }
705
+ current.count++;
706
+ });
707
+ return starts;
708
+ }, ...ngDevMode ? [{ debugName: "groupStarts" }] : /* istanbul ignore next */ []);
709
+ hasFooter = computed(() => this.visibleColumns().some((column) => column.footer !== void 0), ...ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []);
710
+ rowOrderIsOwn = computed(() => !this.lazy() && !this.sorts().length && !this.globalFilter() && !this.activeFilters().length && !this.groupBy(), ...ngDevMode ? [{ debugName: "rowOrderIsOwn" }] : /* istanbul ignore next */ []);
711
+ restoredKey = null;
712
+ total = computed(() => this.lazy() ? this.totalRecords() : this.filtered().length, ...ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []);
713
+ pageRows = computed(() => {
714
+ const rows = this.sorted();
715
+ if (this.lazy() || !this.paginator()) return rows;
716
+ return rows.slice(this.first(), this.first() + this.rows());
717
+ }, ...ngDevMode ? [{ debugName: "pageRows" }] : /* istanbul ignore next */ []);
718
+ scrollTop = signal(0, ...ngDevMode ? [{ debugName: "scrollTop" }] : /* istanbul ignore next */ []);
719
+ viewportHeight = signal(0, ...ngDevMode ? [{ debugName: "viewportHeight" }] : /* istanbul ignore next */ []);
720
+ scroller = viewChild("scroller", ...ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ []);
721
+ body = viewChild("body", ...ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []);
722
+ variableHeights = computed(() => this.virtualScroll() && (this.virtualRowHeights() === "variable" || this.expandable() || !!this.groupBy() || this.responsiveLayout() === "stack"), ...ngDevMode ? [{ debugName: "variableHeights" }] : /* istanbul ignore next */ []);
723
+ headerRows = computed(() => this.hasColumnFilters() ? 2 : 1, ...ngDevMode ? [{ debugName: "headerRows" }] : /* istanbul ignore next */ []);
724
+ ariaRowCount = computed(() => {
725
+ if (!this.virtualScroll()) return null;
726
+ const body = this.layout()?.bodyRows ?? this.pageRows().length;
727
+ return this.headerRows() + body + (this.hasFooter() ? 1 : 0);
728
+ }, ...ngDevMode ? [{ debugName: "ariaRowCount" }] : /* istanbul ignore next */ []);
729
+ expandedSet = computed(() => new Set(this.expandedKeys()), ...ngDevMode ? [{ debugName: "expandedSet" }] : /* istanbul ignore next */ []);
730
+ rowHeights = /* @__PURE__ */ new Map();
731
+ expandedHeights = /* @__PURE__ */ new Map();
732
+ measured = signal(0, ...ngDevMode ? [{ debugName: "measured" }] : /* istanbul ignore next */ []);
733
+ heightEpoch = signal(0, ...ngDevMode ? [{ debugName: "heightEpoch" }] : /* istanbul ignore next */ []);
734
+ bodyOffset = signal(0, ...ngDevMode ? [{ debugName: "bodyOffset" }] : /* istanbul ignore next */ []);
735
+ layout = computed(() => {
736
+ if (!this.variableHeights() || this.loading()) return null;
737
+ const rows = this.pageRows();
738
+ const grouped = !!this.groupBy();
739
+ const collapsed = new Set(this.collapsedGroups());
740
+ const expandable = this.expandable();
741
+ const expanded = this.expandedSet();
742
+ const estimate = Math.max(1, this.virtualRowHeight());
743
+ this.heightEpoch();
744
+ return untracked(() => {
745
+ if (this.rowHeights.size + this.expandedHeights.size > 4 * rows.length + 1e3) {
746
+ this.rowHeights.clear();
747
+ this.expandedHeights.clear();
748
+ }
749
+ return buildVirtualLayout(rows, {
750
+ groupOf: grouped ? (row) => this.groupOf(row) : null,
751
+ isCollapsed: (label) => collapsed.has(label),
752
+ isExpanded: (row) => expandable && expanded.has(this.trackKey(row)),
753
+ keyOf: (row) => this.trackKey(row),
754
+ heightOf: (item) => this.estimateOf(item, estimate)
755
+ });
756
+ });
757
+ }, ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
758
+ estimateOf(item, estimate) {
759
+ if (item.kind === "group") return this.rowHeights.get(item.key) ?? estimate;
760
+ if (!item.expanded) return this.rowHeights.get(item.key) ?? estimate;
761
+ return this.expandedHeights.get(item.key) ?? (this.rowHeights.get(item.key) ?? estimate) + estimate;
762
+ }
763
+ anchorMemo = null;
764
+ pendingScroll = null;
765
+ variableWindow = computed(() => {
766
+ const layout = this.layout();
767
+ if (!layout) return null;
768
+ this.measured();
769
+ const rows = this.pageRows();
770
+ let top = Math.max(0, this.scrollTop() - this.bodyOffset());
771
+ const memo = this.anchorMemo;
772
+ if (memo && memo.layout !== layout && memo.rows === rows && memo.top === top) {
773
+ const anchor = anchorOf(memo.layout.tree, top);
774
+ const key = anchor ? memo.layout.items[anchor.index]?.key : void 0;
775
+ const index = anchor ? layout.indexOfKey.get(key) : void 0;
776
+ if (anchor && index !== void 0) {
777
+ const kept = layout.tree.offsetOf(index) + anchor.inside;
778
+ if (Math.abs(kept - top) > .5) {
779
+ top = kept;
780
+ this.pendingScroll = kept + untracked(this.bodyOffset);
781
+ }
782
+ }
783
+ }
784
+ this.anchorMemo = {
785
+ layout,
786
+ rows,
787
+ top
788
+ };
789
+ const viewport = this.viewportHeight() || VIRTUAL_FALLBACK_VIEWPORT;
790
+ return {
791
+ layout,
792
+ ...variableRange(layout.tree, top, viewport, VIRTUAL_BUFFER_ROWS)
793
+ };
794
+ }, ...ngDevMode ? [{ debugName: "variableWindow" }] : /* istanbul ignore next */ []);
795
+ focusedKey = signal(null, ...ngDevMode ? [{ debugName: "focusedKey" }] : /* istanbul ignore next */ []);
796
+ focusedIndex = computed(() => {
797
+ const focused = this.focusedKey();
798
+ if (!focused || !this.virtualScroll()) return -1;
799
+ const layout = this.layout();
800
+ if (layout) return layout.indexOfKey.get(focused.key) ?? -1;
801
+ return this.pageRows().findIndex((row) => Object.is(this.trackKey(row), focused.key));
802
+ }, ...ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []);
803
+ bodyEntries = computed(() => {
804
+ const rows = this.pageRows();
805
+ if (!this.virtualScroll()) {
806
+ const entries = [];
807
+ const starts = this.groupStarts();
808
+ rows.forEach((row, index) => {
809
+ const group = starts.get(index);
810
+ if (group) entries.push({
811
+ kind: "group",
812
+ key: groupKey(group.label),
813
+ ...group,
814
+ aria: null,
815
+ item: null
816
+ });
817
+ entries.push({
818
+ kind: "row",
819
+ key: this.trackKey(row),
820
+ row,
821
+ index,
822
+ aria: null,
823
+ item: null
824
+ });
825
+ });
826
+ return entries;
827
+ }
828
+ const header = this.headerRows();
829
+ const focused = this.focusedIndex();
830
+ const variable = this.variableWindow();
831
+ if (variable) {
832
+ const { layout } = variable;
833
+ return this.windowEntries(variable, focused, layout.tree.total, (i) => layout.tree.offsetOf(i), (i) => {
834
+ const item = layout.items[i];
835
+ const aria = header + item.aria + 1;
836
+ return item.kind === "group" ? {
837
+ kind: "group",
838
+ key: item.key,
839
+ label: item.label,
840
+ count: item.count,
841
+ aria,
842
+ item: i
843
+ } : {
844
+ kind: "row",
845
+ key: item.key,
846
+ row: item.row,
847
+ index: item.index,
848
+ aria,
849
+ item: i
850
+ };
851
+ });
852
+ }
853
+ const height = Math.max(1, this.virtualRowHeight());
854
+ const window = this.virtualWindow();
855
+ return this.windowEntries(window, focused, rows.length * height, (i) => i * height, (i) => ({
856
+ kind: "row",
857
+ key: this.trackKey(rows[i]),
858
+ row: rows[i],
859
+ index: i,
860
+ aria: header + i + 1,
861
+ item: i
862
+ }));
863
+ }, ...ngDevMode ? [{ debugName: "bodyEntries" }] : /* istanbul ignore next */ []);
864
+ windowEntries(window, focused, total, offsetOf, entryAt) {
865
+ const indexes = [];
866
+ if (focused >= 0 && focused < window.start) indexes.push(focused);
867
+ for (let i = window.start; i < window.end; i++) indexes.push(i);
868
+ if (focused >= window.end) indexes.push(focused);
869
+ const entries = [];
870
+ let cursor = 0;
871
+ let spacers = 0;
872
+ const spacer = (height) => {
873
+ if (height > .01) entries.push({
874
+ kind: "spacer",
875
+ key: `\u0000spacer${spacers++}`,
876
+ height
877
+ });
878
+ };
879
+ for (const index of indexes) {
880
+ spacer(offsetOf(index) - offsetOf(cursor));
881
+ entries.push(entryAt(index));
882
+ cursor = index + 1;
883
+ }
884
+ if (indexes.length) spacer(total - offsetOf(cursor));
885
+ return entries;
886
+ }
887
+ virtualWindow = computed(() => {
888
+ const count = this.pageRows().length;
889
+ if (!this.virtualScroll() || this.loading() || this.variableHeights()) return {
890
+ start: 0,
891
+ end: count,
892
+ before: 0,
893
+ after: 0
894
+ };
895
+ const height = Math.max(1, this.virtualRowHeight());
896
+ const viewport = this.viewportHeight() || VIRTUAL_FALLBACK_VIEWPORT;
897
+ const visible = Math.ceil(viewport / height);
898
+ const first = Math.min(Math.floor(this.scrollTop() / height), Math.max(0, count - visible));
899
+ const start = Math.max(0, first - VIRTUAL_BUFFER_ROWS);
900
+ const end = Math.min(count, first + visible + VIRTUAL_BUFFER_ROWS);
901
+ return {
902
+ start,
903
+ end,
904
+ before: start * height,
905
+ after: (count - end) * height
906
+ };
907
+ }, ...ngDevMode ? [{ debugName: "virtualWindow" }] : /* istanbul ignore next */ []);
908
+ onScroll(event) {
909
+ if (!this.virtualScroll()) return;
910
+ const viewport = event.target;
911
+ this.scrollTop.set(viewport.scrollTop);
912
+ this.viewportHeight.set(viewport.clientHeight);
913
+ }
914
+ observedRows = /* @__PURE__ */ new Set();
915
+ rowObserver = null;
916
+ measureRendered() {
917
+ const layout = untracked(this.layout);
918
+ const scroller = this.scroller()?.nativeElement;
919
+ const body = this.body()?.nativeElement;
920
+ if (!layout || !scroller || !body || !scroller.isConnected || !scroller.clientHeight) return;
921
+ if (this.pendingScroll !== null) {
922
+ scroller.scrollTop = this.pendingScroll;
923
+ this.pendingScroll = null;
924
+ }
925
+ const area = scroller.getBoundingClientRect();
926
+ const offset = body.getBoundingClientRect().top - area.top - scroller.clientTop + scroller.scrollTop;
927
+ const heights = /* @__PURE__ */ new Map();
928
+ for (const row of Array.from(body.children)) {
929
+ const item = row.dataset["vi"];
930
+ if (item === void 0) continue;
931
+ heights.set(Number(item), (heights.get(Number(item)) ?? 0) + row.getBoundingClientRect().height);
932
+ }
933
+ const { tree, items } = layout;
934
+ const anchor = tree.indexAt(scroller.scrollTop - offset);
935
+ const changes = [];
936
+ for (const [index, height] of heights) {
937
+ const item = items[index];
938
+ if (!item || height <= 0) continue;
939
+ const from = tree.get(index);
940
+ if (Math.abs(height - from) < MEASURE_TOLERANCE) continue;
941
+ tree.set(index, height);
942
+ changes.push({
943
+ index,
944
+ from,
945
+ to: height
946
+ });
947
+ (item.kind === "row" && item.expanded ? this.expandedHeights : this.rowHeights).set(item.key, height);
948
+ }
949
+ const shift = anchorShift(changes, anchor);
950
+ if (Math.abs(shift) >= .5) scroller.scrollTop += shift;
951
+ this.bodyOffset.set(offset);
952
+ this.viewportHeight.set(scroller.clientHeight);
953
+ this.scrollTop.set(scroller.scrollTop);
954
+ if (changes.length) this.measured.update((count) => count + 1);
955
+ this.observeRows(body);
956
+ }
957
+ observeRows(body) {
958
+ if (typeof ResizeObserver === "undefined") return;
959
+ this.rowObserver ??= new ResizeObserver(() => this.measureRendered());
960
+ const rows = /* @__PURE__ */ new Set([body, ...Array.from(body.querySelectorAll(":scope > tr[data-vi]"))]);
961
+ for (const row of this.observedRows) if (!rows.has(row)) {
962
+ this.rowObserver.unobserve(row);
963
+ this.observedRows.delete(row);
964
+ }
965
+ for (const row of rows) if (!this.observedRows.has(row)) {
966
+ this.rowObserver.observe(row);
967
+ this.observedRows.add(row);
968
+ }
969
+ }
970
+ itemOf(element) {
971
+ const row = element?.closest("tr[data-vi]");
972
+ return row && this.body()?.nativeElement.contains(row) ? Number(row.dataset["vi"]) : -1;
973
+ }
974
+ keyOfItem(index) {
975
+ const layout = this.layout();
976
+ if (layout) return layout.items[index]?.key;
977
+ const row = this.pageRows()[index];
978
+ return row === void 0 ? void 0 : this.trackKey(row);
979
+ }
980
+ onBodyFocusIn(event) {
981
+ if (!this.virtualScroll()) return;
982
+ const index = this.itemOf(event.target);
983
+ if (index < 0) return;
984
+ const key = this.keyOfItem(index);
985
+ if (!Object.is(this.focusedKey()?.key, key)) this.focusedKey.set({ key });
986
+ const scroller = this.scroller()?.nativeElement;
987
+ if (scroller) {
988
+ this.scrollTop.set(scroller.scrollTop);
989
+ if (scroller.clientHeight) this.viewportHeight.set(scroller.clientHeight);
990
+ }
991
+ }
992
+ onBodyFocusOut(event) {
993
+ if (!this.virtualScroll()) return;
994
+ const body = this.body()?.nativeElement;
995
+ const next = event.relatedTarget;
996
+ if (!body || next && body.contains(next)) return;
997
+ setTimeout(() => {
998
+ if (!body.contains(this.document.activeElement)) this.focusedKey.set(null);
999
+ });
1000
+ }
1001
+ onBodyKeydown(event) {
1002
+ if (event.key !== "Tab" || !this.virtualScroll() || event.defaultPrevented) return;
1003
+ const body = this.body()?.nativeElement;
1004
+ const index = this.itemOf(event.target);
1005
+ if (!body || index < 0) return;
1006
+ const step = event.shiftKey ? -1 : 1;
1007
+ const target = index + step;
1008
+ const count = this.layout()?.items.length ?? this.pageRows().length;
1009
+ if (target < 0 || target >= count || body.querySelector(`:scope > tr[data-vi="${target}"]`)) return;
1010
+ const own = this.focusablesOf(body, index);
1011
+ const position = own.indexOf(event.target);
1012
+ if (position < 0 || (step === 1 ? position < own.length - 1 : position > 0)) return;
1013
+ event.preventDefault();
1014
+ this.revealItem(target);
1015
+ afterNextRender(() => {
1016
+ for (let i = target; i >= 0 && i < count; i += step) {
1017
+ const controls = this.focusablesOf(body, i);
1018
+ if (!body.querySelector(`:scope > tr[data-vi="${i}"]`)) break;
1019
+ if (controls.length) {
1020
+ (step === 1 ? controls[0] : controls[controls.length - 1]).focus();
1021
+ return;
1022
+ }
1023
+ }
1024
+ }, { injector: this.injector });
1025
+ this.appRef.tick();
1026
+ }
1027
+ focusablesOf(body, index) {
1028
+ return Array.from(body.querySelectorAll(`:scope > tr[data-vi="${index}"]`)).flatMap((row) => Array.from(row.querySelectorAll(FOCUSABLE)));
1029
+ }
1030
+ revealItem(index) {
1031
+ const scroller = this.scroller()?.nativeElement;
1032
+ if (!scroller) return;
1033
+ const layout = this.layout();
1034
+ const offset = layout ? layout.tree.offsetOf(index) : index * Math.max(1, this.virtualRowHeight());
1035
+ scroller.scrollTop = Math.max(0, this.bodyOffset() + offset - scroller.clientHeight / 2);
1036
+ this.scrollTop.set(scroller.scrollTop);
1037
+ if (scroller.clientHeight) this.viewportHeight.set(scroller.clientHeight);
1038
+ }
1039
+ skeletonRows = computed(() => Array.from({ length: Math.min(this.rows(), 8) }, (_, i) => i), ...ngDevMode ? [{ debugName: "skeletonRows" }] : /* istanbul ignore next */ []);
1040
+ colspan = computed(() => this.visibleColumns().length + (this.selectionMode() ? 1 : 0) + (this.expandable() ? 1 : 0) + (this.reorderableRows() ? 1 : 0), ...ngDevMode ? [{ debugName: "colspan" }] : /* istanbul ignore next */ []);
1041
+ pageState = computed(() => {
1042
+ const rows = this.pageRows();
1043
+ const count = rows.filter((row) => this.isSelected(row)).length;
1044
+ if (!rows.length || count === 0) return false;
1045
+ return count === rows.length ? true : "mixed";
1046
+ }, ...ngDevMode ? [{ debugName: "pageState" }] : /* istanbul ignore next */ []);
1047
+ constructor() {
1048
+ effect(() => {
1049
+ this.globalFilter();
1050
+ this.filters();
1051
+ untracked(() => {
1052
+ this.first.set(0);
1053
+ this.emitLazy();
1054
+ });
1055
+ });
1056
+ afterRenderEffect({ read: () => this.measureFrozen() });
1057
+ afterRenderEffect(() => {
1058
+ this.bodyEntries();
1059
+ this.expandedKeys();
1060
+ if (this.variableHeights()) untracked(() => this.measureRendered());
1061
+ });
1062
+ const destroyRef = inject(DestroyRef);
1063
+ if (typeof ResizeObserver !== "undefined") {
1064
+ let width = null;
1065
+ const observer = new ResizeObserver((entries) => {
1066
+ this.resized.update((count) => count + 1);
1067
+ const next = Math.round(entries[entries.length - 1].contentRect.width);
1068
+ if (width !== null && next !== width && untracked(this.variableHeights)) {
1069
+ this.rowHeights.clear();
1070
+ this.expandedHeights.clear();
1071
+ this.heightEpoch.update((count) => count + 1);
1072
+ }
1073
+ width = next;
1074
+ });
1075
+ observer.observe(this.host.nativeElement);
1076
+ destroyRef.onDestroy(() => observer.disconnect());
1077
+ }
1078
+ destroyRef.onDestroy(() => this.rowObserver?.disconnect());
1079
+ if (isDevMode()) effect(() => {
1080
+ if (this.virtualScroll() && !this.scrollHeight()) console.warn("star-table: virtualScroll needs scrollHeight. Without it the table does not scroll inside its own area, and rows after the first window are not rendered.");
1081
+ if (this.virtualRowHeights() === "variable" && !this.virtualScroll()) console.warn("star-table: virtualRowHeights has no effect without virtualScroll.");
1082
+ });
1083
+ effect(() => {
1084
+ const key = this.stateKey();
1085
+ if (!key) return;
1086
+ if (this.restoredKey !== key) {
1087
+ this.restoredKey = key;
1088
+ untracked(() => this.restoreState(key));
1089
+ }
1090
+ const state = {
1091
+ sortField: this.sortField(),
1092
+ sortOrder: this.sortOrder(),
1093
+ sortMeta: this.sortMeta(),
1094
+ filters: this.filters(),
1095
+ columnOrder: this.columnOrder(),
1096
+ hiddenColumns: this.hiddenColumns(),
1097
+ columnWidths: this.columnWidths(),
1098
+ rows: this.rows(),
1099
+ collapsedGroups: this.collapsedGroups()
1100
+ };
1101
+ try {
1102
+ this.storage()?.setItem(key, JSON.stringify(state));
1103
+ } catch {}
1104
+ });
1105
+ }
1106
+ storage() {
1107
+ const view = this.document.defaultView;
1108
+ try {
1109
+ return (this.stateStorage() === "session" ? view?.sessionStorage : view?.localStorage) ?? null;
1110
+ } catch {
1111
+ return null;
1112
+ }
1113
+ }
1114
+ restoreState(key) {
1115
+ let state;
1116
+ try {
1117
+ state = JSON.parse(this.storage()?.getItem(key) ?? "null");
1118
+ } catch {
1119
+ return;
1120
+ }
1121
+ if (!state || typeof state !== "object") return;
1122
+ if (state.sortField !== void 0) this.sortField.set(state.sortField);
1123
+ if (state.sortOrder === 1 || state.sortOrder === -1) this.sortOrder.set(state.sortOrder);
1124
+ if (Array.isArray(state.sortMeta)) this.sortMeta.set(state.sortMeta);
1125
+ if (state.filters && typeof state.filters === "object") this.filters.set(state.filters);
1126
+ if (Array.isArray(state.columnOrder)) this.columnOrder.set(state.columnOrder);
1127
+ if (Array.isArray(state.hiddenColumns)) this.hiddenColumns.set(state.hiddenColumns);
1128
+ if (state.columnWidths && typeof state.columnWidths === "object") this.columnWidths.set(state.columnWidths);
1129
+ if (typeof state.rows === "number" && state.rows > 0) this.rows.set(state.rows);
1130
+ if (Array.isArray(state.collapsedGroups)) this.collapsedGroups.set(state.collapsedGroups);
1131
+ }
1132
+ clearState() {
1133
+ const key = this.stateKey();
1134
+ if (key) this.storage()?.removeItem(key);
1135
+ }
1136
+ groupOf(row) {
1137
+ const key = this.groupBy();
1138
+ const group = key ? readOption(row, key) : null;
1139
+ return group === null || group === void 0 ? "" : String(group);
1140
+ }
1141
+ isGroupCollapsed(label) {
1142
+ return this.collapsedGroups().includes(label);
1143
+ }
1144
+ isRowCollapsed(row) {
1145
+ return !!this.groupBy() && this.isGroupCollapsed(this.groupOf(row));
1146
+ }
1147
+ toggleGroup(label) {
1148
+ this.collapsedGroups.update((groups) => groups.includes(label) ? groups.filter((group) => group !== label) : [...groups, label]);
1149
+ }
1150
+ footerText(column) {
1151
+ const footer = column.footer;
1152
+ if (footer === void 0) return "";
1153
+ return typeof footer === "function" ? footer(this.sorted()) : footer;
1154
+ }
1155
+ canMoveRow(row, step) {
1156
+ if (!this.rowOrderIsOwn()) return false;
1157
+ const to = this.value().indexOf(row) + step;
1158
+ return to >= 0 && to < this.value().length;
1159
+ }
1160
+ moveRow(row, step) {
1161
+ if (!this.canMoveRow(row, step)) return;
1162
+ const from = this.value().indexOf(row);
1163
+ this.rowReorder.emit({
1164
+ row,
1165
+ from,
1166
+ to: from + step
1167
+ });
1168
+ }
1169
+ trackKey(row) {
1170
+ return readOption(row, this.dataKey());
1171
+ }
1172
+ cellTemplate(field) {
1173
+ return this.cellTemplates().find((t) => t.starCell() === field)?.template ?? null;
1174
+ }
1175
+ cellValue(row, column) {
1176
+ return column.value ? column.value(row) : row?.[column.field];
1177
+ }
1178
+ cellText(row, column) {
1179
+ if (column.format) return column.format(row);
1180
+ const value = this.cellValue(row, column);
1181
+ return value === null || value === void 0 ? "" : String(value);
1182
+ }
1183
+ isHidden(column) {
1184
+ return this.hiddenColumns().includes(column.field);
1185
+ }
1186
+ canHide(column) {
1187
+ if (column.hideable === false) return false;
1188
+ return this.isHidden(column) || this.visibleColumns().length > 1;
1189
+ }
1190
+ setColumnVisible(column, visible) {
1191
+ this.hiddenColumns.update((hidden) => visible ? hidden.filter((field) => field !== column.field) : [...hidden, column.field]);
1192
+ }
1193
+ moveColumn(field, targetField) {
1194
+ const fields = this.orderedColumns().map((column) => column.field);
1195
+ const from = fields.indexOf(field);
1196
+ const to = fields.indexOf(targetField);
1197
+ if (from < 0 || to < 0 || from === to) return;
1198
+ fields.splice(to, 0, ...fields.splice(from, 1));
1199
+ this.columnOrder.set(fields);
1200
+ }
1201
+ moveColumnBy(column, delta) {
1202
+ const fields = this.orderedColumns().map((item) => item.field);
1203
+ const target = fields[fields.indexOf(column.field) + delta];
1204
+ if (!target) return;
1205
+ this.moveColumn(column.field, target);
1206
+ this.focusMoveButton(column, delta);
1207
+ }
1208
+ moveKey(column, delta) {
1209
+ return `${this.radioName}|${column.field}|${delta}`;
1210
+ }
1211
+ focusMoveButton(column, delta) {
1212
+ afterNextRender(() => {
1213
+ const button = (step) => this.document.querySelector(`[data-move="${CSS.escape(this.moveKey(column, step))}"]`);
1214
+ const same = button(delta);
1215
+ (same && !same.disabled ? same : button(delta === 1 ? -1 : 1))?.focus();
1216
+ }, { injector: this.injector });
1217
+ }
1218
+ onDragStart(column, event) {
1219
+ if (this.resizing || !this.reorderableColumns()) {
1220
+ event.preventDefault();
1221
+ return;
1222
+ }
1223
+ this.dragField.set(column.field);
1224
+ event.dataTransfer?.setData("text/plain", column.field);
1225
+ if (event.dataTransfer) event.dataTransfer.effectAllowed = "move";
1226
+ }
1227
+ onDragOver(column, event) {
1228
+ const field = this.dragField();
1229
+ if (!field || field === column.field) return;
1230
+ event.preventDefault();
1231
+ this.dropField.set(column.field);
1232
+ }
1233
+ onDrop(column, event) {
1234
+ const field = this.dragField();
1235
+ if (!field) return;
1236
+ event.preventDefault();
1237
+ this.moveColumn(field, column.field);
1238
+ this.endDrag();
1239
+ }
1240
+ endDrag() {
1241
+ this.dragField.set(null);
1242
+ this.dropField.set(null);
1243
+ }
1244
+ widthOf(column) {
1245
+ return this.resizedWidth(column) ?? column.width ?? null;
1246
+ }
1247
+ resizedWidth(column) {
1248
+ const width = this.columnWidths()[column.field];
1249
+ return width ? `${width}px` : null;
1250
+ }
1251
+ frozenWidths = signal({}, ...ngDevMode ? [{ debugName: "frozenWidths" }] : /* istanbul ignore next */ []);
1252
+ headerWidths = signal({}, ...ngDevMode ? [{ debugName: "headerWidths" }] : /* istanbul ignore next */ []);
1253
+ scrollable = signal(false, ...ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ []);
1254
+ minColumnWidth = MIN_COLUMN_WIDTH;
1255
+ resizeNow(column) {
1256
+ const width = this.columnWidths()[column.field] ?? this.headerWidths()[column.field];
1257
+ return width === void 0 ? null : Math.round(width);
1258
+ }
1259
+ resizeMax(column) {
1260
+ return Math.max(MAX_COLUMN_WIDTH_HINT, this.resizeNow(column) ?? 0);
1261
+ }
1262
+ resized = signal(0, ...ngDevMode ? [{ debugName: "resized" }] : /* istanbul ignore next */ []);
1263
+ measureFrozen() {
1264
+ const frozen = this.visibleColumns().filter((column) => column.frozen);
1265
+ this.columnWidths();
1266
+ this.value();
1267
+ this.size();
1268
+ this.resized();
1269
+ const scroller = this.scroller()?.nativeElement;
1270
+ if (scroller) this.scrollable.set(scroller.scrollWidth > scroller.clientWidth + 1 || scroller.scrollHeight > scroller.clientHeight + 1);
1271
+ const resizable = this.resizableColumns();
1272
+ if (!frozen.length && !resizable) return;
1273
+ const widths = {};
1274
+ const all = {};
1275
+ for (const cell of this.host.nativeElement.querySelectorAll("thead th[data-field]")) {
1276
+ const field = cell.dataset["field"];
1277
+ if (!field) continue;
1278
+ const width = cell.getBoundingClientRect().width;
1279
+ all[field] = width;
1280
+ if (frozen.some((column) => column.field === field)) widths[field] = width;
1281
+ }
1282
+ const sameWidths = (next, current) => Object.keys(next).length === Object.keys(current).length && Object.entries(next).every(([field, width]) => Math.abs((current[field] ?? -1) - width) < .5);
1283
+ if (!sameWidths(widths, untracked(this.frozenWidths))) this.frozenWidths.set(widths);
1284
+ if (resizable && !sameWidths(all, untracked(this.headerWidths))) this.headerWidths.set(all);
1285
+ }
1286
+ frozenOffset(column) {
1287
+ if (!column.frozen) return null;
1288
+ const measured = this.frozenWidths();
1289
+ const before = [];
1290
+ let pixels = 0;
1291
+ let allMeasured = true;
1292
+ for (const item of this.visibleColumns()) {
1293
+ if (item === column) break;
1294
+ if (!item.frozen) continue;
1295
+ before.push(this.widthOf(item) ?? "0px");
1296
+ const width = measured[item.field];
1297
+ if (width) pixels += width;
1298
+ else allMeasured = false;
1299
+ }
1300
+ if (!before.length) return "0px";
1301
+ return allMeasured ? `${Math.round(pixels * 100) / 100}px` : `calc(${before.join(" + ")})`;
1302
+ }
1303
+ setWidth(column, width) {
1304
+ const next = Math.max(MIN_COLUMN_WIDTH, Math.round(width));
1305
+ this.columnWidths.update((widths) => ({
1306
+ ...widths,
1307
+ [column.field]: next
1308
+ }));
1309
+ }
1310
+ startResize(column, event) {
1311
+ const handle = event.currentTarget;
1312
+ const header = handle.closest("th");
1313
+ if (!header) return;
1314
+ event.preventDefault();
1315
+ event.stopPropagation();
1316
+ this.resizing = true;
1317
+ const direction = starIsRtl(header) ? -1 : 1;
1318
+ const startWidth = header.offsetWidth;
1319
+ const startX = event.clientX;
1320
+ handle.setPointerCapture?.(event.pointerId);
1321
+ const move = (moveEvent) => this.setWidth(column, startWidth + direction * (moveEvent.clientX - startX));
1322
+ const stop = () => {
1323
+ this.resizing = false;
1324
+ handle.removeEventListener("pointermove", move);
1325
+ handle.removeEventListener("pointerup", stop);
1326
+ handle.removeEventListener("pointercancel", stop);
1327
+ };
1328
+ handle.addEventListener("pointermove", move);
1329
+ handle.addEventListener("pointerup", stop);
1330
+ handle.addEventListener("pointercancel", stop);
1331
+ }
1332
+ onResizeKey(column, event) {
1333
+ const step = event.key === "ArrowRight" ? 16 : event.key === "ArrowLeft" ? -16 : 0;
1334
+ if (!step) return;
1335
+ event.preventDefault();
1336
+ const header = event.currentTarget.closest("th");
1337
+ const direction = starIsRtl(header) ? -1 : 1;
1338
+ this.setWidth(column, (this.columnWidths()[column.field] ?? header?.offsetWidth ?? 0) + direction * step);
1339
+ }
1340
+ editKey(row, column) {
1341
+ return `${String(this.trackKey(row))}|${column.field}`;
1342
+ }
1343
+ isEditable(row, column) {
1344
+ return typeof column.editable === "function" ? column.editable(row) : !!column.editable;
1345
+ }
1346
+ isEditing(row, column) {
1347
+ return this.editing() === this.editKey(row, column);
1348
+ }
1349
+ editText(row, column) {
1350
+ const value = this.cellValue(row, column);
1351
+ return value === null || value === void 0 ? "" : String(value);
1352
+ }
1353
+ startEdit(row, column) {
1354
+ this.editing.set(this.editKey(row, column));
1355
+ this.focusAfterRender(".star-table__editor", true);
1356
+ }
1357
+ commitEdit(row, column, text) {
1358
+ if (!this.isEditing(row, column)) return;
1359
+ const previous = this.cellValue(row, column);
1360
+ const value = column.editor === "number" ? text.trim() === "" ? null : Number(text) : text;
1361
+ this.closeEditor(row, column);
1362
+ if (typeof value === "number" && Number.isNaN(value)) return;
1363
+ if (Object.is(value, previous) || value === "" && (previous ?? "") === "") return;
1364
+ this.cellEdit.emit({
1365
+ row,
1366
+ field: column.field,
1367
+ value,
1368
+ previous
1369
+ });
1370
+ }
1371
+ cancelEdit(event) {
1372
+ event.stopPropagation();
1373
+ const key = this.editing();
1374
+ this.editing.set(null);
1375
+ if (key) this.focusAfterRender(`[data-edit="${CSS.escape(key)}"]`);
1376
+ }
1377
+ closeEditor(row, column) {
1378
+ const key = this.editKey(row, column);
1379
+ this.editing.set(null);
1380
+ this.focusAfterRender(`[data-edit="${CSS.escape(key)}"]`);
1381
+ }
1382
+ focusAfterRender(selector, select = false) {
1383
+ afterNextRender(() => {
1384
+ const target = this.host.nativeElement.querySelector(selector);
1385
+ target?.focus();
1386
+ if (select && target instanceof HTMLInputElement && target.type === "text") target.select();
1387
+ }, { injector: this.injector });
1388
+ }
1389
+ isExpanded(row) {
1390
+ return this.expandedSet().has(this.trackKey(row));
1391
+ }
1392
+ detailId(index) {
1393
+ return `${this.radioName}-detail-${index}`;
1394
+ }
1395
+ toggleExpansion(row) {
1396
+ const key = this.trackKey(row);
1397
+ if (this.isExpanded(row)) this.expandedKeys.update((keys) => keys.filter((expanded) => !Object.is(expanded, key)));
1398
+ else this.expandedKeys.update((keys) => this.rowExpandMode() === "single" ? [key] : [...keys, key]);
1399
+ }
1400
+ expandAll() {
1401
+ this.expandedKeys.set(this.pageRows().map((row) => this.trackKey(row)));
1402
+ }
1403
+ collapseAll() {
1404
+ this.expandedKeys.set([]);
1405
+ }
1406
+ matchesColumnFilter(row, column, value) {
1407
+ if (isRange(value)) {
1408
+ const raw = this.cellValue(row, column);
1409
+ if (column.filter === "date") {
1410
+ const day = dayKey(raw);
1411
+ return !!day && (!hasBound(value.min) || day >= String(value.min)) && (!hasBound(value.max) || day <= String(value.max));
1412
+ }
1413
+ const amount = raw === null || raw === void 0 || raw === "" ? NaN : Number(raw);
1414
+ return !Number.isNaN(amount) && (!hasBound(value.min) || amount >= Number(value.min)) && (!hasBound(value.max) || amount <= Number(value.max));
1415
+ }
1416
+ const text = this.cellText(row, column);
1417
+ if (typeof value !== "string") return value.includes(text);
1418
+ return column.filter === "select" ? text === value : matchesFilter(text, value);
1419
+ }
1420
+ filterValue(field) {
1421
+ const value = this.filters()[field];
1422
+ return typeof value === "string" ? value : "";
1423
+ }
1424
+ filterList(field) {
1425
+ const value = this.filters()[field];
1426
+ return Array.isArray(value) ? value : [];
1427
+ }
1428
+ filterBound(field, bound) {
1429
+ const value = this.filters()[field];
1430
+ const side = isRange(value) ? value[bound] : null;
1431
+ return hasBound(side) ? String(side) : "";
1432
+ }
1433
+ setBound(column, bound, text) {
1434
+ const current = this.filters()[column.field];
1435
+ const side = text === "" ? null : column.filter === "number" ? Number(text) : text;
1436
+ this.setFilter(column.field, {
1437
+ ...isRange(current) ? current : {},
1438
+ [bound]: side
1439
+ });
1440
+ }
1441
+ filterChoices(column) {
1442
+ if (column.filterOptions) return column.filterOptions;
1443
+ const texts = new Set(this.value().map((row) => this.cellText(row, column)));
1444
+ texts.delete("");
1445
+ return [...texts].sort((a, b) => compareValues(a, b));
1446
+ }
1447
+ setFilter(field, value) {
1448
+ this.filters.update((filters) => ({
1449
+ ...filters,
1450
+ [field]: value
1451
+ }));
1452
+ }
1453
+ clearFilters() {
1454
+ this.filters.set({});
1455
+ }
1456
+ exportData(options) {
1457
+ return {
1458
+ columns: this.visibleColumns().filter((column) => column.exportable !== false),
1459
+ rows: options.rows ?? (options.selectionOnly ? this.selection() : this.sorted())
1460
+ };
1461
+ }
1462
+ exportText(row, column) {
1463
+ return column.exportValue ? String(column.exportValue(row) ?? "") : this.cellText(row, column);
1464
+ }
1465
+ exportCell(row, column) {
1466
+ const custom = column.exportValue?.(row);
1467
+ if (typeof custom === "number") return custom;
1468
+ const value = this.cellValue(row, column);
1469
+ return !column.exportValue && !column.format && typeof value === "number" ? value : this.exportText(row, column);
1470
+ }
1471
+ toCsv(options = {}) {
1472
+ const separator = options.separator ?? ",";
1473
+ const { columns, rows } = this.exportData(options);
1474
+ const escape = (text) => text.includes(separator) || /["\r\n]/.test(text) ? `"${text.replaceAll("\"", "\"\"")}"` : text;
1475
+ const cell = (row, column) => {
1476
+ const value = this.exportCell(row, column);
1477
+ const text = String(value);
1478
+ return escape(typeof value !== "number" && /^[=+\-@\t\r]/.test(text) ? `'${text}` : text);
1479
+ };
1480
+ return [columns.map((column) => escape(column.header)).join(separator), ...rows.map((row) => columns.map((column) => cell(row, column)).join(separator))].join("\r\n");
1481
+ }
1482
+ exportCsv(options = {}) {
1483
+ this.download(new Blob(["", this.toCsv(options)], { type: "text/csv;charset=utf-8" }), `${options.fileName ?? "export"}.csv`);
1484
+ }
1485
+ toXlsx(options = {}) {
1486
+ const { columns, rows } = this.exportData(options);
1487
+ return buildXlsx(columns.map((column) => column.header), rows.map((row) => columns.map((column) => this.exportCell(row, column))), options.title ?? this.ariaLabel() ?? void 0);
1488
+ }
1489
+ exportExcel(options = {}) {
1490
+ const bytes = this.toXlsx(options);
1491
+ this.download(new Blob([bytes.buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), `${options.fileName ?? "export"}.xlsx`);
1492
+ }
1493
+ print(options = {}) {
1494
+ const { columns, rows } = this.exportData(options);
1495
+ const frame = this.document.createElement("iframe");
1496
+ frame.setAttribute("aria-hidden", "true");
1497
+ frame.style.cssText = "position:fixed;width:0;height:0;border:0;visibility:hidden";
1498
+ frame.srcdoc = buildPrintDocument(options.title ?? this.ariaLabel() ?? "", columns.map((column) => column.header), rows.map((row) => columns.map((column) => this.exportCell(row, column))));
1499
+ frame.addEventListener("load", () => {
1500
+ const view = frame.contentWindow;
1501
+ if (!view) return;
1502
+ fitPrintDocument(view.document);
1503
+ view.addEventListener("afterprint", () => frame.remove());
1504
+ view.focus();
1505
+ view.print();
1506
+ });
1507
+ this.document.body.append(frame);
1508
+ }
1509
+ download(blob, fileName) {
1510
+ const url = URL.createObjectURL(blob);
1511
+ const link = this.document.createElement("a");
1512
+ link.href = url;
1513
+ link.download = fileName;
1514
+ link.click();
1515
+ URL.revokeObjectURL(url);
1516
+ }
1517
+ sortBy(column, event) {
1518
+ const current = this.sorts().find((sort) => sort.field === column.field);
1519
+ const order = current ? current.order === 1 ? -1 : 1 : 1;
1520
+ if (this.multiSort() && event?.shiftKey) {
1521
+ const sorts = this.sorts();
1522
+ this.sortMeta.set(current ? sorts.map((sort) => sort.field === column.field ? {
1523
+ ...sort,
1524
+ order
1525
+ } : sort) : [...sorts, {
1526
+ field: column.field,
1527
+ order
1528
+ }]);
1529
+ } else this.sortMeta.set(this.multiSort() ? [{
1530
+ field: column.field,
1531
+ order
1532
+ }] : []);
1533
+ const first = this.multiSort() ? this.sortMeta()[0] : {
1534
+ field: column.field,
1535
+ order
1536
+ };
1537
+ this.sortField.set(first.field);
1538
+ this.sortOrder.set(first.order);
1539
+ this.first.set(0);
1540
+ this.emitLazy();
1541
+ }
1542
+ sortOf(column) {
1543
+ return this.sorts().find((sort) => sort.field === column.field);
1544
+ }
1545
+ ariaSort(column) {
1546
+ if (!column.sortable) return null;
1547
+ const first = this.sorts()[0];
1548
+ if (first?.field !== column.field) return "none";
1549
+ return first.order === 1 ? "ascending" : "descending";
1550
+ }
1551
+ sortIcon(column) {
1552
+ const sort = this.sortOf(column);
1553
+ if (!sort) return "ph-bold ph-arrows-down-up star-table__sort-idle";
1554
+ return sort.order === 1 ? "ph-bold ph-sort-ascending" : "ph-bold ph-sort-descending";
1555
+ }
1556
+ sortRank(column) {
1557
+ const sorts = this.sorts();
1558
+ if (sorts.length < 2) return null;
1559
+ const index = sorts.findIndex((sort) => sort.field === column.field);
1560
+ return index < 0 ? null : index + 1;
1561
+ }
1562
+ selectedKeys = computed(() => new Set(this.selection().map((row) => this.trackKey(row))), ...ngDevMode ? [{ debugName: "selectedKeys" }] : /* istanbul ignore next */ []);
1563
+ isSelected(row) {
1564
+ return this.selectedKeys().has(this.trackKey(row));
1565
+ }
1566
+ toggleRow(row) {
1567
+ const key = this.trackKey(row);
1568
+ this.selection.update((selection) => this.isSelected(row) ? selection.filter((selected) => !Object.is(this.trackKey(selected), key)) : [...selection, row]);
1569
+ }
1570
+ selectOnly(row) {
1571
+ this.selection.set([row]);
1572
+ }
1573
+ togglePage(checked) {
1574
+ const page = this.pageRows();
1575
+ const keys = new Set(page.map((row) => this.trackKey(row)));
1576
+ this.selection.update((selection) => {
1577
+ const others = selection.filter((row) => !keys.has(this.trackKey(row)));
1578
+ return checked ? [...others, ...page] : others;
1579
+ });
1580
+ }
1581
+ onRowClick(row, event) {
1582
+ if (event.target.closest("button, a, input, select, textarea")) return;
1583
+ if (this.selectionMode() === "single") this.selectOnly(row);
1584
+ this.rowClick.emit(row);
1585
+ }
1586
+ emitLazy() {
1587
+ if (!this.lazy()) return;
1588
+ this.lazyLoad.emit({
1589
+ first: this.first(),
1590
+ rows: this.rows(),
1591
+ field: this.sortField(),
1592
+ order: this.sortOrder(),
1593
+ filter: this.globalFilter(),
1594
+ filters: this.filters(),
1595
+ sorts: this.sorts()
1596
+ });
1597
+ }
1598
+ static ɵfac = i0.ɵɵngDeclareFactory({
1599
+ minVersion: "12.0.0",
1600
+ version: "22.2.6",
1601
+ ngImport: i0,
1602
+ type: StarTable,
1603
+ deps: [],
1604
+ target: i0.ɵɵFactoryTarget.Component
1605
+ });
1606
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1607
+ minVersion: "17.0.0",
1608
+ version: "22.2.6",
1609
+ type: StarTable,
1610
+ isStandalone: true,
1611
+ selector: "star-table",
1612
+ inputs: {
1613
+ value: {
1614
+ classPropertyName: "value",
1615
+ publicName: "value",
1616
+ isSignal: true,
1617
+ isRequired: true,
1618
+ transformFunction: null
1619
+ },
1620
+ columns: {
1621
+ classPropertyName: "columns",
1622
+ publicName: "columns",
1623
+ isSignal: true,
1624
+ isRequired: true,
1625
+ transformFunction: null
1626
+ },
1627
+ dataKey: {
1628
+ classPropertyName: "dataKey",
1629
+ publicName: "dataKey",
1630
+ isSignal: true,
1631
+ isRequired: false,
1632
+ transformFunction: null
1633
+ },
1634
+ loading: {
1635
+ classPropertyName: "loading",
1636
+ publicName: "loading",
1637
+ isSignal: true,
1638
+ isRequired: false,
1639
+ transformFunction: null
1640
+ },
1641
+ emptyMessage: {
1642
+ classPropertyName: "emptyMessage",
1643
+ publicName: "emptyMessage",
1644
+ isSignal: true,
1645
+ isRequired: false,
1646
+ transformFunction: null
1647
+ },
1648
+ striped: {
1649
+ classPropertyName: "striped",
1650
+ publicName: "striped",
1651
+ isSignal: true,
1652
+ isRequired: false,
1653
+ transformFunction: null
1654
+ },
1655
+ size: {
1656
+ classPropertyName: "size",
1657
+ publicName: "size",
1658
+ isSignal: true,
1659
+ isRequired: false,
1660
+ transformFunction: null
1661
+ },
1662
+ stickyHeader: {
1663
+ classPropertyName: "stickyHeader",
1664
+ publicName: "stickyHeader",
1665
+ isSignal: true,
1666
+ isRequired: false,
1667
+ transformFunction: null
1668
+ },
1669
+ scrollHeight: {
1670
+ classPropertyName: "scrollHeight",
1671
+ publicName: "scrollHeight",
1672
+ isSignal: true,
1673
+ isRequired: false,
1674
+ transformFunction: null
1675
+ },
1676
+ responsiveLayout: {
1677
+ classPropertyName: "responsiveLayout",
1678
+ publicName: "responsiveLayout",
1679
+ isSignal: true,
1680
+ isRequired: false,
1681
+ transformFunction: null
1682
+ },
1683
+ virtualScroll: {
1684
+ classPropertyName: "virtualScroll",
1685
+ publicName: "virtualScroll",
1686
+ isSignal: true,
1687
+ isRequired: false,
1688
+ transformFunction: null
1689
+ },
1690
+ virtualRowHeight: {
1691
+ classPropertyName: "virtualRowHeight",
1692
+ publicName: "virtualRowHeight",
1693
+ isSignal: true,
1694
+ isRequired: false,
1695
+ transformFunction: null
1696
+ },
1697
+ virtualRowHeights: {
1698
+ classPropertyName: "virtualRowHeights",
1699
+ publicName: "virtualRowHeights",
1700
+ isSignal: true,
1701
+ isRequired: false,
1702
+ transformFunction: null
1703
+ },
1704
+ ariaLabel: {
1705
+ classPropertyName: "ariaLabel",
1706
+ publicName: "ariaLabel",
1707
+ isSignal: true,
1708
+ isRequired: false,
1709
+ transformFunction: null
1710
+ },
1711
+ paginator: {
1712
+ classPropertyName: "paginator",
1713
+ publicName: "paginator",
1714
+ isSignal: true,
1715
+ isRequired: false,
1716
+ transformFunction: null
1717
+ },
1718
+ first: {
1719
+ classPropertyName: "first",
1720
+ publicName: "first",
1721
+ isSignal: true,
1722
+ isRequired: false,
1723
+ transformFunction: null
1724
+ },
1725
+ rows: {
1726
+ classPropertyName: "rows",
1727
+ publicName: "rows",
1728
+ isSignal: true,
1729
+ isRequired: false,
1730
+ transformFunction: null
1731
+ },
1732
+ rowsPerPageOptions: {
1733
+ classPropertyName: "rowsPerPageOptions",
1734
+ publicName: "rowsPerPageOptions",
1735
+ isSignal: true,
1736
+ isRequired: false,
1737
+ transformFunction: null
1738
+ },
1739
+ sortField: {
1740
+ classPropertyName: "sortField",
1741
+ publicName: "sortField",
1742
+ isSignal: true,
1743
+ isRequired: false,
1744
+ transformFunction: null
1745
+ },
1746
+ sortOrder: {
1747
+ classPropertyName: "sortOrder",
1748
+ publicName: "sortOrder",
1749
+ isSignal: true,
1750
+ isRequired: false,
1751
+ transformFunction: null
1752
+ },
1753
+ globalFilter: {
1754
+ classPropertyName: "globalFilter",
1755
+ publicName: "globalFilter",
1756
+ isSignal: true,
1757
+ isRequired: false,
1758
+ transformFunction: null
1759
+ },
1760
+ filters: {
1761
+ classPropertyName: "filters",
1762
+ publicName: "filters",
1763
+ isSignal: true,
1764
+ isRequired: false,
1765
+ transformFunction: null
1766
+ },
1767
+ lazy: {
1768
+ classPropertyName: "lazy",
1769
+ publicName: "lazy",
1770
+ isSignal: true,
1771
+ isRequired: false,
1772
+ transformFunction: null
1773
+ },
1774
+ totalRecords: {
1775
+ classPropertyName: "totalRecords",
1776
+ publicName: "totalRecords",
1777
+ isSignal: true,
1778
+ isRequired: false,
1779
+ transformFunction: null
1780
+ },
1781
+ selectionMode: {
1782
+ classPropertyName: "selectionMode",
1783
+ publicName: "selectionMode",
1784
+ isSignal: true,
1785
+ isRequired: false,
1786
+ transformFunction: null
1787
+ },
1788
+ selection: {
1789
+ classPropertyName: "selection",
1790
+ publicName: "selection",
1791
+ isSignal: true,
1792
+ isRequired: false,
1793
+ transformFunction: null
1794
+ },
1795
+ expandedKeys: {
1796
+ classPropertyName: "expandedKeys",
1797
+ publicName: "expandedKeys",
1798
+ isSignal: true,
1799
+ isRequired: false,
1800
+ transformFunction: null
1801
+ },
1802
+ rowExpandMode: {
1803
+ classPropertyName: "rowExpandMode",
1804
+ publicName: "rowExpandMode",
1805
+ isSignal: true,
1806
+ isRequired: false,
1807
+ transformFunction: null
1808
+ },
1809
+ columnToggle: {
1810
+ classPropertyName: "columnToggle",
1811
+ publicName: "columnToggle",
1812
+ isSignal: true,
1813
+ isRequired: false,
1814
+ transformFunction: null
1815
+ },
1816
+ reorderableColumns: {
1817
+ classPropertyName: "reorderableColumns",
1818
+ publicName: "reorderableColumns",
1819
+ isSignal: true,
1820
+ isRequired: false,
1821
+ transformFunction: null
1822
+ },
1823
+ resizableColumns: {
1824
+ classPropertyName: "resizableColumns",
1825
+ publicName: "resizableColumns",
1826
+ isSignal: true,
1827
+ isRequired: false,
1828
+ transformFunction: null
1829
+ },
1830
+ columnOrder: {
1831
+ classPropertyName: "columnOrder",
1832
+ publicName: "columnOrder",
1833
+ isSignal: true,
1834
+ isRequired: false,
1835
+ transformFunction: null
1836
+ },
1837
+ hiddenColumns: {
1838
+ classPropertyName: "hiddenColumns",
1839
+ publicName: "hiddenColumns",
1840
+ isSignal: true,
1841
+ isRequired: false,
1842
+ transformFunction: null
1843
+ },
1844
+ columnWidths: {
1845
+ classPropertyName: "columnWidths",
1846
+ publicName: "columnWidths",
1847
+ isSignal: true,
1848
+ isRequired: false,
1849
+ transformFunction: null
1850
+ },
1851
+ multiSort: {
1852
+ classPropertyName: "multiSort",
1853
+ publicName: "multiSort",
1854
+ isSignal: true,
1855
+ isRequired: false,
1856
+ transformFunction: null
1857
+ },
1858
+ sortMeta: {
1859
+ classPropertyName: "sortMeta",
1860
+ publicName: "sortMeta",
1861
+ isSignal: true,
1862
+ isRequired: false,
1863
+ transformFunction: null
1864
+ },
1865
+ groupBy: {
1866
+ classPropertyName: "groupBy",
1867
+ publicName: "groupBy",
1868
+ isSignal: true,
1869
+ isRequired: false,
1870
+ transformFunction: null
1871
+ },
1872
+ collapsedGroups: {
1873
+ classPropertyName: "collapsedGroups",
1874
+ publicName: "collapsedGroups",
1875
+ isSignal: true,
1876
+ isRequired: false,
1877
+ transformFunction: null
1878
+ },
1879
+ reorderableRows: {
1880
+ classPropertyName: "reorderableRows",
1881
+ publicName: "reorderableRows",
1882
+ isSignal: true,
1883
+ isRequired: false,
1884
+ transformFunction: null
1885
+ },
1886
+ stateKey: {
1887
+ classPropertyName: "stateKey",
1888
+ publicName: "stateKey",
1889
+ isSignal: true,
1890
+ isRequired: false,
1891
+ transformFunction: null
1892
+ },
1893
+ stateStorage: {
1894
+ classPropertyName: "stateStorage",
1895
+ publicName: "stateStorage",
1896
+ isSignal: true,
1897
+ isRequired: false,
1898
+ transformFunction: null
1899
+ }
1900
+ },
1901
+ outputs: {
1902
+ first: "firstChange",
1903
+ rows: "rowsChange",
1904
+ sortField: "sortFieldChange",
1905
+ sortOrder: "sortOrderChange",
1906
+ filters: "filtersChange",
1907
+ selection: "selectionChange",
1908
+ expandedKeys: "expandedKeysChange",
1909
+ columnOrder: "columnOrderChange",
1910
+ hiddenColumns: "hiddenColumnsChange",
1911
+ columnWidths: "columnWidthsChange",
1912
+ sortMeta: "sortMetaChange",
1913
+ collapsedGroups: "collapsedGroupsChange",
1914
+ rowClick: "rowClick",
1915
+ rowReorder: "rowReorder",
1916
+ cellEdit: "cellEdit",
1917
+ lazyLoad: "lazyLoad"
1918
+ },
1919
+ host: {
1920
+ listeners: {
1921
+ "focusin": "onBodyFocusIn($event)",
1922
+ "focusout": "onBodyFocusOut($event)",
1923
+ "keydown": "onBodyKeydown($event)"
1924
+ },
1925
+ properties: {
1926
+ "class.star-table--striped": "striped()",
1927
+ "class.star-table--sm": "size() === 'sm'",
1928
+ "class.star-table--sticky": "stickyHeader()",
1929
+ "class.star-table--virtual": "virtualScroll()",
1930
+ "class.star-table--variable": "variableHeights()",
1931
+ "class.star-table--stack": "responsiveLayout() === 'stack'",
1932
+ "style.--star-table-row-height.px": "virtualScroll() ? virtualRowHeight() : null"
1933
+ },
1934
+ classAttribute: "star-table"
1935
+ },
1936
+ queries: [{
1937
+ propertyName: "cellTemplates",
1938
+ predicate: StarCellTemplate,
1939
+ isSignal: true
1940
+ }, {
1941
+ propertyName: "expansion",
1942
+ first: true,
1943
+ predicate: StarRowExpansionTemplate,
1944
+ descendants: true,
1945
+ isSignal: true
1946
+ }],
1947
+ viewQueries: [{
1948
+ propertyName: "scroller",
1949
+ first: true,
1950
+ predicate: ["scroller"],
1951
+ descendants: true,
1952
+ isSignal: true
1953
+ }, {
1954
+ propertyName: "body",
1955
+ first: true,
1956
+ predicate: ["body"],
1957
+ descendants: true,
1958
+ isSignal: true
1959
+ }],
1960
+ ngImport: i0,
1961
+ template: `
1962
+ <ng-content select="[starTableCaption]" />
1963
+ @if (columnToggle()) {
1964
+ <div class="star-table__tools">
1965
+ <star-button
1966
+ size="sm"
1967
+ variant="secondary"
1968
+ leadingIcon="ph-bold ph-columns"
1969
+ (pressed)="columnsPanel.toggle($event)"
1970
+ >
1971
+ {{ text.columns }}
1972
+ </star-button>
1973
+ <star-popover #columnsPanel [ariaLabel]="text.columns">
1974
+ <ul class="star-table__columns">
1975
+ @for (
1976
+ column of orderedColumns();
1977
+ track column.field;
1978
+ let first = $first;
1979
+ let last = $last
1980
+ ) {
1981
+ <li>
1982
+ <star-checkbox
1983
+ [checked]="!isHidden(column)"
1984
+ [disabled]="!canHide(column)"
1985
+ (checkedChange)="setColumnVisible(column, $event)"
1986
+ >
1987
+ {{ column.header }}
1988
+ </star-checkbox>
1989
+ @if (reorderableColumns()) {
1990
+ <span class="star-table__columns-move">
1991
+ <button
1992
+ type="button"
1993
+ class="star-table__toggle"
1994
+ [disabled]="first"
1995
+ [attr.data-move]="moveKey(column, -1)"
1996
+ [attr.aria-label]="text.moveColumnEarlier(column.header)"
1997
+ (click)="moveColumnBy(column, -1)"
1998
+ >
1999
+ <i class="ph-bold ph-arrow-up" aria-hidden="true"></i>
2000
+ </button>
2001
+ <button
2002
+ type="button"
2003
+ class="star-table__toggle"
2004
+ [disabled]="last"
2005
+ [attr.data-move]="moveKey(column, 1)"
2006
+ [attr.aria-label]="text.moveColumnLater(column.header)"
2007
+ (click)="moveColumnBy(column, 1)"
2008
+ >
2009
+ <i class="ph-bold ph-arrow-down" aria-hidden="true"></i>
2010
+ </button>
2011
+ </span>
2012
+ }
2013
+ </li>
2014
+ }
2015
+ </ul>
2016
+ </star-popover>
2017
+ </div>
2018
+ }
2019
+ <div
2020
+ #scroller
2021
+ class="star-table__scroll"
2022
+ [attr.role]="scrollable() ? 'group' : null"
2023
+ [attr.aria-label]="scrollable() ? ariaLabel() : null"
2024
+ [attr.tabindex]="scrollable() ? 0 : null"
2025
+ [style.max-height]="scrollHeight()"
2026
+ (scroll)="onScroll($event)"
2027
+ >
2028
+ <table
2029
+ [attr.aria-label]="ariaLabel()"
2030
+ [attr.aria-busy]="loading() || null"
2031
+ [attr.aria-rowcount]="ariaRowCount()"
2032
+ >
2033
+ <thead>
2034
+ <tr [attr.aria-rowindex]="virtualScroll() ? 1 : null">
2035
+ @if (reorderableRows()) {
2036
+ <th class="star-table__reorder" scope="col">
2037
+ <span class="star-sr-only">{{ text.reorderRows }}</span>
2038
+ </th>
2039
+ }
2040
+ @if (expandable()) {
2041
+ <th class="star-table__expander" scope="col">
2042
+ <span class="star-sr-only">{{ text.rowDetails }}</span>
2043
+ </th>
2044
+ }
2045
+ @if (selectionMode() === 'multiple') {
2046
+ <th class="star-table__select" scope="col">
2047
+ <star-checkbox
2048
+ [checked]="pageState() === true"
2049
+ [indeterminate]="pageState() === 'mixed'"
2050
+ [ariaLabel]="text.selectAllRows"
2051
+ [disabled]="!pageRows().length"
2052
+ (checkedChange)="togglePage($event)"
2053
+ />
2054
+ </th>
2055
+ } @else if (selectionMode() === 'single') {
2056
+ <th class="star-table__select" scope="col">
2057
+ <span class="star-sr-only">{{ text.selectRow }}</span>
2058
+ </th>
2059
+ }
2060
+ @for (column of visibleColumns(); track column.field) {
2061
+ <th
2062
+ scope="col"
2063
+ [style.width]="widthOf(column)"
2064
+ [style.min-width]="resizedWidth(column)"
2065
+ [style.max-width]="resizedWidth(column)"
2066
+ [style.inset-inline-start]="frozenOffset(column)"
2067
+ [attr.data-field]="column.field"
2068
+ [class]="'star-table__th star-table__cell--' + (column.align ?? 'start')"
2069
+ [class.star-table__cell--frozen]="column.frozen"
2070
+ [class.star-table__th--drop]="dropField() === column.field"
2071
+ [attr.aria-sort]="ariaSort(column)"
2072
+ [attr.draggable]="reorderableColumns() ? 'true' : null"
2073
+ (dragstart)="onDragStart(column, $event)"
2074
+ (dragover)="onDragOver(column, $event)"
2075
+ (drop)="onDrop(column, $event)"
2076
+ (dragend)="endDrag()"
2077
+ >
2078
+ @if (column.sortable) {
2079
+ <button
2080
+ type="button"
2081
+ class="star-table__sort"
2082
+ [attr.title]="multiSort() ? text.sortMultiHint : null"
2083
+ (click)="sortBy(column, $event)"
2084
+ >
2085
+ {{ column.header }}
2086
+ <i [class]="sortIcon(column)" aria-hidden="true"></i>
2087
+ @if (sortRank(column); as rank) {
2088
+ <span class="star-table__sort-rank">{{ rank }}</span>
2089
+ }
2090
+ </button>
2091
+ } @else {
2092
+ {{ column.header }}
2093
+ }
2094
+ @if (resizableColumns()) {
2095
+ <span
2096
+ class="star-table__resizer"
2097
+ role="separator"
2098
+ aria-orientation="vertical"
2099
+ tabindex="0"
2100
+ [attr.aria-label]="text.resizeColumn(column.header)"
2101
+ [attr.aria-valuenow]="resizeNow(column)"
2102
+ [attr.aria-valuemin]="minColumnWidth"
2103
+ [attr.aria-valuemax]="resizeMax(column)"
2104
+ (pointerdown)="startResize(column, $event)"
2105
+ (keydown)="onResizeKey(column, $event)"
2106
+ ></span>
2107
+ }
2108
+ </th>
2109
+ }
2110
+ </tr>
2111
+ @if (hasColumnFilters()) {
2112
+ <tr class="star-table__filters" [attr.aria-rowindex]="virtualScroll() ? 2 : null">
2113
+ @if (reorderableRows()) {
2114
+ <td class="star-table__reorder"></td>
2115
+ }
2116
+ @if (expandable()) {
2117
+ <td class="star-table__expander"></td>
2118
+ }
2119
+ @if (selectionMode()) {
2120
+ <td class="star-table__select"></td>
2121
+ }
2122
+ @for (column of visibleColumns(); track column.field) {
2123
+ <td
2124
+ [class.star-table__cell--frozen]="column.frozen"
2125
+ [style.inset-inline-start]="frozenOffset(column)"
2126
+ [attr.data-label]="column.filter ? column.header : null"
2127
+ >
2128
+ @if (column.filter === 'select') {
2129
+ <select
2130
+ class="star-input star-input--sm star-table__filter"
2131
+ [attr.aria-label]="text.filterBy(column.header)"
2132
+ (change)="setFilter(column.field, $any($event.target).value)"
2133
+ >
2134
+ <option value="" [selected]="!filterValue(column.field)">
2135
+ {{ text.filterAll }}
2136
+ </option>
2137
+ @for (option of filterChoices(column); track option) {
2138
+ <option [value]="option" [selected]="option === filterValue(column.field)">
2139
+ {{ option }}
2140
+ </option>
2141
+ }
2142
+ </select>
2143
+ } @else if (column.filter === 'text') {
2144
+ <input
2145
+ type="search"
2146
+ class="star-input star-input--sm star-table__filter"
2147
+ [attr.aria-label]="text.filterBy(column.header)"
2148
+ [value]="filterValue(column.field)"
2149
+ (input)="setFilter(column.field, $any($event.target).value)"
2150
+ />
2151
+ } @else if (column.filter === 'multiselect') {
2152
+ <star-multi-select
2153
+ class="star-table__filter"
2154
+ size="sm"
2155
+ [options]="filterChoices(column)"
2156
+ [value]="filterList(column.field)"
2157
+ [placeholder]="text.filterAll"
2158
+ [ariaLabel]="text.filterBy(column.header)"
2159
+ (valueChange)="setFilter(column.field, $event)"
2160
+ />
2161
+ } @else if (column.filter === 'number' || column.filter === 'date') {
2162
+ <span class="star-table__filter-range">
2163
+ <input
2164
+ class="star-input star-input--sm star-table__filter"
2165
+ [type]="column.filter"
2166
+ [attr.aria-label]="text.filterMin(column.header)"
2167
+ [attr.placeholder]="column.filter === 'number' ? text.filterMinShort : null"
2168
+ [value]="filterBound(column.field, 'min')"
2169
+ (input)="setBound(column, 'min', $any($event.target).value)"
2170
+ />
2171
+ <input
2172
+ class="star-input star-input--sm star-table__filter"
2173
+ [type]="column.filter"
2174
+ [attr.aria-label]="text.filterMax(column.header)"
2175
+ [attr.placeholder]="column.filter === 'number' ? text.filterMaxShort : null"
2176
+ [value]="filterBound(column.field, 'max')"
2177
+ (input)="setBound(column, 'max', $any($event.target).value)"
2178
+ />
2179
+ </span>
2180
+ }
2181
+ </td>
2182
+ }
2183
+ </tr>
2184
+ }
2185
+ </thead>
2186
+ <tbody #body>
2187
+ @if (loading()) {
2188
+ @for (row of skeletonRows(); track row) {
2189
+ <tr class="star-table__row">
2190
+ @if (reorderableRows()) {
2191
+ <td class="star-table__reorder"></td>
2192
+ }
2193
+ @if (expandable()) {
2194
+ <td class="star-table__expander"></td>
2195
+ }
2196
+ @if (selectionMode()) {
2197
+ <td class="star-table__select"><star-skeleton size="1.25rem" /></td>
2198
+ }
2199
+ @for (column of visibleColumns(); track column.field) {
2200
+ <td><star-skeleton height="0.875rem" [width]="row % 2 ? '70%' : '90%'" /></td>
2201
+ }
2202
+ </tr>
2203
+ }
2204
+ } @else {
2205
+ @for (entry of bodyEntries(); track entry.key) {
2206
+ @if (entry.kind === 'spacer') {
2207
+ <tr class="star-table__spacer" aria-hidden="true">
2208
+ <td [attr.colspan]="colspan()" [style.height.px]="entry.height"></td>
2209
+ </tr>
2210
+ } @else if (entry.kind === 'group') {
2211
+ @let group = entry;
2212
+ <tr
2213
+ class="star-table__group"
2214
+ [attr.aria-rowindex]="group.aria"
2215
+ [attr.data-vi]="group.item"
2216
+ >
2217
+ <th [attr.colspan]="colspan()" scope="colgroup">
2218
+ <button
2219
+ type="button"
2220
+ class="star-table__group-toggle"
2221
+ [attr.aria-expanded]="!isGroupCollapsed(group.label)"
2222
+ (click)="toggleGroup(group.label)"
2223
+ >
2224
+ <i class="ph-bold ph-caret-down" aria-hidden="true"></i>
2225
+ {{ group.label }}
2226
+ <span class="star-table__group-count">{{ group.count }}</span>
2227
+ </button>
2228
+ </th>
2229
+ </tr>
2230
+ } @else {
2231
+ @let row = entry.row;
2232
+ @let i = entry.index;
2233
+ <tr
2234
+ [attr.aria-rowindex]="entry.aria"
2235
+ [attr.data-vi]="entry.item"
2236
+ [hidden]="isRowCollapsed(row)"
2237
+ class="star-table__row"
2238
+ [class.star-table__row--alt]="i % 2 === 1"
2239
+ [class.star-table__row--selected]="isSelected(row)"
2240
+ [class.star-table__row--clickable]="clickable()"
2241
+ [class.star-table__row--expanded]="expandable() && isExpanded(row)"
2242
+ [attr.aria-selected]="selectionMode() ? isSelected(row) : null"
2243
+ (click)="onRowClick(row, $event)"
2244
+ >
2245
+ @if (reorderableRows()) {
2246
+ <td class="star-table__reorder">
2247
+ <button
2248
+ type="button"
2249
+ class="star-table__toggle"
2250
+ [disabled]="!canMoveRow(row, -1)"
2251
+ [attr.aria-label]="text.moveUp"
2252
+ (click)="moveRow(row, -1)"
2253
+ >
2254
+ <i class="ph-bold ph-arrow-up" aria-hidden="true"></i>
2255
+ </button>
2256
+ <button
2257
+ type="button"
2258
+ class="star-table__toggle"
2259
+ [disabled]="!canMoveRow(row, 1)"
2260
+ [attr.aria-label]="text.moveDown"
2261
+ (click)="moveRow(row, 1)"
2262
+ >
2263
+ <i class="ph-bold ph-arrow-down" aria-hidden="true"></i>
2264
+ </button>
2265
+ </td>
2266
+ }
2267
+ @if (expandable()) {
2268
+ <td class="star-table__expander">
2269
+ <button
2270
+ type="button"
2271
+ class="star-table__toggle"
2272
+ [attr.aria-expanded]="isExpanded(row)"
2273
+ [attr.aria-controls]="isExpanded(row) ? detailId(i) : null"
2274
+ [attr.aria-label]="isExpanded(row) ? text.collapseRow : text.expandRow"
2275
+ (click)="toggleExpansion(row)"
2276
+ >
2277
+ <i class="ph-bold ph-caret-right" aria-hidden="true"></i>
2278
+ </button>
2279
+ </td>
2280
+ }
2281
+ @if (selectionMode() === 'multiple') {
2282
+ <td class="star-table__select">
2283
+ <star-checkbox
2284
+ [checked]="isSelected(row)"
2285
+ [ariaLabel]="text.selectRow"
2286
+ (checkedChange)="toggleRow(row)"
2287
+ (click)="$event.stopPropagation()"
2288
+ />
2289
+ </td>
2290
+ } @else if (selectionMode() === 'single') {
2291
+ <td class="star-table__select">
2292
+ <input
2293
+ type="radio"
2294
+ class="star-table__radio"
2295
+ [name]="radioName"
2296
+ [checked]="isSelected(row)"
2297
+ [attr.aria-label]="text.selectRow"
2298
+ (change)="selectOnly(row)"
2299
+ (click)="$event.stopPropagation()"
2300
+ />
2301
+ </td>
2302
+ }
2303
+ @for (column of visibleColumns(); track column.field) {
2304
+ <td
2305
+ [class]="'star-table__cell--' + (column.align ?? 'start')"
2306
+ [class.star-table__cell--frozen]="column.frozen"
2307
+ [style.inset-inline-start]="frozenOffset(column)"
2308
+ [attr.data-label]="column.header"
2309
+ >
2310
+ @if (isEditing(row, column)) {
2311
+ @if (column.editor === 'select') {
2312
+ <select
2313
+ class="star-input star-input--sm star-table__editor"
2314
+ [attr.aria-label]="text.editCell(column.header)"
2315
+ (change)="commitEdit(row, column, $any($event.target).value)"
2316
+ (blur)="commitEdit(row, column, $any($event.target).value)"
2317
+ (keydown.escape)="cancelEdit($event)"
2318
+ >
2319
+ @for (option of column.editOptions ?? []; track option) {
2320
+ <option
2321
+ [value]="option"
2322
+ [selected]="option === cellText(row, column)"
2323
+ >
2324
+ {{ option }}
2325
+ </option>
2326
+ }
2327
+ </select>
2328
+ } @else {
2329
+ <input
2330
+ class="star-input star-input--sm star-table__editor"
2331
+ [type]="column.editor === 'number' ? 'number' : 'text'"
2332
+ [attr.aria-label]="text.editCell(column.header)"
2333
+ [value]="editText(row, column)"
2334
+ (blur)="commitEdit(row, column, $any($event.target).value)"
2335
+ (keydown.enter)="commitEdit(row, column, $any($event.target).value)"
2336
+ (keydown.escape)="cancelEdit($event)"
2337
+ />
2338
+ }
2339
+ } @else if (isEditable(row, column)) {
2340
+ <button
2341
+ type="button"
2342
+ class="star-table__edit"
2343
+ [attr.data-edit]="editKey(row, column)"
2344
+ (click)="startEdit(row, column)"
2345
+ >
2346
+ <!-- The name is the action and the visible value (WCAG 2.5.3). -->
2347
+ <span class="star-sr-only">{{ text.editCell(column.header) }}: </span>
2348
+ <span class="star-table__edit-value">
2349
+ <ng-container
2350
+ *ngTemplateOutlet="
2351
+ cell;
2352
+ context: { $implicit: row, column, index: i }
2353
+ "
2354
+ />
2355
+ </span>
2356
+ <i class="ph-bold ph-pencil-simple" aria-hidden="true"></i>
2357
+ </button>
2358
+ } @else {
2359
+ <ng-container
2360
+ *ngTemplateOutlet="cell; context: { $implicit: row, column, index: i }"
2361
+ />
2362
+ }
2363
+ </td>
2364
+ }
2365
+ </tr>
2366
+ @if (expansionTemplate(); as detail) {
2367
+ @if (isExpanded(row) && !isRowCollapsed(row)) {
2368
+ <tr
2369
+ class="star-table__expansion"
2370
+ [id]="detailId(i)"
2371
+ [attr.aria-rowindex]="entry.aria === null ? null : entry.aria + 1"
2372
+ [attr.data-vi]="entry.item"
2373
+ >
2374
+ <td [attr.colspan]="colspan()">
2375
+ <ng-container
2376
+ *ngTemplateOutlet="detail; context: { $implicit: row, index: i }"
2377
+ />
2378
+ </td>
2379
+ </tr>
2380
+ }
2381
+ }
2382
+ }
2383
+ } @empty {
2384
+ <tr>
2385
+ <td class="star-table__empty" [attr.colspan]="colspan()">
2386
+ <i class="ph-bold ph-tray" aria-hidden="true"></i>
2387
+ {{ emptyMessage() ?? text.noData }}
2388
+ </td>
2389
+ </tr>
2390
+ }
2391
+ }
2392
+ </tbody>
2393
+ @if (hasFooter()) {
2394
+ <tfoot>
2395
+ <tr
2396
+ class="star-table__footer"
2397
+ [attr.aria-rowindex]="virtualScroll() ? ariaRowCount() : null"
2398
+ >
2399
+ @if (reorderableRows()) {
2400
+ <td class="star-table__reorder"></td>
2401
+ }
2402
+ @if (expandable()) {
2403
+ <td class="star-table__expander"></td>
2404
+ }
2405
+ @if (selectionMode()) {
2406
+ <td class="star-table__select"></td>
2407
+ }
2408
+ @for (column of visibleColumns(); track column.field) {
2409
+ <td
2410
+ [class]="'star-table__cell--' + (column.align ?? 'start')"
2411
+ [attr.data-label]="footerText(column) ? column.header : null"
2412
+ >
2413
+ {{ footerText(column) }}
2414
+ </td>
2415
+ }
2416
+ </tr>
2417
+ </tfoot>
2418
+ }
2419
+ </table>
2420
+ </div>
2421
+ <ng-template #cell let-row let-column="column" let-i="index">
2422
+ @if (cellTemplate(column.field); as custom) {
2423
+ <ng-container
2424
+ *ngTemplateOutlet="
2425
+ custom;
2426
+ context: { $implicit: row, value: cellValue(row, column), index: i }
2427
+ "
2428
+ />
2429
+ } @else {
2430
+ {{ cellText(row, column) }}
2431
+ }
2432
+ </ng-template>
2433
+ @if (paginator()) {
2434
+ <star-paginator
2435
+ [ariaLabel]="ariaLabel() ? text.pagination + ': ' + ariaLabel() : null"
2436
+ [totalRecords]="total()"
2437
+ [(first)]="first"
2438
+ [(rows)]="rows"
2439
+ [rowsPerPageOptions]="rowsPerPageOptions()"
2440
+ (pageChange)="emitLazy()"
2441
+ />
2442
+ }
2443
+ `,
2444
+ isInline: true,
2445
+ dependencies: [
2446
+ {
2447
+ kind: "directive",
2448
+ type: NgTemplateOutlet,
2449
+ selector: "[ngTemplateOutlet]",
2450
+ inputs: [
2451
+ "ngTemplateOutletContext",
2452
+ "ngTemplateOutlet",
2453
+ "ngTemplateOutletInjector"
2454
+ ]
2455
+ },
2456
+ {
2457
+ kind: "component",
2458
+ type: StarButton,
2459
+ selector: "star-button",
2460
+ inputs: [
2461
+ "variant",
2462
+ "size",
2463
+ "type",
2464
+ "disabled",
2465
+ "loading",
2466
+ "leadingIcon",
2467
+ "trailingIcon",
2468
+ "iconOnly",
2469
+ "fullWidth",
2470
+ "ariaLabel"
2471
+ ],
2472
+ outputs: ["pressed"]
2473
+ },
2474
+ {
2475
+ kind: "component",
2476
+ type: StarCheckbox,
2477
+ selector: "star-checkbox",
2478
+ inputs: [
2479
+ "checked",
2480
+ "indeterminate",
2481
+ "disabled",
2482
+ "readonly",
2483
+ "required",
2484
+ "invalid",
2485
+ "touched",
2486
+ "name",
2487
+ "inputId",
2488
+ "ariaLabel",
2489
+ "ariaDescribedBy"
2490
+ ],
2491
+ outputs: [
2492
+ "checkedChange",
2493
+ "indeterminateChange",
2494
+ "touch"
2495
+ ]
2496
+ },
2497
+ {
2498
+ kind: "component",
2499
+ type: StarMultiSelect,
2500
+ selector: "star-multi-select",
2501
+ inputs: [
2502
+ "value",
2503
+ "display",
2504
+ "maxSelectedLabels",
2505
+ "selectionLimit",
2506
+ "showToggleAll"
2507
+ ],
2508
+ outputs: ["valueChange"]
2509
+ },
2510
+ {
2511
+ kind: "component",
2512
+ type: StarPaginator,
2513
+ selector: "star-paginator",
2514
+ inputs: [
2515
+ "totalRecords",
2516
+ "first",
2517
+ "rows",
2518
+ "rowsPerPageOptions",
2519
+ "pageLinkSize",
2520
+ "showCurrentPageReport",
2521
+ "showFirstLast",
2522
+ "ariaLabel"
2523
+ ],
2524
+ outputs: [
2525
+ "firstChange",
2526
+ "rowsChange",
2527
+ "pageChange"
2528
+ ]
2529
+ },
2530
+ {
2531
+ kind: "component",
2532
+ type: StarPopover,
2533
+ selector: "star-popover",
2534
+ inputs: [
2535
+ "ariaLabel",
2536
+ "focusOnShow",
2537
+ "dismissable"
2538
+ ],
2539
+ outputs: ["shown", "hidden"]
2540
+ },
2541
+ {
2542
+ kind: "component",
2543
+ type: StarSkeleton,
2544
+ selector: "star-skeleton",
2545
+ inputs: [
2546
+ "shape",
2547
+ "width",
2548
+ "height",
2549
+ "size",
2550
+ "borderRadius",
2551
+ "animation"
2552
+ ]
2553
+ }
2554
+ ],
2555
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
2556
+ });
2557
+ };
2558
+ i0.ɵɵngDeclareClassMetadata({
2559
+ minVersion: "12.0.0",
2560
+ version: "22.2.6",
2561
+ ngImport: i0,
2562
+ type: StarTable,
2563
+ decorators: [{
2564
+ type: Component,
2565
+ args: [{
2566
+ selector: "star-table",
2567
+ imports: [
2568
+ NgTemplateOutlet,
2569
+ StarButton,
2570
+ StarCheckbox,
2571
+ StarMultiSelect,
2572
+ StarPaginator,
2573
+ StarPopover,
2574
+ StarSkeleton
2575
+ ],
2576
+ changeDetection: ChangeDetectionStrategy.OnPush,
2577
+ host: {
2578
+ class: "star-table",
2579
+ "[class.star-table--striped]": "striped()",
2580
+ "[class.star-table--sm]": "size() === 'sm'",
2581
+ "[class.star-table--sticky]": "stickyHeader()",
2582
+ "[class.star-table--virtual]": "virtualScroll()",
2583
+ "[class.star-table--variable]": "variableHeights()",
2584
+ "[class.star-table--stack]": "responsiveLayout() === 'stack'",
2585
+ "[style.--star-table-row-height.px]": "virtualScroll() ? virtualRowHeight() : null",
2586
+ "(focusin)": "onBodyFocusIn($event)",
2587
+ "(focusout)": "onBodyFocusOut($event)",
2588
+ "(keydown)": "onBodyKeydown($event)"
2589
+ },
2590
+ template: `
2591
+ <ng-content select="[starTableCaption]" />
2592
+ @if (columnToggle()) {
2593
+ <div class="star-table__tools">
2594
+ <star-button
2595
+ size="sm"
2596
+ variant="secondary"
2597
+ leadingIcon="ph-bold ph-columns"
2598
+ (pressed)="columnsPanel.toggle($event)"
2599
+ >
2600
+ {{ text.columns }}
2601
+ </star-button>
2602
+ <star-popover #columnsPanel [ariaLabel]="text.columns">
2603
+ <ul class="star-table__columns">
2604
+ @for (
2605
+ column of orderedColumns();
2606
+ track column.field;
2607
+ let first = $first;
2608
+ let last = $last
2609
+ ) {
2610
+ <li>
2611
+ <star-checkbox
2612
+ [checked]="!isHidden(column)"
2613
+ [disabled]="!canHide(column)"
2614
+ (checkedChange)="setColumnVisible(column, $event)"
2615
+ >
2616
+ {{ column.header }}
2617
+ </star-checkbox>
2618
+ @if (reorderableColumns()) {
2619
+ <span class="star-table__columns-move">
2620
+ <button
2621
+ type="button"
2622
+ class="star-table__toggle"
2623
+ [disabled]="first"
2624
+ [attr.data-move]="moveKey(column, -1)"
2625
+ [attr.aria-label]="text.moveColumnEarlier(column.header)"
2626
+ (click)="moveColumnBy(column, -1)"
2627
+ >
2628
+ <i class="ph-bold ph-arrow-up" aria-hidden="true"></i>
2629
+ </button>
2630
+ <button
2631
+ type="button"
2632
+ class="star-table__toggle"
2633
+ [disabled]="last"
2634
+ [attr.data-move]="moveKey(column, 1)"
2635
+ [attr.aria-label]="text.moveColumnLater(column.header)"
2636
+ (click)="moveColumnBy(column, 1)"
2637
+ >
2638
+ <i class="ph-bold ph-arrow-down" aria-hidden="true"></i>
2639
+ </button>
2640
+ </span>
2641
+ }
2642
+ </li>
2643
+ }
2644
+ </ul>
2645
+ </star-popover>
2646
+ </div>
2647
+ }
2648
+ <div
2649
+ #scroller
2650
+ class="star-table__scroll"
2651
+ [attr.role]="scrollable() ? 'group' : null"
2652
+ [attr.aria-label]="scrollable() ? ariaLabel() : null"
2653
+ [attr.tabindex]="scrollable() ? 0 : null"
2654
+ [style.max-height]="scrollHeight()"
2655
+ (scroll)="onScroll($event)"
2656
+ >
2657
+ <table
2658
+ [attr.aria-label]="ariaLabel()"
2659
+ [attr.aria-busy]="loading() || null"
2660
+ [attr.aria-rowcount]="ariaRowCount()"
2661
+ >
2662
+ <thead>
2663
+ <tr [attr.aria-rowindex]="virtualScroll() ? 1 : null">
2664
+ @if (reorderableRows()) {
2665
+ <th class="star-table__reorder" scope="col">
2666
+ <span class="star-sr-only">{{ text.reorderRows }}</span>
2667
+ </th>
2668
+ }
2669
+ @if (expandable()) {
2670
+ <th class="star-table__expander" scope="col">
2671
+ <span class="star-sr-only">{{ text.rowDetails }}</span>
2672
+ </th>
2673
+ }
2674
+ @if (selectionMode() === 'multiple') {
2675
+ <th class="star-table__select" scope="col">
2676
+ <star-checkbox
2677
+ [checked]="pageState() === true"
2678
+ [indeterminate]="pageState() === 'mixed'"
2679
+ [ariaLabel]="text.selectAllRows"
2680
+ [disabled]="!pageRows().length"
2681
+ (checkedChange)="togglePage($event)"
2682
+ />
2683
+ </th>
2684
+ } @else if (selectionMode() === 'single') {
2685
+ <th class="star-table__select" scope="col">
2686
+ <span class="star-sr-only">{{ text.selectRow }}</span>
2687
+ </th>
2688
+ }
2689
+ @for (column of visibleColumns(); track column.field) {
2690
+ <th
2691
+ scope="col"
2692
+ [style.width]="widthOf(column)"
2693
+ [style.min-width]="resizedWidth(column)"
2694
+ [style.max-width]="resizedWidth(column)"
2695
+ [style.inset-inline-start]="frozenOffset(column)"
2696
+ [attr.data-field]="column.field"
2697
+ [class]="'star-table__th star-table__cell--' + (column.align ?? 'start')"
2698
+ [class.star-table__cell--frozen]="column.frozen"
2699
+ [class.star-table__th--drop]="dropField() === column.field"
2700
+ [attr.aria-sort]="ariaSort(column)"
2701
+ [attr.draggable]="reorderableColumns() ? 'true' : null"
2702
+ (dragstart)="onDragStart(column, $event)"
2703
+ (dragover)="onDragOver(column, $event)"
2704
+ (drop)="onDrop(column, $event)"
2705
+ (dragend)="endDrag()"
2706
+ >
2707
+ @if (column.sortable) {
2708
+ <button
2709
+ type="button"
2710
+ class="star-table__sort"
2711
+ [attr.title]="multiSort() ? text.sortMultiHint : null"
2712
+ (click)="sortBy(column, $event)"
2713
+ >
2714
+ {{ column.header }}
2715
+ <i [class]="sortIcon(column)" aria-hidden="true"></i>
2716
+ @if (sortRank(column); as rank) {
2717
+ <span class="star-table__sort-rank">{{ rank }}</span>
2718
+ }
2719
+ </button>
2720
+ } @else {
2721
+ {{ column.header }}
2722
+ }
2723
+ @if (resizableColumns()) {
2724
+ <span
2725
+ class="star-table__resizer"
2726
+ role="separator"
2727
+ aria-orientation="vertical"
2728
+ tabindex="0"
2729
+ [attr.aria-label]="text.resizeColumn(column.header)"
2730
+ [attr.aria-valuenow]="resizeNow(column)"
2731
+ [attr.aria-valuemin]="minColumnWidth"
2732
+ [attr.aria-valuemax]="resizeMax(column)"
2733
+ (pointerdown)="startResize(column, $event)"
2734
+ (keydown)="onResizeKey(column, $event)"
2735
+ ></span>
2736
+ }
2737
+ </th>
2738
+ }
2739
+ </tr>
2740
+ @if (hasColumnFilters()) {
2741
+ <tr class="star-table__filters" [attr.aria-rowindex]="virtualScroll() ? 2 : null">
2742
+ @if (reorderableRows()) {
2743
+ <td class="star-table__reorder"></td>
2744
+ }
2745
+ @if (expandable()) {
2746
+ <td class="star-table__expander"></td>
2747
+ }
2748
+ @if (selectionMode()) {
2749
+ <td class="star-table__select"></td>
2750
+ }
2751
+ @for (column of visibleColumns(); track column.field) {
2752
+ <td
2753
+ [class.star-table__cell--frozen]="column.frozen"
2754
+ [style.inset-inline-start]="frozenOffset(column)"
2755
+ [attr.data-label]="column.filter ? column.header : null"
2756
+ >
2757
+ @if (column.filter === 'select') {
2758
+ <select
2759
+ class="star-input star-input--sm star-table__filter"
2760
+ [attr.aria-label]="text.filterBy(column.header)"
2761
+ (change)="setFilter(column.field, $any($event.target).value)"
2762
+ >
2763
+ <option value="" [selected]="!filterValue(column.field)">
2764
+ {{ text.filterAll }}
2765
+ </option>
2766
+ @for (option of filterChoices(column); track option) {
2767
+ <option [value]="option" [selected]="option === filterValue(column.field)">
2768
+ {{ option }}
2769
+ </option>
2770
+ }
2771
+ </select>
2772
+ } @else if (column.filter === 'text') {
2773
+ <input
2774
+ type="search"
2775
+ class="star-input star-input--sm star-table__filter"
2776
+ [attr.aria-label]="text.filterBy(column.header)"
2777
+ [value]="filterValue(column.field)"
2778
+ (input)="setFilter(column.field, $any($event.target).value)"
2779
+ />
2780
+ } @else if (column.filter === 'multiselect') {
2781
+ <star-multi-select
2782
+ class="star-table__filter"
2783
+ size="sm"
2784
+ [options]="filterChoices(column)"
2785
+ [value]="filterList(column.field)"
2786
+ [placeholder]="text.filterAll"
2787
+ [ariaLabel]="text.filterBy(column.header)"
2788
+ (valueChange)="setFilter(column.field, $event)"
2789
+ />
2790
+ } @else if (column.filter === 'number' || column.filter === 'date') {
2791
+ <span class="star-table__filter-range">
2792
+ <input
2793
+ class="star-input star-input--sm star-table__filter"
2794
+ [type]="column.filter"
2795
+ [attr.aria-label]="text.filterMin(column.header)"
2796
+ [attr.placeholder]="column.filter === 'number' ? text.filterMinShort : null"
2797
+ [value]="filterBound(column.field, 'min')"
2798
+ (input)="setBound(column, 'min', $any($event.target).value)"
2799
+ />
2800
+ <input
2801
+ class="star-input star-input--sm star-table__filter"
2802
+ [type]="column.filter"
2803
+ [attr.aria-label]="text.filterMax(column.header)"
2804
+ [attr.placeholder]="column.filter === 'number' ? text.filterMaxShort : null"
2805
+ [value]="filterBound(column.field, 'max')"
2806
+ (input)="setBound(column, 'max', $any($event.target).value)"
2807
+ />
2808
+ </span>
2809
+ }
2810
+ </td>
2811
+ }
2812
+ </tr>
2813
+ }
2814
+ </thead>
2815
+ <tbody #body>
2816
+ @if (loading()) {
2817
+ @for (row of skeletonRows(); track row) {
2818
+ <tr class="star-table__row">
2819
+ @if (reorderableRows()) {
2820
+ <td class="star-table__reorder"></td>
2821
+ }
2822
+ @if (expandable()) {
2823
+ <td class="star-table__expander"></td>
2824
+ }
2825
+ @if (selectionMode()) {
2826
+ <td class="star-table__select"><star-skeleton size="1.25rem" /></td>
2827
+ }
2828
+ @for (column of visibleColumns(); track column.field) {
2829
+ <td><star-skeleton height="0.875rem" [width]="row % 2 ? '70%' : '90%'" /></td>
2830
+ }
2831
+ </tr>
2832
+ }
2833
+ } @else {
2834
+ @for (entry of bodyEntries(); track entry.key) {
2835
+ @if (entry.kind === 'spacer') {
2836
+ <tr class="star-table__spacer" aria-hidden="true">
2837
+ <td [attr.colspan]="colspan()" [style.height.px]="entry.height"></td>
2838
+ </tr>
2839
+ } @else if (entry.kind === 'group') {
2840
+ @let group = entry;
2841
+ <tr
2842
+ class="star-table__group"
2843
+ [attr.aria-rowindex]="group.aria"
2844
+ [attr.data-vi]="group.item"
2845
+ >
2846
+ <th [attr.colspan]="colspan()" scope="colgroup">
2847
+ <button
2848
+ type="button"
2849
+ class="star-table__group-toggle"
2850
+ [attr.aria-expanded]="!isGroupCollapsed(group.label)"
2851
+ (click)="toggleGroup(group.label)"
2852
+ >
2853
+ <i class="ph-bold ph-caret-down" aria-hidden="true"></i>
2854
+ {{ group.label }}
2855
+ <span class="star-table__group-count">{{ group.count }}</span>
2856
+ </button>
2857
+ </th>
2858
+ </tr>
2859
+ } @else {
2860
+ @let row = entry.row;
2861
+ @let i = entry.index;
2862
+ <tr
2863
+ [attr.aria-rowindex]="entry.aria"
2864
+ [attr.data-vi]="entry.item"
2865
+ [hidden]="isRowCollapsed(row)"
2866
+ class="star-table__row"
2867
+ [class.star-table__row--alt]="i % 2 === 1"
2868
+ [class.star-table__row--selected]="isSelected(row)"
2869
+ [class.star-table__row--clickable]="clickable()"
2870
+ [class.star-table__row--expanded]="expandable() && isExpanded(row)"
2871
+ [attr.aria-selected]="selectionMode() ? isSelected(row) : null"
2872
+ (click)="onRowClick(row, $event)"
2873
+ >
2874
+ @if (reorderableRows()) {
2875
+ <td class="star-table__reorder">
2876
+ <button
2877
+ type="button"
2878
+ class="star-table__toggle"
2879
+ [disabled]="!canMoveRow(row, -1)"
2880
+ [attr.aria-label]="text.moveUp"
2881
+ (click)="moveRow(row, -1)"
2882
+ >
2883
+ <i class="ph-bold ph-arrow-up" aria-hidden="true"></i>
2884
+ </button>
2885
+ <button
2886
+ type="button"
2887
+ class="star-table__toggle"
2888
+ [disabled]="!canMoveRow(row, 1)"
2889
+ [attr.aria-label]="text.moveDown"
2890
+ (click)="moveRow(row, 1)"
2891
+ >
2892
+ <i class="ph-bold ph-arrow-down" aria-hidden="true"></i>
2893
+ </button>
2894
+ </td>
2895
+ }
2896
+ @if (expandable()) {
2897
+ <td class="star-table__expander">
2898
+ <button
2899
+ type="button"
2900
+ class="star-table__toggle"
2901
+ [attr.aria-expanded]="isExpanded(row)"
2902
+ [attr.aria-controls]="isExpanded(row) ? detailId(i) : null"
2903
+ [attr.aria-label]="isExpanded(row) ? text.collapseRow : text.expandRow"
2904
+ (click)="toggleExpansion(row)"
2905
+ >
2906
+ <i class="ph-bold ph-caret-right" aria-hidden="true"></i>
2907
+ </button>
2908
+ </td>
2909
+ }
2910
+ @if (selectionMode() === 'multiple') {
2911
+ <td class="star-table__select">
2912
+ <star-checkbox
2913
+ [checked]="isSelected(row)"
2914
+ [ariaLabel]="text.selectRow"
2915
+ (checkedChange)="toggleRow(row)"
2916
+ (click)="$event.stopPropagation()"
2917
+ />
2918
+ </td>
2919
+ } @else if (selectionMode() === 'single') {
2920
+ <td class="star-table__select">
2921
+ <input
2922
+ type="radio"
2923
+ class="star-table__radio"
2924
+ [name]="radioName"
2925
+ [checked]="isSelected(row)"
2926
+ [attr.aria-label]="text.selectRow"
2927
+ (change)="selectOnly(row)"
2928
+ (click)="$event.stopPropagation()"
2929
+ />
2930
+ </td>
2931
+ }
2932
+ @for (column of visibleColumns(); track column.field) {
2933
+ <td
2934
+ [class]="'star-table__cell--' + (column.align ?? 'start')"
2935
+ [class.star-table__cell--frozen]="column.frozen"
2936
+ [style.inset-inline-start]="frozenOffset(column)"
2937
+ [attr.data-label]="column.header"
2938
+ >
2939
+ @if (isEditing(row, column)) {
2940
+ @if (column.editor === 'select') {
2941
+ <select
2942
+ class="star-input star-input--sm star-table__editor"
2943
+ [attr.aria-label]="text.editCell(column.header)"
2944
+ (change)="commitEdit(row, column, $any($event.target).value)"
2945
+ (blur)="commitEdit(row, column, $any($event.target).value)"
2946
+ (keydown.escape)="cancelEdit($event)"
2947
+ >
2948
+ @for (option of column.editOptions ?? []; track option) {
2949
+ <option
2950
+ [value]="option"
2951
+ [selected]="option === cellText(row, column)"
2952
+ >
2953
+ {{ option }}
2954
+ </option>
2955
+ }
2956
+ </select>
2957
+ } @else {
2958
+ <input
2959
+ class="star-input star-input--sm star-table__editor"
2960
+ [type]="column.editor === 'number' ? 'number' : 'text'"
2961
+ [attr.aria-label]="text.editCell(column.header)"
2962
+ [value]="editText(row, column)"
2963
+ (blur)="commitEdit(row, column, $any($event.target).value)"
2964
+ (keydown.enter)="commitEdit(row, column, $any($event.target).value)"
2965
+ (keydown.escape)="cancelEdit($event)"
2966
+ />
2967
+ }
2968
+ } @else if (isEditable(row, column)) {
2969
+ <button
2970
+ type="button"
2971
+ class="star-table__edit"
2972
+ [attr.data-edit]="editKey(row, column)"
2973
+ (click)="startEdit(row, column)"
2974
+ >
2975
+ <!-- The name is the action and the visible value (WCAG 2.5.3). -->
2976
+ <span class="star-sr-only">{{ text.editCell(column.header) }}: </span>
2977
+ <span class="star-table__edit-value">
2978
+ <ng-container
2979
+ *ngTemplateOutlet="
2980
+ cell;
2981
+ context: { $implicit: row, column, index: i }
2982
+ "
2983
+ />
2984
+ </span>
2985
+ <i class="ph-bold ph-pencil-simple" aria-hidden="true"></i>
2986
+ </button>
2987
+ } @else {
2988
+ <ng-container
2989
+ *ngTemplateOutlet="cell; context: { $implicit: row, column, index: i }"
2990
+ />
2991
+ }
2992
+ </td>
2993
+ }
2994
+ </tr>
2995
+ @if (expansionTemplate(); as detail) {
2996
+ @if (isExpanded(row) && !isRowCollapsed(row)) {
2997
+ <tr
2998
+ class="star-table__expansion"
2999
+ [id]="detailId(i)"
3000
+ [attr.aria-rowindex]="entry.aria === null ? null : entry.aria + 1"
3001
+ [attr.data-vi]="entry.item"
3002
+ >
3003
+ <td [attr.colspan]="colspan()">
3004
+ <ng-container
3005
+ *ngTemplateOutlet="detail; context: { $implicit: row, index: i }"
3006
+ />
3007
+ </td>
3008
+ </tr>
3009
+ }
3010
+ }
3011
+ }
3012
+ } @empty {
3013
+ <tr>
3014
+ <td class="star-table__empty" [attr.colspan]="colspan()">
3015
+ <i class="ph-bold ph-tray" aria-hidden="true"></i>
3016
+ {{ emptyMessage() ?? text.noData }}
3017
+ </td>
3018
+ </tr>
3019
+ }
3020
+ }
3021
+ </tbody>
3022
+ @if (hasFooter()) {
3023
+ <tfoot>
3024
+ <tr
3025
+ class="star-table__footer"
3026
+ [attr.aria-rowindex]="virtualScroll() ? ariaRowCount() : null"
3027
+ >
3028
+ @if (reorderableRows()) {
3029
+ <td class="star-table__reorder"></td>
3030
+ }
3031
+ @if (expandable()) {
3032
+ <td class="star-table__expander"></td>
3033
+ }
3034
+ @if (selectionMode()) {
3035
+ <td class="star-table__select"></td>
3036
+ }
3037
+ @for (column of visibleColumns(); track column.field) {
3038
+ <td
3039
+ [class]="'star-table__cell--' + (column.align ?? 'start')"
3040
+ [attr.data-label]="footerText(column) ? column.header : null"
3041
+ >
3042
+ {{ footerText(column) }}
3043
+ </td>
3044
+ }
3045
+ </tr>
3046
+ </tfoot>
3047
+ }
3048
+ </table>
3049
+ </div>
3050
+ <ng-template #cell let-row let-column="column" let-i="index">
3051
+ @if (cellTemplate(column.field); as custom) {
3052
+ <ng-container
3053
+ *ngTemplateOutlet="
3054
+ custom;
3055
+ context: { $implicit: row, value: cellValue(row, column), index: i }
3056
+ "
3057
+ />
3058
+ } @else {
3059
+ {{ cellText(row, column) }}
3060
+ }
3061
+ </ng-template>
3062
+ @if (paginator()) {
3063
+ <star-paginator
3064
+ [ariaLabel]="ariaLabel() ? text.pagination + ': ' + ariaLabel() : null"
3065
+ [totalRecords]="total()"
3066
+ [(first)]="first"
3067
+ [(rows)]="rows"
3068
+ [rowsPerPageOptions]="rowsPerPageOptions()"
3069
+ (pageChange)="emitLazy()"
3070
+ />
3071
+ }
3072
+ `
3073
+ }]
3074
+ }],
3075
+ ctorParameters: () => [],
3076
+ propDecorators: {
3077
+ value: [{
3078
+ type: i0.Input,
3079
+ args: [{
3080
+ isSignal: true,
3081
+ alias: "value",
3082
+ required: true
3083
+ }]
3084
+ }],
3085
+ columns: [{
3086
+ type: i0.Input,
3087
+ args: [{
3088
+ isSignal: true,
3089
+ alias: "columns",
3090
+ required: true
3091
+ }]
3092
+ }],
3093
+ dataKey: [{
3094
+ type: i0.Input,
3095
+ args: [{
3096
+ isSignal: true,
3097
+ alias: "dataKey",
3098
+ required: false
3099
+ }]
3100
+ }],
3101
+ loading: [{
3102
+ type: i0.Input,
3103
+ args: [{
3104
+ isSignal: true,
3105
+ alias: "loading",
3106
+ required: false
3107
+ }]
3108
+ }],
3109
+ emptyMessage: [{
3110
+ type: i0.Input,
3111
+ args: [{
3112
+ isSignal: true,
3113
+ alias: "emptyMessage",
3114
+ required: false
3115
+ }]
3116
+ }],
3117
+ striped: [{
3118
+ type: i0.Input,
3119
+ args: [{
3120
+ isSignal: true,
3121
+ alias: "striped",
3122
+ required: false
3123
+ }]
3124
+ }],
3125
+ size: [{
3126
+ type: i0.Input,
3127
+ args: [{
3128
+ isSignal: true,
3129
+ alias: "size",
3130
+ required: false
3131
+ }]
3132
+ }],
3133
+ stickyHeader: [{
3134
+ type: i0.Input,
3135
+ args: [{
3136
+ isSignal: true,
3137
+ alias: "stickyHeader",
3138
+ required: false
3139
+ }]
3140
+ }],
3141
+ scrollHeight: [{
3142
+ type: i0.Input,
3143
+ args: [{
3144
+ isSignal: true,
3145
+ alias: "scrollHeight",
3146
+ required: false
3147
+ }]
3148
+ }],
3149
+ responsiveLayout: [{
3150
+ type: i0.Input,
3151
+ args: [{
3152
+ isSignal: true,
3153
+ alias: "responsiveLayout",
3154
+ required: false
3155
+ }]
3156
+ }],
3157
+ virtualScroll: [{
3158
+ type: i0.Input,
3159
+ args: [{
3160
+ isSignal: true,
3161
+ alias: "virtualScroll",
3162
+ required: false
3163
+ }]
3164
+ }],
3165
+ virtualRowHeight: [{
3166
+ type: i0.Input,
3167
+ args: [{
3168
+ isSignal: true,
3169
+ alias: "virtualRowHeight",
3170
+ required: false
3171
+ }]
3172
+ }],
3173
+ virtualRowHeights: [{
3174
+ type: i0.Input,
3175
+ args: [{
3176
+ isSignal: true,
3177
+ alias: "virtualRowHeights",
3178
+ required: false
3179
+ }]
3180
+ }],
3181
+ ariaLabel: [{
3182
+ type: i0.Input,
3183
+ args: [{
3184
+ isSignal: true,
3185
+ alias: "ariaLabel",
3186
+ required: false
3187
+ }]
3188
+ }],
3189
+ paginator: [{
3190
+ type: i0.Input,
3191
+ args: [{
3192
+ isSignal: true,
3193
+ alias: "paginator",
3194
+ required: false
3195
+ }]
3196
+ }],
3197
+ first: [{
3198
+ type: i0.Input,
3199
+ args: [{
3200
+ isSignal: true,
3201
+ alias: "first",
3202
+ required: false
3203
+ }]
3204
+ }, {
3205
+ type: i0.Output,
3206
+ args: ["firstChange"]
3207
+ }],
3208
+ rows: [{
3209
+ type: i0.Input,
3210
+ args: [{
3211
+ isSignal: true,
3212
+ alias: "rows",
3213
+ required: false
3214
+ }]
3215
+ }, {
3216
+ type: i0.Output,
3217
+ args: ["rowsChange"]
3218
+ }],
3219
+ rowsPerPageOptions: [{
3220
+ type: i0.Input,
3221
+ args: [{
3222
+ isSignal: true,
3223
+ alias: "rowsPerPageOptions",
3224
+ required: false
3225
+ }]
3226
+ }],
3227
+ sortField: [{
3228
+ type: i0.Input,
3229
+ args: [{
3230
+ isSignal: true,
3231
+ alias: "sortField",
3232
+ required: false
3233
+ }]
3234
+ }, {
3235
+ type: i0.Output,
3236
+ args: ["sortFieldChange"]
3237
+ }],
3238
+ sortOrder: [{
3239
+ type: i0.Input,
3240
+ args: [{
3241
+ isSignal: true,
3242
+ alias: "sortOrder",
3243
+ required: false
3244
+ }]
3245
+ }, {
3246
+ type: i0.Output,
3247
+ args: ["sortOrderChange"]
3248
+ }],
3249
+ globalFilter: [{
3250
+ type: i0.Input,
3251
+ args: [{
3252
+ isSignal: true,
3253
+ alias: "globalFilter",
3254
+ required: false
3255
+ }]
3256
+ }],
3257
+ filters: [{
3258
+ type: i0.Input,
3259
+ args: [{
3260
+ isSignal: true,
3261
+ alias: "filters",
3262
+ required: false
3263
+ }]
3264
+ }, {
3265
+ type: i0.Output,
3266
+ args: ["filtersChange"]
3267
+ }],
3268
+ lazy: [{
3269
+ type: i0.Input,
3270
+ args: [{
3271
+ isSignal: true,
3272
+ alias: "lazy",
3273
+ required: false
3274
+ }]
3275
+ }],
3276
+ totalRecords: [{
3277
+ type: i0.Input,
3278
+ args: [{
3279
+ isSignal: true,
3280
+ alias: "totalRecords",
3281
+ required: false
3282
+ }]
3283
+ }],
3284
+ selectionMode: [{
3285
+ type: i0.Input,
3286
+ args: [{
3287
+ isSignal: true,
3288
+ alias: "selectionMode",
3289
+ required: false
3290
+ }]
3291
+ }],
3292
+ selection: [{
3293
+ type: i0.Input,
3294
+ args: [{
3295
+ isSignal: true,
3296
+ alias: "selection",
3297
+ required: false
3298
+ }]
3299
+ }, {
3300
+ type: i0.Output,
3301
+ args: ["selectionChange"]
3302
+ }],
3303
+ expandedKeys: [{
3304
+ type: i0.Input,
3305
+ args: [{
3306
+ isSignal: true,
3307
+ alias: "expandedKeys",
3308
+ required: false
3309
+ }]
3310
+ }, {
3311
+ type: i0.Output,
3312
+ args: ["expandedKeysChange"]
3313
+ }],
3314
+ rowExpandMode: [{
3315
+ type: i0.Input,
3316
+ args: [{
3317
+ isSignal: true,
3318
+ alias: "rowExpandMode",
3319
+ required: false
3320
+ }]
3321
+ }],
3322
+ columnToggle: [{
3323
+ type: i0.Input,
3324
+ args: [{
3325
+ isSignal: true,
3326
+ alias: "columnToggle",
3327
+ required: false
3328
+ }]
3329
+ }],
3330
+ reorderableColumns: [{
3331
+ type: i0.Input,
3332
+ args: [{
3333
+ isSignal: true,
3334
+ alias: "reorderableColumns",
3335
+ required: false
3336
+ }]
3337
+ }],
3338
+ resizableColumns: [{
3339
+ type: i0.Input,
3340
+ args: [{
3341
+ isSignal: true,
3342
+ alias: "resizableColumns",
3343
+ required: false
3344
+ }]
3345
+ }],
3346
+ columnOrder: [{
3347
+ type: i0.Input,
3348
+ args: [{
3349
+ isSignal: true,
3350
+ alias: "columnOrder",
3351
+ required: false
3352
+ }]
3353
+ }, {
3354
+ type: i0.Output,
3355
+ args: ["columnOrderChange"]
3356
+ }],
3357
+ hiddenColumns: [{
3358
+ type: i0.Input,
3359
+ args: [{
3360
+ isSignal: true,
3361
+ alias: "hiddenColumns",
3362
+ required: false
3363
+ }]
3364
+ }, {
3365
+ type: i0.Output,
3366
+ args: ["hiddenColumnsChange"]
3367
+ }],
3368
+ columnWidths: [{
3369
+ type: i0.Input,
3370
+ args: [{
3371
+ isSignal: true,
3372
+ alias: "columnWidths",
3373
+ required: false
3374
+ }]
3375
+ }, {
3376
+ type: i0.Output,
3377
+ args: ["columnWidthsChange"]
3378
+ }],
3379
+ multiSort: [{
3380
+ type: i0.Input,
3381
+ args: [{
3382
+ isSignal: true,
3383
+ alias: "multiSort",
3384
+ required: false
3385
+ }]
3386
+ }],
3387
+ sortMeta: [{
3388
+ type: i0.Input,
3389
+ args: [{
3390
+ isSignal: true,
3391
+ alias: "sortMeta",
3392
+ required: false
3393
+ }]
3394
+ }, {
3395
+ type: i0.Output,
3396
+ args: ["sortMetaChange"]
3397
+ }],
3398
+ groupBy: [{
3399
+ type: i0.Input,
3400
+ args: [{
3401
+ isSignal: true,
3402
+ alias: "groupBy",
3403
+ required: false
3404
+ }]
3405
+ }],
3406
+ collapsedGroups: [{
3407
+ type: i0.Input,
3408
+ args: [{
3409
+ isSignal: true,
3410
+ alias: "collapsedGroups",
3411
+ required: false
3412
+ }]
3413
+ }, {
3414
+ type: i0.Output,
3415
+ args: ["collapsedGroupsChange"]
3416
+ }],
3417
+ reorderableRows: [{
3418
+ type: i0.Input,
3419
+ args: [{
3420
+ isSignal: true,
3421
+ alias: "reorderableRows",
3422
+ required: false
3423
+ }]
3424
+ }],
3425
+ stateKey: [{
3426
+ type: i0.Input,
3427
+ args: [{
3428
+ isSignal: true,
3429
+ alias: "stateKey",
3430
+ required: false
3431
+ }]
3432
+ }],
3433
+ stateStorage: [{
3434
+ type: i0.Input,
3435
+ args: [{
3436
+ isSignal: true,
3437
+ alias: "stateStorage",
3438
+ required: false
3439
+ }]
3440
+ }],
3441
+ rowClick: [{
3442
+ type: i0.Output,
3443
+ args: ["rowClick"]
3444
+ }],
3445
+ rowReorder: [{
3446
+ type: i0.Output,
3447
+ args: ["rowReorder"]
3448
+ }],
3449
+ cellEdit: [{
3450
+ type: i0.Output,
3451
+ args: ["cellEdit"]
3452
+ }],
3453
+ lazyLoad: [{
3454
+ type: i0.Output,
3455
+ args: ["lazyLoad"]
3456
+ }],
3457
+ cellTemplates: [{
3458
+ type: i0.ContentChildren,
3459
+ args: [i0.forwardRef(() => StarCellTemplate), { isSignal: true }]
3460
+ }],
3461
+ expansion: [{
3462
+ type: i0.ContentChild,
3463
+ args: [i0.forwardRef(() => StarRowExpansionTemplate), { isSignal: true }]
3464
+ }],
3465
+ scroller: [{
3466
+ type: i0.ViewChild,
3467
+ args: ["scroller", { isSignal: true }]
3468
+ }],
3469
+ body: [{
3470
+ type: i0.ViewChild,
3471
+ args: ["body", { isSignal: true }]
3472
+ }]
3473
+ }
3474
+ });
3475
+ export { PRINT_FIT_STEPS, StarCellTemplate, StarRowExpansionTemplate, StarTable, buildPrintDocument, buildXlsx, fitPrintDocument, printFitStyle };
3476
+
3477
+ //# sourceMappingURL=star-ng-ui-table.mjs.map