argus-table 0.2.1 → 0.3.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 (69) hide show
  1. package/README.md +1 -1
  2. package/dist/argus-column.js +24 -1
  3. package/dist/argus-column.js.map +1 -1
  4. package/dist/argus-table.js +1026 -167
  5. package/dist/argus-table.js.map +1 -1
  6. package/dist/cdn/argus-table.js +74 -50
  7. package/dist/cdn/argus-table.js.map +1 -1
  8. package/dist/controllers/auto-width.js +11 -0
  9. package/dist/controllers/auto-width.js.map +1 -1
  10. package/dist/controllers/column-window.js +139 -0
  11. package/dist/controllers/column-window.js.map +1 -0
  12. package/dist/controllers/data-controller.js +9 -4
  13. package/dist/controllers/data-controller.js.map +1 -1
  14. package/dist/controllers/plugins.js +102 -0
  15. package/dist/controllers/plugins.js.map +1 -0
  16. package/dist/controllers/reorder-drag.js +9 -10
  17. package/dist/controllers/reorder-drag.js.map +1 -1
  18. package/dist/controllers/row-measure.js +121 -0
  19. package/dist/controllers/row-measure.js.map +1 -0
  20. package/dist/controllers/virtual-controller.js +316 -10
  21. package/dist/controllers/virtual-controller.js.map +1 -1
  22. package/dist/core/src/columns/column-order.js +14 -10
  23. package/dist/core/src/columns/column-order.js.map +1 -1
  24. package/dist/core/src/columns/resolve-columns.js +18 -4
  25. package/dist/core/src/columns/resolve-columns.js.map +1 -1
  26. package/dist/core/src/data/page-cache.js +4 -0
  27. package/dist/core/src/data/page-cache.js.map +1 -1
  28. package/dist/core/src/filters/filter.js +185 -0
  29. package/dist/core/src/filters/filter.js.map +1 -0
  30. package/dist/core/src/state/selection.js +70 -0
  31. package/dist/core/src/state/selection.js.map +1 -0
  32. package/dist/core/src/table/create-table.js +239 -64
  33. package/dist/core/src/table/create-table.js.map +1 -1
  34. package/dist/core/src/table/filtered-row-model.js +48 -0
  35. package/dist/core/src/table/filtered-row-model.js.map +1 -0
  36. package/dist/core/src/table/sorted-row-model.js +13 -2
  37. package/dist/core/src/table/sorted-row-model.js.map +1 -1
  38. package/dist/core/src/virtual/column-window.js +72 -0
  39. package/dist/core/src/virtual/column-window.js.map +1 -0
  40. package/dist/core/src/virtual/row-pool.js +2 -1
  41. package/dist/core/src/virtual/row-pool.js.map +1 -1
  42. package/dist/core/src/virtual/row-sizes.js +156 -0
  43. package/dist/core/src/virtual/row-sizes.js.map +1 -0
  44. package/dist/core/src/virtual/scroll-scale.js +41 -3
  45. package/dist/core/src/virtual/scroll-scale.js.map +1 -1
  46. package/dist/custom-elements.json +1320 -74
  47. package/dist/events.js +9 -1
  48. package/dist/events.js.map +1 -1
  49. package/dist/index.d.ts +609 -74
  50. package/dist/index.js +3 -2
  51. package/dist/interactive.js +22 -0
  52. package/dist/interactive.js.map +1 -0
  53. package/dist/max-height.js +22 -8
  54. package/dist/max-height.js.map +1 -1
  55. package/dist/render/body.js +47 -7
  56. package/dist/render/body.js.map +1 -1
  57. package/dist/render/cells.js +14 -11
  58. package/dist/render/cells.js.map +1 -1
  59. package/dist/render/content-directive.js +115 -0
  60. package/dist/render/content-directive.js.map +1 -0
  61. package/dist/render/content.js +20 -9
  62. package/dist/render/content.js.map +1 -1
  63. package/dist/render/header.js +24 -5
  64. package/dist/render/header.js.map +1 -1
  65. package/dist/render/pinned-rows.js +1 -1
  66. package/dist/render/pinned-rows.js.map +1 -1
  67. package/dist/styles/base.js +1 -1
  68. package/dist/styles/base.js.map +1 -1
  69. package/package.json +1 -1
@@ -89,7 +89,7 @@
89
89
  },
