argus-table 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/argus-table.js +2 -2
- package/dist/argus-table.js.map +1 -1
- package/dist/cdn/argus-table.js +26 -26
- package/dist/cdn/argus-table.js.map +1 -1
- package/dist/controllers/virtual-controller.js +8 -1
- package/dist/controllers/virtual-controller.js.map +1 -1
- package/dist/core/src/virtual/steady-window.js +30 -0
- package/dist/core/src/virtual/steady-window.js.map +1 -0
- package/dist/custom-elements.json +40 -22
- package/dist/styles/base.js +1 -1
- package/dist/styles/base.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RowPool } from "../core/src/virtual/row-pool.js";
|
|
2
2
|
import { ScrollScale } from "../core/src/virtual/scroll-scale.js";
|
|
3
|
+
import { maxVisibleRows, steadyWindow } from "../core/src/virtual/steady-window.js";
|
|
3
4
|
import { VirtualizerController } from "@tanstack/lit-virtual";
|
|
4
5
|
// src/controllers/virtual-controller.ts
|
|
5
6
|
/**
|
|
@@ -56,7 +57,8 @@ var VirtualController = class {
|
|
|
56
57
|
};
|
|
57
58
|
},
|
|
58
59
|
estimateSize: () => this.#config.rowHeight,
|
|
59
|
-
overscan: this.#config.overscan
|
|
60
|
+
overscan: this.#config.overscan,
|
|
61
|
+
rangeExtractor: (range) => steadyWindow(range, maxVisibleRows(this.#element?.clientHeight ?? 0, this.#config.rowHeight))
|
|
60
62
|
});
|
|
61
63
|
host.addController(this);
|
|
62
64
|
}
|
|
@@ -188,6 +190,11 @@ var VirtualController = class {
|
|
|
188
190
|
const element = this.#element;
|
|
189
191
|
if (element) this.#write(element, this.#top(element) + delta);
|
|
190
192
|
}
|
|
193
|
+
/** Scrolls to the start or the end of the body. */
|
|
194
|
+
scrollToEdge(edge) {
|
|
195
|
+
const element = this.#element;
|
|
196
|
+
if (element) this.#write(element, edge === "start" ? 0 : Number.MAX_SAFE_INTEGER);
|
|
197
|
+
}
|
|
191
198
|
/**
|
|
192
199
|
* Scrolls the least distance that shows row `index` in full, between the
|
|
193
200
|
* content above the body (`before` px: the header and top pinned rows) and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-controller.js","names":[],"sources":["../../src/controllers/virtual-controller.ts"],"sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport { VirtualizerController } from '@tanstack/lit-virtual';\nimport { RowPool, ScrollScale } from '@argus-table/core';\n\n/** A rendered body row: its pool slot, its index in the row model and its offset. */\nexport interface WindowRow {\n slot: number;\n index: number;\n /** Offset in the rendered body, in px (scaled bodies: relative to the scroll position). */\n start: number;\n}\n\nexport interface VirtualWindow {\n /** Rendered rows, in pool order (ADR 0001 addendum). */\n rows: WindowRow[];\n /** Rendered height of the body in px: all rows, or the cap. */\n totalSize: number;\n /** Visible rows, without overscan; `null` before the first layout. */\n range: { start: number; end: number } | null;\n}\n\nexport interface VirtualConfig {\n count: number;\n rowHeight: number;\n overscan: number;\n /** Row id at an index of the row model; pool slots follow row ids. */\n rowIdAt: (index: number) => string;\n /**\n * The row to keep rendered outside the range (the one holding the grid's tab\n * stop), so its DOM and focus survive scrolling. `undefined`: none.\n */\n keep?: { id: string; index: number } | undefined;\n /** The tallest the body may render (`bodyCap()`); a taller one scrolls scaled. */\n cap: number;\n}\n\n/**\n * Row virtualization (TanStack Virtual) plus the row pool: which rows render,\n * where, and which pool slot's DOM each one uses. The virtualizer registers itself\n * with the host and requests updates on scroll.\n *\n * Scroll scaling: engines limit an element's height, so a body taller than the\n * cap 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\n * for the scroller whose `scrollTop`, `scrollHeight` and `scrollTo()` are\n * logical, and everything else passes through. Rows render relative to the\n * scroll position (`start` minus the difference between the logical and the\n * physical offset). Scroll through this controller (`scrollBy`, `reveal`,\n * `scrollToIndex`): physical px no longer match rows once the body is scaled.\n */\nexport class VirtualController implements ReactiveController {\n readonly #virtual: VirtualizerController<HTMLElement, Element>;\n readonly #pool = new RowPool();\n readonly #scale = new ScrollScale();\n readonly #host: ReactiveControllerHost;\n readonly #getScrollElement: () => HTMLElement | null;\n #element: HTMLElement | undefined;\n #standIn: HTMLElement | undefined;\n #config: VirtualConfig = {\n count: 0,\n rowHeight: 40,\n overscan: 6,\n rowIdAt: String,\n cap: Infinity,\n };\n /** A logical offset to restore after the update, once the body has its new height. */\n #anchor: number | undefined;\n\n constructor(host: ReactiveControllerHost, getScrollElement: () => HTMLElement | null) {\n this.#host = host;\n this.#getScrollElement = getScrollElement;\n this.#virtual = new VirtualizerController<HTMLElement, Element>(host, {\n count: 0,\n getScrollElement: () => this.#scroller(),\n // The real element: a ResizeObserver can't observe the stand-in.\n observeElementRect: (_instance, cb) => {\n const element = this.#element;\n if (!element) return undefined;\n const report = () => {\n cb({ width: element.clientWidth, height: element.clientHeight });\n };\n report();\n const observer = new ResizeObserver(report);\n observer.observe(element);\n return () => {\n observer.disconnect();\n };\n },\n estimateSize: () => this.#config.rowHeight,\n overscan: this.#config.overscan,\n });\n host.addController(this);\n }\n\n /** The scroller's stand-in for the virtualizer: vertical offsets and height in logical px. */\n #scroller(): HTMLElement | null {\n const element = this.#getScrollElement();\n if (!element) return null;\n if (this.#element !== element || !this.#standIn) {\n this.#element = element;\n this.#standIn = new Proxy(element, {\n get: (target, key) => {\n if (key === 'scrollTop') return this.#top(target);\n if (key === 'scrollHeight') return target.scrollHeight + this.#scale.excess;\n if (key === 'scrollTo') {\n return (options: ScrollToOptions) => {\n if (options.top === undefined) target.scrollTo(options);\n else this.#write(target, options.top, options.behavior);\n };\n }\n const value: unknown = Reflect.get(target, key);\n // Methods run on the element itself (DOM methods reject the proxy).\n return typeof value === 'function'\n ? (value as (...args: unknown[]) => unknown).bind(target)\n : value;\n },\n });\n }\n return this.#standIn;\n }\n\n /** The scroller's logical offset. */\n #top(element: HTMLElement): number {\n const top = element.scrollTop;\n const scale = this.#scale;\n return scale.scaled ? scale.toLogical(top, element.scrollHeight - element.clientHeight) : top;\n }\n\n /**\n * Scrolls to a logical offset. `round` rounds the physical one, so that a\n * scaled offset moves the scroller at all.\n */\n #write(\n element: HTMLElement,\n logical: number,\n behavior?: ScrollBehavior,\n round?: (px: number) => number,\n ): void {\n const scale = this.#scale;\n if (!scale.scaled) {\n element.scrollTo({ top: logical, behavior });\n return;\n }\n const range = element.scrollHeight - element.clientHeight;\n const target = Math.min(Math.max(logical, 0), range + scale.excess);\n const physical = scale.toPhysical(target, range);\n element.scrollTo({ top: round ? round(physical) : physical, behavior });\n if (behavior !== 'smooth') scale.land(target, element.scrollTop);\n }\n\n configure(next: VirtualConfig): void {\n const prev = this.#config;\n this.#config = next;\n if (\n next.count !== prev.count ||\n next.overscan !== prev.overscan ||\n next.rowHeight !== prev.rowHeight\n ) {\n this.#virtual.setOptions({ count: next.count, overscan: next.overscan });\n if (next.rowHeight !== prev.rowHeight) this.#virtual.getVirtualizer().measure();\n }\n // Not `scaled`: TypeScript would take it for unchanged after `configure()`.\n const wasScaled = this.#scale.excess > 0;\n const offset = this.#virtual.getVirtualizer().scrollOffset;\n if (this.#scale.configure(next.count * next.rowHeight, next.cap)) {\n // A new mapping would move the rows under a scaled scroll position (a data\n // source growing, a zoom change): keep the logical offset once the body\n // has its new height.\n if ((wasScaled || this.#scale.scaled) && offset !== null && offset > 0) {\n this.#anchor = offset;\n }\n }\n }\n\n hostUpdated(): void {\n const anchor = this.#anchor;\n if (anchor === undefined) return;\n this.#anchor = undefined;\n if (this.#element) this.#write(this.#element, anchor);\n // The logical offset is the same, so the virtualizer sees no change; the\n // rows still have to move to the new physical one.\n this.#host.requestUpdate();\n }\n\n /**\n * Computes the rendered window and updates the pool. Call once per render.\n */\n computeWindow(): VirtualWindow {\n const v = this.#virtual.getVirtualizer();\n const items = v.getVirtualItems();\n // Scaled: rows render relative to the scroll position. The physical offset is\n // read now, so rows for the virtualizer's offset fill the view even if the\n // scroller has moved on since its last scroll event.\n const scaled = this.#scale.scaled;\n const size = this.#scale.size;\n const shift = scaled ? (v.scrollOffset ?? 0) - (this.#element?.scrollTop ?? 0) : 0;\n const byId = new Map<string, { index: number; start: number }>();\n for (const item of items) {\n byId.set(this.#config.rowIdAt(item.index), { index: item.index, start: item.start - shift });\n }\n const { keep, rowHeight } = this.#config;\n this.#pool.pin(keep?.id);\n if (keep && !byId.has(keep.id)) {\n // Fixed row heights: the virtualizer would place it here too. Scaled, it is\n // out of view: keep it inside the body (or just above it, under the header),\n // so it doesn't stretch the scroll range past the cap.\n const start = keep.index * rowHeight - shift;\n byId.set(keep.id, {\n index: keep.index,\n start: scaled ? Math.min(Math.max(start, -rowHeight), size) : start,\n });\n }\n const rows: WindowRow[] = [];\n for (const { id, slot } of this.#pool.update(byId.keys())) {\n const item = byId.get(id);\n if (item) rows.push({ slot, ...item });\n }\n const range = v.range;\n return {\n rows,\n totalSize: scaled ? size : v.getTotalSize(),\n range: range ? { start: range.startIndex, end: range.endIndex } : null,\n };\n }\n\n /** Number of pool slots created so far: bounded by the most rows rendered at once. */\n get poolSize(): number {\n return this.#pool.size;\n }\n\n /** Whether the body is taller than the cap and scrolls scaled. */\n get scaled(): boolean {\n return this.#scale.scaled;\n }\n\n /** `'start'` puts the row at the top; `'auto'` scrolls only as far as needed to show it. */\n scrollToIndex(index: number, align: 'start' | 'auto' = 'start'): void {\n this.#virtual.getVirtualizer().scrollToIndex(index, { align });\n }\n\n /** Scrolls by `delta` px of rows (logical px). */\n scrollBy(delta: number): void {\n const element = this.#element;\n if (element) this.#write(element, this.#top(element) + delta);\n }\n\n /**\n * Scrolls the least distance that shows row `index` in full, between the\n * content above the body (`before` px: the header and top pinned rows) and\n * below it (`after` px). Returns whether the rows are yet to move there (with\n * the update after the scroll event): until then the row's DOM isn't where it\n * will be.\n */\n reveal(index: number, before: number, after: number): boolean {\n const element = this.#element;\n if (!element) return false;\n const { rowHeight } = this.#config;\n const offset = this.#top(element);\n const view = element.clientHeight - before - after;\n const start = index * rowHeight;\n let target: number;\n let round: ((px: number) => number) | undefined;\n if (start < offset) {\n target = start;\n round = Math.floor;\n } else if (start + rowHeight > offset + view) {\n target = start + rowHeight - view;\n round = Math.ceil;\n } else {\n target = offset;\n }\n if (target !== offset) this.#write(element, target, undefined, round);\n // Rendered for an offset the scroller has since left: they move with the\n // update after the scroll event.\n return this.#virtual.getVirtualizer().scrollOffset !== this.#top(element);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"virtual-controller.js","names":[],"sources":["../../src/controllers/virtual-controller.ts"],"sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport { VirtualizerController } from '@tanstack/lit-virtual';\nimport { RowPool, ScrollScale, maxVisibleRows, steadyWindow } from '@argus-table/core';\n\n/** A rendered body row: its pool slot, its index in the row model and its offset. */\nexport interface WindowRow {\n slot: number;\n index: number;\n /** Offset in the rendered body, in px (scaled bodies: relative to the scroll position). */\n start: number;\n}\n\nexport interface VirtualWindow {\n /** Rendered rows, in pool order (ADR 0001 addendum). */\n rows: WindowRow[];\n /** Rendered height of the body in px: all rows, or the cap. */\n totalSize: number;\n /** Visible rows, without overscan; `null` before the first layout. */\n range: { start: number; end: number } | null;\n}\n\nexport interface VirtualConfig {\n count: number;\n rowHeight: number;\n overscan: number;\n /** Row id at an index of the row model; pool slots follow row ids. */\n rowIdAt: (index: number) => string;\n /**\n * The row to keep rendered outside the range (the one holding the grid's tab\n * stop), so its DOM and focus survive scrolling. `undefined`: none.\n */\n keep?: { id: string; index: number } | undefined;\n /** The tallest the body may render (`bodyCap()`); a taller one scrolls scaled. */\n cap: number;\n}\n\n/**\n * Row virtualization (TanStack Virtual) plus the row pool: which rows render,\n * where, and which pool slot's DOM each one uses. The virtualizer registers itself\n * with the host and requests updates on scroll.\n *\n * Scroll scaling: engines limit an element's height, so a body taller than the\n * cap 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\n * for the scroller whose `scrollTop`, `scrollHeight` and `scrollTo()` are\n * logical, and everything else passes through. Rows render relative to the\n * scroll position (`start` minus the difference between the logical and the\n * physical offset). Scroll through this controller (`scrollBy`, `reveal`,\n * `scrollToIndex`): physical px no longer match rows once the body is scaled.\n */\nexport class VirtualController implements ReactiveController {\n readonly #virtual: VirtualizerController<HTMLElement, Element>;\n readonly #pool = new RowPool();\n readonly #scale = new ScrollScale();\n readonly #host: ReactiveControllerHost;\n readonly #getScrollElement: () => HTMLElement | null;\n #element: HTMLElement | undefined;\n #standIn: HTMLElement | undefined;\n #config: VirtualConfig = {\n count: 0,\n rowHeight: 40,\n overscan: 6,\n rowIdAt: String,\n cap: Infinity,\n };\n /** A logical offset to restore after the update, once the body has its new height. */\n #anchor: number | undefined;\n\n constructor(host: ReactiveControllerHost, getScrollElement: () => HTMLElement | null) {\n this.#host = host;\n this.#getScrollElement = getScrollElement;\n this.#virtual = new VirtualizerController<HTMLElement, Element>(host, {\n count: 0,\n getScrollElement: () => this.#scroller(),\n // The real element: a ResizeObserver can't observe the stand-in.\n observeElementRect: (_instance, cb) => {\n const element = this.#element;\n if (!element) return undefined;\n const report = () => {\n cb({ width: element.clientWidth, height: element.clientHeight });\n };\n report();\n const observer = new ResizeObserver(report);\n observer.observe(element);\n return () => {\n observer.disconnect();\n };\n },\n estimateSize: () => this.#config.rowHeight,\n overscan: this.#config.overscan,\n // One window size from the first render: the pool never grows while scrolling\n // (in WebKit, new rows' slots would cut a wheel scroll short; see steadyWindow).\n rangeExtractor: (range) =>\n steadyWindow(\n range,\n maxVisibleRows(this.#element?.clientHeight ?? 0, this.#config.rowHeight),\n ),\n });\n host.addController(this);\n }\n\n /** The scroller's stand-in for the virtualizer: vertical offsets and height in logical px. */\n #scroller(): HTMLElement | null {\n const element = this.#getScrollElement();\n if (!element) return null;\n if (this.#element !== element || !this.#standIn) {\n this.#element = element;\n this.#standIn = new Proxy(element, {\n get: (target, key) => {\n if (key === 'scrollTop') return this.#top(target);\n if (key === 'scrollHeight') return target.scrollHeight + this.#scale.excess;\n if (key === 'scrollTo') {\n return (options: ScrollToOptions) => {\n if (options.top === undefined) target.scrollTo(options);\n else this.#write(target, options.top, options.behavior);\n };\n }\n const value: unknown = Reflect.get(target, key);\n // Methods run on the element itself (DOM methods reject the proxy).\n return typeof value === 'function'\n ? (value as (...args: unknown[]) => unknown).bind(target)\n : value;\n },\n });\n }\n return this.#standIn;\n }\n\n /** The scroller's logical offset. */\n #top(element: HTMLElement): number {\n const top = element.scrollTop;\n const scale = this.#scale;\n return scale.scaled ? scale.toLogical(top, element.scrollHeight - element.clientHeight) : top;\n }\n\n /**\n * Scrolls to a logical offset. `round` rounds the physical one, so that a\n * scaled offset moves the scroller at all.\n */\n #write(\n element: HTMLElement,\n logical: number,\n behavior?: ScrollBehavior,\n round?: (px: number) => number,\n ): void {\n const scale = this.#scale;\n if (!scale.scaled) {\n element.scrollTo({ top: logical, behavior });\n return;\n }\n const range = element.scrollHeight - element.clientHeight;\n const target = Math.min(Math.max(logical, 0), range + scale.excess);\n const physical = scale.toPhysical(target, range);\n element.scrollTo({ top: round ? round(physical) : physical, behavior });\n if (behavior !== 'smooth') scale.land(target, element.scrollTop);\n }\n\n configure(next: VirtualConfig): void {\n const prev = this.#config;\n this.#config = next;\n if (\n next.count !== prev.count ||\n next.overscan !== prev.overscan ||\n next.rowHeight !== prev.rowHeight\n ) {\n this.#virtual.setOptions({ count: next.count, overscan: next.overscan });\n if (next.rowHeight !== prev.rowHeight) this.#virtual.getVirtualizer().measure();\n }\n // Not `scaled`: TypeScript would take it for unchanged after `configure()`.\n const wasScaled = this.#scale.excess > 0;\n const offset = this.#virtual.getVirtualizer().scrollOffset;\n if (this.#scale.configure(next.count * next.rowHeight, next.cap)) {\n // A new mapping would move the rows under a scaled scroll position (a data\n // source growing, a zoom change): keep the logical offset once the body\n // has its new height.\n if ((wasScaled || this.#scale.scaled) && offset !== null && offset > 0) {\n this.#anchor = offset;\n }\n }\n }\n\n hostUpdated(): void {\n const anchor = this.#anchor;\n if (anchor === undefined) return;\n this.#anchor = undefined;\n if (this.#element) this.#write(this.#element, anchor);\n // The logical offset is the same, so the virtualizer sees no change; the\n // rows still have to move to the new physical one.\n this.#host.requestUpdate();\n }\n\n /**\n * Computes the rendered window and updates the pool. Call once per render.\n */\n computeWindow(): VirtualWindow {\n const v = this.#virtual.getVirtualizer();\n const items = v.getVirtualItems();\n // Scaled: rows render relative to the scroll position. The physical offset is\n // read now, so rows for the virtualizer's offset fill the view even if the\n // scroller has moved on since its last scroll event.\n const scaled = this.#scale.scaled;\n const size = this.#scale.size;\n const shift = scaled ? (v.scrollOffset ?? 0) - (this.#element?.scrollTop ?? 0) : 0;\n const byId = new Map<string, { index: number; start: number }>();\n for (const item of items) {\n byId.set(this.#config.rowIdAt(item.index), { index: item.index, start: item.start - shift });\n }\n const { keep, rowHeight } = this.#config;\n this.#pool.pin(keep?.id);\n if (keep && !byId.has(keep.id)) {\n // Fixed row heights: the virtualizer would place it here too. Scaled, it is\n // out of view: keep it inside the body (or just above it, under the header),\n // so it doesn't stretch the scroll range past the cap.\n const start = keep.index * rowHeight - shift;\n byId.set(keep.id, {\n index: keep.index,\n start: scaled ? Math.min(Math.max(start, -rowHeight), size) : start,\n });\n }\n const rows: WindowRow[] = [];\n for (const { id, slot } of this.#pool.update(byId.keys())) {\n const item = byId.get(id);\n if (item) rows.push({ slot, ...item });\n }\n const range = v.range;\n return {\n rows,\n totalSize: scaled ? size : v.getTotalSize(),\n range: range ? { start: range.startIndex, end: range.endIndex } : null,\n };\n }\n\n /** Number of pool slots created so far: bounded by the most rows rendered at once. */\n get poolSize(): number {\n return this.#pool.size;\n }\n\n /** Whether the body is taller than the cap and scrolls scaled. */\n get scaled(): boolean {\n return this.#scale.scaled;\n }\n\n /** `'start'` puts the row at the top; `'auto'` scrolls only as far as needed to show it. */\n scrollToIndex(index: number, align: 'start' | 'auto' = 'start'): void {\n this.#virtual.getVirtualizer().scrollToIndex(index, { align });\n }\n\n /** Scrolls by `delta` px of rows (logical px). */\n scrollBy(delta: number): void {\n const element = this.#element;\n if (element) this.#write(element, this.#top(element) + delta);\n }\n\n /** Scrolls to the start or the end of the body. */\n scrollToEdge(edge: 'start' | 'end'): void {\n const element = this.#element;\n // The end: #write clamps to the last logical offset.\n if (element) this.#write(element, edge === 'start' ? 0 : Number.MAX_SAFE_INTEGER);\n }\n\n /**\n * Scrolls the least distance that shows row `index` in full, between the\n * content above the body (`before` px: the header and top pinned rows) and\n * below it (`after` px). Returns whether the rows are yet to move there (with\n * the update after the scroll event): until then the row's DOM isn't where it\n * will be.\n */\n reveal(index: number, before: number, after: number): boolean {\n const element = this.#element;\n if (!element) return false;\n const { rowHeight } = this.#config;\n const offset = this.#top(element);\n const view = element.clientHeight - before - after;\n const start = index * rowHeight;\n let target: number;\n let round: ((px: number) => number) | undefined;\n if (start < offset) {\n target = start;\n round = Math.floor;\n } else if (start + rowHeight > offset + view) {\n target = start + rowHeight - view;\n round = Math.ceil;\n } else {\n target = offset;\n }\n if (target !== offset) this.#write(element, target, undefined, round);\n // Rendered for an offset the scroller has since left: they move with the\n // update after the scroll event.\n return this.#virtual.getVirtualizer().scrollOffset !== this.#top(element);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// ../core/src/virtual/steady-window.ts
|
|
2
|
+
/**
|
|
3
|
+
* The most rows of `rowHeight` px a view `viewHeight` px tall can show at once,
|
|
4
|
+
* partly: one more than fit, when the view starts inside a row.
|
|
5
|
+
*/
|
|
6
|
+
function maxVisibleRows(viewHeight, rowHeight) {
|
|
7
|
+
return viewHeight > 0 && rowHeight > 0 ? Math.ceil(viewHeight / rowHeight) + 1 : 0;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The row indexes to render: the visible rows plus `overscan` on each side,
|
|
11
|
+
* always the same number of rows (`maxVisible` plus twice the overscan, or all
|
|
12
|
+
* rows when there are fewer). At either end the overscan that has no room goes to
|
|
13
|
+
* the other side.
|
|
14
|
+
*
|
|
15
|
+
* The usual window is cut off at the ends instead: at the top it holds only the
|
|
16
|
+
* overscan below, and the row pool grows by a row, its cells and their slots,
|
|
17
|
+
* with every row scrolled until the overscan above is full. WebKit cancels a
|
|
18
|
+
* wheel scroll's animation when slot assignment changes inside the scroller, so
|
|
19
|
+
* from the top each wheel step moved a few px instead of a full step. A window of
|
|
20
|
+
* one size fills the pool on the first render, and scrolling only reuses it.
|
|
21
|
+
*/
|
|
22
|
+
function steadyWindow({ startIndex, endIndex, overscan, count }, maxVisible) {
|
|
23
|
+
const visible = Math.max(maxVisible, endIndex - startIndex + 1);
|
|
24
|
+
const size = Math.min(count, visible + 2 * overscan);
|
|
25
|
+
const first = Math.max(0, Math.min(startIndex - overscan, count - size));
|
|
26
|
+
return Array.from({ length: size }, (_, i) => first + i);
|
|
27
|
+
}
|
|
28
|
+
export { maxVisibleRows, steadyWindow };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=steady-window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steady-window.js","names":[],"sources":["../../../../../core/src/virtual/steady-window.ts"],"sourcesContent":["/** The visible rows as the virtualizer reports them: indexes inclusive. */\nexport interface VisibleRange {\n startIndex: number;\n endIndex: number;\n overscan: number;\n count: number;\n}\n\n/**\n * The most rows of `rowHeight` px a view `viewHeight` px tall can show at once,\n * partly: one more than fit, when the view starts inside a row.\n */\nexport function maxVisibleRows(viewHeight: number, rowHeight: number): number {\n return viewHeight > 0 && rowHeight > 0 ? Math.ceil(viewHeight / rowHeight) + 1 : 0;\n}\n\n/**\n * The row indexes to render: the visible rows plus `overscan` on each side,\n * always the same number of rows (`maxVisible` plus twice the overscan, or all\n * rows when there are fewer). At either end the overscan that has no room goes to\n * the other side.\n *\n * The usual window is cut off at the ends instead: at the top it holds only the\n * overscan below, and the row pool grows by a row, its cells and their slots,\n * with every row scrolled until the overscan above is full. WebKit cancels a\n * wheel scroll's animation when slot assignment changes inside the scroller, so\n * from the top each wheel step moved a few px instead of a full step. A window of\n * one size fills the pool on the first render, and scrolling only reuses it.\n */\nexport function steadyWindow(\n { startIndex, endIndex, overscan, count }: VisibleRange,\n maxVisible: number,\n): number[] {\n const visible = Math.max(maxVisible, endIndex - startIndex + 1);\n const size = Math.min(count, visible + 2 * overscan);\n const first = Math.max(0, Math.min(startIndex - overscan, count - size));\n return Array.from({ length: size }, (_, i) => first + i);\n}\n"],"mappings":";;;;;AAYA,SAAgB,eAAe,YAAoB,WAA2B;CAC5E,OAAO,aAAa,KAAK,YAAY,IAAI,KAAK,KAAK,aAAa,SAAS,IAAI,IAAI;AACnF;;;;;;;;;;;;;;AAeA,SAAgB,aACd,EAAE,YAAY,UAAU,UAAU,SAClC,YACU;CACV,MAAM,UAAU,KAAK,IAAI,YAAY,WAAW,aAAa,CAAC;CAC9D,MAAM,OAAO,KAAK,IAAI,OAAO,UAAU,IAAI,QAAQ;CACnD,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,aAAa,UAAU,QAAQ,IAAI,CAAC;CACvE,OAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,QAAQ,CAAC;AACzD"}
|
|
@@ -2042,6 +2042,24 @@
|
|
|
2042
2042
|
],
|
|
2043
2043
|
"description": "Scrolls by `delta` px of rows (logical px)."
|
|
2044
2044
|
},
|
|
2045
|
+
{
|
|
2046
|
+
"kind": "method",
|
|
2047
|
+
"name": "scrollToEdge",
|
|
2048
|
+
"return": {
|
|
2049
|
+
"type": {
|
|
2050
|
+
"text": "void"
|
|
2051
|
+
}
|
|
2052
|
+
},
|
|
2053
|
+
"parameters": [
|
|
2054
|
+
{
|
|
2055
|
+
"name": "edge",
|
|
2056
|
+
"type": {
|
|
2057
|
+
"text": "'start' | 'end'"
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
],
|
|
2061
|
+
"description": "Scrolls to the start or the end of the body."
|
|
2062
|
+
},
|
|
2045
2063
|
{
|
|
2046
2064
|
"kind": "method",
|
|
2047
2065
|
"name": "reveal",
|
|
@@ -2086,28 +2104,6 @@
|
|
|
2086
2104
|
}
|
|
2087
2105
|
]
|
|
2088
2106
|
},
|
|
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
2107
|
{
|
|
2112
2108
|
"kind": "javascript-module",
|
|
2113
2109
|
"path": "src/render/body.ts",
|
|
@@ -2587,6 +2583,28 @@
|
|
|
2587
2583
|
}
|
|
2588
2584
|
}
|
|
2589
2585
|
]
|
|
2586
|
+
},
|
|
2587
|
+
{
|
|
2588
|
+
"kind": "javascript-module",
|
|
2589
|
+
"path": "src/styles/base.ts",
|
|
2590
|
+
"declarations": [
|
|
2591
|
+
{
|
|
2592
|
+
"kind": "variable",
|
|
2593
|
+
"name": "baseStyles",
|
|
2594
|
+
"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)); } /* * 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; } } `",
|
|
2595
|
+
"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."
|
|
2596
|
+
}
|
|
2597
|
+
],
|
|
2598
|
+
"exports": [
|
|
2599
|
+
{
|
|
2600
|
+
"kind": "js",
|
|
2601
|
+
"name": "baseStyles",
|
|
2602
|
+
"declaration": {
|
|
2603
|
+
"name": "baseStyles",
|
|
2604
|
+
"module": "src/styles/base.ts"
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
]
|
|
2590
2608
|
}
|
|
2591
2609
|
]
|
|
2592
2610
|
}
|
package/dist/styles/base.js
CHANGED
|
@@ -5,7 +5,7 @@ import { css } from "lit";
|
|
|
5
5
|
* public token with a neutral fallback, so themes and page CSS always win.
|
|
6
6
|
* `--_*` properties are private.
|
|
7
7
|
*/
|
|
8
|
-
var baseStyles = css`@layer argus-base{:host{box-sizing:border-box;contain:content;color-scheme:light dark;block-size:400px;color:var(--argus-fg,CanvasText);background:var(--argus-bg,Canvas);font:var(--argus-font,inherit);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));--_dir:1;display:block}: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]{overscroll-behavior:contain;block-size:100%;scroll-
|
|
8
|
+
var baseStyles = css`@layer argus-base{:host{box-sizing:border-box;contain:content;color-scheme:light dark;block-size:400px;color:var(--argus-fg,CanvasText);background:var(--argus-bg,Canvas);font:var(--argus-font,inherit);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));--_dir:1;display:block}: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]{overscroll-behavior:contain;block-size:100%;position:relative;overflow:auto}[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{grid-template-columns:var(--_cols);inline-size:var(--_width);min-inline-size:100%;block-size:var(--_row-height);box-sizing:border-box;display:grid}[part~=header]{z-index:2;position:sticky;inset-block-start:0}[part~=body]{contain:layout;position:relative}[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{z-index:2;position:sticky}.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]{box-sizing:border-box;min-inline-size:0;padding-inline:var(--_pad);white-space:nowrap;border-block-end:var(--_border);align-items:center;display:flex;overflow:hidden}[part~=header-cell]{background:var(--argus-header-bg,light-dark(#f9fafb,#111827));color:var(--argus-header-fg,inherit);font-weight:600;position:relative}[part~=resize-handle]{z-index:1;cursor:col-resize;touch-action:none;inline-size:8px;position:absolute;inset-block:0;inset-inline-end:0}[part~=resize-handle]:after{content:"";background:var(--argus-resize-handle-color,light-dark(#9ca3af,#6b7280));opacity:0;inline-size:2px;position:absolute;inset-block:25%;inset-inline-end: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}[data-move-col]{user-select:none}[data-dragging],[data-dragging] [part~=header-cell]{cursor:grabbing}[part~=header-cell-dragging]{opacity:.5}[part~=drop-indicator]{z-index:2;background:var(--argus-drop-indicator-color,Highlight);pointer-events:none;inline-size:2px;position:absolute;inset-block:0}[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}.sort-indicator{visibility:hidden;border-bottom:.12em solid;border-right:.12em solid;flex:none;block-size:.35em;inline-size:.35em;margin-inline-start:.4em}[aria-sort] .sort-indicator{visibility:visible}[aria-sort=ascending] .sort-indicator{transform:translateY(.1em)rotate(-135deg)}[aria-sort=descending] .sort-indicator{transform:translateY(-.1em)rotate(45deg)}[data-align=end] .sort-indicator{order:-1;margin-inline:0 .4em}[data-pin]{z-index:1;position:sticky}[data-pin=start]{inset-inline-start:var(--_pin-offset)}[data-pin=end]{inset-inline-end:var(--_pin-offset)}[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)}.pin-shadow{block-size:min(var(--_view-h,100%), var(--_content-h,100%));z-index:3;pointer-events:none;position:absolute;inset-block-start:0}.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:"";box-shadow:var(--argus-pinned-shadow,4px 0 6px -4px light-dark(#0003,#0009));transform:scaleX(var(--_dir));position:absolute;inset:0}.pin-shadow[data-side=end]:after{transform:scaleX(calc(-1 * var(--_dir)))}[data-align=center]{text-align:center;justify-content:center}[data-align=end]{text-align:end;justify-content:flex-end}::slotted(*){text-overflow:ellipsis;min-inline-size:0;overflow:hidden}[data-measure]{inline-size:max-content}[part~=skeleton]{background:var(--argus-skeleton-bg,color-mix(in srgb, currentColor 12%, transparent));border-radius:.3em;flex:none;block-size:.6em;inline-size:min(60%,8em);animation:1.6s ease-in-out infinite argus-skeleton-pulse}[part~=skeleton-error]{opacity:.5;animation:none}@keyframes argus-skeleton-pulse{50%{opacity:.45}}@media (prefers-reduced-motion:reduce){[part~=skeleton]{animation:none}}[part~=retry]{font:inherit;color:inherit;cursor:pointer}[part~=empty]{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;justify-content:center;align-items:center;display:flex}.probe{inline-size:0;block-size:var(--_row-height);visibility:hidden;pointer-events:none;position:absolute;inset-block-start:0}}`;
|
|
9
9
|
export { baseStyles };
|
|
10
10
|
|
|
11
11
|
//# sourceMappingURL=base.js.map
|
package/dist/styles/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[],"sources":["../../src/styles/base.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Base styles. Everything sits in `@layer argus-base`, and every value reads a\n * public token with a neutral fallback, so themes and page CSS always win.\n * `--_*` properties are private.\n */\nexport const baseStyles = css`\n @layer argus-base {\n :host {\n display: block;\n /* A table that virtualizes needs a bounded height; set your own on the element. */\n block-size: 400px;\n box-sizing: border-box;\n contain: content;\n color-scheme: light dark;\n color: var(--argus-fg, CanvasText);\n background: var(--argus-bg, Canvas);\n font: var(--argus-font, inherit);\n /* contain: content clips the header, rows and pinned shadows to the rounded corners. */\n border: var(--argus-outline, none);\n border-radius: var(--argus-radius, 0);\n --_row-height: var(--argus-row-height, 40px);\n --_pad: var(--argus-cell-padding-inline, 12px);\n --_border: var(--argus-border-width, 1px) solid\n var(--argus-border-color, light-dark(#e5e7eb, #374151));\n /* 1 in LTR, -1 in RTL: mirrors the pinned-edge shadow. */\n --_dir: 1;\n }\n :host(:dir(rtl)) {\n --_dir: -1;\n }\n :host([density='compact']) {\n --_row-height: var(--argus-row-height, 32px);\n --_pad: var(--argus-cell-padding-inline, 8px);\n }\n :host([density='spacious']) {\n --_row-height: var(--argus-row-height, 52px);\n --_pad: var(--argus-cell-padding-inline, 16px);\n }\n :host([hidden]) {\n display: none;\n }\n\n [part~='table'] {\n position: relative;\n block-size: 100%;\n overflow: auto;\n overscroll-behavior: contain;\n /*\n * A cell moved to by keyboard scrolls clear of the sticky header, the pinned\n * rows and the pinned columns.\n */\n scroll-padding-block-start: calc((1 + var(--_pin-top-rows, 0)) * var(--_row-height));\n scroll-padding-block-end: calc(var(--_pin-bottom-rows, 0) * var(--_row-height));\n scroll-padding-inline: var(--_pin-start, 0) var(--_pin-end, 0);\n }\n\n .row {\n display: grid;\n grid-template-columns: var(--_cols);\n inline-size: var(--_width);\n min-inline-size: 100%;\n block-size: var(--_row-height);\n box-sizing: border-box;\n }\n\n [part~='header'] {\n position: sticky;\n inset-block-start: 0;\n z-index: 2;\n }\n\n [part~='body'] {\n position: relative;\n contain: layout;\n }\n [part~='body'] > .row {\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n }\n [part~='row'] {\n --_row-bg: var(--argus-bg, Canvas);\n --_row-surface: var(--_row-bg);\n background: var(--_row-surface);\n }\n [part~='row-odd'] {\n --_row-bg: var(--argus-row-stripe-bg, var(--argus-bg, Canvas));\n }\n [part~='row']:hover {\n --_row-surface: var(--argus-row-hover-bg, var(--_row-bg));\n }\n\n /*\n * Pinned rows: a sticky row group below the header and one at the bottom of\n * the view. The header is one row tall. They keep their place in the flow,\n * so body row i still starts i rows below the top group.\n */\n .pinned {\n position: sticky;\n z-index: 2;\n }\n .pinned[data-side='top'] {\n inset-block-start: var(--_row-height);\n }\n .pinned[data-side='bottom'] {\n inset-block-end: 0;\n }\n [part~='row-pinned'] {\n --_row-bg: var(--argus-pinned-row-bg, var(--argus-bg, Canvas));\n }\n\n [part~='cell'],\n [part~='header-cell'] {\n display: flex;\n align-items: center;\n min-inline-size: 0;\n box-sizing: border-box;\n padding-inline: var(--_pad);\n overflow: hidden;\n white-space: nowrap;\n border-block-end: var(--_border);\n }\n [part~='header-cell'] {\n background: var(--argus-header-bg, light-dark(#f9fafb, #111827));\n color: var(--argus-header-fg, inherit);\n font-weight: 600;\n }\n [part~='header-cell'] {\n position: relative;\n }\n [part~='resize-handle'] {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n inline-size: 8px;\n z-index: 1;\n cursor: col-resize;\n touch-action: none;\n }\n [part~='resize-handle']::after {\n content: '';\n position: absolute;\n inset-block: 25%;\n inset-inline-end: 0;\n inline-size: 2px;\n background: var(--argus-resize-handle-color, light-dark(#9ca3af, #6b7280));\n opacity: 0;\n }\n [part~='header-cell']:hover [part~='resize-handle']::after,\n [part~='header-cell']:focus-visible [part~='resize-handle']::after,\n [part~='resize-handle'][data-active]::after {\n opacity: 1;\n }\n [data-sort-col] {\n cursor: pointer;\n user-select: none;\n }\n /* A drag on a reorderable header moves the column, so its text isn't selectable. */\n [data-move-col] {\n user-select: none;\n }\n [data-dragging],\n [data-dragging] [part~='header-cell'] {\n cursor: grabbing;\n }\n [part~='header-cell-dragging'] {\n opacity: 0.5;\n }\n /* The line where a dragged column would land, on the target header's logical edge. */\n [part~='drop-indicator'] {\n position: absolute;\n inset-block: 0;\n inline-size: 2px;\n z-index: 2;\n background: var(--argus-drop-indicator-color, Highlight);\n pointer-events: none;\n }\n [part~='drop-indicator'][data-edge='start'] {\n inset-inline-start: 0;\n }\n [part~='drop-indicator'][data-edge='end'] {\n inset-inline-end: 0;\n }\n [part~='header-cell']:focus-visible,\n [part~='cell']:focus-visible {\n outline: var(--argus-focus-ring, 2px solid Highlight);\n outline-offset: -2px;\n }\n /* A small chevron after the header content; only the sorted column shows it. */\n .sort-indicator {\n flex: none;\n inline-size: 0.35em;\n block-size: 0.35em;\n margin-inline-start: 0.4em;\n /* Physical sides on purpose: the chevron is rotated, so it must not mirror in RTL. */\n border-right: 0.12em solid currentColor;\n border-bottom: 0.12em solid currentColor;\n visibility: hidden;\n }\n [aria-sort] .sort-indicator {\n visibility: visible;\n }\n [aria-sort='ascending'] .sort-indicator {\n transform: translateY(0.1em) rotate(-135deg);\n }\n [aria-sort='descending'] .sort-indicator {\n transform: translateY(-0.1em) rotate(45deg);\n }\n [data-align='end'] .sort-indicator {\n order: -1;\n margin-inline: 0 0.4em;\n }\n /*\n * Pinned columns: sticky inside the scroll container, with offsets from the\n * table model. Logical insets make RTL work without extra rules.\n */\n [data-pin] {\n position: sticky;\n z-index: 1;\n }\n [data-pin='start'] {\n inset-inline-start: var(--_pin-offset);\n }\n [data-pin='end'] {\n inset-inline-end: var(--_pin-offset);\n }\n /*\n * Pinned body cells are sticky only while the table scrolls sideways\n * (data-hscroll on the scroller). At rest they are plain cells shifted by the\n * horizontal scroll offset, which vertical scrolling never changes: a sticky\n * cell per row is a compositing layer each, and Safari stutters moving them\n * (PinScrollController). Both place the cells at the same spot.\n */\n [part~='row'] > [data-pin] {\n position: relative;\n inset-inline: auto;\n }\n [part~='row'] > [data-pin='start'] {\n transform: translateX(var(--_sx, 0px));\n }\n [part~='row'] > [data-pin='end'] {\n transform: translateX(calc(var(--_sx, 0px) - var(--_dir) * var(--_max-x, 0px)));\n }\n [data-hscroll] [part~='row'] > [data-pin] {\n position: sticky;\n transform: none;\n }\n [data-hscroll] [part~='row'] > [data-pin='start'] {\n inset-inline-start: var(--_pin-offset);\n }\n [data-hscroll] [part~='row'] > [data-pin='end'] {\n inset-inline-end: var(--_pin-offset);\n }\n [part~='cell-pinned'] {\n background: var(--_row-surface);\n }\n /*\n * The edge shadow, once per pinned side (.pin-shadow, beside the scroller).\n * --argus-pinned-shadow is written for a shadow falling toward the end side;\n * the start edge in RTL and the end edge in LTR mirror it.\n */\n .pin-shadow {\n position: absolute;\n inset-block-start: 0;\n block-size: min(var(--_view-h, 100%), var(--_content-h, 100%));\n z-index: 3;\n pointer-events: none;\n }\n .pin-shadow[data-side='start'] {\n inset-inline-start: 0;\n }\n .pin-shadow[data-side='end'] {\n inset-inline-end: var(--_sb-x, 0px);\n }\n .pin-shadow::after {\n content: '';\n position: absolute;\n inset: 0;\n box-shadow: var(\n --argus-pinned-shadow,\n 4px 0 6px -4px light-dark(rgb(0 0 0 / 0.2), rgb(0 0 0 / 0.6))\n );\n transform: scaleX(var(--_dir));\n }\n .pin-shadow[data-side='end']::after {\n transform: scaleX(calc(-1 * var(--_dir)));\n }\n\n [data-align='center'] {\n justify-content: center;\n text-align: center;\n }\n [data-align='end'] {\n justify-content: flex-end;\n text-align: end;\n }\n ::slotted(*) {\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n /* Fitting a column to its content: set for one synchronous measurement, never painted. */\n [data-measure] {\n inline-size: max-content;\n }\n\n /* Rows of a data source that haven't loaded: a bar per cell, pulsing gently. */\n [part~='skeleton'] {\n flex: none;\n inline-size: min(60%, 8em);\n block-size: 0.6em;\n border-radius: 0.3em;\n background: var(--argus-skeleton-bg, color-mix(in srgb, currentColor 12%, transparent));\n animation: argus-skeleton-pulse 1.6s ease-in-out infinite;\n }\n [part~='skeleton-error'] {\n animation: none;\n opacity: 0.5;\n }\n @keyframes argus-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n [part~='skeleton'] {\n animation: none;\n }\n }\n [part~='retry'] {\n font: inherit;\n color: inherit;\n cursor: pointer;\n }\n\n [part~='empty'] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-block-size: calc(\n 100% - (1 + var(--_pin-top-rows, 0) + var(--_pin-bottom-rows, 0)) * var(--_row-height)\n );\n padding: var(--_pad);\n box-sizing: border-box;\n }\n\n /* Measures the resolved row height in px for the virtualizer. */\n .probe {\n position: absolute;\n inset-block-start: 0;\n inline-size: 0;\n block-size: var(--_row-height);\n visibility: hidden;\n pointer-events: none;\n }\n }\n`;\n"],"mappings":";;;;;;;AAOA,IAAa,aAAa,GAAG"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../src/styles/base.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Base styles. Everything sits in `@layer argus-base`, and every value reads a\n * public token with a neutral fallback, so themes and page CSS always win.\n * `--_*` properties are private.\n */\nexport const baseStyles = css`\n @layer argus-base {\n :host {\n display: block;\n /* A table that virtualizes needs a bounded height; set your own on the element. */\n block-size: 400px;\n box-sizing: border-box;\n contain: content;\n color-scheme: light dark;\n color: var(--argus-fg, CanvasText);\n background: var(--argus-bg, Canvas);\n font: var(--argus-font, inherit);\n /* contain: content clips the header, rows and pinned shadows to the rounded corners. */\n border: var(--argus-outline, none);\n border-radius: var(--argus-radius, 0);\n --_row-height: var(--argus-row-height, 40px);\n --_pad: var(--argus-cell-padding-inline, 12px);\n --_border: var(--argus-border-width, 1px) solid\n var(--argus-border-color, light-dark(#e5e7eb, #374151));\n /* 1 in LTR, -1 in RTL: mirrors the pinned-edge shadow. */\n --_dir: 1;\n }\n :host(:dir(rtl)) {\n --_dir: -1;\n }\n :host([density='compact']) {\n --_row-height: var(--argus-row-height, 32px);\n --_pad: var(--argus-cell-padding-inline, 8px);\n }\n :host([density='spacious']) {\n --_row-height: var(--argus-row-height, 52px);\n --_pad: var(--argus-cell-padding-inline, 16px);\n }\n :host([hidden]) {\n display: none;\n }\n\n [part~='table'] {\n position: relative;\n block-size: 100%;\n overflow: auto;\n overscroll-behavior: contain;\n }\n\n /*\n * A cell focused or moved to by keyboard scrolls clear of the sticky header, the\n * pinned rows and the pinned columns: scroll margins on the cells that scroll.\n * Not scroll padding on the scroller: Chromium and WebKit measure the sticky\n * header and pinned rows against it too, so focusing one of them (a click, Tab,\n * an arrow key) scrolled the body.\n */\n [part~='body'] > .row > [role='gridcell'] {\n scroll-margin-block: calc((1 + var(--_pin-top-rows, 0)) * var(--_row-height))\n calc(var(--_pin-bottom-rows, 0) * var(--_row-height));\n }\n [role='gridcell']:not([data-pin]),\n [role='columnheader']:not([data-pin]) {\n scroll-margin-inline: var(--_pin-start, 0) var(--_pin-end, 0);\n }\n\n .row {\n display: grid;\n grid-template-columns: var(--_cols);\n inline-size: var(--_width);\n min-inline-size: 100%;\n block-size: var(--_row-height);\n box-sizing: border-box;\n }\n\n [part~='header'] {\n position: sticky;\n inset-block-start: 0;\n z-index: 2;\n }\n\n [part~='body'] {\n position: relative;\n contain: layout;\n }\n [part~='body'] > .row {\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n }\n [part~='row'] {\n --_row-bg: var(--argus-bg, Canvas);\n --_row-surface: var(--_row-bg);\n background: var(--_row-surface);\n }\n [part~='row-odd'] {\n --_row-bg: var(--argus-row-stripe-bg, var(--argus-bg, Canvas));\n }\n [part~='row']:hover {\n --_row-surface: var(--argus-row-hover-bg, var(--_row-bg));\n }\n\n /*\n * Pinned rows: a sticky row group below the header and one at the bottom of\n * the view. The header is one row tall. They keep their place in the flow,\n * so body row i still starts i rows below the top group.\n */\n .pinned {\n position: sticky;\n z-index: 2;\n }\n .pinned[data-side='top'] {\n inset-block-start: var(--_row-height);\n }\n .pinned[data-side='bottom'] {\n inset-block-end: 0;\n }\n [part~='row-pinned'] {\n --_row-bg: var(--argus-pinned-row-bg, var(--argus-bg, Canvas));\n }\n\n [part~='cell'],\n [part~='header-cell'] {\n display: flex;\n align-items: center;\n min-inline-size: 0;\n box-sizing: border-box;\n padding-inline: var(--_pad);\n overflow: hidden;\n white-space: nowrap;\n border-block-end: var(--_border);\n }\n [part~='header-cell'] {\n background: var(--argus-header-bg, light-dark(#f9fafb, #111827));\n color: var(--argus-header-fg, inherit);\n font-weight: 600;\n }\n [part~='header-cell'] {\n position: relative;\n }\n [part~='resize-handle'] {\n position: absolute;\n inset-block: 0;\n inset-inline-end: 0;\n inline-size: 8px;\n z-index: 1;\n cursor: col-resize;\n touch-action: none;\n }\n [part~='resize-handle']::after {\n content: '';\n position: absolute;\n inset-block: 25%;\n inset-inline-end: 0;\n inline-size: 2px;\n background: var(--argus-resize-handle-color, light-dark(#9ca3af, #6b7280));\n opacity: 0;\n }\n [part~='header-cell']:hover [part~='resize-handle']::after,\n [part~='header-cell']:focus-visible [part~='resize-handle']::after,\n [part~='resize-handle'][data-active]::after {\n opacity: 1;\n }\n [data-sort-col] {\n cursor: pointer;\n user-select: none;\n }\n /* A drag on a reorderable header moves the column, so its text isn't selectable. */\n [data-move-col] {\n user-select: none;\n }\n [data-dragging],\n [data-dragging] [part~='header-cell'] {\n cursor: grabbing;\n }\n [part~='header-cell-dragging'] {\n opacity: 0.5;\n }\n /* The line where a dragged column would land, on the target header's logical edge. */\n [part~='drop-indicator'] {\n position: absolute;\n inset-block: 0;\n inline-size: 2px;\n z-index: 2;\n background: var(--argus-drop-indicator-color, Highlight);\n pointer-events: none;\n }\n [part~='drop-indicator'][data-edge='start'] {\n inset-inline-start: 0;\n }\n [part~='drop-indicator'][data-edge='end'] {\n inset-inline-end: 0;\n }\n [part~='header-cell']:focus-visible,\n [part~='cell']:focus-visible {\n outline: var(--argus-focus-ring, 2px solid Highlight);\n outline-offset: -2px;\n }\n /* A small chevron after the header content; only the sorted column shows it. */\n .sort-indicator {\n flex: none;\n inline-size: 0.35em;\n block-size: 0.35em;\n margin-inline-start: 0.4em;\n /* Physical sides on purpose: the chevron is rotated, so it must not mirror in RTL. */\n border-right: 0.12em solid currentColor;\n border-bottom: 0.12em solid currentColor;\n visibility: hidden;\n }\n [aria-sort] .sort-indicator {\n visibility: visible;\n }\n [aria-sort='ascending'] .sort-indicator {\n transform: translateY(0.1em) rotate(-135deg);\n }\n [aria-sort='descending'] .sort-indicator {\n transform: translateY(-0.1em) rotate(45deg);\n }\n [data-align='end'] .sort-indicator {\n order: -1;\n margin-inline: 0 0.4em;\n }\n /*\n * Pinned columns: sticky inside the scroll container, with offsets from the\n * table model. Logical insets make RTL work without extra rules.\n */\n [data-pin] {\n position: sticky;\n z-index: 1;\n }\n [data-pin='start'] {\n inset-inline-start: var(--_pin-offset);\n }\n [data-pin='end'] {\n inset-inline-end: var(--_pin-offset);\n }\n /*\n * Pinned body cells are sticky only while the table scrolls sideways\n * (data-hscroll on the scroller). At rest they are plain cells shifted by the\n * horizontal scroll offset, which vertical scrolling never changes: a sticky\n * cell per row is a compositing layer each, and Safari stutters moving them\n * (PinScrollController). Both place the cells at the same spot.\n */\n [part~='row'] > [data-pin] {\n position: relative;\n inset-inline: auto;\n }\n [part~='row'] > [data-pin='start'] {\n transform: translateX(var(--_sx, 0px));\n }\n [part~='row'] > [data-pin='end'] {\n transform: translateX(calc(var(--_sx, 0px) - var(--_dir) * var(--_max-x, 0px)));\n }\n [data-hscroll] [part~='row'] > [data-pin] {\n position: sticky;\n transform: none;\n }\n [data-hscroll] [part~='row'] > [data-pin='start'] {\n inset-inline-start: var(--_pin-offset);\n }\n [data-hscroll] [part~='row'] > [data-pin='end'] {\n inset-inline-end: var(--_pin-offset);\n }\n [part~='cell-pinned'] {\n background: var(--_row-surface);\n }\n /*\n * The edge shadow, once per pinned side (.pin-shadow, beside the scroller).\n * --argus-pinned-shadow is written for a shadow falling toward the end side;\n * the start edge in RTL and the end edge in LTR mirror it.\n */\n .pin-shadow {\n position: absolute;\n inset-block-start: 0;\n block-size: min(var(--_view-h, 100%), var(--_content-h, 100%));\n z-index: 3;\n pointer-events: none;\n }\n .pin-shadow[data-side='start'] {\n inset-inline-start: 0;\n }\n .pin-shadow[data-side='end'] {\n inset-inline-end: var(--_sb-x, 0px);\n }\n .pin-shadow::after {\n content: '';\n position: absolute;\n inset: 0;\n box-shadow: var(\n --argus-pinned-shadow,\n 4px 0 6px -4px light-dark(rgb(0 0 0 / 0.2), rgb(0 0 0 / 0.6))\n );\n transform: scaleX(var(--_dir));\n }\n .pin-shadow[data-side='end']::after {\n transform: scaleX(calc(-1 * var(--_dir)));\n }\n\n [data-align='center'] {\n justify-content: center;\n text-align: center;\n }\n [data-align='end'] {\n justify-content: flex-end;\n text-align: end;\n }\n ::slotted(*) {\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n /* Fitting a column to its content: set for one synchronous measurement, never painted. */\n [data-measure] {\n inline-size: max-content;\n }\n\n /* Rows of a data source that haven't loaded: a bar per cell, pulsing gently. */\n [part~='skeleton'] {\n flex: none;\n inline-size: min(60%, 8em);\n block-size: 0.6em;\n border-radius: 0.3em;\n background: var(--argus-skeleton-bg, color-mix(in srgb, currentColor 12%, transparent));\n animation: argus-skeleton-pulse 1.6s ease-in-out infinite;\n }\n [part~='skeleton-error'] {\n animation: none;\n opacity: 0.5;\n }\n @keyframes argus-skeleton-pulse {\n 50% {\n opacity: 0.45;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n [part~='skeleton'] {\n animation: none;\n }\n }\n [part~='retry'] {\n font: inherit;\n color: inherit;\n cursor: pointer;\n }\n\n [part~='empty'] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-block-size: calc(\n 100% - (1 + var(--_pin-top-rows, 0) + var(--_pin-bottom-rows, 0)) * var(--_row-height)\n );\n padding: var(--_pad);\n box-sizing: border-box;\n }\n\n /* Measures the resolved row height in px for the virtualizer. */\n .probe {\n position: absolute;\n inset-block-start: 0;\n inline-size: 0;\n block-size: var(--_row-height);\n visibility: hidden;\n pointer-events: none;\n }\n }\n`;\n"],"mappings":";;;;;;;AAOA,IAAa,aAAa,GAAG"}
|