import React from "react"; import { XmDataTable as XmDataTableElement, CustomEvent, } from "../lit/components/data-table/index.js"; /** * A generic type for strongly typing custom events with their targets * @template T - The type of the event target (extends EventTarget) * @template D - The type of the detail payload for the custom event */ type TypedEvent = E & { target: T; }; /** `XmDataTable` component event */ export type XmDataTableElementEvent = TypedEvent< XmDataTableElement, E >; export type { XmDataTableElement, CustomEvent }; export interface XmDataTableProps extends Pick< React.AllHTMLAttributes, | "children" | "dir" | "hidden" | "id" | "lang" | "slot" | "style" | "title" | "translate" | "onClick" | "onFocus" | "onBlur" > { /** undefined */ loading?: boolean; /** Server/controlled mode (AD-14): the consumer owns sort + paging. The table renders `rows` verbatim, never sorts/slices a copy, derives the page count from `total-items` (not `rows.length`), and emits intents only. */ server?: boolean; /** Make rows clickable — emits xm-data-table-row-click (AD-15). */ rowClick?: boolean; /** Pin the header rows while the table body scrolls inside the frame. Pair with `max-height` (or a host height) so the frame actually scrolls. */ stickyHeader?: boolean; /** Stretch the frame to fill the host's full height instead of collapsing to content height. Pair with `sticky-header` and a definite-height host so the table reaches the bottom edge and the scrollbar pins there even when the rows don't fill the viewport. */ fill?: boolean; /** Drop the frame's hairline border + corner radius for edge-to-edge embedding (the frame becomes flush with its container). */ flush?: boolean; /** Enable per-row expansion (ADR 0019): adds a leading expander column whose chevron button toggles an in-place detail row under its data row. */ expandable?: boolean; /** Keep the action rail visible at rest instead of revealing it on hover. */ actionsAlways?: boolean; /** Fixed-width column layout (ADR 0034): each column renders at a declared pixel width via `` + `table-layout: fixed`. This is what makes sticky offsets computable, so it also gates pinning and resizing. Off by default — without it the table auto-sizes exactly as before. */ columnLayout?: boolean; /** Drag a header's trailing edge to resize; double-click resets to the column's declared `width`. Requires `column-layout`. */ resizableColumns?: boolean; /** Grow the columns to fill the scroll frame whenever the declared widths add up to less than the space available. Surplus is shared across the unpinned columns in proportion to their declared width; an overflowing table is untouched and still scrolls. Requires `column-layout`. */ fitColumns?: boolean; /** Render the aggregate `` row built from each column's `total`. Under `sticky-header` it pins to the bottom of the scroll frame. */ totals?: boolean; /** Replace the frame's native scrollbars with overlay rails, so nothing reserves a band inside the frame. Wheel and trackpad are untouched. */ overlayScroll?: boolean; /** undefined */ pageSize?: XmDataTableElement["pageSize"]; /** undefined */ emptyHeading?: XmDataTableElement["emptyHeading"]; /** undefined */ emptyText?: XmDataTableElement["emptyText"]; /** Total item count for server-mode paging (pages = ceil(total-items/page-size)). */ totalItems?: XmDataTableElement["totalItems"]; /** Scroll-viewport cap for `sticky-header` — any CSS length ("360px", "50vh"). */ maxHeight?: XmDataTableElement["maxHeight"]; /** `single` (default) keeps at most one row open; `multiple` allows any number. */ expandMode?: XmDataTableElement["expandMode"]; /** Column key whose value is a row's stable expansion identity. Without it, identity falls back to the row's position, which drifts across sort order and server-mode page swaps — set it whenever rows have an id. */ rowKey?: XmDataTableElement["rowKey"]; /** Row rhythm. `compact` tightens the vertical cell padding one step so a long list fits on one screen; the type scale and hairlines are unchanged. */ density?: XmDataTableElement["density"]; /** Column key whose value groups consecutive rows under a foldable header row (ADR 0030). Grouping runs over the rendered page, after sort. */ groupBy?: XmDataTableElement["groupBy"]; /** Copy for the totals row's first cell (e.g. "18 tools"). */ totalsLabel?: XmDataTableElement["totalsLabel"]; /** A space-separated list of the classes of the element. Classes allows CSS and JavaScript to select and access specific elements via the class selectors or functions like the method `Document.getElementsByClassName()`. */ className?: string; /** Contains a space-separated list of the part names of the element that should be exposed on the host element. */ exportparts?: string; /** Used for labels to link them with their inputs (using input id). */ htmlFor?: string; /** Used to help React identify which items have changed, are added, or are removed within a list. */ key?: number | string; /** Contains a space-separated list of the part names of the element. Part names allows CSS to select and style specific elements in a shadow tree via the ::part pseudo-element. */ part?: string; /** A mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. */ ref?: React.Ref; /** Allows developers to make HTML elements focusable, allow or prevent them from being sequentially focusable (usually with the `Tab` key, hence the name) and determine their relative ordering for sequential focus navigation. */ tabIndex?: number; /** Controlled sort indicator for server mode (`{ key, direction }`); reflected, never reordered locally. */ sort?: XmDataTableElement["sort"]; /** Lazy per-row detail content — called only while the row is open, with the row and its index in the rendered page. May return a Lit template, a DOM node, or a string (rendered as text). */ renderDetail?: XmDataTableElement["renderDetail"]; /** Controlled expansion (AD-14): when non-null the consumer owns the open set — toggles emit intents only. `null` (default) is uncontrolled. */ expandedKeys?: XmDataTableElement["expandedKeys"]; /** Aggregate line for a group's header row, called with that group's rows. */ groupSummary?: XmDataTableElement["groupSummary"]; /** Escape hatch owning the group header's body (mirrors `renderCell`). When set it supersedes the summary chrome; the fold control stays table-owned. */ renderGroupRow?: XmDataTableElement["renderGroupRow"]; /** Controlled folding (AD-14): when non-null the consumer owns the collapsed set — toggles emit intents only. `null` (default) is uncontrolled. */ collapsedGroups?: XmDataTableElement["collapsedGroups"]; /** Marks a row as a group header that keeps its own cells (ADR 0041). Use it when the header of a group is itself a record — `group-by` cannot express that, because it renders per-column aggregates over the children. The row takes the group row's surface; returning `open` also puts the table's fold chip in the first laid-out cell, and folding stays the consumer's state: the chip emits an intent, never a local change. */ rowHeader?: XmDataTableElement["rowHeader"]; /** Trailing per-row action rail — a copy button, a download, a row menu. Revealed on row hover and on `:focus-within`, so it stays keyboard-reachable in source order. Row-click never fires from it (AD-15). */ rowActions?: XmDataTableElement["rowActions"]; /** Controlled column widths (AD-14). `null` (default) is uncontrolled. */ columnWidths?: XmDataTableElement["columnWidths"]; /** Controlled pinned set (AD-14). `null` (default) is uncontrolled. */ pinnedColumns?: XmDataTableElement["pinnedColumns"]; /** Controlled hidden set (AD-14). `null` (default) is uncontrolled. */ hiddenColumns?: XmDataTableElement["hiddenColumns"]; /** Controlled wrapped set (AD-14). `null` (default) is uncontrolled. */ wrappedColumns?: XmDataTableElement["wrappedColumns"]; /** Trailing control inside a header cell — the column's own options menu. Mirrors `renderCell` / `rowActions`: the consumer owns the button and whatever it opens; sorting and resizing stay table-owned. */ renderHeaderAction?: XmDataTableElement["renderHeaderAction"]; /** Fired when the page changes (`detail.page`). */ onXmDataTablePageChange?: (event: XmDataTableElementEvent) => void; /** Fired when a `row-header` row's fold chip is pressed (`detail.row`, `detail.index`, `detail.open`). */ onXmDataTableRowHeaderToggle?: (event: XmDataTableElementEvent) => void; /** undefined */ onType?: (event: XmDataTableElementEvent) => void; /** Fired when the sort changes (`detail.key`, `detail.direction`). */ onXmDataTableSortChange?: (event: XmDataTableElementEvent) => void; /** Fired when a clickable row is activated (`detail.row`, `detail.index`). */ onXmDataTableRowClick?: (event: XmDataTableElementEvent) => void; /** Fired when a `group-by` header row folds or unfolds (`detail.key`, `detail.open`, `detail.rows`). */ onXmDataTableGroupToggle?: (event: XmDataTableElementEvent) => void; /** Fired when a row's detail region opens (`detail.row`, `detail.index`, `detail.key`, `detail.open`). */ onXmDataTableRowExpand?: (event: XmDataTableElementEvent) => void; /** Fired when a row's detail region closes (`detail.row`, `detail.index`, `detail.key`, `detail.open`). */ onXmDataTableRowCollapse?: (event: XmDataTableElementEvent) => void; /** Fired when a column's width changes (`detail.key`, `detail.width`). */ onXmDataTableColumnResize?: (event: XmDataTableElementEvent) => void; /** Fired when a column is pinned or released (`detail.key`, `detail.pinned`). */ onXmDataTableColumnPin?: (event: XmDataTableElementEvent) => void; /** Fired when a column is hidden or restored (`detail.key`, `detail.visible`). */ onXmDataTableColumnVisibility?: (event: XmDataTableElementEvent) => void; /** Fired when a column's text wrapping is toggled (`detail.key`, `detail.wrapped`). */ onXmDataTableColumnWrap?: (event: XmDataTableElementEvent) => void; } /** * * * ## Attributes & Properties * * Component attributes and properties that can be applied to the element or by using JavaScript. * * - `loading`: undefined * - `page-size`/`pageSize`: undefined * - `empty-heading`/`emptyHeading`: undefined * - `empty-text`/`emptyText`: undefined * - `server`: Server/controlled mode (AD-14): the consumer owns sort + paging. The table * renders `rows` verbatim, never sorts/slices a copy, derives the page count * from `total-items` (not `rows.length`), and emits intents only. * - `total-items`/`totalItems`: Total item count for server-mode paging (pages = ceil(total-items/page-size)). * - `row-click`/`rowClick`: Make rows clickable — emits xm-data-table-row-click (AD-15). * - `sticky-header`/`stickyHeader`: Pin the header rows while the table body scrolls inside the frame. Pair * with `max-height` (or a host height) so the frame actually scrolls. * - `max-height`/`maxHeight`: Scroll-viewport cap for `sticky-header` — any CSS length ("360px", "50vh"). * - `fill`: Stretch the frame to fill the host's full height instead of collapsing to * content height. Pair with `sticky-header` and a definite-height host so the * table reaches the bottom edge and the scrollbar pins there even when the * rows don't fill the viewport. * - `flush`: Drop the frame's hairline border + corner radius for edge-to-edge * embedding (the frame becomes flush with its container). * - `expandable`: Enable per-row expansion (ADR 0019): adds a leading expander column whose * chevron button toggles an in-place detail row under its data row. * - `expand-mode`/`expandMode`: `single` (default) keeps at most one row open; `multiple` allows any number. * - `row-key`/`rowKey`: Column key whose value is a row's stable expansion identity. Without it, * identity falls back to the row's position, which drifts across sort order * and server-mode page swaps — set it whenever rows have an id. * - `density`: Row rhythm. `compact` tightens the vertical cell padding one step so a * long list fits on one screen; the type scale and hairlines are unchanged. * - `group-by`/`groupBy`: Column key whose value groups consecutive rows under a foldable header * row (ADR 0030). Grouping runs over the rendered page, after sort. * - `actions-always`/`actionsAlways`: Keep the action rail visible at rest instead of revealing it on hover. * - `column-layout`/`columnLayout`: Fixed-width column layout (ADR 0034): each column renders at a declared * pixel width via `` + `table-layout: fixed`. This is what makes * sticky offsets computable, so it also gates pinning and resizing. Off by * default — without it the table auto-sizes exactly as before. * - `resizable-columns`/`resizableColumns`: Drag a header's trailing edge to resize; double-click resets to the * column's declared `width`. Requires `column-layout`. * - `fit-columns`/`fitColumns`: Grow the columns to fill the scroll frame whenever the declared widths add * up to less than the space available. Surplus is shared across the unpinned * columns in proportion to their declared width; an overflowing table is * untouched and still scrolls. Requires `column-layout`. * - `totals`: Render the aggregate `` row built from each column's `total`. Under * `sticky-header` it pins to the bottom of the scroll frame. * - `totals-label`/`totalsLabel`: Copy for the totals row's first cell (e.g. "18 tools"). * - `overlay-scroll`/`overlayScroll`: Replace the frame's native scrollbars with overlay rails, so nothing * reserves a band inside the frame. Wheel and trackpad are untouched. * - `columns`: undefined (property only) * - `rows`: undefined (property only) * - `sort`: Controlled sort indicator for server mode (`{ key, direction }`); reflected, * never reordered locally. (property only) * - `renderDetail`: Lazy per-row detail content — called only while the row is open, with the * row and its index in the rendered page. May return a Lit template, a DOM * node, or a string (rendered as text). (property only) * - `expandedKeys`: Controlled expansion (AD-14): when non-null the consumer owns the open * set — toggles emit intents only. `null` (default) is uncontrolled. (property only) * - `groupSummary`: Aggregate line for a group's header row, called with that group's rows. (property only) * - `renderGroupRow`: Escape hatch owning the group header's body (mirrors `renderCell`). When * set it supersedes the summary chrome; the fold control stays table-owned. (property only) * - `collapsedGroups`: Controlled folding (AD-14): when non-null the consumer owns the collapsed * set — toggles emit intents only. `null` (default) is uncontrolled. (property only) * - `rowHeader`: Marks a row as a group header that keeps its own cells (ADR 0041). Use it * when the header of a group is itself a record — `group-by` cannot express * that, because it renders per-column aggregates over the children. The row * takes the group row's surface; returning `open` also puts the table's fold * chip in the first laid-out cell, and folding stays the consumer's state: * the chip emits an intent, never a local change. (property only) * - `rowActions`: Trailing per-row action rail — a copy button, a download, a row menu. * Revealed on row hover and on `:focus-within`, so it stays keyboard-reachable * in source order. Row-click never fires from it (AD-15). (property only) * - `columnWidths`: Controlled column widths (AD-14). `null` (default) is uncontrolled. (property only) * - `pinnedColumns`: Controlled pinned set (AD-14). `null` (default) is uncontrolled. (property only) * - `hiddenColumns`: Controlled hidden set (AD-14). `null` (default) is uncontrolled. (property only) * - `wrappedColumns`: Controlled wrapped set (AD-14). `null` (default) is uncontrolled. (property only) * - `renderHeaderAction`: Trailing control inside a header cell — the column's own options menu. * Mirrors `renderCell` / `rowActions`: the consumer owns the button and * whatever it opens; sorting and resizing stay table-owned. (property only) * * ## Events * * Events that will be emitted by the component. * * - `xm-data-table-page-change`: Fired when the page changes (`detail.page`). * - `xm-data-table-row-header-toggle`: Fired when a `row-header` row's fold chip is pressed (`detail.row`, `detail.index`, `detail.open`). * - `type`: undefined * - `xm-data-table-sort-change`: Fired when the sort changes (`detail.key`, `detail.direction`). * - `xm-data-table-row-click`: Fired when a clickable row is activated (`detail.row`, `detail.index`). * - `undefined`: undefined * - `xm-data-table-group-toggle`: Fired when a `group-by` header row folds or unfolds (`detail.key`, `detail.open`, `detail.rows`). * - `xm-data-table-row-expand`: Fired when a row's detail region opens (`detail.row`, `detail.index`, `detail.key`, `detail.open`). * - `xm-data-table-row-collapse`: Fired when a row's detail region closes (`detail.row`, `detail.index`, `detail.key`, `detail.open`). * - `xm-data-table-column-resize`: Fired when a column's width changes (`detail.key`, `detail.width`). * - `xm-data-table-column-pin`: Fired when a column is pinned or released (`detail.key`, `detail.pinned`). * - `xm-data-table-column-visibility`: Fired when a column is hidden or restored (`detail.key`, `detail.visible`). * - `xm-data-table-column-wrap`: Fired when a column's text wrapping is toggled (`detail.key`, `detail.wrapped`). * * ## Methods * * Methods that can be called to access component functionality. * * - `pinColumn(key: string, pinned: boolean) => void`: Pin a column to the left edge, or release it. A `locked` column ignores this. * - `setColumnHidden(key: string, hidden: boolean) => void`: Take a column out of the view, or put it back. A `locked` column ignores this. * - `setColumnWrapped(key: string, wrapped: boolean) => void`: Wrap a column's copy to three lines, or return it to one line + ellipsis. * Only a `wrappable` column responds. * - `setColumnWidth(key: string, width: number) => void`: Set a column's width in px, clamped to its own floor and the shared cap. * - `resetColumnWidth(key: string) => void`: Return a column to its declared `width`. * - `setSort(key: string | null, direction: SortDirection = "asc") => void`: Set (or clear, with `null`) the sort from outside the header row — a column * options menu, or restoring a saved layout. Applies locally in client mode * and emits either way, exactly like a header click; `sort` stays the * server-mode controlled property and is untouched here. A cleared sort * emits with an empty `key`. */ export const XmDataTable: React.ForwardRefExoticComponent;