90
90
  {
91
91
  "kind": "class",
92
- "description": "One column of the parent `<argus-table>`, written as markup instead of an entry in\nits `columns` property. It is data only and renders nothing.\n\nOnly direct children of the table count, in document order. A non-empty `columns`\nproperty wins over the children. Adding, removing, moving or changing a column\nupdates the table; sizes, order and sorting are kept by `column-id`.\n\nA `<template>` child is the content of every cell in the column (static: the same\nfor each row). Set the `cell` property for content that depends on the row.",
92
+ "description": "One column of the parent `<argus-table>`, written as markup instead of an entry in\nits `columns` property. It is data only and renders nothing.\n\nOnly direct children of the table count, in document order. A non-empty `columns`\nproperty wins over the children. Adding, removing, moving or changing a column\nupdates the table; sizes, order and sorting are kept by `column-id`.\n\nA `<template>` child is the content of every cell in the column (static: the same\nfor each row). Set the `cell` property for content that depends on the row.\n\nThe standard `hidden` attribute (or property) hides the column, like `hidden` in\n`columns`; the table's `columnVisibility` overrides it.",
93
93
  "name": "ArgusColumn",
94
94
  "members": [
95
95
  {
@@ -120,6 +120,15 @@
120
120
  "description": "How to read the cell value: a property path such as `customer.name`, or (as a\nproperty) a function of the row and its index.",
121
121
  "attribute": "accessor"
122
122
  },
123
+ {
124
+ "kind": "field",
125
+ "name": "formula",
126
+ "type": {
127
+ "text": "string | undefined"
128
+ },
129
+ "description": "A spreadsheet formula computed per row from other columns, such as\n`[price] * [quantity]`. Needs the `formulas()` plugin from `@argus-table/formulas`.",
130
+ "attribute": "formula"
131
+ },
123
132
  {
124
133
  "kind": "field",
125
134
  "name": "cell",
@@ -161,9 +170,27 @@
161
170
  "type": {
162
171
  "text": "ColumnPin | undefined"
163
172
  },
164
- "description": "Pins the column to the `start` or `end` side.",
173
+ "description": "Pins the column to the `start` or `end` side. The table's `columnPinning` overrides it.",
165
174
  "attribute": "pin"
166
175
  },
176
+ {
177
+ "kind": "field",
178
+ "name": "pinnable",
179
+ "type": {
180
+ "text": "boolean | undefined"
181
+ },
182
+ "description": "Whether the user can pin or unpin the column. Default: `true`; `pinnable=\"false\"` turns it off.",
183
+ "attribute": "pinnable"
184
+ },
185
+ {
186
+ "kind": "field",
187
+ "name": "hideable",
188
+ "type": {
189
+ "text": "boolean | undefined"
190
+ },
191
+ "description": "Whether the user can hide the column. Default: `true`; `hideable=\"false\"` turns it off.",
192
+ "attribute": "hideable"
193
+ },
167
194
  {
168
195
  "kind": "field",
169
196
  "name": "align",
@@ -173,6 +200,15 @@
173
200
  "description": "Text alignment: `start`, `center` or `end`. Default: `start`.",
174
201
  "attribute": "align"
175
202
  },
203
+ {
204
+ "kind": "field",
205
+ "name": "wrap",
206
+ "type": {
207
+ "text": "boolean | undefined"
208
+ },
209
+ "description": "Wraps the cell text onto more lines instead of cutting it off. Default:\n`false`. With a fixed row height, text that doesn't fit is clipped.",
210
+ "attribute": "wrap"
211
+ },
176
212
  {
177
213
  "kind": "field",
178
214
  "name": "sortable",
@@ -200,6 +236,31 @@
200
236
  "description": "Whether the column can be moved. Default: `true`; `reorderable=\"false\"` turns it off.",
201
237
  "attribute": "reorderable"
202
238
  },
239
+ {
240
+ "kind": "field",
241
+ "name": "filter",
242
+ "type": {
243
+ "text": "FilterKind | undefined"
244
+ },
245
+ "description": "The kind of filter users can set, e.g. from the column menu: `text`, `number`,\n`date` or `set`. Unset: users can't filter the column.",
246
+ "attribute": "filter"
247
+ },
248
+ {
249
+ "kind": "field",
250
+ "name": "filterFn",
251
+ "type": {
252
+ "text": "ColumnDef<T>['filterFn'] | undefined"
253
+ },
254
+ "description": "Replaces the built-in matching for this column's filter. Property only."
255
+ },
256
+ {
257
+ "kind": "field",
258
+ "name": "filterOptions",
259
+ "type": {
260
+ "text": "readonly FilterValue[] | undefined"
261
+ },
262
+ "description": "The values a `set` filter offers; needed with a `dataSource`. Property only."
263
+ },
203
264
  {
204
265
  "kind": "method",
205
266
  "name": "toColumnDef",
@@ -212,6 +273,9 @@
212
273
  }
213
274
  ],
214
275
  "attributes": [
276
+ {
277
+ "name": "hidden"
278
+ },
215
279
  {
216
280
  "name": "column-id",
217
281
  "type": {
@@ -237,6 +301,14 @@
237
301
  "description": "How to read the cell value: a property path such as `customer.name`, or (as a\nproperty) a function of the row and its index.",
238
302
  "fieldName": "accessor"
239
303
  },
304
+ {
305
+ "name": "formula",
306
+ "type": {
307
+ "text": "string | undefined"
308
+ },
309
+ "description": "A spreadsheet formula computed per row from other columns, such as\n`[price] * [quantity]`. Needs the `formulas()` plugin from `@argus-table/formulas`.",
310
+ "fieldName": "formula"
311
+ },
240
312
  {
241
313
  "name": "width",
242
314
  "type": {
@@ -266,9 +338,25 @@
266
338
  "type": {
267
339
  "text": "ColumnPin | undefined"
268
340
  },
269
- "description": "Pins the column to the `start` or `end` side.",
341
+ "description": "Pins the column to the `start` or `end` side. The table's `columnPinning` overrides it.",
270
342
  "fieldName": "pin"
271
343
  },
344
+ {
345
+ "name": "pinnable",
346
+ "type": {
347
+ "text": "boolean | undefined"
348
+ },
349
+ "description": "Whether the user can pin or unpin the column. Default: `true`; `pinnable=\"false\"` turns it off.",
350
+ "fieldName": "pinnable"
351
+ },
352
+ {
353
+ "name": "hideable",
354
+ "type": {
355
+ "text": "boolean | undefined"
356
+ },
357
+ "description": "Whether the user can hide the column. Default: `true`; `hideable=\"false\"` turns it off.",
358
+ "fieldName": "hideable"
359
+ },
272
360
  {
273
361
  "name": "align",
274
362
  "type": {
@@ -277,6 +365,14 @@
277
365
  "description": "Text alignment: `start`, `center` or `end`. Default: `start`.",
278
366
  "fieldName": "align"
279
367
  },
368
+ {
369
+ "name": "wrap",
370
+ "type": {
371
+ "text": "boolean | undefined"
372
+ },
373
+ "description": "Wraps the cell text onto more lines instead of cutting it off. Default:\n`false`. With a fixed row height, text that doesn't fit is clipped.",
374
+ "fieldName": "wrap"
375
+ },
280
376
  {
281
377
  "name": "sortable",
282
378
  "type": {
@@ -300,6 +396,14 @@
300
396
  },
301
397
  "description": "Whether the column can be moved. Default: `true`; `reorderable=\"false\"` turns it off.",
302
398
  "fieldName": "reorderable"
399
+ },
400
+ {
401
+ "name": "filter",
402
+ "type": {
403
+ "text": "FilterKind | undefined"
404
+ },
405
+ "description": "The kind of filter users can set, e.g. from the column menu: `text`, `number`,\n`date` or `set`. Unset: users can't filter the column.",
406
+ "fieldName": "filter"
303
407
  }
304
408
  ],
305
409
  "superclass": {
@@ -399,13 +503,17 @@
399
503
  "default": "0"
400
504
  },
401
505
  {
402
- "description": "Height of a row. Default per density: 32px, 40px, 52px.",
506
+ "description": "Height of a row. Default per density: 32px, 40px, 52px. With `rowHeight: 'auto'`: the header's height and the least a body or pinned row is.",
403
507
  "name": "--argus-row-height"
404
508
  },
405
509
  {
406
510
  "description": "Inline padding of cells. Default per density: 8px, 12px, 16px.",
407
511
  "name": "--argus-cell-padding-inline"
408
512
  },
513
+ {
514
+ "description": "Block padding of body and pinned-row cells with `rowHeight: 'auto'`, where content sits at the top of the cell. Default: what centres one line of text in `--argus-row-height`.",
515
+ "name": "--argus-cell-padding-block"
516
+ },
409
517
  {
410
518
  "description": "Background of odd rows. Default: no stripes.",
411
519
  "name": "--argus-row-stripe-bg"
@@ -423,6 +531,11 @@
423
531
  "name": "--argus-focus-ring",
424
532
  "default": "2px solid Highlight"
425
533
  },
534
+ {
535
+ "description": "Colour of the mark in the header of a filtered column.",
536
+ "name": "--argus-filter-indicator-color",
537
+ "default": "currentColor"
538
+ },
426
539
  {
427
540
  "description": "Colour of the line that marks where a dragged column would land.",
428
541
  "name": "--argus-drop-indicator-color",
@@ -442,7 +555,7 @@
442
555
  "name": "--argus-skeleton-bg"
443
556
  },
444
557
  {
445
- "description": "Reserved for row selection, which comes after v0.1. The table doesn't read it yet.",
558
+ "description": "Background of selected rows, pinned columns included. Default: the system highlight colour, mixed into `--argus-bg`. It wins over `--argus-row-hover-bg`.",
446
559
  "name": "--argus-row-selected-bg"
447
560
  }
448
561
  ],
@@ -467,6 +580,14 @@
467
580
  "description": "The header of the sorted column. The direction is in `aria-sort`.",
468
581
  "name": "header-cell-sorted"
469
582
  },
583
+ {
584
+ "description": "Added to `header-cell` on the headers of filtered columns.",
585
+ "name": "header-cell-filtered"
586
+ },
587
+ {
588
+ "description": "The mark in the header of a filtered column, after the sort indicator.",
589
+ "name": "filter-indicator"
590
+ },
470
591
  {
471
592
  "description": "Added to `header-cell` on the header being dragged to a new position.",
472
593
  "name": "header-cell-dragging"
@@ -499,6 +620,22 @@
499
620
  "description": "Body rows whose `dataSource` page hasn't loaded yet, or failed.",
500
621
  "name": "row-loading"
501
622
  },
623
+ {
624
+ "description": "Body rows whose id is in `selection`.",
625
+ "name": "row-selected"
626
+ },
627
+ {
628
+ "description": "Added to `cell` in the checkbox column (`selectionCheckboxes`), pinned rows included.",
629
+ "name": "cell-selection"
630
+ },
631
+ {
632
+ "description": "Added to `header-cell` on the checkbox column's header.",
633
+ "name": "header-cell-selection"
634
+ },
635
+ {
636
+ "description": "The checkboxes of the checkbox column: one per selectable row, and the select-all one in the header (`multi` mode).",
637
+ "name": "selection-checkbox"
638
+ },
502
639
  {
503
640
  "description": "Every row from `pinnedRows`, on either side. Also has `row`, but no `row-even`/`row-odd`.",
504
641
  "name": "row-pinned"
@@ -599,9 +736,9 @@
599
736
  "kind": "field",
600
737
  "name": "rowHeight",
601
738
  "type": {
602
- "text": "number | undefined"
739
+ "text": "number | 'auto' | undefined"
603
740
  },
604
- "description": "Row height in px. Unset: the density (or the `--argus-row-height` token) decides.",
741
+ "description": "Row height in px, or `'auto'` to fit each row to its content (`row-height=\"auto\"`).\nUnset: the density (or the `--argus-row-height` token) decides. With\n`'auto'`, that height is the header's and the least a body or pinned row is;\nrows grow to fit wrapped text (`wrap` columns) and taller content, and cell\ncontent sits at the top. Rows are measured as they render: a row's height\ncounts the columns rendered (see `virtualizeColumns`), and rows not seen yet\ncount as one line. Give images a size, so rows don't move when they load.",
605
742
  "attribute": "row-height"
606
743
  },
607
744
  {
@@ -624,6 +761,16 @@
624
761
  "description": "Rows rendered above and below the visible ones. `null` or `undefined` means the default, 6.",
625
762
  "attribute": "overscan"
626
763
  },
764
+ {
765
+ "kind": "field",
766
+ "name": "virtualizeColumns",
767
+ "type": {
768
+ "text": "boolean"
769
+ },
770
+ "default": "false",
771
+ "description": "Renders only the scrolling columns in view (plus two on each side), for\nwide tables: a few dozen columns and more. Pinned columns, the checkbox\ncolumn and the focused cell's column always render. Off by default: then\nevery column renders, as before. Cells are placed in their grid column\nexplicitly, so page CSS that relies on their order in the DOM (`:nth-child`\non cells) doesn't apply. `autosizeColumns()` and `width: 'auto'` columns\nstill measure columns out of view: they render for the measurement.",
772
+ "attribute": "virtualize-columns"
773
+ },
627
774
  {
628
775
  "kind": "field",
629
776
  "name": "sorting",
@@ -648,6 +795,83 @@
648
795
  },
649
796
  "description": "The column order: column ids as the table shows them, e.g.\n`['id', 'total', 'customer']`. `[]` (the default) keeps the order of `columns`.\nEach pin group (start-pinned, scrolling, end-pinned) takes its columns in this\norder; unknown ids are ignored and columns it doesn't list follow the listed\nones of their group. After a move it holds every column id. Uncontrolled\nuntil set, like `sorting`: once set, a move only fires `argus-column-reorder`\nwith the proposed order. `undefined` hands it back."
650
797
  },
798
+ {
799
+ "kind": "field",
800
+ "name": "columnPinning",
801
+ "type": {
802
+ "text": "ColumnPinningState"
803
+ },
804
+ "description": "Pins by column id, over the columns' own `pin`: `'start'` or `'end'` pins a\ncolumn, `false` unpins one whose definition pins it, e.g.\n`{ total: 'end', id: false }`. Columns it doesn't list keep their `pin`. A pinned\ncolumn joins the edge of its group nearest its place in `columnOrder`, and stops\nflexing. Uncontrolled until set, like `sorting`: once set, pinning from a plugin\nonly fires `argus-column-pin` with the proposed pins. `undefined` hands it back."
805
+ },
806
+ {
807
+ "kind": "field",
808
+ "name": "columnVisibility",
809
+ "type": {
810
+ "text": "ColumnVisibilityState"
811
+ },
812
+ "description": "Visibility by column id, over the columns' own `hidden`: `false` hides a column,\n`true` shows one defined as `hidden`, e.g. `{ email: false }`. Columns it\ndoesn't list keep their `hidden`. A hidden column isn't rendered, but sorting by\nit still works and it keeps its place in `columnOrder`. Uncontrolled until set,\nlike `sorting`: once set, hiding or showing from a plugin only fires\n`argus-column-hide` with the proposed visibility. `undefined` hands it back."
813
+ },
814
+ {
815
+ "kind": "field",
816
+ "name": "columnFilters",
817
+ "type": {
818
+ "text": "ColumnFilterState"
819
+ },
820
+ "description": "Filters by column id, e.g. `{ city: { kind: 'set', values: ['Berlin'] } }` or\n`{ total: { kind: 'number', op: 'gt', value: 100 } }`. A row shows when it passes\nevery filter and `quickFilter`. Filters on hidden columns still apply; unknown ids\nare ignored. A column's `filterFn` replaces the built-in matching. With a\n`dataSource`, the filters go to `getRows()` and the server filters. Users set\nfilters through plugins (the column menu) on columns with a `filter` kind.\nUncontrolled until set, like `sorting`: once set, a change from a plugin only\nfires `argus-column-filter` with the proposed filters. `undefined` hands it back."
821
+ },
822
+ {
823
+ "kind": "field",
824
+ "name": "quickFilter",
825
+ "type": {
826
+ "text": "string"
827
+ },
828
+ "description": "Shows only rows that contain each word of this text in one of their shown\ncolumns, ignoring case, e.g. from a search box. Values are matched as text\n(dates as `2026-11-10`); objects aren't searched. With a `dataSource`, it goes\nto `getRows()` and the server filters. `''` (the default) shows every row.",
829
+ "attribute": "quick-filter"
830
+ },
831
+ {
832
+ "kind": "field",
833
+ "name": "selectionMode",
834
+ "type": {
835
+ "text": "SelectionMode"
836
+ },
837
+ "default": "'none'",
838
+ "description": "How rows can be selected: `none` (the default), `single` or `multi`. A click\non a body row selects it; in `multi` mode Ctrl/Cmd+click toggles a row,\nShift+click selects the range from the last clicked row, and Ctrl/Cmd+A\nselects every row. Space toggles the focused row. Clicks on buttons, links\nand inputs inside cells don't select. Pinned rows, and `dataSource` rows not\nloaded yet, can't be selected.",
839
+ "attribute": "selection-mode"
840
+ },
841
+ {
842
+ "kind": "field",
843
+ "name": "selectionCheckboxes",
844
+ "type": {
845
+ "text": "boolean"
846
+ },
847
+ "default": "false",
848
+ "description": "Adds a checkbox column, pinned first at the start, while `selectionMode` is\n`single` or `multi`. A row's checkbox toggles it (Shift+click adds the range\nfrom the last row clicked); in `multi` mode the header's checkbox selects\nevery row, or clears the selection when all are selected. Space on a\nfocused checkbox cell does the same. The column isn't part of `columns`,\n`columnOrder` or `columnSizing`, and it fires no `argus-cell-click`.",
849
+ "attribute": "selection-checkboxes"
850
+ },
851
+ {
852
+ "kind": "field",
853
+ "name": "selection",
854
+ "type": {
855
+ "text": "SelectionState"
856
+ },
857
+ "description": "The selected rows, as row ids (from `getRowId`, or the row's index as a\nstring), e.g. `['p4', 'p7']`. Uncontrolled until set, like `sorting`: once\nset, a click only fires `argus-row-select` with the proposed ids.\n`undefined` hands it back. The table never drops ids on its own: they stay\nthrough sorting, a new `data` or reloaded pages. With a `dataSource`,\nCtrl/Cmd+A selects the loaded rows only."
858
+ },
859
+ {
860
+ "kind": "field",
861
+ "name": "contentRenderer",
862
+ "type": {
863
+ "text": "ContentRenderer | undefined"
864
+ },
865
+ "description": "Renders header and cell content the table can't render itself, such as React\nelements, Vue VNodes or Angular templates: `{ render(target, content),\nrelease(target), flush?() }`. A `header` or `cell` that returns anything other\nthan a string, a number, a DOM node or a Lit template hands it to the renderer,\nwith a target element the table keeps while the cell is reused for other rows.\nThe framework wrappers set it; set it yourself only for another framework."
866
+ },
867
+ {
868
+ "kind": "field",
869
+ "name": "plugins",
870
+ "type": {
871
+ "text": "readonly ArgusPlugin<T>[]"
872
+ },
873
+ "description": "Add-ons, such as `headerMenu()` from `@argus-table/header-menu`. Each one can\nchange the column definitions, handle keys on a focused header or cell, and\nuse the table through a small API. They run in array order. Replace the\narray to change them; an array with the same plugins in the same order\nchanges nothing. `null` or `undefined` means `[]`."
874
+ },
651
875
  {
652
876
  "kind": "method",
653
877
  "name": "refresh",
@@ -675,7 +899,7 @@
675
899
  }
676
900
  }
677
901
  ],
678
- "description": "Fits columns to their content: the header, the pinned rows and the body rows\nrendered now (rows out of view aren't measured). It resizes them like a drag\nwould, so `argus-column-resize` fires for each column that changes, and with a\ncontrolled `columnSizing` nothing changes until you set it. Without `ids`, fits\nevery resizable column; columns with `resizable: false` keep their width.\nResolves once the table has re-rendered."
902
+ "description": "Fits columns to their content: the header, the pinned rows and the body rows\nrendered now (rows out of view aren't measured). It resizes them like a drag\nwould, so `argus-column-resize` fires for each column that changes, and with a\ncontrolled `columnSizing` nothing changes until you set it. Without `ids`, fits\nevery resizable column; columns with `resizable: false` keep their width.\nWith `virtualizeColumns`, columns out of view render for the measurement.\nResolves once the table has re-rendered."
679
903
  },
680
904
  {
681
905
  "kind": "method",
@@ -694,6 +918,34 @@
694
918
  }
695
919
  ],
696
920
  "description": "Scrolls so that the row at `index` (in the current row order) is at the top."
921
+ },
922
+ {
923
+ "kind": "method",
924
+ "name": "getState",
925
+ "return": {
926
+ "type": {
927
+ "text": "Required<TableState>"
928
+ }
929
+ },
930
+ "description": "The state users change, as one object of plain JSON for saving a user's\nlayout: `sorting`, `columnSizing`, `columnOrder`, `columnPinning`,\n`columnVisibility`, `columnFilters`, `selection`, `quickFilter`, and `scroll`\n(the row at the top and the horizontal offset). Controlled properties are\nincluded with the values you set. The object is a copy: changing it changes\nnothing in the table."
931
+ },
932
+ {
933
+ "kind": "method",
934
+ "name": "setState",
935
+ "return": {
936
+ "type": {
937
+ "text": "Promise<void>"
938
+ }
939
+ },
940
+ "parameters": [
941
+ {
942
+ "name": "state",
943
+ "type": {
944
+ "text": "TableState"
945
+ }
946
+ }
947
+ ],
948
+ "description": "Restores state from `getState()`, for example a layout saved in\n`localStorage`. Only the keys given change; ids of columns that no longer\nexist are ignored. Properties you control are left alone (set them\nyourself), and the others stay uncontrolled. No change events fire.\n`quickFilter` is set like the property: a search box of yours shows it only\nif you read it back. `scroll` is applied after the rest, so with a\n`dataSource` the restored rows load where it points. Resolves once the table\nhas re-rendered there."
697
949
  }
698
950
  ],
699
951
  "events": [
@@ -718,6 +970,27 @@
718
970
  "description": "A column was moved: by dragging its header, or with Alt+Shift+Arrow on its focused header. Columns move within their own group (start-pinned, scrolling, end-pinned). `detail: { columnId, order }`: the new order, or the proposed one when `columnOrder` is controlled. Fires once per move, on drop.",
719
971
  "name": "argus-column-reorder"
720
972
  },
973
+ {
974
+ "type": {
975
+ "text": "CustomEvent<ColumnPinDetail>"
976
+ },
977
+ "description": "A column was pinned to a side or unpinned, through a plugin such as the column menu. `detail: { columnId, pin, pinning }`: `pin` is `'start'`, `'end'` or `false`; `pinning` is the new state, or the proposed one when `columnPinning` is controlled.",
978
+ "name": "argus-column-pin"
979
+ },
980
+ {
981
+ "type": {
982
+ "text": "CustomEvent<ColumnHideDetail>"
983
+ },
984
+ "description": "A column was hidden or shown, through a plugin such as the column menu. `detail: { columnId, hidden, visibility }`: `hidden` is `true` when it was hidden; `visibility` is the new state, or the proposed one when `columnVisibility` is controlled.",
985
+ "name": "argus-column-hide"
986
+ },
987
+ {
988
+ "type": {
989
+ "text": "CustomEvent<ColumnFilterDetail>"
990
+ },
991
+ "description": "A column's filter was set, changed or cleared, through a plugin such as the column menu. `detail: { columnId, filter, filters }`: `filter` is the column's new filter, or `undefined` when it was cleared; `filters` is the new state, or the proposed one when `columnFilters` is controlled.",
992
+ "name": "argus-column-filter"
993
+ },
721
994
  {
722
995
  "type": {
723
996
  "text": "CustomEvent<CellClickDetail<T>>"
@@ -739,6 +1012,13 @@
739
1012
  "description": "The visible rows changed. `detail: { start, end }` (row indices, inclusive).",
740
1013
  "name": "argus-range-change"
741
1014
  },
1015
+ {
1016
+ "type": {
1017
+ "text": "CustomEvent<RowSelectDetail>"
1018
+ },
1019
+ "description": "The selected rows changed: by a click on a row (Ctrl/Cmd toggles, Shift selects a range), with Space, Shift+Arrow or Shift+PageUp/PageDown on a body cell, or with Ctrl/Cmd+A. Only with a `selectionMode`. `detail: { selection }`: the new row ids, or the proposed ones when `selection` is controlled.",
1020
+ "name": "argus-row-select"
1021
+ },
742
1022
  {
743
1023
  "type": {
744
1024
  "text": "CustomEvent<LoadErrorDetail>"
@@ -751,9 +1031,9 @@
751
1031
  {
752
1032
  "name": "row-height",
753
1033
  "type": {
754
- "text": "number | undefined"
1034
+ "text": "number | 'auto' | undefined"
755
1035
  },
756
- "description": "Row height in px. Unset: the density (or the `--argus-row-height` token) decides.",
1036
+ "description": "Row height in px, or `'auto'` to fit each row to its content (`row-height=\"auto\"`).\nUnset: the density (or the `--argus-row-height` token) decides. With\n`'auto'`, that height is the header's and the least a body or pinned row is;\nrows grow to fit wrapped text (`wrap` columns) and taller content, and cell\ncontent sits at the top. Rows are measured as they render: a row's height\ncounts the columns rendered (see `virtualizeColumns`), and rows not seen yet\ncount as one line. Give images a size, so rows don't move when they load.",
757
1037
  "fieldName": "rowHeight"
758
1038
  },
759
1039
  {
@@ -772,6 +1052,41 @@
772
1052
  },
773
1053
  "description": "Rows rendered above and below the visible ones. `null` or `undefined` means the default, 6.",
774
1054
  "fieldName": "overscan"
1055
+ },
1056
+ {
1057
+ "name": "virtualize-columns",
1058
+ "type": {
1059
+ "text": "boolean"
1060
+ },
1061
+ "default": "false",
1062
+ "description": "Renders only the scrolling columns in view (plus two on each side), for\nwide tables: a few dozen columns and more. Pinned columns, the checkbox\ncolumn and the focused cell's column always render. Off by default: then\nevery column renders, as before. Cells are placed in their grid column\nexplicitly, so page CSS that relies on their order in the DOM (`:nth-child`\non cells) doesn't apply. `autosizeColumns()` and `width: 'auto'` columns\nstill measure columns out of view: they render for the measurement.",
1063
+ "fieldName": "virtualizeColumns"
1064
+ },
1065
+ {
1066
+ "name": "quick-filter",
1067
+ "type": {
1068
+ "text": "string"
1069
+ },
1070
+ "description": "Shows only rows that contain each word of this text in one of their shown\ncolumns, ignoring case, e.g. from a search box. Values are matched as text\n(dates as `2026-11-10`); objects aren't searched. With a `dataSource`, it goes\nto `getRows()` and the server filters. `''` (the default) shows every row.",
1071
+ "fieldName": "quickFilter"
1072
+ },
1073
+ {
1074
+ "name": "selection-mode",
1075
+ "type": {
1076
+ "text": "SelectionMode"
1077
+ },
1078
+ "default": "'none'",
1079
+ "description": "How rows can be selected: `none` (the default), `single` or `multi`. A click\non a body row selects it; in `multi` mode Ctrl/Cmd+click toggles a row,\nShift+click selects the range from the last clicked row, and Ctrl/Cmd+A\nselects every row. Space toggles the focused row. Clicks on buttons, links\nand inputs inside cells don't select. Pinned rows, and `dataSource` rows not\nloaded yet, can't be selected.",
1080
+ "fieldName": "selectionMode"
1081
+ },
1082
+ {
1083
+ "name": "selection-checkboxes",
1084
+ "type": {
1085
+ "text": "boolean"
1086
+ },
1087
+ "default": "false",
1088
+ "description": "Adds a checkbox column, pinned first at the start, while `selectionMode` is\n`single` or `multi`. A row's checkbox toggles it (Shift+click adds the range\nfrom the last row clicked); in `multi` mode the header's checkbox selects\nevery row, or clears the selection when all are selected. Space on a\nfocused checkbox cell does the same. The column isn't part of `columns`,\n`columnOrder` or `columnSizing`, and it fires no `argus-cell-click`.",
1089
+ "fieldName": "selectionCheckboxes"
775
1090
  }
776
1091
  ],
777
1092
  "superclass": {
@@ -842,6 +1157,33 @@
842
1157
  "default": "'argus-column-reorder'",
843
1158
  "description": "Fired when a column was moved (uncontrolled), or with the proposed order (controlled)."
844
1159
  },
1160
+ {
1161
+ "kind": "variable",
1162
+ "name": "COLUMN_PIN",
1163
+ "type": {
1164
+ "text": "string"
1165
+ },
1166
+ "default": "'argus-column-pin'",
1167
+ "description": "Fired when a column was pinned or unpinned (uncontrolled), or with the proposed pins (controlled)."
1168
+ },
1169
+ {
1170
+ "kind": "variable",
1171
+ "name": "COLUMN_HIDE",
1172
+ "type": {
1173
+ "text": "string"
1174
+ },
1175
+ "default": "'argus-column-hide'",
1176
+ "description": "Fired when a column was hidden or shown (uncontrolled), or with the proposed visibility (controlled)."
1177
+ },
1178
+ {
1179
+ "kind": "variable",
1180
+ "name": "COLUMN_FILTER",
1181
+ "type": {
1182
+ "text": "string"
1183
+ },
1184
+ "default": "'argus-column-filter'",
1185
+ "description": "Fired when a column's filter was set, changed or cleared (uncontrolled), or with the proposed filters (controlled)."
1186
+ },
845
1187
  {
846
1188
  "kind": "variable",
847
1189
  "name": "ROW_CLICK",
@@ -860,6 +1202,15 @@
860
1202
  "default": "'argus-cell-click'",
861
1203
  "description": "Fired when a body cell was clicked, before `argus-row-click`."
862
1204
  },
1205
+ {
1206
+ "kind": "variable",
1207
+ "name": "ROW_SELECT",
1208
+ "type": {
1209
+ "text": "string"
1210
+ },
1211
+ "default": "'argus-row-select'",
1212
+ "description": "Fired when the selected rows changed (uncontrolled), or with the proposed ids (controlled)."
1213
+ },
863
1214
  {
864
1215
  "kind": "variable",
865
1216
  "name": "LOAD_ERROR",
@@ -933,6 +1284,30 @@
933
1284
  "module": "src/events.ts"
934
1285
  }
935
1286
  },
1287
+ {
1288
+ "kind": "js",
1289
+ "name": "COLUMN_PIN",
1290
+ "declaration": {
1291
+ "name": "COLUMN_PIN",
1292
+ "module": "src/events.ts"
1293
+ }
1294
+ },
1295
+ {
1296
+ "kind": "js",
1297
+ "name": "COLUMN_HIDE",
1298
+ "declaration": {
1299
+ "name": "COLUMN_HIDE",
1300
+ "module": "src/events.ts"
1301
+ }
1302
+ },
1303
+ {
1304
+ "kind": "js",
1305
+ "name": "COLUMN_FILTER",
1306
+ "declaration": {
1307
+ "name": "COLUMN_FILTER",
1308
+ "module": "src/events.ts"
1309
+ }
1310
+ },
936
1311
  {
937
1312
  "kind": "js",
938
1313
  "name": "ROW_CLICK",
@@ -949,6 +1324,14 @@
949
1324
  "module": "src/events.ts"
950
1325
  }
951
1326
  },
1327
+ {
1328
+ "kind": "js",
1329
+ "name": "ROW_SELECT",
1330
+ "declaration": {
1331
+ "name": "ROW_SELECT",
1332
+ "module": "src/events.ts"
1333
+ }
1334
+ },
952
1335
  {
953
1336
  "kind": "js",
954
1337
  "name": "LOAD_ERROR",
@@ -988,6 +1371,14 @@
988
1371
  "module": "./argus-table.js"
989
1372
  }
990
1373
  },
1374
+ {
1375
+ "kind": "js",
1376
+ "name": "content",
1377
+ "declaration": {
1378
+ "name": "content",
1379
+ "module": "./render/content-directive.js"
1380
+ }
1381
+ },
991
1382
  {
992
1383
  "kind": "js",
993
1384
  "name": "CELL_CLICK",
@@ -998,44 +1389,76 @@
998
1389
  },
999
1390
  {
1000
1391
  "kind": "js",
1001
- "name": "COLUMN_REORDER",
1392
+ "name": "COLUMN_FILTER",
1002
1393
  "declaration": {
1003
- "name": "COLUMN_REORDER",
1394
+ "name": "COLUMN_FILTER",
1004
1395
  "module": "./events.js"
1005
1396
  }
1006
1397
  },
1007
1398
  {
1008
1399
  "kind": "js",
1009
- "name": "COLUMN_RESIZE",
1400
+ "name": "COLUMN_HIDE",
1010
1401
  "declaration": {
1011
- "name": "COLUMN_RESIZE",
1402
+ "name": "COLUMN_HIDE",
1012
1403
  "module": "./events.js"
1013
1404
  }
1014
1405
  },
1015
1406
  {
1016
1407
  "kind": "js",
1017
- "name": "LOAD_ERROR",
1408
+ "name": "COLUMN_PIN",
1018
1409
  "declaration": {
1019
- "name": "LOAD_ERROR",
1410
+ "name": "COLUMN_PIN",
1020
1411
  "module": "./events.js"
1021
1412
  }
1022
1413
  },
1023
1414
  {
1024
1415
  "kind": "js",
1025
- "name": "RANGE_CHANGE",
1416
+ "name": "COLUMN_REORDER",
1026
1417
  "declaration": {
1027
- "name": "RANGE_CHANGE",
1418
+ "name": "COLUMN_REORDER",
1028
1419
  "module": "./events.js"
1029
1420
  }
1030
1421
  },
1031
1422
  {
1032
1423
  "kind": "js",
1033
- "name": "ROW_CLICK",
1424
+ "name": "COLUMN_RESIZE",
1425
+ "declaration": {
1426
+ "name": "COLUMN_RESIZE",
1427
+ "module": "./events.js"
1428
+ }
1429
+ },
1430
+ {
1431
+ "kind": "js",
1432
+ "name": "LOAD_ERROR",
1433
+ "declaration": {
1434
+ "name": "LOAD_ERROR",
1435
+ "module": "./events.js"
1436
+ }
1437
+ },
1438
+ {
1439
+ "kind": "js",
1440
+ "name": "RANGE_CHANGE",
1441
+ "declaration": {
1442
+ "name": "RANGE_CHANGE",
1443
+ "module": "./events.js"
1444
+ }
1445
+ },
1446
+ {
1447
+ "kind": "js",
1448
+ "name": "ROW_CLICK",
1034
1449
  "declaration": {
1035
1450
  "name": "ROW_CLICK",
1036
1451
  "module": "./events.js"
1037
1452
  }
1038
1453
  },
1454
+ {
1455
+ "kind": "js",
1456
+ "name": "ROW_SELECT",
1457
+ "declaration": {
1458
+ "name": "ROW_SELECT",
1459
+ "module": "./events.js"
1460
+ }
1461
+ },
1039
1462
  {
1040
1463
  "kind": "js",
1041
1464
  "name": "SORT_CHANGE",
@@ -1054,6 +1477,63 @@
1054
1477
  }
1055
1478
  ]
1056
1479
  },
1480
+ {
1481
+ "kind": "javascript-module",
1482
+ "path": "src/interactive.ts",
1483
+ "declarations": [
1484
+ {
1485
+ "kind": "variable",
1486
+ "name": "INTERACTIVE",
1487
+ "type": {
1488
+ "text": "string"
1489
+ },
1490
+ "default": "'button,input,select,textarea,a[href],label,[contenteditable],[popover],dialog'",
1491
+ "description": "Interactive content a page may put in a header or cell. A press on it belongs\nto that content: it doesn't sort, start a column drag or select a row. A\npopover or a dialog (a menu or an editor a plugin opens from a header) counts\nas a whole, padding included."
1492
+ },
1493
+ {
1494
+ "kind": "function",
1495
+ "name": "fromInteractive",
1496
+ "return": {
1497
+ "type": {
1498
+ "text": "boolean"
1499
+ }
1500
+ },
1501
+ "parameters": [
1502
+ {
1503
+ "name": "path",
1504
+ "type": {
1505
+ "text": "readonly EventTarget[]"
1506
+ }
1507
+ },
1508
+ {
1509
+ "name": "stop",
1510
+ "type": {
1511
+ "text": "Element"
1512
+ }
1513
+ }
1514
+ ],
1515
+ "description": "Whether an event path reaches interactive content before `stop` (the cell or\nrow the table handles the event for)."
1516
+ }
1517
+ ],
1518
+ "exports": [
1519
+ {
1520
+ "kind": "js",
1521
+ "name": "INTERACTIVE",
1522
+ "declaration": {
1523
+ "name": "INTERACTIVE",
1524
+ "module": "src/interactive.ts"
1525
+ }
1526
+ },
1527
+ {
1528
+ "kind": "js",
1529
+ "name": "fromInteractive",
1530
+ "declaration": {
1531
+ "name": "fromInteractive",
1532
+ "module": "src/interactive.ts"
1533
+ }
1534
+ }
1535
+ ]
1536
+ },
1057
1537
  {
1058
1538
  "kind": "javascript-module",
1059
1539
  "path": "src/max-height.ts",
@@ -1146,11 +1626,57 @@
1146
1626
  }
1147
1627
  ]
1148
1628
  },
1629
+ {
1630
+ "kind": "javascript-module",
1631
+ "path": "src/plugins.ts",
1632
+ "declarations": [],
1633
+ "exports": []
1634
+ },
1149
1635
  {
1150
1636
  "kind": "javascript-module",
1151
1637
  "path": "src/types.ts",
1152
1638
  "declarations": [],
1153
1639
  "exports": [
1640
+ {
1641
+ "kind": "js",
1642
+ "name": "ArgusPlugin",
1643
+ "declaration": {
1644
+ "name": "ArgusPlugin",
1645
+ "module": "./plugins.js"
1646
+ }
1647
+ },
1648
+ {
1649
+ "kind": "js",
1650
+ "name": "CellTarget",
1651
+ "declaration": {
1652
+ "name": "CellTarget",
1653
+ "module": "./plugins.js"
1654
+ }
1655
+ },
1656
+ {
1657
+ "kind": "js",
1658
+ "name": "ColumnInfo",
1659
+ "declaration": {
1660
+ "name": "ColumnInfo",
1661
+ "module": "./plugins.js"
1662
+ }
1663
+ },
1664
+ {
1665
+ "kind": "js",
1666
+ "name": "PluginHost",
1667
+ "declaration": {
1668
+ "name": "PluginHost",
1669
+ "module": "./plugins.js"
1670
+ }
1671
+ },
1672
+ {
1673
+ "kind": "js",
1674
+ "name": "ContentRenderer",
1675
+ "declaration": {
1676
+ "name": "ContentRenderer",
1677
+ "module": "./render/content-directive.js"
1678
+ }
1679
+ },
1154
1680
  {
1155
1681
  "kind": "js",
1156
1682
  "name": "CellClickDetail",
@@ -1175,6 +1701,38 @@
1175
1701
  "package": "@argus-table/core"
1176
1702
  }
1177
1703
  },
1704
+ {
1705
+ "kind": "js",
1706
+ "name": "ColumnFilter",
1707
+ "declaration": {
1708
+ "name": "ColumnFilter",
1709
+ "package": "@argus-table/core"
1710
+ }
1711
+ },
1712
+ {
1713
+ "kind": "js",
1714
+ "name": "ColumnFilterDetail",
1715
+ "declaration": {
1716
+ "name": "ColumnFilterDetail",
1717
+ "package": "@argus-table/core"
1718
+ }
1719
+ },
1720
+ {
1721
+ "kind": "js",
1722
+ "name": "ColumnFilterState",
1723
+ "declaration": {
1724
+ "name": "ColumnFilterState",
1725
+ "package": "@argus-table/core"
1726
+ }
1727
+ },
1728
+ {
1729
+ "kind": "js",
1730
+ "name": "ColumnHideDetail",
1731
+ "declaration": {
1732
+ "name": "ColumnHideDetail",
1733
+ "package": "@argus-table/core"
1734
+ }
1735
+ },
1178
1736
  {
1179
1737
  "kind": "js",
1180
1738
  "name": "ColumnOrderState",
@@ -1191,6 +1749,22 @@
1191
1749
  "package": "@argus-table/core"
1192
1750
  }
1193
1751
  },
1752
+ {
1753
+ "kind": "js",
1754
+ "name": "ColumnPinDetail",
1755
+ "declaration": {
1756
+ "name": "ColumnPinDetail",
1757
+ "package": "@argus-table/core"
1758
+ }
1759
+ },
1760
+ {
1761
+ "kind": "js",
1762
+ "name": "ColumnPinningState",
1763
+ "declaration": {
1764
+ "name": "ColumnPinningState",
1765
+ "package": "@argus-table/core"
1766
+ }
1767
+ },
1194
1768
  {
1195
1769
  "kind": "js",
1196
1770
  "name": "ColumnReorderDetail",
@@ -1215,6 +1789,14 @@
1215
1789
  "package": "@argus-table/core"
1216
1790
  }
1217
1791
  },
1792
+ {
1793
+ "kind": "js",
1794
+ "name": "ColumnVisibilityState",
1795
+ "declaration": {
1796
+ "name": "ColumnVisibilityState",
1797
+ "package": "@argus-table/core"
1798
+ }
1799
+ },
1218
1800
  {
1219
1801
  "kind": "js",
1220
1802
  "name": "ColumnWidth",
@@ -1231,6 +1813,30 @@
1231
1813
  "package": "@argus-table/core"
1232
1814
  }
1233
1815
  },
1816
+ {
1817
+ "kind": "js",
1818
+ "name": "DateFilter",
1819
+ "declaration": {
1820
+ "name": "DateFilter",
1821
+ "package": "@argus-table/core"
1822
+ }
1823
+ },
1824
+ {
1825
+ "kind": "js",
1826
+ "name": "FilterKind",
1827
+ "declaration": {
1828
+ "name": "FilterKind",
1829
+ "package": "@argus-table/core"
1830
+ }
1831
+ },
1832
+ {
1833
+ "kind": "js",
1834
+ "name": "FilterValue",
1835
+ "declaration": {
1836
+ "name": "FilterValue",
1837
+ "package": "@argus-table/core"
1838
+ }
1839
+ },
1234
1840
  {
1235
1841
  "kind": "js",
1236
1842
  "name": "LoadErrorDetail",
@@ -1239,6 +1845,14 @@
1239
1845
  "package": "@argus-table/core"
1240
1846
  }
1241
1847
  },
1848
+ {
1849
+ "kind": "js",
1850
+ "name": "NumberFilter",
1851
+ "declaration": {
1852
+ "name": "NumberFilter",
1853
+ "package": "@argus-table/core"
1854
+ }
1855
+ },
1242
1856
  {
1243
1857
  "kind": "js",
1244
1858
  "name": "PinnedRows",
@@ -1255,6 +1869,14 @@
1255
1869
  "package": "@argus-table/core"
1256
1870
  }
1257
1871
  },
1872
+ {
1873
+ "kind": "js",
1874
+ "name": "RangeFilterOp",
1875
+ "declaration": {
1876
+ "name": "RangeFilterOp",
1877
+ "package": "@argus-table/core"
1878
+ }
1879
+ },
1258
1880
  {
1259
1881
  "kind": "js",
1260
1882
  "name": "RowClickDetail",
@@ -1287,6 +1909,46 @@
1287
1909
  "package": "@argus-table/core"
1288
1910
  }
1289
1911
  },
1912
+ {
1913
+ "kind": "js",
1914
+ "name": "RowSelectDetail",
1915
+ "declaration": {
1916
+ "name": "RowSelectDetail",
1917
+ "package": "@argus-table/core"
1918
+ }
1919
+ },
1920
+ {
1921
+ "kind": "js",
1922
+ "name": "ScrollState",
1923
+ "declaration": {
1924
+ "name": "ScrollState",
1925
+ "package": "@argus-table/core"
1926
+ }
1927
+ },
1928
+ {
1929
+ "kind": "js",
1930
+ "name": "SelectionMode",
1931
+ "declaration": {
1932
+ "name": "SelectionMode",
1933
+ "package": "@argus-table/core"
1934
+ }
1935
+ },
1936
+ {
1937
+ "kind": "js",
1938
+ "name": "SelectionState",
1939
+ "declaration": {
1940
+ "name": "SelectionState",
1941
+ "package": "@argus-table/core"
1942
+ }
1943
+ },
1944
+ {
1945
+ "kind": "js",
1946
+ "name": "SetFilter",
1947
+ "declaration": {
1948
+ "name": "SetFilter",
1949
+ "package": "@argus-table/core"
1950
+ }
1951
+ },
1290
1952
  {
1291
1953
  "kind": "js",
1292
1954
  "name": "SortChangeDetail",
@@ -1310,6 +1972,30 @@
1310
1972
  "name": "SortState",
1311
1973
  "package": "@argus-table/core"
1312
1974
  }
1975
+ },
1976
+ {
1977
+ "kind": "js",
1978
+ "name": "TableState",
1979
+ "declaration": {
1980
+ "name": "TableState",
1981
+ "package": "@argus-table/core"
1982
+ }
1983
+ },
1984
+ {
1985
+ "kind": "js",
1986
+ "name": "TextFilter",
1987
+ "declaration": {
1988
+ "name": "TextFilter",
1989
+ "package": "@argus-table/core"
1990
+ }
1991
+ },
1992
+ {
1993
+ "kind": "js",
1994
+ "name": "TextFilterOp",
1995
+ "declaration": {
1996
+ "name": "TextFilterOp",
1997
+ "package": "@argus-table/core"
1998
+ }
1313
1999
  }
1314
2000
  ]
1315
2001
  },
@@ -1373,6 +2059,24 @@
1373
2059
  ],
1374
2060
  "description": "Forgets columns that are gone or no longer `'auto'`, given the ids of the auto columns."
1375
2061
  },
2062
+ {
2063
+ "kind": "method",
2064
+ "name": "pending",
2065
+ "return": {
2066
+ "type": {
2067
+ "text": "string[]"
2068
+ }
2069
+ },
2070
+ "parameters": [
2071
+ {
2072
+ "name": "columns",
2073
+ "type": {
2074
+ "text": "readonly { id: string; auto: boolean }[]"
2075
+ }
2076
+ }
2077
+ ],
2078
+ "description": "The auto columns still to be measured: never, or without loaded rows yet.\nWith `virtualizeColumns` they render out of view until they are."
2079
+ },
1376
2080
  {
1377
2081
  "kind": "method",
1378
2082
  "name": "measure",
@@ -1484,6 +2188,112 @@
1484
2188
  }
1485
2189
  ]
1486
2190
  },
2191
+ {
2192
+ "kind": "javascript-module",
2193
+ "path": "src/controllers/column-window.ts",
2194
+ "declarations": [
2195
+ {
2196
+ "kind": "variable",
2197
+ "name": "COLUMN_OVERSCAN",
2198
+ "type": {
2199
+ "text": "number"
2200
+ },
2201
+ "default": "2",
2202
+ "description": "Scrolling columns rendered beyond each side of the visible ones."
2203
+ },
2204
+ {
2205
+ "kind": "class",
2206
+ "description": "Column virtualization (`virtualizeColumns`): which columns render, and which\npool slot's DOM each one uses.\n\nOff, every column renders in visual order, its slot is its `colIndex` and\nits cells are keyed by column id: the DOM is what it always was.\n\nOn, the scrolling columns in view render, plus `COLUMN_OVERSCAN` on each\nside, and the pinned columns, the checkbox column and the columns the table\nkeeps (the active one, one being dragged, auto widths still to measure)\nwhatever the scroll position. They are pooled like rows (ADR 0001): a column\nentering the view reuses the cells, slots and content of one that left, so\nthe DOM is updated in place, and the window has one size, so the pool fills\non the first render and scrolling only reuses it (in WebKit, new slots\nwhile scrolling cut a wheel scroll short; see `steadyWindow`). DOM order is\nthen pool order: each cell is placed in its grid column explicitly, and\n`aria-colindex` carries the position, as `aria-rowindex` does for rows.",
2207
+ "name": "ColumnWindowController",
2208
+ "members": [
2209
+ {
2210
+ "kind": "method",
2211
+ "name": "hostConnected",
2212
+ "return": {
2213
+ "type": {
2214
+ "text": "void"
2215
+ }
2216
+ }
2217
+ },
2218
+ {
2219
+ "kind": "method",
2220
+ "name": "hostUpdated",
2221
+ "return": {
2222
+ "type": {
2223
+ "text": "void"
2224
+ }
2225
+ }
2226
+ },
2227
+ {
2228
+ "kind": "method",
2229
+ "name": "hostDisconnected",
2230
+ "return": {
2231
+ "type": {
2232
+ "text": "void"
2233
+ }
2234
+ }
2235
+ },
2236
+ {
2237
+ "kind": "field",
2238
+ "name": "poolSize",
2239
+ "type": {
2240
+ "text": "number"
2241
+ },
2242
+ "description": "Number of column pool slots created so far.",
2243
+ "readonly": true
2244
+ },
2245
+ {
2246
+ "kind": "method",
2247
+ "name": "compute",
2248
+ "return": {
2249
+ "type": {
2250
+ "text": "RenderedColumn<T>[]"
2251
+ }
2252
+ },
2253
+ "parameters": [
2254
+ {
2255
+ "name": "columns",
2256
+ "type": {
2257
+ "text": "readonly Column<T>[]"
2258
+ }
2259
+ },
2260
+ {
2261
+ "name": "enabled",
2262
+ "type": {
2263
+ "text": "boolean"
2264
+ }
2265
+ },
2266
+ {
2267
+ "name": "keep",
2268
+ "type": {
2269
+ "text": "Iterable<string | undefined>"
2270
+ }
2271
+ }
2272
+ ],
2273
+ "description": "The columns to render, given the model's columns in visual order. With\n`enabled`, `keep` names columns to render wherever they are. Call once per\nrender."
2274
+ }
2275
+ ]
2276
+ }
2277
+ ],
2278
+ "exports": [
2279
+ {
2280
+ "kind": "js",
2281
+ "name": "COLUMN_OVERSCAN",
2282
+ "declaration": {
2283
+ "name": "COLUMN_OVERSCAN",
2284
+ "module": "src/controllers/column-window.ts"
2285
+ }
2286
+ },
2287
+ {
2288
+ "kind": "js",
2289
+ "name": "ColumnWindowController",
2290
+ "declaration": {
2291
+ "name": "ColumnWindowController",
2292
+ "module": "src/controllers/column-window.ts"
2293
+ }
2294
+ }
2295
+ ]
2296
+ },
1487
2297
  {
1488
2298
  "kind": "javascript-module",
1489
2299
  "path": "src/controllers/data-controller.ts",
@@ -1508,7 +2318,7 @@
1508
2318
  },
1509
2319
  {
1510
2320
  "kind": "class",
1511
- "description": "Loads `dataSource` pages for the rendered rows (infinite loading). It owns the\npage cache: a new source, sort order or row id function starts a fresh one, and\nanswers for an old cache are dropped. Requests wait until the range has been\nquiet for `LOAD_DEBOUNCE_MS`; pages that scrolled away are aborted.",
2321
+ "description": "Loads `dataSource` pages for the rendered rows (infinite loading). It owns the\npage cache: a new source, sort order, filter or row id function starts a fresh one, and\nanswers for an old cache are dropped. Requests wait until the range has been\nquiet for `LOAD_DEBOUNCE_MS`; pages that scrolled away are aborted.",
1512
2322
  "name": "DataController",
1513
2323
  "members": [
1514
2324
  {
@@ -1554,7 +2364,7 @@
1554
2364
  }
1555
2365
  }
1556
2366
  ],
1557
- "description": "Takes the source, sort order and row id function. Any change starts a fresh\ncache; a sort or row id change keeps the row count (the rows are the same)."
2367
+ "description": "Takes the source, sort order, filters and row id function. Any change starts a\nfresh cache; a sort or row id change keeps the row count (the rows are the same),\na new source or filter doesn't (the rows aren't)."
1558
2368
  },
1559
2369
  {
1560
2370
  "kind": "method",
@@ -1725,6 +2535,149 @@
1725
2535
  }
1726
2536
  ]
1727
2537
  },
2538
+ {
2539
+ "kind": "javascript-module",
2540
+ "path": "src/controllers/plugins.ts",
2541
+ "declarations": [
2542
+ {
2543
+ "kind": "class",
2544
+ "description": "Runs the table's plugins: connects them while the table is connected (in\narray order, cleaning up in reverse), chains their column transforms, and\noffers keys to them before the table handles them. A hook that throws is\nreported and skipped, so a broken plugin can't break the update.",
2545
+ "name": "PluginController",
2546
+ "members": [
2547
+ {
2548
+ "kind": "method",
2549
+ "name": "set",
2550
+ "return": {
2551
+ "type": {
2552
+ "text": "void"
2553
+ }
2554
+ },
2555
+ "parameters": [
2556
+ {
2557
+ "name": "plugins",
2558
+ "type": {
2559
+ "text": "readonly ArgusPlugin<T>[]"
2560
+ }
2561
+ }
2562
+ ],
2563
+ "description": "Takes a new plugin list; connects and cleans up to match it if the host is connected."
2564
+ },
2565
+ {
2566
+ "kind": "method",
2567
+ "name": "hostConnected",
2568
+ "return": {
2569
+ "type": {
2570
+ "text": "void"
2571
+ }
2572
+ }
2573
+ },
2574
+ {
2575
+ "kind": "method",
2576
+ "name": "hostDisconnected",
2577
+ "return": {
2578
+ "type": {
2579
+ "text": "void"
2580
+ }
2581
+ }
2582
+ },
2583
+ {
2584
+ "kind": "method",
2585
+ "name": "transform",
2586
+ "return": {
2587
+ "type": {
2588
+ "text": "readonly ColumnDef<T>[]"
2589
+ }
2590
+ },
2591
+ "parameters": [
2592
+ {
2593
+ "name": "input",
2594
+ "type": {
2595
+ "text": "readonly ColumnDef<T>[]"
2596
+ }
2597
+ }
2598
+ ],
2599
+ "description": "The plugins' `columns` transforms applied in order; the same array while nothing changed."
2600
+ },
2601
+ {
2602
+ "kind": "method",
2603
+ "name": "invalidate",
2604
+ "return": {
2605
+ "type": {
2606
+ "text": "void"
2607
+ }
2608
+ },
2609
+ "description": "Runs the transforms again on the next `transform()`."
2610
+ },
2611
+ {
2612
+ "kind": "method",
2613
+ "name": "keydown",
2614
+ "return": {
2615
+ "type": {
2616
+ "text": "boolean"
2617
+ }
2618
+ },
2619
+ "parameters": [
2620
+ {
2621
+ "name": "event",
2622
+ "type": {
2623
+ "text": "KeyboardEvent"
2624
+ }
2625
+ },
2626
+ {
2627
+ "name": "target",
2628
+ "type": {
2629
+ "text": "CellTarget"
2630
+ }
2631
+ }
2632
+ ],
2633
+ "description": "Offers a key to the plugins in order; `true` once one claims it."
2634
+ }
2635
+ ]
2636
+ },
2637
+ {
2638
+ "kind": "function",
2639
+ "name": "sameItems",
2640
+ "return": {
2641
+ "type": {
2642
+ "text": "boolean"
2643
+ }
2644
+ },
2645
+ "parameters": [
2646
+ {
2647
+ "name": "a",
2648
+ "type": {
2649
+ "text": "readonly V[]"
2650
+ }
2651
+ },
2652
+ {
2653
+ "name": "b",
2654
+ "type": {
2655
+ "text": "readonly V[]"
2656
+ }
2657
+ }
2658
+ ],
2659
+ "description": "Whether two lists hold the same items in the same order."
2660
+ }
2661
+ ],
2662
+ "exports": [
2663
+ {
2664
+ "kind": "js",
2665
+ "name": "PluginController",
2666
+ "declaration": {
2667
+ "name": "PluginController",
2668
+ "module": "src/controllers/plugins.ts"
2669
+ }
2670
+ },
2671
+ {
2672
+ "kind": "js",
2673
+ "name": "sameItems",
2674
+ "declaration": {
2675
+ "name": "sameItems",
2676
+ "module": "src/controllers/plugins.ts"
2677
+ }
2678
+ }
2679
+ ]
2680
+ },
1728
2681
  {
1729
2682
  "kind": "javascript-module",
1730
2683
  "path": "src/controllers/reorder-drag.ts",
@@ -1763,7 +2716,7 @@
1763
2716
  }
1764
2717
  }
1765
2718
  ],
1766
- "description": "The drop target for a pointer at `x`: the gap between headers nearest to it,\ndecided by each header's midpoint. `undefined` where the column would stay\nput. `direction` is 1 in LTR and -1 in RTL, where the group runs right to left."
2719
+ "description": "The drop target for a pointer at `x`: the gap between headers nearest to it,\ndecided by each header's midpoint. `undefined` where the column would stay\nput. `direction` is 1 in LTR and -1 in RTL, where the group runs right to left.\nThe slots needn't be next to each other in the order: with\n`virtualizeColumns`, headers out of view aren't rendered."
1767
2720
  },
1768
2721
  {
1769
2722
  "kind": "function",
@@ -1879,28 +2832,98 @@
1879
2832
  }
1880
2833
  },
1881
2834
  {
1882
- "name": "direction",
1883
- "type": {
1884
- "text": "1 | -1"
1885
- }
2835
+ "name": "direction",
2836
+ "type": {
2837
+ "text": "1 | -1"
2838
+ }
2839
+ },
2840
+ {
2841
+ "name": "onWidth",
2842
+ "type": {
2843
+ "text": "(width: number) => void"
2844
+ }
2845
+ }
2846
+ ],
2847
+ "description": "One pointer drag on a resize handle. The pointer is captured, so the drag keeps\nworking outside the handle, and moves are batched to one `onWidth` call per\nanimation frame (TanStack's `onChange` mode: the width updates while dragging).\n\n`direction` is 1 in LTR and -1 in RTL: the handle sits on the inline-end edge,\nso moving toward the inline end always grows the column."
2848
+ }
2849
+ ],
2850
+ "exports": [
2851
+ {
2852
+ "kind": "js",
2853
+ "name": "startResizeDrag",
2854
+ "declaration": {
2855
+ "name": "startResizeDrag",
2856
+ "module": "src/controllers/resize-drag.ts"
2857
+ }
2858
+ }
2859
+ ]
2860
+ },
2861
+ {
2862
+ "kind": "javascript-module",
2863
+ "path": "src/controllers/row-measure.ts",
2864
+ "declarations": [
2865
+ {
2866
+ "kind": "class",
2867
+ "description": "Rows of different heights (`rowHeight: 'auto'`): reads the heights of the\nrendered body rows and of the pinned row groups once their content has\nrendered, and watches them for changes the table doesn't render (an image\nloading, a web font, a framework component updating), which request an\nupdate that reads them again. Pooled rows show other rows as the body\nscrolls, so every update reads every rendered row: one that now shows a row\nof the same height doesn't resize, and the observer wouldn't report it.",
2868
+ "name": "RowMeasure",
2869
+ "members": [
2870
+ {
2871
+ "kind": "field",
2872
+ "name": "pinned",
2873
+ "type": {
2874
+ "text": "PinnedHeights"
2875
+ },
2876
+ "description": "The pinned groups' heights from the last `read()`.",
2877
+ "readonly": true
2878
+ },
2879
+ {
2880
+ "kind": "method",
2881
+ "name": "invalidate",
2882
+ "return": {
2883
+ "type": {
2884
+ "text": "void"
2885
+ }
2886
+ },
2887
+ "description": "The next `read()` reads every row: their content may have changed size\n(new data or columns, a resize, content that grew)."
2888
+ },
2889
+ {
2890
+ "kind": "method",
2891
+ "name": "read",
2892
+ "return": {
2893
+ "type": {
2894
+ "text": "{ rows: [number, number][]; pinnedChanged: boolean }"
2895
+ }
2896
+ },
2897
+ "parameters": [
2898
+ {
2899
+ "name": "root",
2900
+ "type": {
2901
+ "text": "ParentNode"
2902
+ }
2903
+ }
2904
+ ],
2905
+ "description": "Reads the rows in `root` (the shadow root): the body rows' heights as\n`[index, px]`, and whether the pinned groups changed height. Scrolling,\nonly the pooled rows that now show another row are read."
1886
2906
  },
1887
2907
  {
1888
- "name": "onWidth",
1889
- "type": {
1890
- "text": "(width: number) => void"
1891
- }
2908
+ "kind": "method",
2909
+ "name": "stop",
2910
+ "return": {
2911
+ "type": {
2912
+ "text": "void"
2913
+ }
2914
+ },
2915
+ "description": "Stops watching (fixed row heights again, or the table left the page)."
1892
2916
  }
1893
- ],
1894
- "description": "One pointer drag on a resize handle. The pointer is captured, so the drag keeps\nworking outside the handle, and moves are batched to one `onWidth` call per\nanimation frame (TanStack's `onChange` mode: the width updates while dragging).\n\n`direction` is 1 in LTR and -1 in RTL: the handle sits on the inline-end edge,\nso moving toward the inline end always grows the column."
2917
+ ]
1895
2918
  }
1896
2919
  ],
1897
2920
  "exports": [
1898
2921
  {
1899
2922
  "kind": "js",
1900
- "name": "startResizeDrag",
2923
+ "name": "RowMeasure",
1901
2924
  "declaration": {
1902
- "name": "startResizeDrag",
1903
- "module": "src/controllers/resize-drag.ts"
2925
+ "name": "RowMeasure",
2926
+ "module": "src/controllers/row-measure.ts"
1904
2927
  }
1905
2928
  }
1906
2929
  ]
@@ -1942,7 +2965,7 @@
1942
2965
  "declarations": [
1943
2966
  {
1944
2967
  "kind": "class",
1945
- "description": "Row virtualization (TanStack Virtual) plus the row pool: which rows render,\nwhere, and which pool slot's DOM each one uses. The virtualizer registers itself\nwith the host and requests updates on scroll.\n\nScroll scaling: engines limit an element's height, so a body taller than the\ncap renders at the cap and its scroll position maps linearly onto the rows\n(`ScrollScale`). The virtualizer works in logical offsets: it gets a stand-in\nfor the scroller whose `scrollTop`, `scrollHeight` and `scrollTo()` are\nlogical, and everything else passes through. Rows render relative to the\nscroll position (`start` minus the difference between the logical and the\nphysical offset). Scroll through this controller (`scrollBy`, `reveal`,\n`scrollToIndex`): physical px no longer match rows once the body is scaled.",
2968
+ "description": "Row virtualization (TanStack Virtual) plus the row pool: which rows render,\nwhere, and which pool slot's DOM each one uses. The virtualizer registers itself\nwith the host and requests updates on scroll.\n\nScroll scaling: engines limit an element's height, so a body taller than the\ncap renders at the cap and its scroll position maps linearly onto the rows\n(`ScrollScale`). The virtualizer works in logical offsets: it gets a stand-in\nfor the scroller whose `scrollTop`, `scrollHeight` and `scrollTo()` are\nlogical, and everything else passes through. Rows render relative to the\nscroll position (`start` minus the difference between the logical and the\nphysical offset). Scroll through this controller (`scrollBy`, `reveal`,\n`scrollToIndex`): physical px no longer match rows once the body is scaled.\n\nRows of different heights (`auto`): TanStack's own measuring recomputes every\nrow below a measured one, too slow for a million rows, so in this mode the\nvirtualizer sits idle (no rows) and the controller does its part: the window\nfrom `RowSizes` (heights by index, O(log n) offsets), a scroll listener that\nre-renders when the window moves, and anchoring. Heights follow row ids, so\na sort or filter keeps them. A measured row above the top row would move\nthe rows in view: unscaled, the rows render shifted by the difference until\nscrolling stops (`#hold`); scaled, the mapping pivots at the current offset.\nNeither writes the scroll position while the user scrolls.",
1946
2969
  "name": "VirtualController",
1947
2970
  "members": [
1948
2971
  {
@@ -1971,6 +2994,15 @@
1971
2994
  }
1972
2995
  }
1973
2996
  },
2997
+ {
2998
+ "kind": "method",
2999
+ "name": "hostDisconnected",
3000
+ "return": {
3001
+ "type": {
3002
+ "text": "void"
3003
+ }
3004
+ }
3005
+ },
1974
3006
  {
1975
3007
  "kind": "method",
1976
3008
  "name": "computeWindow",
@@ -1981,6 +3013,90 @@
1981
3013
  },
1982
3014
  "description": "Computes the rendered window and updates the pool. Call once per render."
1983
3015
  },
3016
+ {
3017
+ "kind": "method",
3018
+ "name": "measureRows",
3019
+ "return": {
3020
+ "type": {
3021
+ "text": "boolean"
3022
+ }
3023
+ },
3024
+ "parameters": [
3025
+ {
3026
+ "name": "measured",
3027
+ "type": {
3028
+ "text": "Iterable<readonly [number, number]>"
3029
+ }
3030
+ }
3031
+ ],
3032
+ "description": "Auto mode: records the heights of rendered body rows (`[index, px]`), read\nonce their content has rendered. Heights under the row height count as it.\nReturns whether any changed; the controller then requests the update that\nplaces the rows. Rows above the top row keep the rows in view in place."
3033
+ },
3034
+ {
3035
+ "kind": "method",
3036
+ "name": "sizeOf",
3037
+ "return": {
3038
+ "type": {
3039
+ "text": "number"
3040
+ }
3041
+ },
3042
+ "parameters": [
3043
+ {
3044
+ "name": "index",
3045
+ "type": {
3046
+ "text": "number"
3047
+ }
3048
+ }
3049
+ ],
3050
+ "description": "The height of the row at `index` (auto mode: measured, or the row height)."
3051
+ },
3052
+ {
3053
+ "kind": "method",
3054
+ "name": "startOf",
3055
+ "return": {
3056
+ "type": {
3057
+ "text": "number"
3058
+ }
3059
+ },
3060
+ "parameters": [
3061
+ {
3062
+ "name": "index",
3063
+ "type": {
3064
+ "text": "number"
3065
+ }
3066
+ }
3067
+ ],
3068
+ "description": "The logical offset of the row at `index` in the body."
3069
+ },
3070
+ {
3071
+ "kind": "method",
3072
+ "name": "pageRows",
3073
+ "return": {
3074
+ "type": {
3075
+ "text": "number"
3076
+ }
3077
+ },
3078
+ "parameters": [
3079
+ {
3080
+ "name": "from",
3081
+ "type": {
3082
+ "text": "number"
3083
+ }
3084
+ },
3085
+ {
3086
+ "name": "down",
3087
+ "type": {
3088
+ "text": "boolean"
3089
+ }
3090
+ },
3091
+ {
3092
+ "name": "view",
3093
+ "type": {
3094
+ "text": "number"
3095
+ }
3096
+ }
3097
+ ],
3098
+ "description": "Auto mode: how many rows a page moves from row `from`, the rows that fit in\n`view` px below it (`down`) or above it. At least one."
3099
+ },
1984
3100
  {
1985
3101
  "kind": "field",
1986
3102
  "name": "poolSize",
@@ -1999,6 +3115,15 @@
1999
3115
  "description": "Whether the body is taller than the cap and scrolls scaled.",
2000
3116
  "readonly": true
2001
3117
  },
3118
+ {
3119
+ "kind": "field",
3120
+ "name": "topRow",
3121
+ "type": {
3122
+ "text": "number"
3123
+ },
3124
+ "description": "The index of the row at the top of the body (0 before the first layout).",
3125
+ "readonly": true
3126
+ },
2002
3127
  {
2003
3128
  "kind": "method",
2004
3129
  "name": "scrollToIndex",
@@ -2042,6 +3167,24 @@
2042
3167
  ],
2043
3168
  "description": "Scrolls by `delta` px of rows (logical px)."
2044
3169
  },
3170
+ {
3171
+ "kind": "method",
3172
+ "name": "scrollToEdge",
3173
+ "return": {
3174
+ "type": {
3175
+ "text": "void"
3176
+ }
3177
+ },
3178
+ "parameters": [
3179
+ {
3180
+ "name": "edge",
3181
+ "type": {
3182
+ "text": "'start' | 'end'"
3183
+ }
3184
+ }
3185
+ ],
3186
+ "description": "Scrolls to the start or the end of the body."
3187
+ },
2045
3188
  {
2046
3189
  "kind": "method",
2047
3190
  "name": "reveal",
@@ -2086,28 +3229,6 @@
2086
3229
  }
2087
3230
  ]
2088
3231
  },
2089
- {
2090
- "kind": "javascript-module",
2091
- "path": "src/styles/base.ts",
2092
- "declarations": [
2093
- {
2094
- "kind": "variable",
2095
- "name": "baseStyles",
2096
- "default": "css` @layer argus-base { :host { display: block; /* A table that virtualizes needs a bounded height; set your own on the element. */ block-size: 400px; box-sizing: border-box; contain: content; color-scheme: light dark; color: var(--argus-fg, CanvasText); background: var(--argus-bg, Canvas); font: var(--argus-font, inherit); /* contain: content clips the header, rows and pinned shadows to the rounded corners. */ border: var(--argus-outline, none); border-radius: var(--argus-radius, 0); --_row-height: var(--argus-row-height, 40px); --_pad: var(--argus-cell-padding-inline, 12px); --_border: var(--argus-border-width, 1px) solid var(--argus-border-color, light-dark(#e5e7eb, #374151)); /* 1 in LTR, -1 in RTL: mirrors the pinned-edge shadow. */ --_dir: 1; } :host(:dir(rtl)) { --_dir: -1; } :host([density='compact']) { --_row-height: var(--argus-row-height, 32px); --_pad: var(--argus-cell-padding-inline, 8px); } :host([density='spacious']) { --_row-height: var(--argus-row-height, 52px); --_pad: var(--argus-cell-padding-inline, 16px); } :host([hidden]) { display: none; } [part~='table'] { position: relative; block-size: 100%; overflow: auto; overscroll-behavior: contain; /* * A cell moved to by keyboard scrolls clear of the sticky header, the pinned * rows and the pinned columns. */ scroll-padding-block-start: calc((1 + var(--_pin-top-rows, 0)) * var(--_row-height)); scroll-padding-block-end: calc(var(--_pin-bottom-rows, 0) * var(--_row-height)); scroll-padding-inline: var(--_pin-start, 0) var(--_pin-end, 0); } .row { display: grid; grid-template-columns: var(--_cols); inline-size: var(--_width); min-inline-size: 100%; block-size: var(--_row-height); box-sizing: border-box; } [part~='header'] { position: sticky; inset-block-start: 0; z-index: 2; } [part~='body'] { position: relative; contain: layout; } [part~='body'] > .row { position: absolute; inset-block-start: 0; inset-inline-start: 0; } [part~='row'] { --_row-bg: var(--argus-bg, Canvas); --_row-surface: var(--_row-bg); background: var(--_row-surface); } [part~='row-odd'] { --_row-bg: var(--argus-row-stripe-bg, var(--argus-bg, Canvas)); } [part~='row']:hover { --_row-surface: var(--argus-row-hover-bg, var(--_row-bg)); } /* * Pinned rows: a sticky row group below the header and one at the bottom of * the view. The header is one row tall. They keep their place in the flow, * so body row i still starts i rows below the top group. */ .pinned { position: sticky; z-index: 2; } .pinned[data-side='top'] { inset-block-start: var(--_row-height); } .pinned[data-side='bottom'] { inset-block-end: 0; } [part~='row-pinned'] { --_row-bg: var(--argus-pinned-row-bg, var(--argus-bg, Canvas)); } [part~='cell'], [part~='header-cell'] { display: flex; align-items: center; min-inline-size: 0; box-sizing: border-box; padding-inline: var(--_pad); overflow: hidden; white-space: nowrap; border-block-end: var(--_border); } [part~='header-cell'] { background: var(--argus-header-bg, light-dark(#f9fafb, #111827)); color: var(--argus-header-fg, inherit); font-weight: 600; } [part~='header-cell'] { position: relative; } [part~='resize-handle'] { position: absolute; inset-block: 0; inset-inline-end: 0; inline-size: 8px; z-index: 1; cursor: col-resize; touch-action: none; } [part~='resize-handle']::after { content: ''; position: absolute; inset-block: 25%; inset-inline-end: 0; inline-size: 2px; background: var(--argus-resize-handle-color, light-dark(#9ca3af, #6b7280)); opacity: 0; } [part~='header-cell']:hover [part~='resize-handle']::after, [part~='header-cell']:focus-visible [part~='resize-handle']::after, [part~='resize-handle'][data-active]::after { opacity: 1; } [data-sort-col] { cursor: pointer; user-select: none; } /* A drag on a reorderable header moves the column, so its text isn't selectable. */ [data-move-col] { user-select: none; } [data-dragging], [data-dragging] [part~='header-cell'] { cursor: grabbing; } [part~='header-cell-dragging'] { opacity: 0.5; } /* The line where a dragged column would land, on the target header's logical edge. */ [part~='drop-indicator'] { position: absolute; inset-block: 0; inline-size: 2px; z-index: 2; background: var(--argus-drop-indicator-color, Highlight); pointer-events: none; } [part~='drop-indicator'][data-edge='start'] { inset-inline-start: 0; } [part~='drop-indicator'][data-edge='end'] { inset-inline-end: 0; } [part~='header-cell']:focus-visible, [part~='cell']:focus-visible { outline: var(--argus-focus-ring, 2px solid Highlight); outline-offset: -2px; } /* A small chevron after the header content; only the sorted column shows it. */ .sort-indicator { flex: none; inline-size: 0.35em; block-size: 0.35em; margin-inline-start: 0.4em; /* Physical sides on purpose: the chevron is rotated, so it must not mirror in RTL. */ border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; visibility: hidden; } [aria-sort] .sort-indicator { visibility: visible; } [aria-sort='ascending'] .sort-indicator { transform: translateY(0.1em) rotate(-135deg); } [aria-sort='descending'] .sort-indicator { transform: translateY(-0.1em) rotate(45deg); } [data-align='end'] .sort-indicator { order: -1; margin-inline: 0 0.4em; } /* * Pinned columns: sticky inside the scroll container, with offsets from the * table model. Logical insets make RTL work without extra rules. */ [data-pin] { position: sticky; z-index: 1; } [data-pin='start'] { inset-inline-start: var(--_pin-offset); } [data-pin='end'] { inset-inline-end: var(--_pin-offset); } /* * Pinned body cells are sticky only while the table scrolls sideways * (data-hscroll on the scroller). At rest they are plain cells shifted by the * horizontal scroll offset, which vertical scrolling never changes: a sticky * cell per row is a compositing layer each, and Safari stutters moving them * (PinScrollController). Both place the cells at the same spot. */ [part~='row'] > [data-pin] { position: relative; inset-inline: auto; } [part~='row'] > [data-pin='start'] { transform: translateX(var(--_sx, 0px)); } [part~='row'] > [data-pin='end'] { transform: translateX(calc(var(--_sx, 0px) - var(--_dir) * var(--_max-x, 0px))); } [data-hscroll] [part~='row'] > [data-pin] { position: sticky; transform: none; } [data-hscroll] [part~='row'] > [data-pin='start'] { inset-inline-start: var(--_pin-offset); } [data-hscroll] [part~='row'] > [data-pin='end'] { inset-inline-end: var(--_pin-offset); } [part~='cell-pinned'] { background: var(--_row-surface); } /* * The edge shadow, once per pinned side (.pin-shadow, beside the scroller). * --argus-pinned-shadow is written for a shadow falling toward the end side; * the start edge in RTL and the end edge in LTR mirror it. */ .pin-shadow { position: absolute; inset-block-start: 0; block-size: min(var(--_view-h, 100%), var(--_content-h, 100%)); z-index: 3; pointer-events: none; } .pin-shadow[data-side='start'] { inset-inline-start: 0; } .pin-shadow[data-side='end'] { inset-inline-end: var(--_sb-x, 0px); } .pin-shadow::after { content: ''; position: absolute; inset: 0; box-shadow: var( --argus-pinned-shadow, 4px 0 6px -4px light-dark(rgb(0 0 0 / 0.2), rgb(0 0 0 / 0.6)) ); transform: scaleX(var(--_dir)); } .pin-shadow[data-side='end']::after { transform: scaleX(calc(-1 * var(--_dir))); } [data-align='center'] { justify-content: center; text-align: center; } [data-align='end'] { justify-content: flex-end; text-align: end; } ::slotted(*) { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; } /* Fitting a column to its content: set for one synchronous measurement, never painted. */ [data-measure] { inline-size: max-content; } /* Rows of a data source that haven't loaded: a bar per cell, pulsing gently. */ [part~='skeleton'] { flex: none; inline-size: min(60%, 8em); block-size: 0.6em; border-radius: 0.3em; background: var(--argus-skeleton-bg, color-mix(in srgb, currentColor 12%, transparent)); animation: argus-skeleton-pulse 1.6s ease-in-out infinite; } [part~='skeleton-error'] { animation: none; opacity: 0.5; } @keyframes argus-skeleton-pulse { 50% { opacity: 0.45; } } @media (prefers-reduced-motion: reduce) { [part~='skeleton'] { animation: none; } } [part~='retry'] { font: inherit; color: inherit; cursor: pointer; } [part~='empty'] { display: flex; align-items: center; justify-content: center; min-block-size: calc( 100% - (1 + var(--_pin-top-rows, 0) + var(--_pin-bottom-rows, 0)) * var(--_row-height) ); padding: var(--_pad); box-sizing: border-box; } /* Measures the resolved row height in px for the virtualizer. */ .probe { position: absolute; inset-block-start: 0; inline-size: 0; block-size: var(--_row-height); visibility: hidden; pointer-events: none; } } `",
2097
- "description": "Base styles. Everything sits in `@layer argus-base`, and every value reads a\npublic token with a neutral fallback, so themes and page CSS always win.\n`--_*` properties are private."
2098
- }
2099
- ],
2100
- "exports": [
2101
- {
2102
- "kind": "js",
2103
- "name": "baseStyles",
2104
- "declaration": {
2105
- "name": "baseStyles",
2106
- "module": "src/styles/base.ts"
2107
- }
2108
- }
2109
- ]
2110
- },
2111
3232
  {
2112
3233
  "kind": "javascript-module",
2113
3234
  "path": "src/render/body.ts",
@@ -2152,9 +3273,27 @@
2152
3273
  "type": {
2153
3274
  "text": "Loading"
2154
3275
  }
3276
+ },
3277
+ {
3278
+ "name": "selectedAt",
3279
+ "optional": true,
3280
+ "type": {
3281
+ "text": "SelectedAt"
3282
+ }
3283
+ },
3284
+ {
3285
+ "name": "checkboxes",
3286
+ "optional": true,
3287
+ "type": {
3288
+ "text": "CheckboxHandlers"
3289
+ }
3290
+ },
3291
+ {
3292
+ "name": "inset",
3293
+ "default": "false"
2155
3294
  }
2156
3295
  ],
2157
- "description": "The virtualized body. Rows are keyed by pool slot, so a row entering the window\nreuses the DOM of one that left (ADR 0001), and they stay in pool order: screen\nreaders get the position from `aria-rowindex`. `firstRowIndex` is the\n`aria-rowindex` of row 0: after the header and the rows pinned to the top."
3296
+ "description": "The virtualized body. Rows are keyed by pool slot, so a row entering the window\nreuses the DOM of one that left (ADR 0001), and they stay in pool order: screen\nreaders get the position from `aria-rowindex`. `firstRowIndex` is the\n`aria-rowindex` of row 0: after the header and the rows pinned to the top.\n`inset`: rows of different heights (`rowHeight: 'auto'`) are placed with\n`inset-block-start` and render at least their measured `size`, which is on\nthe controller's px grid, so they stay flush however far down they are."
2158
3297
  },
2159
3298
  {
2160
3299
  "kind": "function",
@@ -2163,7 +3302,7 @@
2163
3302
  {
2164
3303
  "name": "c",
2165
3304
  "type": {
2166
- "text": "ColumnView<T, CellContent>"
3305
+ "text": "RenderedColumn<T>"
2167
3306
  }
2168
3307
  },
2169
3308
  {
@@ -2223,7 +3362,7 @@
2223
3362
  "name": "renderLightDom",
2224
3363
  "return": {
2225
3364
  "type": {
2226
- "text": "void"
3365
+ "text": "RootPart"
2227
3366
  }
2228
3367
  },
2229
3368
  "parameters": [
@@ -2245,6 +3384,12 @@
2245
3384
  "text": "readonly WindowRow[]"
2246
3385
  }
2247
3386
  },
3387
+ {
3388
+ "name": "rendered",
3389
+ "type": {
3390
+ "text": "readonly RenderedColumn<T>[]"
3391
+ }
3392
+ },
2248
3393
  {
2249
3394
  "name": "renderBefore",
2250
3395
  "type": {
@@ -2252,7 +3397,7 @@
2252
3397
  }
2253
3398
  }
2254
3399
  ],
2255
- "description": "Renders header and cell content into the host's light DOM, as direct children\n(a slot only takes the host's own children). Keyed and ordered by pool slot,\nso recycled content updates in place instead of moving (ADR 0001). The part\nends at `renderBefore`, so the host's other children (`<argus-column>`) stay\noutside it, wherever they are added."
3400
+ "description": "Renders header and cell content into the host's light DOM, as direct children\n(a slot only takes the host's own children). Keyed and ordered by pool slot,\nso recycled content updates in place instead of moving (ADR 0001). The part\nends at `renderBefore`, so the host's other children (`<argus-column>`) stay\noutside it, wherever they are added. `rendered` are the columns the shadow\nroot renders, with their slots and keys. What `header` and `cell` return goes\nthrough `content()`, so foreign content reaches the table's `contentRenderer`.\nReturns the part, which the table disconnects when it is disconnected."
2256
3401
  }
2257
3402
  ],
2258
3403
  "exports": [
@@ -2266,6 +3411,78 @@
2266
3411
  }
2267
3412
  ]
2268
3413
  },
3414
+ {
3415
+ "kind": "javascript-module",
3416
+ "path": "src/render/content-directive.ts",
3417
+ "declarations": [
3418
+ {
3419
+ "kind": "function",
3420
+ "name": "flushContent",
3421
+ "return": {
3422
+ "type": {
3423
+ "text": "void"
3424
+ }
3425
+ },
3426
+ "parameters": [
3427
+ {
3428
+ "name": "host",
3429
+ "type": {
3430
+ "text": "object"
3431
+ }
3432
+ }
3433
+ ],
3434
+ "description": "Calls `flush()` on the renderers that rendered or released for `host` since the last call."
3435
+ },
3436
+ {
3437
+ "kind": "function",
3438
+ "name": "isForeign",
3439
+ "return": {
3440
+ "type": {
3441
+ "text": "boolean"
3442
+ }
3443
+ },
3444
+ "parameters": [
3445
+ {
3446
+ "name": "value",
3447
+ "type": {
3448
+ "text": "unknown"
3449
+ }
3450
+ }
3451
+ ],
3452
+ "description": "Whether the table renders `value` itself: strings, numbers, Lit templates and\ndirective results, DOM nodes, `nothing` and empty values, and arrays of those.\nAnything else is foreign: it goes to the `contentRenderer`."
3453
+ },
3454
+ {
3455
+ "kind": "variable",
3456
+ "name": "content"
3457
+ }
3458
+ ],
3459
+ "exports": [
3460
+ {
3461
+ "kind": "js",
3462
+ "name": "flushContent",
3463
+ "declaration": {
3464
+ "name": "flushContent",
3465
+ "module": "src/render/content-directive.ts"
3466
+ }
3467
+ },
3468
+ {
3469
+ "kind": "js",
3470
+ "name": "isForeign",
3471
+ "declaration": {
3472
+ "name": "isForeign",
3473
+ "module": "src/render/content-directive.ts"
3474
+ }
3475
+ },
3476
+ {
3477
+ "kind": "js",
3478
+ "name": "content",
3479
+ "declaration": {
3480
+ "name": "content",
3481
+ "module": "src/render/content-directive.ts"
3482
+ }
3483
+ }
3484
+ ]
3485
+ },
2269
3486
  {
2270
3487
  "kind": "javascript-module",
2271
3488
  "path": "src/render/content.ts",
@@ -2317,20 +3534,20 @@
2317
3534
  }
2318
3535
  },
2319
3536
  {
2320
- "name": "colIndex",
3537
+ "name": "colSlot",
2321
3538
  "type": {
2322
3539
  "text": "number"
2323
3540
  }
2324
3541
  }
2325
3542
  ],
2326
- "description": "Private slot names (ADR 0001): cells by pool slot and column, headers by\ncolumn, pinned rows by side, index and column."
3543
+ "description": "Private slot names (ADR 0001): cells by row pool slot and column slot,\nheaders by column slot, pinned rows by side, index and column slot. A\ncolumn's slot is its `colIndex`, or its pool slot with `virtualizeColumns`."
2327
3544
  },
2328
3545
  {
2329
3546
  "kind": "function",
2330
3547
  "name": "headerSlot",
2331
3548
  "parameters": [
2332
3549
  {
2333
- "name": "colIndex",
3550
+ "name": "colSlot",
2334
3551
  "type": {
2335
3552
  "text": "number"
2336
3553
  }
@@ -2354,7 +3571,7 @@
2354
3571
  }
2355
3572
  },
2356
3573
  {
2357
- "name": "colIndex",
3574
+ "name": "colSlot",
2358
3575
  "type": {
2359
3576
  "text": "number"
2360
3577
  }
@@ -2373,7 +3590,7 @@
2373
3590
  {
2374
3591
  "name": "column",
2375
3592
  "type": {
2376
- "text": "Pinnable & { sorted: 'asc' | 'desc' | false }"
3593
+ "text": "Pinnable & { sorted: 'asc' | 'desc' | false; kind: 'data' | 'selection' }"
2377
3594
  }
2378
3595
  },
2379
3596
  {
@@ -2403,7 +3620,7 @@
2403
3620
  },
2404
3621
  {
2405
3622
  "kind": "function",
2406
- "name": "pinStyle",
3623
+ "name": "cellStyle",
2407
3624
  "return": {
2408
3625
  "type": {
2409
3626
  "text": "string | undefined"
@@ -2413,11 +3630,11 @@
2413
3630
  {
2414
3631
  "name": "column",
2415
3632
  "type": {
2416
- "text": "Pinnable & { offset: number }"
3633
+ "text": "Pinnable & { offset: number; place: number | undefined }"
2417
3634
  }
2418
3635
  }
2419
3636
  ],
2420
- "description": "Inline style of a pinned cell: its sticky inset, from the start or the end edge."
3637
+ "description": "Inline style of a cell or header: a pinned one's sticky inset, from the\nstart or the end edge, and with `virtualizeColumns` the grid cell it is\nplaced in. Cells are in pool order there, not in column order, so the row is\nexplicit too: auto-placement would wrap a cell that comes after one of a\nlater column into a new grid row."
2421
3638
  }
2422
3639
  ],
2423
3640
  "exports": [
@@ -2479,9 +3696,9 @@
2479
3696
  },
2480
3697
  {
2481
3698
  "kind": "js",
2482
- "name": "pinStyle",
3699
+ "name": "cellStyle",
2483
3700
  "declaration": {
2484
- "name": "pinStyle",
3701
+ "name": "cellStyle",
2485
3702
  "module": "src/render/content.ts"
2486
3703
  }
2487
3704
  }
@@ -2498,7 +3715,7 @@
2498
3715
  {
2499
3716
  "name": "columns",
2500
3717
  "type": {
2501
- "text": "readonly ColumnView<T, CellContent>[]"
3718
+ "text": "readonly RenderedColumn<T>[]"
2502
3719
  }
2503
3720
  },
2504
3721
  {
@@ -2519,6 +3736,13 @@
2519
3736
  "type": {
2520
3737
  "text": "HeaderDrag"
2521
3738
  }
3739
+ },
3740
+ {
3741
+ "name": "checkAll",
3742
+ "optional": true,
3743
+ "type": {
3744
+ "text": "CheckAll"
3745
+ }
2522
3746
  }
2523
3747
  ],
2524
3748
  "description": "The sticky header row. Header content is slotted from the light DOM. Pinned\nheader cells use the same private `data-pin` hooks as body cells, but no parts.\nEvery header carries `data-col` (its column id) and sortable ones also\n`data-sort-col`; the element's delegated handlers read them. Headers take part\nin the grid's roving tabindex: the active one is the tab stop (`activeCol`).\nResizable columns get a `resize-handle` on the header's inline-end edge; a\ndouble-click on it fits the column to its content. It is not focusable: the\nfocused header resizes with Alt+Arrow.\n\nReorderable columns carry `data-move-col`: a drag on the header moves the\ncolumn. While one is dragged (`drag`), its header adds `header-cell-dragging`\nand the target header shows a `drop-indicator` on the edge it would land at."
@@ -2558,7 +3782,7 @@
2558
3782
  {
2559
3783
  "name": "columns",
2560
3784
  "type": {
2561
- "text": "readonly ColumnView<T, CellContent>[]"
3785
+ "text": "readonly RenderedColumn<T>[]"
2562
3786
  }
2563
3787
  },
2564
3788
  {
@@ -2587,6 +3811,28 @@
2587
3811
  }
2588
3812
  }
2589
3813
  ]
3814
+ },
3815
+ {
3816
+ "kind": "javascript-module",
3817
+ "path": "src/styles/base.ts",
3818
+ "declarations": [
3819
+ {
3820
+ "kind": "variable",
3821
+ "name": "baseStyles",
3822
+ "default": "css` @layer argus-base { :host { display: block; /* A table that virtualizes needs a bounded height; set your own on the element. */ block-size: 400px; box-sizing: border-box; contain: content; color-scheme: light dark; color: var(--argus-fg, CanvasText); background: var(--argus-bg, Canvas); font: var(--argus-font, inherit); /* contain: content clips the header, rows and pinned shadows to the rounded corners. */ border: var(--argus-outline, none); border-radius: var(--argus-radius, 0); --_row-height: var(--argus-row-height, 40px); --_pad: var(--argus-cell-padding-inline, 12px); --_border: var(--argus-border-width, 1px) solid var(--argus-border-color, light-dark(#e5e7eb, #374151)); /* 1 in LTR, -1 in RTL: mirrors the pinned-edge shadow. */ --_dir: 1; } :host(:dir(rtl)) { --_dir: -1; } :host([density='compact']) { --_row-height: var(--argus-row-height, 32px); --_pad: var(--argus-cell-padding-inline, 8px); } :host([density='spacious']) { --_row-height: var(--argus-row-height, 52px); --_pad: var(--argus-cell-padding-inline, 16px); } :host([hidden]) { display: none; } [part~='table'] { position: relative; block-size: 100%; overflow: auto; overscroll-behavior: contain; } /* * A cell focused or moved to by keyboard scrolls clear of the sticky header, the * pinned rows and the pinned columns: scroll margins on the cells that scroll. * Not scroll padding on the scroller: Chromium and WebKit measure the sticky * header and pinned rows against it too, so focusing one of them (a click, Tab, * an arrow key) scrolled the body. */ [part~='body'] > .row > [role='gridcell'] { scroll-margin-block: calc((1 + var(--_pin-top-rows, 0)) * var(--_row-height)) calc(var(--_pin-bottom-rows, 0) * var(--_row-height)); } [role='gridcell']:not([data-pin]), [role='columnheader']:not([data-pin]) { scroll-margin-inline: var(--_pin-start, 0) var(--_pin-end, 0); } .row { display: grid; grid-template-columns: var(--_cols); inline-size: var(--_width); min-inline-size: 100%; block-size: var(--_row-height); box-sizing: border-box; } [part~='header'] { position: sticky; inset-block-start: 0; z-index: 2; } [part~='body'] { position: relative; contain: layout; } [part~='body'] > .row { position: absolute; inset-block-start: 0; inset-inline-start: 0; } [part~='row'] { --_row-bg: var(--argus-bg, Canvas); --_row-surface: var(--_row-bg); background: var(--_row-surface); } [part~='row-odd'] { --_row-bg: var(--argus-row-stripe-bg, var(--argus-bg, Canvas)); } [part~='row']:hover { --_row-surface: var(--argus-row-hover-bg, var(--_row-bg)); } /* Selected wins over stripes and hover. */ [part~='row-selected'], [part~='row-selected']:hover { --_row-bg: var( --argus-row-selected-bg, color-mix(in srgb, Highlight 22%, var(--argus-bg, Canvas)) ); --_row-surface: var(--_row-bg); } @media (forced-colors: active) { [part~='row-selected'] { forced-color-adjust: none; --_row-bg: Highlight; color: HighlightText; } } /* * Pinned rows: a sticky row group below the header and one at the bottom of * the view. The header is one row tall. They keep their place in the flow, * so body row i still starts i rows below the top group. */ .pinned { position: sticky; z-index: 2; } .pinned[data-side='top'] { inset-block-start: var(--_row-height); } .pinned[data-side='bottom'] { inset-block-end: 0; } [part~='row-pinned'] { --_row-bg: var(--argus-pinned-row-bg, var(--argus-bg, Canvas)); } [part~='cell'], [part~='header-cell'] { display: flex; align-items: center; min-inline-size: 0; box-sizing: border-box; padding-inline: var(--_pad); overflow: hidden; white-space: nowrap; border-block-end: var(--_border); } /* The checkbox column: the checkbox centred, no padding to squeeze it. */ [part~='cell-selection'], [part~='header-cell-selection'] { justify-content: center; padding-inline: 0; } [part~='selection-checkbox'] { margin: 0; cursor: pointer; } [part~='header-cell'] { background: var(--argus-header-bg, light-dark(#f9fafb, #111827)); color: var(--argus-header-fg, inherit); font-weight: 600; } [part~='header-cell'] { position: relative; } [part~='resize-handle'] { position: absolute; inset-block: 0; inset-inline-end: 0; inline-size: 8px; z-index: 1; cursor: col-resize; touch-action: none; } [part~='resize-handle']::after { content: ''; position: absolute; inset-block: 25%; inset-inline-end: 0; inline-size: 2px; background: var(--argus-resize-handle-color, light-dark(#9ca3af, #6b7280)); opacity: 0; } [part~='header-cell']:hover [part~='resize-handle']::after, [part~='header-cell']:focus-visible [part~='resize-handle']::after, [part~='resize-handle'][data-active]::after { opacity: 1; } [data-sort-col] { cursor: pointer; user-select: none; } /* A drag on a reorderable header moves the column, so its text isn't selectable. */ [data-move-col] { user-select: none; } [data-dragging], [data-dragging] [part~='header-cell'] { cursor: grabbing; } [part~='header-cell-dragging'] { opacity: 0.5; } /* The line where a dragged column would land, on the target header's logical edge. */ [part~='drop-indicator'] { position: absolute; inset-block: 0; inline-size: 2px; z-index: 2; background: var(--argus-drop-indicator-color, Highlight); pointer-events: none; } [part~='drop-indicator'][data-edge='start'] { inset-inline-start: 0; } [part~='drop-indicator'][data-edge='end'] { inset-inline-end: 0; } [part~='header-cell']:focus-visible, [part~='cell']:focus-visible { outline: var(--argus-focus-ring, 2px solid Highlight); outline-offset: -2px; } /* A small chevron after the header content; only the sorted column shows it. */ .sort-indicator { flex: none; inline-size: 0.35em; block-size: 0.35em; margin-inline-start: 0.4em; /* Physical sides on purpose: the chevron is rotated, so it must not mirror in RTL. */ border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; visibility: hidden; } [aria-sort] .sort-indicator { visibility: visible; } [aria-sort='ascending'] .sort-indicator { transform: translateY(0.1em) rotate(-135deg); } [aria-sort='descending'] .sort-indicator { transform: translateY(-0.1em) rotate(45deg); } [data-align='end'] .sort-indicator { order: -1; margin-inline: 0 0.4em; } /* A funnel: the column is filtered. */ [part~='filter-indicator'] { flex: none; inline-size: 0.7em; block-size: 0.7em; margin-inline-start: 0.35em; background: var(--argus-filter-indicator-color, currentColor); clip-path: polygon(0 0, 100% 0, 62% 48%, 62% 100%, 38% 82%, 38% 48%); } [data-align='end'] [part~='filter-indicator'] { order: -2; margin-inline: 0 0.35em; } @media (forced-colors: active) { /* Backgrounds are forced to Canvas there, which would hide the funnel. */ [part~='filter-indicator'] { forced-color-adjust: none; background: CanvasText; } } /* * Pinned columns: sticky inside the scroll container, with offsets from the * table model. Logical insets make RTL work without extra rules. */ [data-pin] { position: sticky; z-index: 1; } [data-pin='start'] { inset-inline-start: var(--_pin-offset); } [data-pin='end'] { inset-inline-end: var(--_pin-offset); } /* * Pinned body cells are sticky only while the table scrolls sideways * (data-hscroll on the scroller). At rest they are plain cells shifted by the * horizontal scroll offset, which vertical scrolling never changes: a sticky * cell per row is a compositing layer each, and Safari stutters moving them * (PinScrollController). Both place the cells at the same spot. */ [part~='row'] > [data-pin] { position: relative; inset-inline: auto; } [part~='row'] > [data-pin='start'] { transform: translateX(var(--_sx, 0px)); } [part~='row'] > [data-pin='end'] { transform: translateX(calc(var(--_sx, 0px) - var(--_dir) * var(--_max-x, 0px))); } [data-hscroll] [part~='row'] > [data-pin] { position: sticky; transform: none; } [data-hscroll] [part~='row'] > [data-pin='start'] { inset-inline-start: var(--_pin-offset); } [data-hscroll] [part~='row'] > [data-pin='end'] { inset-inline-end: var(--_pin-offset); } [part~='cell-pinned'] { background: var(--_row-surface); } /* * The edge shadow, once per pinned side (.pin-shadow, beside the scroller). * --argus-pinned-shadow is written for a shadow falling toward the end side; * the start edge in RTL and the end edge in LTR mirror it. */ .pin-shadow { position: absolute; inset-block-start: 0; block-size: min(var(--_view-h, 100%), var(--_content-h, 100%)); z-index: 3; pointer-events: none; } .pin-shadow[data-side='start'] { inset-inline-start: 0; } .pin-shadow[data-side='end'] { inset-inline-end: var(--_sb-x, 0px); } .pin-shadow::after { content: ''; position: absolute; inset: 0; box-shadow: var( --argus-pinned-shadow, 4px 0 6px -4px light-dark(rgb(0 0 0 / 0.2), rgb(0 0 0 / 0.6)) ); transform: scaleX(var(--_dir)); } .pin-shadow[data-side='end']::after { transform: scaleX(calc(-1 * var(--_dir))); } [data-align='center'] { justify-content: center; text-align: center; } [data-align='end'] { justify-content: flex-end; text-align: end; } /* * Wrapped text (ColumnDef.wrap). In a fixed-height row, text taller than the row * starts at the top (safe) and is clipped below. */ [part~='cell'][data-wrap] { white-space: normal; overflow-wrap: anywhere; align-items: center; align-items: safe center; } /* * rowHeight: 'auto'. Body and pinned rows fit their content, at least one row * tall; the header keeps its height. Content sits at the top of the cell, with * the block padding that centres one line in a one-row cell, so one-line rows * look as they do with a fixed height. The rows' heights are measured and * placed by the table: the browser's scroll anchoring would fight it. */ [data-auto-rows] { overflow-anchor: none; } [data-auto-rows] > [part~='body'] > .row, [data-auto-rows] > .pinned > .row { block-size: auto; min-block-size: var(--_row-height); grid-template-rows: minmax(var(--_row-height), auto); } /* Reading the rows' own heights: without the height each row renders at. */ [data-auto-rows] > [part~='body'] > .row[data-measure-row] { min-block-size: var(--_row-height) !important; } [data-auto-rows] [part~='cell'] { align-items: start; padding-block: var( --argus-cell-padding-block, max(0px, (var(--_row-height) - 1lh - var(--argus-border-width, 1px)) / 2) ); } /* Skeleton bars and the Retry button, centred in a one-row row as before. */ [data-auto-rows] [part~='row-loading'] > [part~='cell'] { align-items: center; padding-block: 0; } [data-auto-rows] > [part~='body'] > .row > [role='gridcell'] { scroll-margin-block: calc(var(--_row-height) + var(--_pin-top-h, 0px)) var(--_pin-bottom-h, 0px); } [data-auto-rows] > [part~='empty'] { min-block-size: calc( 100% - var(--_row-height) - var(--_pin-top-h, 0px) - var(--_pin-bottom-h, 0px) ); } ::slotted(*) { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; } /* Fitting a column to its content: set for one synchronous measurement, never painted. */ [data-measure] { inline-size: max-content; } /* Rows of a data source that haven't loaded: a bar per cell, pulsing gently. */ [part~='skeleton'] { flex: none; inline-size: min(60%, 8em); block-size: 0.6em; border-radius: 0.3em; background: var(--argus-skeleton-bg, color-mix(in srgb, currentColor 12%, transparent)); animation: argus-skeleton-pulse 1.6s ease-in-out infinite; } [part~='skeleton-error'] { animation: none; opacity: 0.5; } @keyframes argus-skeleton-pulse { 50% { opacity: 0.45; } } @media (prefers-reduced-motion: reduce) { [part~='skeleton'] { animation: none; } } [part~='retry'] { font: inherit; color: inherit; cursor: pointer; } [part~='empty'] { display: flex; align-items: center; justify-content: center; min-block-size: calc( 100% - (1 + var(--_pin-top-rows, 0) + var(--_pin-bottom-rows, 0)) * var(--_row-height) ); padding: var(--_pad); box-sizing: border-box; } /* Measures the resolved row height in px for the virtualizer. */ .probe { position: absolute; inset-block-start: 0; inline-size: 0; block-size: var(--_row-height); visibility: hidden; pointer-events: none; } } `",
3823
+ "description": "Base styles. Everything sits in `@layer argus-base`, and every value reads a\npublic token with a neutral fallback, so themes and page CSS always win.\n`--_*` properties are private."
3824
+ }
3825
+ ],
3826
+ "exports": [
3827
+ {
3828
+ "kind": "js",
3829
+ "name": "baseStyles",
3830
+ "declaration": {
3831
+ "name": "baseStyles",
3832
+ "module": "src/styles/base.ts"
3833
+ }
3834
+ }
3835
+ ]
2590
3836
  }
2591
3837
  ]
2592
3838
  }