@skdx/docs-kit 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/angular-inputs.json +1 -1
- package/dist/data/api-manifest.json +1 -1
- package/dist/shared/contracts/accordion.js +1 -1
- package/dist/shared/contracts/alert.js +1 -1
- package/dist/shared/contracts/autocomplete.d.ts +1 -1
- package/dist/shared/contracts/autocomplete.js +1 -1
- package/dist/shared/contracts/avatar.js +1 -1
- package/dist/shared/contracts/breadcrumb.js +1 -1
- package/dist/shared/contracts/button.js +1 -1
- package/dist/shared/contracts/calendar.js +1 -1
- package/dist/shared/contracts/card.js +1 -1
- package/dist/shared/contracts/carousel.js +1 -1
- package/dist/shared/contracts/checkbox-card.js +1 -1
- package/dist/shared/contracts/checkbox-group.js +1 -1
- package/dist/shared/contracts/collapsible.js +1 -1
- package/dist/shared/contracts/combobox.js +1 -1
- package/dist/shared/contracts/command.js +1 -1
- package/dist/shared/contracts/dashboard-layout.js +1 -1
- package/dist/shared/contracts/date-picker.js +1 -1
- package/dist/shared/contracts/dialog.d.ts +1 -1
- package/dist/shared/contracts/dialog.js +1 -1
- package/dist/shared/contracts/drawer.d.ts +1 -1
- package/dist/shared/contracts/drawer.js +1 -1
- package/dist/shared/contracts/field.js +1 -1
- package/dist/shared/contracts/file-upload.js +1 -1
- package/dist/shared/contracts/floating-panel.js +1 -1
- package/dist/shared/contracts/form.js +1 -1
- package/dist/shared/contracts/image.js +1 -1
- package/dist/shared/contracts/listbox.js +1 -1
- package/dist/shared/contracts/loading-overlay.js +1 -1
- package/dist/shared/contracts/mentions.js +1 -1
- package/dist/shared/contracts/menu.js +1 -1
- package/dist/shared/contracts/menubar.js +1 -1
- package/dist/shared/contracts/navigation-menu.js +1 -1
- package/dist/shared/contracts/pagination.js +1 -1
- package/dist/shared/contracts/password-input.js +1 -1
- package/dist/shared/contracts/popover.js +1 -1
- package/dist/shared/contracts/progress.js +1 -1
- package/dist/shared/contracts/qr-code.js +1 -1
- package/dist/shared/contracts/radio-card.js +1 -1
- package/dist/shared/contracts/radio-group.js +1 -1
- package/dist/shared/contracts/rating.js +1 -1
- package/dist/shared/contracts/resizable.js +1 -1
- package/dist/shared/contracts/scroll-area.js +1 -1
- package/dist/shared/contracts/select.js +1 -1
- package/dist/shared/contracts/slider.js +1 -1
- package/dist/shared/contracts/speed-dial.js +1 -1
- package/dist/shared/contracts/split-button.js +1 -1
- package/dist/shared/contracts/stepper.js +1 -1
- package/dist/shared/contracts/switch.js +1 -1
- package/dist/shared/contracts/table.js +3 -1
- package/dist/shared/contracts/tabs.js +1 -1
- package/dist/shared/contracts/tag-group.js +1 -1
- package/dist/shared/contracts/tags-input.js +1 -1
- package/dist/shared/contracts/text-field.js +1 -1
- package/dist/shared/contracts/textarea.js +1 -1
- package/dist/shared/contracts/timeline.js +1 -1
- package/dist/shared/contracts/toast.js +9 -1
- package/dist/shared/contracts/toolbar.js +1 -1
- package/dist/shared/contracts/tour.js +1 -1
- package/dist/shared/contracts/transfer.js +1 -1
- package/dist/shared/contracts/tree-select.js +1 -1
- package/dist/shared/contracts/tree.js +1 -1
- package/dist/shared/contracts/types.d.ts +2 -0
- package/dist/shared/contracts/workspace-switcher.js +1 -1
- package/dist/shared/core/field-core.d.ts +2 -0
- package/dist/shared/core/field-core.js +1 -1
- package/dist/skins-src/_foundation-fallback.css +2 -1
- package/dist/skins-src/components/_actuator.css +1 -1
- package/dist/skins-src/components/_card-control.css +1 -1
- package/dist/skins-src/components/_collection.css +2 -2
- package/dist/skins-src/components/_overlay.css +1 -1
- package/dist/skins-src/components/_trigger.css +1 -1
- package/dist/skins-src/components/accordion.css +1 -1
- package/dist/skins-src/components/alert.css +2 -2
- package/dist/skins-src/components/autocomplete.css +1 -1
- package/dist/skins-src/components/avatar.css +1 -1
- package/dist/skins-src/components/badge.css +1 -1
- package/dist/skins-src/components/button.css +1 -1
- package/dist/skins-src/components/calendar.css +8 -6
- package/dist/skins-src/components/card.css +1 -1
- package/dist/skins-src/components/carousel.css +1 -1
- package/dist/skins-src/components/chat-composer.css +1 -1
- package/dist/skins-src/components/chat-message.css +1 -1
- package/dist/skins-src/components/checkbox-card.css +2 -2
- package/dist/skins-src/components/checkbox.css +1 -1
- package/dist/skins-src/components/clipboard.css +2 -2
- package/dist/skins-src/components/color-picker.css +4 -4
- package/dist/skins-src/components/combobox.css +2 -2
- package/dist/skins-src/components/command.css +1 -1
- package/dist/skins-src/components/dashboard-layout.css +1 -1
- package/dist/skins-src/components/date-field.css +2 -2
- package/dist/skins-src/components/dialog.css +4 -4
- package/dist/skins-src/components/drawer.css +9 -9
- package/dist/skins-src/components/editable.css +3 -3
- package/dist/skins-src/components/file-upload.css +4 -4
- package/dist/skins-src/components/floating-panel.css +1 -1
- package/dist/skins-src/components/forgot-password-page.css +1 -1
- package/dist/skins-src/components/form-section.css +1 -1
- package/dist/skins-src/components/form.css +12 -2
- package/dist/skins-src/components/image.css +1 -1
- package/dist/skins-src/components/kbd.css +1 -1
- package/dist/skins-src/components/link.css +1 -1
- package/dist/skins-src/components/listbox.css +1 -1
- package/dist/skins-src/components/mentions.css +1 -1
- package/dist/skins-src/components/menubar.css +2 -2
- package/dist/skins-src/components/navigation-menu.css +1 -1
- package/dist/skins-src/components/number-field.css +1 -1
- package/dist/skins-src/components/onboarding-checklist.css +1 -1
- package/dist/skins-src/components/pagination.css +2 -2
- package/dist/skins-src/components/password-input.css +80 -16
- package/dist/skins-src/components/pin-input.css +2 -2
- package/dist/skins-src/components/popover.css +1 -1
- package/dist/skins-src/components/qr-code.css +2 -2
- package/dist/skins-src/components/radio-card.css +1 -1
- package/dist/skins-src/components/reset-password-page.css +1 -1
- package/dist/skins-src/components/select.css +3 -3
- package/dist/skins-src/components/sign-in-page.css +1 -1
- package/dist/skins-src/components/sign-up-page.css +1 -1
- package/dist/skins-src/components/skeleton.css +1 -1
- package/dist/skins-src/components/skip-link.css +1 -1
- package/dist/skins-src/components/speed-dial.css +3 -3
- package/dist/skins-src/components/stat-card.css +6 -1
- package/dist/skins-src/components/stepper.css +3 -1
- package/dist/skins-src/components/switch.css +21 -1
- package/dist/skins-src/components/table.css +4 -4
- package/dist/skins-src/components/tags-input.css +2 -2
- package/dist/skins-src/components/text-field.css +26 -21
- package/dist/skins-src/components/text.css +1 -1
- package/dist/skins-src/components/textarea.css +1 -1
- package/dist/skins-src/components/time-field.css +2 -2
- package/dist/skins-src/components/toast.css +2 -2
- package/dist/skins-src/components/toggle-group.css +3 -3
- package/dist/skins-src/components/toggle.css +1 -1
- package/dist/skins-src/components/toolbar.css +2 -2
- package/dist/skins-src/components/tree-select.css +2 -2
- package/dist/skins-src/components/tree.css +1 -1
- package/dist/skins-src/components/usage-card.css +1 -1
- package/dist/skins-src/components/user-menu.css +1 -1
- package/dist/skins-src/components/verification-page.css +1 -1
- package/dist/skins-src/components/workspace-switcher.css +2 -2
- package/package.json +14 -14
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{constraintValidationMethods as e,setCustomValidityMethod as t}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as r}from"./styling-hooks.js";var o={name:"Table",purpose:"A structural data-table primitive. Owns only sort and row-selection state; consumers map over their own row data to render rows and cells. Renders a plain <table>.",props:[{name:"sort",type:"TableSortState[]",required:!1,description:"Sorted columns, most significant first, for controlled usage. Always an array, whatever multiSort is set to; [] means nothing is sorted. The shape does not change when multiSort is toggled at runtime \u2014 multiSort governs only whether the array may hold more than one entry."},{name:"defaultSort",type:"TableSortState[]",defaultValue:"[]",required:!1,description:"Initially sorted columns, most significant first, for uncontrolled usage."},{name:"filter",type:"TableFilterState",required:!1,description:"Active column filters for controlled usage: a map from columnKey to the text that column's cells must contain. A column with no entry is unfiltered; {} means nothing is filtered."},{name:"defaultFilter",type:"TableFilterState",defaultValue:"{}",required:!1,description:"Initial column filters, for uncontrolled usage."},{name:"multiSort",type:"boolean",defaultValue:"false",required:!1,description:`Whether activating a second column appends it to the sort instead of replacing the first. It governs the array's length, never its type: off, sort holds at most one entry and at most one header can report aria-sort="ascending" | "descending"; on, it holds as many as the user has activated, most significant first.`},{name:"selected",type:"Set<string> | string[]",required:!1,description:"Selected row ids, for controlled usage."},{name:"defaultSelected",type:"Set<string> | string[]",required:!1,description:"Initially selected row ids, for uncontrolled usage."},{name:"selectionMode",type:"'single' | 'multiple' | 'none'",defaultValue:"'none'",required:!1,description:"Whether rows can be selected at all, and if so, one or many at once."},{name:"getSortLabel",type:"(column: string, direction: 'asc' | 'desc' | null) => string",defaultValue:"defaultGetSortLabel",required:!1,description:'Formats the message announced through the LiveAnnouncer when a sortable header is activated. `column` is the header cell\'s own text. Return an empty string to announce nothing. The default names the column and new direction \u2014 "Amount sorted ascending" / "Amount sorted descending", and "Amount not sorted" once cleared.'},{name:"expandedRowIds",type:"string[]",required:!1,description:"Row ids whose ExpandedRow detail row is open, for controlled usage."},{name:"defaultExpandedRowIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded detail rows, for uncontrolled usage."},{name:"columnWidths",type:"Record<string, number>",required:!1,description:"Per-column pixel widths keyed by a header cell's columnKey, for controlled usage."},{name:"defaultColumnWidths",type:"Record<string, number>",defaultValue:"{}",required:!1,description:"Initial per-column pixel widths, for uncontrolled usage. Columns left out size themselves until resized."},{name:"columnOrder",type:"string[]",required:!1,description:"Display order of column keys, for controlled usage. Keys not listed follow in source order; [] means source order. The primitive never reorders your cells \u2014 only the derived columns/data view renders in this order."},{name:"defaultColumnOrder",type:"string[]",defaultValue:"[]",required:!1,description:"Initial column order, for uncontrolled usage."},{name:"columnPins",type:"TableColumnPins",required:!1,description:"Pinned columns for controlled usage: a map from columnKey to 'start' or 'end'. An unpinned column is absent; {} means nothing is pinned. Pinned cells become sticky and receive --skdx-table-pin-offset."},{name:"defaultColumnPins",type:"TableColumnPins",defaultValue:"{}",required:!1,description:"Initially pinned columns, for uncontrolled usage."},{name:"getMoveLabel",type:"(column: string, position: number, count: number) => string",defaultValue:"defaultGetMoveLabel",required:!1,description:'Formats the message announced through the LiveAnnouncer after a column is moved by keyboard or dropped. `column` is the header cell\'s own text, `position` is 1-based. Return an empty string to announce nothing. The default reads "Amount moved to position 2 of 5".'},{name:"collapsedGroups",type:"string[]",required:!1,description:"Group keys whose rows are hidden, for controlled usage. Groups start expanded, so [] shows every group."},{name:"defaultCollapsedGroups",type:"string[]",defaultValue:"[]",required:!1,description:"Initially collapsed groups, for uncontrolled usage."},{name:"expandedNodeIds",type:"string[]",required:!1,description:"Tree parents whose child rows are rendered, for controlled usage. Distinct from expandedRowIds, which opens detail rows."},{name:"defaultExpandedNodeIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded tree parents, for uncontrolled usage."},{name:"rowCount",type:"number",required:!1,description:"The total number of rows in the full dataset, reflected as aria-rowcount on the <table>. Set it when rows in the DOM are not all rows there are (pagination, virtualization, infinite scroll), else assistive tech counts rendered rows and reports wrong position. Use -1 when the total is unknown \u2014 what ARIA reserves it for. Omitted when unset, so a table rendering all rows says nothing. Per-row aria-rowindex stays the consumer's: Table renders no rows and cannot number them."},{name:"columnCount",type:"number",required:!1,description:"The total number of columns in the full dataset, reflected as aria-colcount on the <table>. Column counterpart of rowCount for tables showing a horizontal window. Use -1 when unknown. Omitted when unset. Per-cell aria-colindex, like aria-rowindex, is consumer-supplied."},{name:"columns",type:"TableColumn<T>[]",required:!1,description:"The columns the derived <thead>/<tbody> draws from \u2014 one HeaderCell and one Cell per row. Each is { key, header?, cell?, sortable?, resizable?, minWidth?, maxWidth? }: key is the columnKey, header defaults to key, and column settings override root defaults. Required together with data to derive the whole table; omit both and compose the body by hand from Row and Cell instead. React alone enforces the pair in its types, because only there is the deriving recipe a separate component from the root."},{name:"data",type:"T[]",required:!1,description:"The rows to render, one derived Row per entry. columns' datum type is inferred from this, so a consumer annotates neither columns nor renderCell. Required together with columns to derive the whole table; omit both and compose the body by hand."},{name:"rowId",type:"(row: T, index: number) => string",defaultValue:"(row, index) => String(row.id ?? index)",required:!1,description:"Derives each row's identity for selection, expansion, and list keys. Defaults to the row's id if it's a string/number, otherwise its index. Index-only identity breaks selection when data reorders, since a selected id silently points to a different row."},{name:"getRowLabel",type:"(row: T, index: number) => string",required:!1,description:`Names each row for the derived RowSelectCheckbox and ExpandTrigger, which speak it as "Select <label>" and "Details for <label>". Return the row's own human-readable text \u2014 a person's name, an invoice number \u2014 because without it a control is named from bookkeeping: the rowId or the row's position, neither of which identifies anything to a screen reader, and the position goes stale the moment a sort reorders the rows.`},{name:"sortable",type:"boolean",defaultValue:"false",required:!1,description:"Default sortable for columns with no own setting. Makes the derived view render rows in live sort order \u2014 a copy of data sorted by most-significant column first, never data itself. The primitive never reorders your rows; this recipe sorts its own copy on top of the sort state."},{name:"filterable",type:"boolean",defaultValue:"false",required:!1,description:"Default filterable for columns with no own setting. A filterable column derives a ColumnHeaderFilterInput under its header, and the derived view renders only the rows whose stringified cell contains every active filter's text, case-insensitively \u2014 a filtered copy, applied before the sort, never data itself."},{name:"selectable",type:"boolean",defaultValue:"false",required:!1,description:"Derives a leading SelectAllCheckbox/RowSelectCheckbox column. Sugar over selectionMode: raises 'none' to 'multiple' once; explicit selectionMode always wins for a single source of truth."},{name:"expandable",type:"boolean",defaultValue:"false",required:!1,description:"Derives a leading ExpandTrigger column and an ExpandedRow per row. A boolean, not the content itself \u2014 renderExpanded supplies the detail row's content, and without it the derived detail row is empty."},{name:"renderExpanded",type:"(row: T) => React.ReactNode",required:!1,description:"Renders a derived ExpandedRow's detail content for one row. Ignored while expandable is false."},{name:"resizable",type:"boolean",defaultValue:"false",required:!1,description:"Default resizable for every column that doesn't set its own."},{name:"reorderable",type:"boolean",defaultValue:"false",required:!1,description:"Default reorderable for every column that doesn't set its own. A reorderable column derives a ColumnReorderTrigger, and the derived view renders columns in columnOrder."},{name:"pinnable",type:"boolean",defaultValue:"false",required:!1,description:"Default pinnable for every column that doesn't set its own. A pinnable column derives a ColumnPinTrigger, and the derived view renders pinned-start columns first and pinned-end columns last."},{name:"groupBy",type:"string",required:!1,description:"A column key to group rows by. The derived view emits a GroupRow per distinct String(row[groupBy]) after filter and sort, groups ordered by first appearance, and hides a group's rows while its key is in collapsedGroups."},{name:"renderGroupHeader",type:"(groupKey: string, rows: T[]) => React.ReactNode",required:!1,description:`Renders a derived GroupRow's label for one group. Ignored without groupBy. Defaults to the key and the row count, as in "EMEA (12)".`},{name:"getSubRows",type:"(row: T) => T[] | undefined",required:!1,description:"Returns a row's child rows to render it as a tree parent. Children render under the parent while its id is in expandedNodeIds, sorted per level, one level deeper each time; the filter applies to top-level rows only. A parent derives a TreeTrigger in its first data cell."},{name:"empty",type:"React.ReactNode",required:!1,description:"Content for the derived Empty row, shown in place of body rows while data is empty. No default text: with no empty supplied, no empty row is derived \u2014 avoiding an i18n leak."},{name:"caption",type:"React.ReactNode",required:!1,description:"Content for a derived Caption, rendered before the header. No caption is derived when omitted."},{name:"renderCell",type:"(row: T, column: TableColumn<T>) => React.ReactNode",required:!1,description:"Fallback cell renderer for a column with no cell of its own. With neither, a cell renders String(row[column.key])."},{name:"density",type:"'compact' | (string & {})",required:!1,description:"Vertical rhythm rung, written to data-density on the root; the data-density attribute may be set directly instead."},{name:"stickyHeader",type:"boolean",required:!1,description:"Pins the header row while the body scrolls, written to data-sticky-header on the root; the data-sticky-header attribute may be set directly instead."},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Size rung forwarded to RowSelectCheckbox's and SelectAllCheckbox's data-size; either attribute may be written directly instead."}],events:[{name:"sort-change",description:"Fires with the new sort state whenever a sortable header is activated. The payload is always a TableSortState[], most significant first \u2014 [] once the last sorted column has cycled back to unsorted \u2014 regardless of multiSort.",detail:"TableSortState[]"},{name:"filter-change",detail:"TableFilterState",description:"Fires with the new filter map whenever a column's filter text changes; a cleared column leaves the map, so {} means nothing is filtered."},{name:"selected-change",detail:"string[]",description:"Fires with the new selected row ids whenever selection changes."},{name:"expanded-row-ids-change",detail:"string[]",description:"Fires with the new set of expanded row ids whenever an ExpandTrigger is activated."},{name:"column-widths-change",description:"Fires with the full width map whenever a resizable column is dragged or keyboard-resized \u2014 continuously, on every drag frame and every arrow-key nudge, because the column must follow the pointer. Persist from column-widths-commit instead.",detail:"Record<string, number>"},{name:"column-widths-commit",description:'The settled counterpart of column-widths-change, carrying the same width map: fired once per gesture rather than per frame, so persisting writes once instead of dozens. Fires on pointerup, pointercancel at drag end, Escape (reverting the width), and keyup after Arrow/Home/End resize. Never fires for unchanged gestures (movement-less pointerdown or clamped arrow), so it means "this is the width to store".',detail:"Record<string, number>"},{name:"column-order-change",detail:"string[]",description:"Fires with the full column order whenever a ColumnReorderTrigger moves its column by keyboard or drop."},{name:"column-pins-change",detail:"TableColumnPins",description:"Fires with the full pin map whenever a ColumnPinTrigger is activated."},{name:"collapsed-groups-change",detail:"string[]",description:"Fires with the collapsed group keys whenever a GroupRow is toggled."},{name:"expanded-node-ids-change",detail:"string[]",description:"Fires with the expanded tree parents whenever a TreeTrigger is activated."}],parts:[{name:"Row",description:`A <tr>. Given a rowId and while selectionMode is not 'none', publishes data-row-id, reports selection as data-state="selected", and toggles selection when clicked. The click is pointer sugar, not the affordance: the row is never focusable and never carries a tabindex, so every selectable Row MUST contain a RowSelectCheckbox \u2014 the keyboard path to selecting.`,props:[{name:"rowId",type:"string",required:!1,description:"This row's identifier within the table's selection state. Required for the row to be selectable; a row without one is never selected and never clickable-to-select."},{name:"level",type:"number",required:!1,description:"Tree depth, 0 for a top-level row. Written to data-level and --skdx-table-row-level so the skin indents the first cell; the derived view sets it for every tree row."}]},{name:"Cell",description:"A <td>. Given a columnKey it reflects that column's pin as data-pinned and --skdx-table-pin-offset.",props:[{name:"columnKey",type:"string",required:!1,description:"The column this cell belongs to, so it can follow a pinned header. Set by the derived view; optional when composing by hand."}]},{name:"RowSelectCheckbox",description:"One row's selection checkbox, driven by the table's selection state, rendered inside a Cell of its row. Required in every selectable row: it's the only focusable control that selects one, so omitting it makes the table pointer-only. Space toggles it, Shift-activation extends selection to a range. Needs a row-specific accessible name \u2014 no default because only the consumer knows what names the row. Being a Checkbox, it inherits form participation: name and value submit as a pair from inside a <form> (see formBehavior).",props:[{name:"checked",type:"boolean",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"Only the custom element publishes it. The other four hand this derived state down to their parts through context, so a consumer never reads it off a part; here every part is its own element with no such channel, and reading it back is the only way to reflect the state in surrounding markup.",description:"Whether this row is currently selected. Read-only: toggle it through the table's selected row ids."},{name:"rowId",type:"string",required:!0,description:"The row this checkbox selects. Must match the rowId on the enclosing Row."},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the checkbox; the data-size attribute may be set directly instead."}],methods:[...e,t]},{name:"SelectAllCheckbox",description:'The header checkbox that selects or clears a whole set of rows at once. Tri-state: checked when every id in rowIds is selected, indeterminate when only some are, unchecked otherwise \u2014 including over an empty list, where a select-all above no rows reads unchecked rather than vacuously checked. Meaningful only with selectionMode="multiple".',props:[{name:"checked",type:"boolean",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"Only the custom element publishes it. The other four hand this derived state down to their parts through context, so a consumer never reads it off a part; here every part is its own element with no such channel, and reading it back is the only way to reflect the state in surrounding markup.",description:"Whether every row in rowIds is currently selected. Read-only: toggle it through the table's selected row ids."},{name:"rowIds",type:"string[]",required:!0,description:'Exactly the rows this checkbox covers. Required because Table keeps no row registry: "select all" means the ids you hand it and nothing else, so under pagination or virtualization it is either the rendered page or the whole dataset, and only the consumer knows which.'},{name:"scope",type:"'page' | 'all'",required:!0,description:"Which set rowIds is \u2014 the rendered page or the entire dataset. Required and undefaulted: the two behave identically until the table is paginated or virtualized, at which point a select-all that silently covered only the visible window is a bug found in production. It is also published as data-scope and spoken in the default accessible name."},{name:"getSelectAllLabel",type:"(scope: 'page' | 'all', count: number) => string",defaultValue:"defaultSelectAllLabel \u2014 `Select all N rows on this page` / `Select all N rows`",required:!1,description:`Formats the checkbox's own accessible name. The default names the count and the scope rather than a bare "Select all", because "select all 40 rows on this page" and "select all 1,204 rows" are different promises and the user has to hear which one is on offer.`},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the checkbox; the data-size attribute may be set directly instead."}],methods:[...e,t]},{name:"HeaderCell",description:"A <th>. A column has one identifier, columnKey, and sorting, filtering and resizing all key off it. Sortable when given `sortable`; filterable when given `filterable`; resizable when given `resizable`. Any affordance needs a columnKey \u2014 a column with no identifier has nowhere to read its sort or filter from or store its width in, so all are suppressed however the booleans are set. Carries data-filterable, and data-filtered while its filter text is non-empty.",props:[{name:"columnKey",type:"string",required:!1,description:"This column's single identifier, used by both sorting and resizing. Required for a column that does either. It is the key that appears in a TableSortState and in the columnWidths map."},{name:"sortable",type:"boolean",defaultValue:"false",required:!1,description:"Whether this column can be sorted. A sortable cell sets aria-sort and data-sort-direction and wraps its children in a ColumnHeaderSortTrigger unless the consumer rendered one."},{name:"filterable",type:"boolean",defaultValue:"false",required:!1,description:"Whether this column can be filtered. A filterable cell renders a ColumnHeaderFilterInput after its label unless the consumer rendered one."},{name:"filterLabel",type:"string",defaultValue:"Filter ${columnKey}",required:!1,description:'Accessible name for the derived filter input, which needs one of its own; the deriving recipe passes "Filter <header text>".'},{name:"resizable",type:"boolean",defaultValue:"false",required:!1,description:`Renders a focusable role="separator" resize handle at the cell's inline end, driven by pointer drag or Arrow Left/Right (Home/End for the bounds).`},{name:"minWidth",type:"number",defaultValue:"40",required:!1,description:"Smallest width in pixels the column can be resized to."},{name:"maxWidth",type:"number",defaultValue:"1000",required:!1,description:"Largest width in pixels the column can be resized to."},{name:"resizeStep",type:"number",defaultValue:"8",required:!1,description:"Pixels one Arrow Left/Right press moves the edge, handed down to this cell's ColumnResizeTrigger."},{name:"resizeLabel",type:"string",defaultValue:"'Resize column'",required:!1,description:"Accessible name for the resize handle, which needs one of its own."},{name:"reorderable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a ColumnReorderTrigger after the label unless the consumer rendered one. Needs a columnKey. Carries data-reorderable."},{name:"pinnable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a ColumnPinTrigger after the label unless the consumer rendered one. Needs a columnKey. Carries data-pinnable, and data-pinned plus --skdx-table-pin-offset while pinned."},{name:"reorderLabel",type:"string",defaultValue:"'Move column'",required:!1,description:"Accessible name for the derived reorder trigger."},{name:"pinLabel",type:"string",defaultValue:"'Pin column'",required:!1,description:"Accessible name for the derived pin trigger."}]},{name:"ColumnHeaderFilterInput",description:`The <input type="search"> inside a filterable HeaderCell, bound to that column's entry in the filter map: typing writes it, clearing removes it. A filterable HeaderCell renders one after its label automatically, standing down when it finds one, so exactly one exists per column. Marked data-skdx-table-filter-input, and data-filtered while non-empty. Renders nothing when it can't find a column to filter.`,props:[{name:"columnKey",type:"string",required:!1,description:"The column this input filters. Normally omitted: inside a filterable HeaderCell it inherits the cell's columnKey. Pass it when the input sits outside a header cell or inside one left non-filterable \u2014 an explicit key is itself the opt-in."}]},{name:"ColumnHeaderSortTrigger",description:"The <button> inside a sortable HeaderCell that cycles ascending \u2192 descending \u2192 unsorted (APG sortable-table pattern). The control is a button inside the <th>, announcing as a button, activating on Enter/Space with no library key handling, and leaving the header out of the tab order. A sortable HeaderCell renders one around its children automatically, standing down when it finds one, so exactly one exists per column whether or not the consumer wrote it. Writing one is how to add an indicator, icon, or count inside the button. Carries data-sort-direction and, under multiSort, data-sort-index (the 0-based position for multi-sorted badges). Renders nothing when it can't find a column to sort, because a button that does nothing is worse than no button.",props:[{name:"columnKey",type:"string",required:!1,description:"The column this trigger sorts. Normally omitted: inside a sortable HeaderCell it inherits the cell's columnKey, which is the whole point of the cell owning one identifier for sorting and resizing alike. Pass it when the trigger sits outside a header cell, or inside one deliberately left non-sortable \u2014 an explicit key here is itself the opt-in, so the trigger sorts without the cell having to declare sortable and light up its own aria-sort wiring."}]},{name:"ColumnResizeTrigger",description:'The role="separator" handle a HeaderCell\'s `resizable` renders \u2014 or that a consumer renders directly to place it elsewhere or to give one column a different step. Drag, or focus and use Arrow Left/Right/Home/End, to resize the column.',props:[{name:"columnKey",type:"string",required:!1,description:"Which column this handle resizes. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"minWidth",type:"number",required:!1,description:"Lower clamp for the drag and for the Home key. Falls back to the enclosing HeaderCell's minWidth, then to a component default of 40."},{name:"maxWidth",type:"number",required:!1,description:"Upper clamp for the drag and for the End key. Falls back to the enclosing HeaderCell's maxWidth, then to a component default of 1000."},{name:"step",type:"number",required:!1,description:"Pixels one Arrow Left/Right press moves the edge. Falls back to the enclosing HeaderCell's resizeStep, then to a component default of 8. Keyboard only \u2014 a pointer drag follows the pointer."}]},{name:"ColumnReorderTrigger",description:'The <button> a HeaderCell\'s `reorderable` renders, or a consumer places, to move the column. Focus it and press Arrow Left/Right to move one position (mirrored under dir="rtl") or Home/End to move to the ends; drag it over another header cell to drop the column there. Every move publishes the full order and is announced through getMoveLabel. Carries data-dragging during a drag. Renders nothing without a column key.',props:[{name:"columnKey",type:"string",required:!1,description:"Which column this trigger moves. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"label",type:"string",required:!1,description:"Accessible name for the trigger. Falls back to the enclosing HeaderCell's reorderLabel, then to 'Move column'."}]},{name:"ColumnPinTrigger",description:"The <button aria-pressed> a HeaderCell's `pinnable` renders, or a consumer places, to pin the column to one side. Pressed while the column is pinned to `side`; activating it unpins, otherwise pins to `side`. Carries data-pinned mirroring the column. Renders nothing without a column key.",props:[{name:"columnKey",type:"string",required:!1,description:"Which column this trigger pins. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"side",type:"'start' | 'end'",defaultValue:"'start'",required:!1,description:"Which edge the column pins to."},{name:"label",type:"string",required:!1,description:"Accessible name for the trigger. Falls back to the enclosing HeaderCell's pinLabel, then to 'Pin column'."}]},{name:"GroupRow",description:'The row that heads a group of rows: a <tr> holding one <th scope="rowgroup" colspan> whose <button aria-expanded> wraps the children and toggles the group. Carries data-state="expanded" | "collapsed".',props:[{name:"groupKey",type:"string",required:!0,description:"The group this row heads; the key that appears in collapsedGroups."},{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the group cell spans \u2014 the table's column count."}]},{name:"TreeTrigger",lightDom:!0,description:"Disclosure button inside a tree parent's first cell, carrying aria-expanded for that row's child rows. No aria-controls: the children are sibling rows, not one element.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the parent row this trigger expands; the id that appears in expandedNodeIds."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue, Svelte and Angular take `aria-label` on the element through attribute passthrough.",description:"Accessible name for the disclosure button, since its content is usually an icon."}]},{name:"SortIndicator",description:'The arrow, caret, or badge showing how a column is sorted: a <span aria-hidden="true"> with data-sort-direction ("asc"/"desc"/"none") and, under multiSort, data-sort-index. The aria-hidden is fixed \u2014 the HeaderCell publishes aria-sort and the sort trigger announces through the live announcer, so an indicator that also spoke would triple-announce the sort. It renders children and stays mounted in all three states, not swapping in/out, so a CSS arrow can rotate between them and an unsorted column reserves space.',props:[{name:"columnKey",type:"string",required:!1,description:"The column whose direction this indicator reflects. Normally omitted: it inherits the enclosing HeaderCell's columnKey, so an indicator dropped inside a header needs no wiring. Unlike the sort trigger it inherits from any header cell rather than only a sortable one, because reflecting a direction is not the same act as offering to change it \u2014 an indicator is free to sit in a column sorted from outside the header."}]},{name:"ExpandTrigger",lightDom:!0,description:"Disclosure button placed inside a row's cell, carrying aria-expanded and aria-controls pointing at that row's ExpandedRow.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the row this trigger expands; must match the paired ExpandedRow."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue, Svelte and Angular take `aria-label` on the element through attribute passthrough.",description:"Accessible name for the disclosure button, since its content is usually an icon."}]},{name:"ExpandedRow",description:"The full-width detail row an ExpandTrigger reveals: a <tr> with a single <td colspan> holding the expanded content. Stays mounted while collapsed so aria-controls resolves.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the row this detail row belongs to."},{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the detail cell spans \u2014 the table's column count."}]},{name:"Empty",description:'The row rendered in place of body rows when there is no data: a <tr data-state="empty"> whose single <td colspan> holds the empty-state message.',props:[{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the empty cell spans \u2014 the table's column count."}]}],slots:[{name:"default",description:"Table sections \u2014 Header, Body, Footer, Caption."},{name:"header-cell",description:"A TableHeaderCell \u2014 optionally sortable via `sortable` plus a columnKey, in which case it wraps its label in a sort button."},{name:"cell",description:"A plain TableCell data cell."},{name:"detail",description:"An ExpandedRow's detail content, spanning the full column width."},{name:"empty",description:"The empty-state message shown in place of body rows when there is no data."},{name:"group-header",description:"A derived GroupRow's label, given the group key and its rows."}],appearance:[{attribute:"data-density",values:["compact"],stylesheet:"table.css"},{attribute:"data-sticky-header",values:[],stylesheet:"table.css"}],states:["default","selected","expanded","collapsed","empty"],controlledUncontrolled:"Sort, selection, expanded detail rows, column widths, column order, column pins, collapsed groups and expanded tree nodes each work controlled or uncontrolled, independently of one another.",formBehavior:`The Table root submits nothing (no name, value, or hidden input), so a <form> containing it gains no field. But its two checkbox parts are different: RowSelectCheckbox and SelectAllCheckbox inherit Checkbox's form participation wholly \u2014 name, value, required, invalid all work. A named RowSelectCheckbox submits its pair through a hidden input like any other checkbox. This makes a selection table usable as HTML form: name="rowIds" and value={row.id} means formData.getAll("rowIds") is the selection. Important: checkbox checked state stays owned by table selection, not the form, so form reset doesn't clear selection. Required on a row checkbox blocks submission on that row, not "select at least one row" \u2014 validate selection yourself.`,validationBehavior:"Not applicable \u2014 Table carries no single value and participates in no validation.",accessibility:{role:"table (native <table>)",keyboard:[{key:"Enter/Space",behavior:"Activates a focused sort button, cycling its column's sort, or a focused ExpandTrigger, toggling its detail row (native button activation). Likewise a focused ColumnPinTrigger, GroupRow button, or TreeTrigger."},{key:"Space",behavior:"Toggles a focused RowSelectCheckbox, selecting/deselecting its row, or a focused SelectAllCheckbox (native activation). With Shift on a RowSelectCheckbox it extends selection to a range, like Shift-click. This is the only keyboard path to row selection: the row itself is never focusable, so a Table without RowSelectCheckbox is operable by pointer alone."},{key:"ArrowLeft/ArrowRight",behavior:'Narrows/widens the column while its resize handle has focus, clamped to minWidth/maxWidth; moves the column one position while its reorder trigger has focus. Mirrored under dir="rtl".'},{key:"Home/End",behavior:"Jumps the focused resize handle's column to minWidth/maxWidth; moves the focused reorder trigger's column to the first/last position."}],ariaAttributes:["aria-sort on a sortable TableHeaderCell reflects its current sort direction","activating a sort button announces the new sort through the shared LiveAnnouncer polite region, formatted by getSortLabel \u2014 a changed aria-sort is not itself re-announced","aria-expanded on an ExpandTrigger, with aria-controls pointing at its row's ExpandedRow id","aria-pressed on a ColumnPinTrigger while its column is pinned to its side","aria-expanded on a GroupRow's button and on a TreeTrigger; neither carries aria-controls because the rows they reveal are siblings, not one element","a keyboard move or a drop announces the new position through the shared LiveAnnouncer, formatted by getMoveLabel",'role="separator" with aria-orientation="vertical", aria-valuenow/valuemin/valuemax and its own aria-label on a resize handle',`role="checkbox" with aria-checked on each row's RowSelectCheckbox, which is what exposes that row's selection as an operable control rather than as state alone`,"aria-rowcount/aria-colcount on the <table> when rendered rows/columns are a window onto a larger set; omitted unless set. Per-row aria-rowindex on <tr> and aria-colindex on cells are consumer-supplied \u2014 Table renders no rows and cannot number them. rowCount without per-row aria-rowindex is incomplete.",`no aria-selected on a <tr>, in either mode: it is a grid state, this family is a role="table", and emitting it would promise a grid keyboard contract Table does not implement. data-state="selected" carries the same fact for styling, and the row's RowSelectCheckbox carries it for assistive tech`],focusManagement:`A sortable TableHeaderCell renders a <button data-skdx-table-sort-trigger> around its label (APG pattern) \u2014 the focusable sort control. A resizable one appends a tabbable role="separator" handle. The <th> itself is never focusable. Neither is a <tr>: selection is reached only through the row's own RowSelectCheckbox, so tables where selectionMode is not 'none' MUST render one in every selectable row, and no row gets a tabindex. In role="table" every focusable element joins the tab sequence, so focusable rows would put the entire body in it; one checkbox per row is a single tab stop with the state as aria-checked. Row clicks stay pointer-only shortcuts. assertTableSelectionContract in @skdx/shared/testing enforces this.`},styling:{cssParts:["table","header","body","footer","row","header-cell","sort-trigger","indicator","resizer","cell","checkbox","caption","expand-trigger","detail-row","detail-cell","empty","empty-cell","column-header-sort-trigger","column-header-filter-input","column-resize-trigger","sort-indicator","select-all-checkbox","row-select-checkbox","expanded-row","column-reorder-trigger","column-pin-trigger","group-row","group-cell","group-trigger","tree-trigger"],dataAttributes:[...r,"data-state","data-sort-direction","data-filterable","data-filtered","data-resizable","data-readonly","data-dragging","data-row-id","data-scope","data-skdx-table-detail-row","data-skdx-table-empty","data-skdx-table-expand-trigger","data-skdx-table-filter-input","data-skdx-table-resizer","data-skdx-table-row-select","data-skdx-table-select-all","data-skdx-table-sort-indicator","data-skdx-table-sort-trigger","data-sort-index","data-column-key","data-reorderable","data-pinnable","data-pinned","data-level","data-skdx-table-reorder-trigger","data-skdx-table-pin-trigger","data-skdx-table-group-row","data-skdx-table-tree-trigger","data-disabled","data-density","data-sticky-header","data-size",{name:"data-skdx-table-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:["--skdx-table-column-width","--skdx-table-pin-offset","--skdx-table-row-level","--skdx-table-sticky-header-height","--skdx-table-cell-padding-inline","--skdx-table-cell-padding-block"]},publicMethods:[{name:"toggleAll",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => void",description:'Selects every id in allIds, or deselects all when every one is already selected. A no-op while selectionMode is "none". Table keeps no row registry, so the caller supplies the id list \u2014 under pagination or virtualization that must be the full list, not the rendered page. An element method on <skdx-table>; reached through the table context in other frameworks (see contextApi).'},{name:"isAllSelected",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => boolean",description:"Whether every id in allIds is selected. False for an empty list, so a select-all checkbox over no rows reads unchecked rather than checked. An element method on <skdx-table>; reached through the table context in the other four frameworks (see contextApi)."},{name:"isSomeSelected",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => boolean",description:"Whether some but not all of allIds are selected \u2014 the indeterminate third state of a select-all checkbox. Mutually exclusive with isAllSelected. An element method on <skdx-table>; reached through the table context in the other four frameworks (see contextApi)."}],contextApi:[{name:"toggleAll",signature:"(allIds: string[]) => void",description:`Selects every id in allIds, or deselects all when every one is already selected. A no-op while selectionMode is "none". The id list must be the full dataset under pagination or virtualization, not the rendered page \u2014 this is what SelectAllCheckbox's scope prop expresses. Also an element method on <skdx-table>.`,accessors:{react:"useTableContext('MyComponent').toggleAll",vue:"inject(TABLE_CONTEXT).toggleAll",svelte:"getContext(TABLE_CONTEXT).toggleAll",angular:"inject(SkdxTableState).toggleAll"}},{name:"isAllSelected",signature:"(allIds: string[]) => boolean",description:"Whether every id in allIds is selected. False for an empty list, so a select-all checkbox over no rows reads unchecked rather than checked. Also an element method on <skdx-table>.",accessors:{react:"useTableContext('MyComponent').isAllSelected",vue:"inject(TABLE_CONTEXT).isAllSelected",svelte:"getContext(TABLE_CONTEXT).isAllSelected",angular:"inject(SkdxTableState).isAllSelected"}},{name:"isSomeSelected",signature:"(allIds: string[]) => boolean",description:"Whether some but not all of allIds are selected \u2014 the indeterminate third state of a select-all checkbox. Mutually exclusive with isAllSelected. Also an element method on <skdx-table>.",accessors:{react:"useTableContext('MyComponent').isSomeSelected",vue:"inject(TABLE_CONTEXT).isSomeSelected",svelte:"getContext(TABLE_CONTEXT).isSomeSelected",angular:"inject(SkdxTableState).isSomeSelected"}}]};export{o as tableContract};
|
|
1
|
+
import{constraintValidationMethods as e,setCustomValidityMethod as t}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as r}from"./styling-hooks.js";var i={name:"Table",purpose:"A structural data-table primitive. Owns only sort and row-selection state; consumers map over their own row data to render rows and cells. Renders a plain <table>.",props:[{name:"sort",type:"TableSortState[]",required:!1,description:"Sorted columns, most significant first, for controlled usage. Always an array, whatever multiSort is set to; [] means nothing is sorted. The shape does not change when multiSort is toggled at runtime \u2014 multiSort governs only whether the array may hold more than one entry."},{name:"defaultSort",type:"TableSortState[]",defaultValue:"[]",required:!1,description:"Initially sorted columns, most significant first, for uncontrolled usage."},{name:"filter",type:"TableFilterState",required:!1,description:"Active column filters for controlled usage: a map from columnKey to the text that column's cells must contain. A column with no entry is unfiltered; {} means nothing is filtered."},{name:"defaultFilter",type:"TableFilterState",defaultValue:"{}",required:!1,description:"Initial column filters, for uncontrolled usage."},{name:"multiSort",type:"boolean",defaultValue:"false",required:!1,description:`Whether activating a second column appends it to the sort instead of replacing the first. It governs the array's length, never its type: off, sort holds at most one entry and at most one header can report aria-sort="ascending" | "descending"; on, it holds as many as the user has activated, most significant first.`},{name:"selected",type:"Set<string> | string[]",required:!1,description:"Selected row ids, for controlled usage."},{name:"defaultSelected",type:"Set<string> | string[]",required:!1,description:"Initially selected row ids, for uncontrolled usage."},{name:"selectionMode",type:"'single' | 'multiple' | 'none'",defaultValue:"'none'",required:!1,description:"Whether rows can be selected at all, and if so, one or many at once."},{name:"getSortLabel",type:"(column: string, direction: 'asc' | 'desc' | null) => string",defaultValue:"defaultGetSortLabel",required:!1,description:'Formats the message announced through the LiveAnnouncer when a sortable header is activated. `column` is the header cell\'s own text. Return an empty string to announce nothing. The default names the column and new direction \u2014 "Amount sorted ascending" / "Amount sorted descending", and "Amount not sorted" once cleared.'},{name:"expandedRowIds",type:"string[]",required:!1,description:"Row ids whose ExpandedRow detail row is open, for controlled usage."},{name:"defaultExpandedRowIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded detail rows, for uncontrolled usage."},{name:"columnWidths",type:"Record<string, number>",required:!1,description:"Per-column pixel widths keyed by a header cell's columnKey, for controlled usage."},{name:"defaultColumnWidths",type:"Record<string, number>",defaultValue:"{}",required:!1,description:"Initial per-column pixel widths, for uncontrolled usage. Columns left out size themselves until resized."},{name:"columnOrder",type:"string[]",required:!1,description:"Display order of column keys, for controlled usage. Keys not listed follow in source order; [] means source order. The primitive never reorders your cells \u2014 only the derived columns/data view renders in this order."},{name:"defaultColumnOrder",type:"string[]",defaultValue:"[]",required:!1,description:"Initial column order, for uncontrolled usage."},{name:"columnPins",type:"TableColumnPins",required:!1,description:"Pinned columns for controlled usage: a map from columnKey to 'start' or 'end'. An unpinned column is absent; {} means nothing is pinned. Pinned cells become sticky and receive --skdx-table-pin-offset."},{name:"defaultColumnPins",type:"TableColumnPins",defaultValue:"{}",required:!1,description:"Initially pinned columns, for uncontrolled usage."},{name:"getMoveLabel",type:"(column: string, position: number, count: number) => string",defaultValue:"defaultGetMoveLabel",required:!1,description:'Formats the message announced through the LiveAnnouncer after a column is moved by keyboard or dropped. `column` is the header cell\'s own text, `position` is 1-based. Return an empty string to announce nothing. The default reads "Amount moved to position 2 of 5".'},{name:"collapsedGroups",type:"string[]",required:!1,description:"Group keys whose rows are hidden, for controlled usage. Groups start expanded, so [] shows every group."},{name:"defaultCollapsedGroups",type:"string[]",defaultValue:"[]",required:!1,description:"Initially collapsed groups, for uncontrolled usage."},{name:"expandedNodeIds",type:"string[]",required:!1,description:"Tree parents whose child rows are rendered, for controlled usage. Distinct from expandedRowIds, which opens detail rows."},{name:"defaultExpandedNodeIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded tree parents, for uncontrolled usage."},{name:"rowCount",type:"number",required:!1,description:"The total number of rows in the full dataset, reflected as aria-rowcount on the <table>. Set it when rows in the DOM are not all rows there are (pagination, virtualization, infinite scroll), else assistive tech counts rendered rows and reports wrong position. Use -1 when the total is unknown \u2014 what ARIA reserves it for. Omitted when unset, so a table rendering all rows says nothing. Per-row aria-rowindex stays the consumer's: Table renders no rows and cannot number them."},{name:"columnCount",type:"number",required:!1,description:"The total number of columns in the full dataset, reflected as aria-colcount on the <table>. Column counterpart of rowCount for tables showing a horizontal window. Use -1 when unknown. Omitted when unset. Per-cell aria-colindex, like aria-rowindex, is consumer-supplied."},{name:"columns",type:"TableColumn<T>[]",required:!1,description:"The columns the derived <thead>/<tbody> draws from \u2014 one HeaderCell and one Cell per row. Each is { key, header?, cell?, sortable?, resizable?, minWidth?, maxWidth? }: key is the columnKey, header defaults to key, and column settings override root defaults. Required together with data to derive the whole table; omit both and compose the body by hand from Row and Cell instead. React alone enforces the pair in its types, because only there is the deriving recipe a separate component from the root."},{name:"data",type:"T[]",required:!1,description:"The rows to render, one derived Row per entry. columns' datum type is inferred from this, so a consumer annotates neither columns nor renderCell. Required together with columns to derive the whole table; omit both and compose the body by hand."},{name:"rowId",type:"(row: T, index: number) => string",defaultValue:"(row, index) => String(row.id ?? index)",required:!1,description:"Derives each row's identity for selection, expansion, and list keys. Defaults to the row's id if it's a string/number, otherwise its index. Index-only identity breaks selection when data reorders, since a selected id silently points to a different row."},{name:"getRowLabel",type:"(row: T, index: number) => string",required:!1,description:`Names each row for the derived RowSelectCheckbox and ExpandTrigger, which speak it as "Select <label>" and "Details for <label>". Return the row's own human-readable text \u2014 a person's name, an invoice number \u2014 because without it a control is named from bookkeeping: the rowId or the row's position, neither of which identifies anything to a screen reader, and the position goes stale the moment a sort reorders the rows.`},{name:"sortable",type:"boolean",defaultValue:"false",required:!1,description:"Default sortable for columns with no own setting. Makes the derived view render rows in live sort order \u2014 a copy of data sorted by most-significant column first, never data itself. The primitive never reorders your rows; this recipe sorts its own copy on top of the sort state."},{name:"filterable",type:"boolean",defaultValue:"false",required:!1,description:"Default filterable for columns with no own setting. A filterable column derives a ColumnHeaderFilterInput under its header, and the derived view renders only the rows whose stringified cell contains every active filter's text, case-insensitively \u2014 a filtered copy, applied before the sort, never data itself."},{name:"selectable",type:"boolean",defaultValue:"false",required:!1,description:"Derives a leading SelectAllCheckbox/RowSelectCheckbox column. Sugar over selectionMode: raises 'none' to 'multiple' once; explicit selectionMode always wins for a single source of truth."},{name:"expandable",type:"boolean",defaultValue:"false",required:!1,description:"Derives a leading ExpandTrigger column and an ExpandedRow per row. A boolean, not the content itself \u2014 renderExpanded supplies the detail row's content, and without it the derived detail row is empty."},{name:"renderExpanded",type:"(row: T) => React.ReactNode",required:!1,description:"Renders a derived ExpandedRow's detail content for one row. Ignored while expandable is false."},{name:"resizable",type:"boolean",defaultValue:"false",required:!1,description:"Default resizable for every column that doesn't set its own."},{name:"reorderable",type:"boolean",defaultValue:"false",required:!1,description:"Default reorderable for every column that doesn't set its own. A reorderable column derives a ColumnReorderTrigger, and the derived view renders columns in columnOrder."},{name:"pinnable",type:"boolean",defaultValue:"false",required:!1,description:"Default pinnable for every column that doesn't set its own. A pinnable column derives a ColumnPinTrigger, and the derived view renders pinned-start columns first and pinned-end columns last."},{name:"groupBy",type:"string",required:!1,description:"A column key to group rows by. The derived view emits a GroupRow per distinct String(row[groupBy]) after filter and sort, groups ordered by first appearance, and hides a group's rows while its key is in collapsedGroups."},{name:"renderGroupHeader",type:"(groupKey: string, rows: T[]) => React.ReactNode",required:!1,description:`Renders a derived GroupRow's label for one group. Ignored without groupBy. Defaults to the key and the row count, as in "EMEA (12)".`},{name:"getSubRows",type:"(row: T) => T[] | undefined",required:!1,description:"Returns a row's child rows to render it as a tree parent. Children render under the parent while its id is in expandedNodeIds, sorted per level, one level deeper each time; the filter applies to top-level rows only. A parent derives a TreeTrigger in its first data cell."},{name:"empty",type:"React.ReactNode",required:!1,description:"Content for the derived Empty row, shown in place of body rows while data is empty. No default text: with no empty supplied, no empty row is derived \u2014 avoiding an i18n leak."},{name:"caption",type:"React.ReactNode",required:!1,description:"Content for a derived Caption, rendered before the header. No caption is derived when omitted."},{name:"renderCell",type:"(row: T, column: TableColumn<T>) => React.ReactNode",required:!1,description:"Fallback cell renderer for a column with no cell of its own. With neither, a cell renders String(row[column.key])."},{name:"density",type:"'compact' | (string & {})",required:!1,description:"Vertical rhythm rung, written to data-density on the root; the data-density attribute may be set directly instead."},{name:"stickyHeader",type:"boolean",required:!1,description:"Pins the header row while the body scrolls, written to data-sticky-header on the root; the data-sticky-header attribute may be set directly instead."},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Size rung forwarded to RowSelectCheckbox's and SelectAllCheckbox's data-size; either attribute may be written directly instead."}],events:[{name:"sort-change",description:"Fires with the new sort state whenever a sortable header is activated. The payload is always a TableSortState[], most significant first \u2014 [] once the last sorted column has cycled back to unsorted \u2014 regardless of multiSort.",detail:"TableSortState[]"},{name:"filter-change",detail:"TableFilterState",description:"Fires with the new filter map whenever a column's filter text changes; a cleared column leaves the map, so {} means nothing is filtered."},{name:"selected-change",detail:"string[]",description:"Fires with the new selected row ids whenever selection changes."},{name:"expanded-row-ids-change",detail:"string[]",description:"Fires with the new set of expanded row ids whenever an ExpandTrigger is activated."},{name:"column-widths-change",description:"Fires with the full width map whenever a resizable column is dragged or keyboard-resized \u2014 continuously, on every drag frame and every arrow-key nudge, because the column must follow the pointer. Persist from column-widths-commit instead.",detail:"Record<string, number>"},{name:"column-widths-commit",description:'The settled counterpart of column-widths-change, carrying the same width map: fired once per gesture rather than per frame, so persisting writes once instead of dozens. Fires on pointerup, pointercancel at drag end, Escape (reverting the width), and keyup after Arrow/Home/End resize. Never fires for unchanged gestures (movement-less pointerdown or clamped arrow), so it means "this is the width to store".',detail:"Record<string, number>"},{name:"column-order-change",detail:"string[]",description:"Fires with the full column order whenever a ColumnReorderTrigger moves its column by keyboard or drop."},{name:"column-pins-change",detail:"TableColumnPins",description:"Fires with the full pin map whenever a ColumnPinTrigger is activated."},{name:"collapsed-groups-change",detail:"string[]",description:"Fires with the collapsed group keys whenever a GroupRow is toggled."},{name:"expanded-node-ids-change",detail:"string[]",description:"Fires with the expanded tree parents whenever a TreeTrigger is activated."}],parts:[{name:"Row",description:`A <tr>. Given a rowId and while selectionMode is not 'none', publishes data-row-id, reports selection as data-state="selected", and toggles selection when clicked. The click is pointer sugar, not the affordance: the row is never focusable and never carries a tabindex, so every selectable Row MUST contain a RowSelectCheckbox \u2014 the keyboard path to selecting.`,props:[{name:"rowId",type:"string",required:!1,description:"This row's identifier within the table's selection state. Required for the row to be selectable; a row without one is never selected and never clickable-to-select."},{name:"level",type:"number",required:!1,description:"Tree depth, 0 for a top-level row. Written to data-level and --skdx-table-row-level so the skin indents the first cell; the derived view sets it for every tree row."}]},{name:"Cell",description:"A <td>. Given a columnKey it reflects that column's pin as data-pinned and --skdx-table-pin-offset.",props:[{name:"columnKey",type:"string",required:!1,description:"The column this cell belongs to, so it can follow a pinned header. Set by the derived view; optional when composing by hand."}],slots:[{name:"default",description:"A plain TableCell data cell."}]},{name:"RowSelectCheckbox",description:"One row's selection checkbox, driven by the table's selection state, rendered inside a Cell of its row. Required in every selectable row: it's the only focusable control that selects one, so omitting it makes the table pointer-only. Space toggles it, Shift-activation extends selection to a range. Needs a row-specific accessible name \u2014 no default because only the consumer knows what names the row. Being a Checkbox, it inherits form participation: name and value submit as a pair from inside a <form> (see formBehavior).",props:[{name:"checked",type:"boolean",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"Only the custom element publishes it. The other four hand this derived state down to their parts through context, so a consumer never reads it off a part; here every part is its own element with no such channel, and reading it back is the only way to reflect the state in surrounding markup.",description:"Whether this row is currently selected. Read-only: toggle it through the table's selected row ids."},{name:"rowId",type:"string",required:!0,description:"The row this checkbox selects. Must match the rowId on the enclosing Row."},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the checkbox; the data-size attribute may be set directly instead."}],methods:[...e,t]},{name:"SelectAllCheckbox",description:'The header checkbox that selects or clears a whole set of rows at once. Tri-state: checked when every id in rowIds is selected, indeterminate when only some are, unchecked otherwise \u2014 including over an empty list, where a select-all above no rows reads unchecked rather than vacuously checked. Meaningful only with selectionMode="multiple".',props:[{name:"checked",type:"boolean",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"Only the custom element publishes it. The other four hand this derived state down to their parts through context, so a consumer never reads it off a part; here every part is its own element with no such channel, and reading it back is the only way to reflect the state in surrounding markup.",description:"Whether every row in rowIds is currently selected. Read-only: toggle it through the table's selected row ids."},{name:"rowIds",type:"string[]",required:!0,description:'Exactly the rows this checkbox covers. Required because Table keeps no row registry: "select all" means the ids you hand it and nothing else, so under pagination or virtualization it is either the rendered page or the whole dataset, and only the consumer knows which.'},{name:"scope",type:"'page' | 'all'",required:!0,description:"Which set rowIds is \u2014 the rendered page or the entire dataset. Required and undefaulted: the two behave identically until the table is paginated or virtualized, at which point a select-all that silently covered only the visible window is a bug found in production. It is also published as data-scope and spoken in the default accessible name."},{name:"getSelectAllLabel",type:"(scope: 'page' | 'all', count: number) => string",defaultValue:"defaultSelectAllLabel \u2014 `Select all N rows on this page` / `Select all N rows`",required:!1,description:`Formats the checkbox's own accessible name. The default names the count and the scope rather than a bare "Select all", because "select all 40 rows on this page" and "select all 1,204 rows" are different promises and the user has to hear which one is on offer.`},{name:"size",type:"'sm' | 'md' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the checkbox; the data-size attribute may be set directly instead."}],methods:[...e,t]},{name:"HeaderCell",description:"A <th>. A column has one identifier, columnKey, and sorting, filtering and resizing all key off it. Sortable when given `sortable`; filterable when given `filterable`; resizable when given `resizable`. Any affordance needs a columnKey \u2014 a column with no identifier has nowhere to read its sort or filter from or store its width in, so all are suppressed however the booleans are set. Carries data-filterable, and data-filtered while its filter text is non-empty.",props:[{name:"columnKey",type:"string",required:!1,description:"This column's single identifier, used by both sorting and resizing. Required for a column that does either. It is the key that appears in a TableSortState and in the columnWidths map."},{name:"sortable",type:"boolean",defaultValue:"false",required:!1,description:"Whether this column can be sorted. A sortable cell sets aria-sort and data-sort-direction and wraps its children in a ColumnHeaderSortTrigger unless the consumer rendered one."},{name:"filterable",type:"boolean",defaultValue:"false",required:!1,description:"Whether this column can be filtered. A filterable cell renders a ColumnHeaderFilterInput after its label unless the consumer rendered one."},{name:"filterLabel",type:"string",defaultValue:"Filter ${columnKey}",required:!1,description:'Accessible name for the derived filter input, which needs one of its own; the deriving recipe passes "Filter <header text>".'},{name:"resizable",type:"boolean",defaultValue:"false",required:!1,description:`Renders a focusable role="separator" resize handle at the cell's inline end, driven by pointer drag or Arrow Left/Right (Home/End for the bounds).`},{name:"minWidth",type:"number",defaultValue:"40",required:!1,description:"Smallest width in pixels the column can be resized to."},{name:"maxWidth",type:"number",defaultValue:"1000",required:!1,description:"Largest width in pixels the column can be resized to."},{name:"resizeStep",type:"number",defaultValue:"8",required:!1,description:"Pixels one Arrow Left/Right press moves the edge, handed down to this cell's ColumnResizeTrigger."},{name:"resizeLabel",type:"string",defaultValue:"'Resize column'",required:!1,description:"Accessible name for the resize handle, which needs one of its own."},{name:"reorderable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a ColumnReorderTrigger after the label unless the consumer rendered one. Needs a columnKey. Carries data-reorderable."},{name:"pinnable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a ColumnPinTrigger after the label unless the consumer rendered one. Needs a columnKey. Carries data-pinnable, and data-pinned plus --skdx-table-pin-offset while pinned."},{name:"reorderLabel",type:"string",defaultValue:"'Move column'",required:!1,description:"Accessible name for the derived reorder trigger."},{name:"pinLabel",type:"string",defaultValue:"'Pin column'",required:!1,description:"Accessible name for the derived pin trigger."}],slots:[{name:"default",description:"A TableHeaderCell \u2014 optionally sortable via `sortable` plus a columnKey, in which case it wraps its label in a sort button."}]},{name:"ColumnHeaderFilterInput",description:`The <input type="search"> inside a filterable HeaderCell, bound to that column's entry in the filter map: typing writes it, clearing removes it. A filterable HeaderCell renders one after its label automatically, standing down when it finds one, so exactly one exists per column. Marked data-skdx-table-filter-input, and data-filtered while non-empty. Renders nothing when it can't find a column to filter.`,props:[{name:"columnKey",type:"string",required:!1,description:"The column this input filters. Normally omitted: inside a filterable HeaderCell it inherits the cell's columnKey. Pass it when the input sits outside a header cell or inside one left non-filterable \u2014 an explicit key is itself the opt-in."}]},{name:"ColumnHeaderSortTrigger",description:"The <button> inside a sortable HeaderCell that cycles ascending \u2192 descending \u2192 unsorted (APG sortable-table pattern). The control is a button inside the <th>, announcing as a button, activating on Enter/Space with no library key handling, and leaving the header out of the tab order. A sortable HeaderCell renders one around its children automatically, standing down when it finds one, so exactly one exists per column whether or not the consumer wrote it. Writing one is how to add an indicator, icon, or count inside the button. Carries data-sort-direction and, under multiSort, data-sort-index (the 0-based position for multi-sorted badges). Renders nothing when it can't find a column to sort, because a button that does nothing is worse than no button.",props:[{name:"columnKey",type:"string",required:!1,description:"The column this trigger sorts. Normally omitted: inside a sortable HeaderCell it inherits the cell's columnKey, which is the whole point of the cell owning one identifier for sorting and resizing alike. Pass it when the trigger sits outside a header cell, or inside one deliberately left non-sortable \u2014 an explicit key here is itself the opt-in, so the trigger sorts without the cell having to declare sortable and light up its own aria-sort wiring."}]},{name:"ColumnResizeTrigger",description:'The role="separator" handle a HeaderCell\'s `resizable` renders \u2014 or that a consumer renders directly to place it elsewhere or to give one column a different step. Drag, or focus and use Arrow Left/Right/Home/End, to resize the column.',props:[{name:"columnKey",type:"string",required:!1,description:"Which column this handle resizes. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"minWidth",type:"number",required:!1,description:"Lower clamp for the drag and for the Home key. Falls back to the enclosing HeaderCell's minWidth, then to a component default of 40."},{name:"maxWidth",type:"number",required:!1,description:"Upper clamp for the drag and for the End key. Falls back to the enclosing HeaderCell's maxWidth, then to a component default of 1000."},{name:"step",type:"number",required:!1,description:"Pixels one Arrow Left/Right press moves the edge. Falls back to the enclosing HeaderCell's resizeStep, then to a component default of 8. Keyboard only \u2014 a pointer drag follows the pointer."}]},{name:"ColumnReorderTrigger",description:'The <button> a HeaderCell\'s `reorderable` renders, or a consumer places, to move the column. Focus it and press Arrow Left/Right to move one position (mirrored under dir="rtl") or Home/End to move to the ends; drag it over another header cell to drop the column there. Every move publishes the full order and is announced through getMoveLabel. Carries data-dragging during a drag. Renders nothing without a column key.',props:[{name:"columnKey",type:"string",required:!1,description:"Which column this trigger moves. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"label",type:"string",required:!1,description:"Accessible name for the trigger. Falls back to the enclosing HeaderCell's reorderLabel, then to 'Move column'."}]},{name:"ColumnPinTrigger",description:"The <button aria-pressed> a HeaderCell's `pinnable` renders, or a consumer places, to pin the column to one side. Pressed while the column is pinned to `side`; activating it unpins, otherwise pins to `side`. Carries data-pinned mirroring the column. Renders nothing without a column key.",props:[{name:"columnKey",type:"string",required:!1,description:"Which column this trigger pins. Normally omitted: inside a HeaderCell it inherits the cell's columnKey."},{name:"side",type:"'start' | 'end'",defaultValue:"'start'",required:!1,description:"Which edge the column pins to."},{name:"label",type:"string",required:!1,description:"Accessible name for the trigger. Falls back to the enclosing HeaderCell's pinLabel, then to 'Pin column'."}]},{name:"GroupRow",description:'The row that heads a group of rows: a <tr> holding one <th scope="rowgroup" colspan> whose <button aria-expanded> wraps the children and toggles the group. Carries data-state="expanded" | "collapsed".',props:[{name:"groupKey",type:"string",required:!0,description:"The group this row heads; the key that appears in collapsedGroups."},{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the group cell spans \u2014 the table's column count."}],slots:[{name:"default",description:"A derived GroupRow's label, given the group key and its rows."}]},{name:"TreeTrigger",lightDom:!0,description:"Disclosure button inside a tree parent's first cell, carrying aria-expanded for that row's child rows. No aria-controls: the children are sibling rows, not one element.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the parent row this trigger expands; the id that appears in expandedNodeIds."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue, Svelte and Angular take `aria-label` on the element through attribute passthrough.",description:"Accessible name for the disclosure button, since its content is usually an icon."}]},{name:"SortIndicator",description:'The arrow, caret, or badge showing how a column is sorted: a <span aria-hidden="true"> with data-sort-direction ("asc"/"desc"/"none") and, under multiSort, data-sort-index. The aria-hidden is fixed \u2014 the HeaderCell publishes aria-sort and the sort trigger announces through the live announcer, so an indicator that also spoke would triple-announce the sort. It renders children and stays mounted in all three states, not swapping in/out, so a CSS arrow can rotate between them and an unsorted column reserves space.',props:[{name:"columnKey",type:"string",required:!1,description:"The column whose direction this indicator reflects. Normally omitted: it inherits the enclosing HeaderCell's columnKey, so an indicator dropped inside a header needs no wiring. Unlike the sort trigger it inherits from any header cell rather than only a sortable one, because reflecting a direction is not the same act as offering to change it \u2014 an indicator is free to sit in a column sorted from outside the header."}]},{name:"ExpandTrigger",lightDom:!0,description:"Disclosure button placed inside a row's cell, carrying aria-expanded and aria-controls pointing at that row's ExpandedRow.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the row this trigger expands; must match the paired ExpandedRow."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue, Svelte and Angular take `aria-label` on the element through attribute passthrough.",description:"Accessible name for the disclosure button, since its content is usually an icon."}]},{name:"ExpandedRow",description:"The full-width detail row an ExpandTrigger reveals: a <tr> with a single <td colspan> holding the expanded content. Stays mounted while collapsed so aria-controls resolves.",props:[{name:"rowId",type:"string",required:!0,description:"Id of the row this detail row belongs to."},{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the detail cell spans \u2014 the table's column count."}],slots:[{name:"default",description:"An ExpandedRow's detail content, spanning the full column width."}]},{name:"Empty",description:'The row rendered in place of body rows when there is no data: a <tr data-state="empty"> whose single <td colspan> holds the empty-state message.',props:[{name:"colSpan",type:"number",defaultValue:"1",required:!1,description:"How many columns the empty cell spans \u2014 the table's column count."}],slots:[{name:"default",description:"The empty-state message shown in place of body rows when there is no data."}]}],slots:[{name:"default",description:"Table sections \u2014 Header, Body, Footer, Caption."},{name:"empty",description:"The empty-state message shown in place of body rows when there is no data.",frameworks:["react","svelte"],exception:"derived-anatomy",frameworksReason:"The root exposes empty as content projection in react, svelte. Other wrappers project default content into the Empty part or use their separately documented rendering property; they do not accept a root named slot with this spelling."},{name:"group-header",description:"A derived GroupRow's label, given the group key and its rows.",frameworks:["vue"],exception:"derived-anatomy",frameworksReason:"Vue spells this root projection group-header; the other wrappers compose GroupRow with default content or use the documented rendering callback instead of that named slot."},{name:"caption",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose caption as native content projection for the caption rendering capability. Other frameworks pass the documented caption render prop or template instead of a named slot with this spelling.",description:"Content for a derived Caption, rendered before the header. No caption is derived when omitted."},{name:"render-cell",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose render-cell as native content projection for the renderCell rendering capability. Other frameworks pass the documented renderCell render prop or template instead of a named slot with this spelling.",description:"Fallback cell renderer for a column with no cell of its own. With neither, a cell renders String(row[column.key])."},{name:"render-expanded",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose render-expanded as native content projection for the renderExpanded rendering capability. Other frameworks pass the documented renderExpanded render prop or template instead of a named slot with this spelling.",description:"Renders a derived ExpandedRow's detail content for one row. Ignored while expandable is false."},{name:"render-group-header",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose render-group-header as native content projection for the renderGroupHeader rendering capability. Other frameworks pass the documented renderGroupHeader render prop or template instead of a named slot with this spelling.",description:`Renders a derived GroupRow's label for one group. Ignored without groupBy. Defaults to the key and the row count, as in "EMEA (12)".`}],appearance:[{attribute:"data-density",values:["compact"],stylesheet:"table.css"},{attribute:"data-sticky-header",values:[],stylesheet:"table.css"}],states:["default","selected","expanded","collapsed","empty"],controlledUncontrolled:"Sort, selection, expanded detail rows, column widths, column order, column pins, collapsed groups and expanded tree nodes each work controlled or uncontrolled, independently of one another.",formBehavior:`The Table root submits nothing (no name, value, or hidden input), so a <form> containing it gains no field. But its two checkbox parts are different: RowSelectCheckbox and SelectAllCheckbox inherit Checkbox's form participation wholly \u2014 name, value, required, invalid all work. A named RowSelectCheckbox submits its pair through a hidden input like any other checkbox. This makes a selection table usable as HTML form: name="rowIds" and value={row.id} means formData.getAll("rowIds") is the selection. Important: checkbox checked state stays owned by table selection, not the form, so form reset doesn't clear selection. Required on a row checkbox blocks submission on that row, not "select at least one row" \u2014 validate selection yourself.`,validationBehavior:"Not applicable \u2014 Table carries no single value and participates in no validation.",accessibility:{role:"table (native <table>)",keyboard:[{key:"Enter/Space",behavior:"Activates a focused sort button, cycling its column's sort, or a focused ExpandTrigger, toggling its detail row (native button activation). Likewise a focused ColumnPinTrigger, GroupRow button, or TreeTrigger."},{key:"Space",behavior:"Toggles a focused RowSelectCheckbox, selecting/deselecting its row, or a focused SelectAllCheckbox (native activation). With Shift on a RowSelectCheckbox it extends selection to a range, like Shift-click. This is the only keyboard path to row selection: the row itself is never focusable, so a Table without RowSelectCheckbox is operable by pointer alone."},{key:"ArrowLeft/ArrowRight",behavior:'Narrows/widens the column while its resize handle has focus, clamped to minWidth/maxWidth; moves the column one position while its reorder trigger has focus. Mirrored under dir="rtl".'},{key:"Home/End",behavior:"Jumps the focused resize handle's column to minWidth/maxWidth; moves the focused reorder trigger's column to the first/last position."}],ariaAttributes:["aria-sort on a sortable TableHeaderCell reflects its current sort direction","activating a sort button announces the new sort through the shared LiveAnnouncer polite region, formatted by getSortLabel \u2014 a changed aria-sort is not itself re-announced","aria-expanded on an ExpandTrigger, with aria-controls pointing at its row's ExpandedRow id","aria-pressed on a ColumnPinTrigger while its column is pinned to its side","aria-expanded on a GroupRow's button and on a TreeTrigger; neither carries aria-controls because the rows they reveal are siblings, not one element","a keyboard move or a drop announces the new position through the shared LiveAnnouncer, formatted by getMoveLabel",'role="separator" with aria-orientation="vertical", aria-valuenow/valuemin/valuemax and its own aria-label on a resize handle',`role="checkbox" with aria-checked on each row's RowSelectCheckbox, which is what exposes that row's selection as an operable control rather than as state alone`,"aria-rowcount/aria-colcount on the <table> when rendered rows/columns are a window onto a larger set; omitted unless set. Per-row aria-rowindex on <tr> and aria-colindex on cells are consumer-supplied \u2014 Table renders no rows and cannot number them. rowCount without per-row aria-rowindex is incomplete.",`no aria-selected on a <tr>, in either mode: it is a grid state, this family is a role="table", and emitting it would promise a grid keyboard contract Table does not implement. data-state="selected" carries the same fact for styling, and the row's RowSelectCheckbox carries it for assistive tech`],focusManagement:`A sortable TableHeaderCell renders a <button data-skdx-table-sort-trigger> around its label (APG pattern) \u2014 the focusable sort control. A resizable one appends a tabbable role="separator" handle. The <th> itself is never focusable. Neither is a <tr>: selection is reached only through the row's own RowSelectCheckbox, so tables where selectionMode is not 'none' MUST render one in every selectable row, and no row gets a tabindex. In role="table" every focusable element joins the tab sequence, so focusable rows would put the entire body in it; one checkbox per row is a single tab stop with the state as aria-checked. Row clicks stay pointer-only shortcuts. assertTableSelectionContract in @skdx/shared/testing enforces this.`},styling:{cssParts:["table","header","body","footer","row","header-cell","sort-trigger","indicator","resizer","cell","checkbox","caption","expand-trigger","detail-row","detail-cell","empty","empty-cell","column-header-sort-trigger","column-header-filter-input","column-resize-trigger","sort-indicator","select-all-checkbox","row-select-checkbox","expanded-row","column-reorder-trigger","column-pin-trigger","group-row","group-cell","group-trigger","tree-trigger"],dataAttributes:[...r,"data-state","data-sort-direction","data-filterable","data-filtered","data-resizable","data-readonly","data-dragging","data-row-id","data-scope","data-skdx-table-detail-row","data-skdx-table-empty","data-skdx-table-expand-trigger","data-skdx-table-filter-input","data-skdx-table-resizer","data-skdx-table-row-select","data-skdx-table-select-all","data-skdx-table-sort-indicator","data-skdx-table-sort-trigger","data-sort-index","data-column-key","data-reorderable","data-pinnable","data-pinned","data-level","data-skdx-table-reorder-trigger","data-skdx-table-pin-trigger","data-skdx-table-group-row","data-skdx-table-tree-trigger","data-disabled","data-density","data-sticky-header","data-size",{name:"data-skdx-table-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:["--skdx-table-column-width","--skdx-table-pin-offset","--skdx-table-row-level","--skdx-table-sticky-header-height","--skdx-table-cell-padding-inline","--skdx-table-cell-padding-block"]},publicMethods:[{name:"toggleAll",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => void",description:'Selects every id in allIds, or deselects all when every one is already selected. A no-op while selectionMode is "none". Table keeps no row registry, so the caller supplies the id list \u2014 under pagination or virtualization that must be the full list, not the rendered page. An element method on <skdx-table>; reached through the table context in other frameworks (see contextApi).'},{name:"isAllSelected",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => boolean",description:"Whether every id in allIds is selected. False for an empty list, so a select-all checkbox over no rows reads unchecked rather than checked. An element method on <skdx-table>; reached through the table context in the other four frameworks (see contextApi)."},{name:"isSomeSelected",frameworks:["angular","webComponents"],exception:"imperative",frameworksReason:"React, Vue and Svelte have no component instance to hang a method off \u2014 Table's root forwards a DOM ref, not an imperative handle \u2014 so `useTableContext` and the two context injections are those frameworks' binding of this member, declared under `contextApi` below. Angular's component and `<skdx-table>` do have instances, and expose it as a method.",signature:"(allIds: string[]) => boolean",description:"Whether some but not all of allIds are selected \u2014 the indeterminate third state of a select-all checkbox. Mutually exclusive with isAllSelected. An element method on <skdx-table>; reached through the table context in the other four frameworks (see contextApi)."}],contextApi:[{name:"toggleAll",signature:"(allIds: string[]) => void",description:`Selects every id in allIds, or deselects all when every one is already selected. A no-op while selectionMode is "none". The id list must be the full dataset under pagination or virtualization, not the rendered page \u2014 this is what SelectAllCheckbox's scope prop expresses. Also an element method on <skdx-table>.`,accessors:{react:"useTableContext('MyComponent').toggleAll",vue:"inject(TABLE_CONTEXT).toggleAll",svelte:"getContext(TABLE_CONTEXT).toggleAll",angular:"inject(SkdxTableState).toggleAll"}},{name:"isAllSelected",signature:"(allIds: string[]) => boolean",description:"Whether every id in allIds is selected. False for an empty list, so a select-all checkbox over no rows reads unchecked rather than checked. Also an element method on <skdx-table>.",accessors:{react:"useTableContext('MyComponent').isAllSelected",vue:"inject(TABLE_CONTEXT).isAllSelected",svelte:"getContext(TABLE_CONTEXT).isAllSelected",angular:"inject(SkdxTableState).isAllSelected"}},{name:"isSomeSelected",signature:"(allIds: string[]) => boolean",description:"Whether some but not all of allIds are selected \u2014 the indeterminate third state of a select-all checkbox. Mutually exclusive with isAllSelected. Also an element method on <skdx-table>.",accessors:{react:"useTableContext('MyComponent').isSomeSelected",vue:"inject(TABLE_CONTEXT).isSomeSelected",svelte:"getContext(TABLE_CONTEXT).isSomeSelected",angular:"inject(SkdxTableState).isSomeSelected"}}],frameworkExtensions:[{framework:"react",part:"RowSelectCheckbox",name:"disabled",type:"boolean | undefined",description:"Native <input> disabled binding on react TableRowSelectCheckbox. Disables the checkbox and excludes it from the tab order. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"disabled",type:"boolean",description:"Native <input> disabled binding on angular TableRowSelectCheckbox. Disables toggling and takes the checkbox out of the tab order. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"disabled",type:"boolean",description:"Native <input> disabled binding on webComponents TableRowSelectCheckbox. Disables toggling and excludes the control from the tab order and from submission. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"RowSelectCheckbox",name:"form",type:"string | undefined",description:"Native <input> form binding on react TableRowSelectCheckbox. Id of the `<form>` that owns this checkbox when it renders outside it, forwarded to the hidden input's `form` attribute. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"RowSelectCheckbox",name:"form",type:"string | null | undefined",description:"Native <input> form binding on svelte TableRowSelectCheckbox. Id of the `<form>` that owns this checkbox, forwarded to the hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"form",type:"string",description:"Native <input> form binding on angular TableRowSelectCheckbox. Id of the `<form>` that owns this checkbox, forwarded to the hidden input's `form` attribute. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"form",type:"HTMLFormElement | null",description:'Native <input> form binding on webComponents TableRowSelectCheckbox. Re-associates with `value`\'s form via the native `form="id"` attribute, or clears it for a target with no `id`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.',kind:"prop"},{framework:"react",part:"RowSelectCheckbox",name:"name",type:"string | undefined",description:"Native <input> name binding on react TableRowSelectCheckbox. Name for native form participation via a hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"RowSelectCheckbox",name:"name",type:"string | null | undefined",description:"Native <input> name binding on svelte TableRowSelectCheckbox. Name for native form participation via a hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"name",type:"string",description:"Native <input> name binding on angular TableRowSelectCheckbox. Name for native form participation via a hidden input. Omitted: no hidden input is rendered. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"name",type:"string | undefined",description:"Native <input> name binding on webComponents TableRowSelectCheckbox. Name used as the `FormData` entry key when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"RowSelectCheckbox",name:"readOnly",type:"boolean | undefined",description:"Native <input> read-only binding on react TableRowSelectCheckbox. Freezes the checked state without freezing the control: keeps focus and `aria-readonly`/`data-readonly`, and ignores click and Space. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"RowSelectCheckbox",name:"readOnly",type:"boolean | undefined",description:"Native <input> read-only binding on svelte TableRowSelectCheckbox. Freezes the selection without freezing the control: keeps its tab stop, but activating it no longer toggles the row. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"readOnly",type:"boolean",description:`Native <input> read-only binding on angular TableRowSelectCheckbox. Freezes the selection without freezing the control: it keeps its tab stop
|
|
2
|
+
and its name, and refuses the toggle. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.`,kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"readOnly",type:"boolean",description:"Native <input> read-only binding on webComponents TableRowSelectCheckbox. Freezes the checked state without disabling the control or its form value. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"RowSelectCheckbox",name:"required",type:"boolean | undefined",description:"Native <input> required binding on react TableRowSelectCheckbox. Marks the underlying hidden input as required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"RowSelectCheckbox",name:"required",type:"boolean | undefined",description:"Native <input> required binding on svelte TableRowSelectCheckbox. Marks the hidden input required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"required",type:"boolean",description:"Native <input> required binding on angular TableRowSelectCheckbox. Marks the hidden input required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"required",type:"boolean",description:"Native <input> required binding on webComponents TableRowSelectCheckbox. Marks the control required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"RowSelectCheckbox",name:"value",type:"string | undefined",description:"Native <input> value binding on react TableRowSelectCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"RowSelectCheckbox",name:"value",type:"string | undefined",description:"Native <input> value binding on svelte TableRowSelectCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"value",type:"string",description:"Native <input> value binding on angular TableRowSelectCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",name:"value",type:"string",description:"Native <input> value binding on webComponents TableRowSelectCheckbox. Value submitted with the form when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"disabled",type:"boolean | undefined",description:"Native <input> disabled binding on react TableSelectAllCheckbox. Disables the checkbox and excludes it from the tab order. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"disabled",type:"boolean",description:"Native <input> disabled binding on angular TableSelectAllCheckbox. Disables toggling and takes the checkbox out of the tab order. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"disabled",type:"boolean",description:"Native <input> disabled binding on webComponents TableSelectAllCheckbox. Disables toggling and excludes the control from the tab order and from submission. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"form",type:"string | undefined",description:"Native <input> form binding on react TableSelectAllCheckbox. Id of the `<form>` that owns this checkbox when it renders outside it, forwarded to the hidden input's `form` attribute. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"SelectAllCheckbox",name:"form",type:"string | null | undefined",description:"Native <input> form binding on svelte TableSelectAllCheckbox. Id of the `<form>` that owns this checkbox, forwarded to the hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"form",type:"string",description:"Native <input> form binding on angular TableSelectAllCheckbox. Id of the `<form>` that owns this checkbox, forwarded to the hidden input's `form` attribute. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"form",type:"HTMLFormElement | null",description:'Native <input> form binding on webComponents TableSelectAllCheckbox. Re-associates with `value`\'s form via the native `form="id"` attribute, or clears it for a target with no `id`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.',kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"name",type:"string | undefined",description:"Native <input> name binding on react TableSelectAllCheckbox. Name for native form participation via a hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"SelectAllCheckbox",name:"name",type:"string | null | undefined",description:"Native <input> name binding on svelte TableSelectAllCheckbox. Name for native form participation via a hidden input. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"name",type:"string",description:"Native <input> name binding on angular TableSelectAllCheckbox. Name for native form participation via a hidden input. Omitted: no hidden input is rendered. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"name",type:"string | undefined",description:"Native <input> name binding on webComponents TableSelectAllCheckbox. Name used as the `FormData` entry key when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"readOnly",type:"boolean | undefined",description:"Native <input> read-only binding on react TableSelectAllCheckbox. Freezes the checked state without freezing the control: keeps focus and `aria-readonly`/`data-readonly`, and ignores click and Space. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"SelectAllCheckbox",name:"readOnly",type:"boolean | undefined",description:"Native <input> read-only binding on svelte TableSelectAllCheckbox. Freezes the selection without freezing the control: keeps its tab stop, but activating it no longer toggles rows. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"readOnly",type:"boolean",description:`Native <input> read-only binding on angular TableSelectAllCheckbox. Freezes the selection without freezing the control: it keeps its tab stop
|
|
3
|
+
and its name, and refuses the toggle. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.`,kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"readOnly",type:"boolean",description:"Native <input> read-only binding on webComponents TableSelectAllCheckbox. Freezes the checked state without disabling the control or its form value. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"required",type:"boolean | undefined",description:"Native <input> required binding on react TableSelectAllCheckbox. Marks the underlying hidden input as required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"SelectAllCheckbox",name:"required",type:"boolean | undefined",description:"Native <input> required binding on svelte TableSelectAllCheckbox. Marks the hidden input required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"required",type:"boolean",description:"Native <input> required binding on angular TableSelectAllCheckbox. Marks the hidden input required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"required",type:"boolean",description:"Native <input> required binding on webComponents TableSelectAllCheckbox. Marks the control required for native form validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"react",part:"SelectAllCheckbox",name:"value",type:"string | undefined",description:"Native <input> value binding on react TableSelectAllCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"svelte",part:"SelectAllCheckbox",name:"value",type:"string | undefined",description:"Native <input> value binding on svelte TableSelectAllCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"value",type:"string",description:"Native <input> value binding on angular TableSelectAllCheckbox. Value submitted with the hidden input when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"SelectAllCheckbox",name:"value",type:"string",description:"Native <input> value binding on webComponents TableSelectAllCheckbox. Value submitted with the form when checked. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"RowSelectCheckbox",kind:"event",name:"checked-change",type:"Content projection",description:"Fired with the new `boolean` checked value whenever the checkbox is toggled; an indeterminate box resolves to checked. This element exposes its native/custom bubbling event to addEventListener consumers; other wrappers integrate the corresponding action through callback props or native DOM listeners. This records the element event spelling without inventing an emitted event on the other wrappers."},{framework:"react",part:"RowSelectCheckbox",name:"indicator",type:"React.ReactNode",description:"Renders a derived `CheckboxIndicator` holding this content in place of the default check glyph, ignored when `children` is given. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax.",kind:"prop"},{framework:"angular",part:"RowSelectCheckbox",name:"indicator",type:"TemplateRef<unknown>",description:"Content drawn into a derived Indicator, when deriving from no content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax.",kind:"prop"},{framework:"vue",part:"RowSelectCheckbox",kind:"slot",name:"indicator",type:"Content projection",description:"indicator content projected by TableRowSelectCheckbox. This framework spells the content customization as a native named slot/snippet on this part; consumers of other wrappers compose the corresponding part or use their documented rendering property."},{framework:"webComponents",part:"SelectAllCheckbox",kind:"event",name:"checked-change",type:"Content projection",description:"Fired with the new `boolean` checked value whenever the checkbox is toggled; an indeterminate box resolves to checked. This element exposes its native/custom bubbling event to addEventListener consumers; other wrappers integrate the corresponding action through callback props or native DOM listeners. This records the element event spelling without inventing an emitted event on the other wrappers."},{framework:"react",part:"SelectAllCheckbox",name:"indicator",type:"React.ReactNode",description:"Renders a derived `CheckboxIndicator` holding this content in place of the default check glyph, ignored when `children` is given. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax.",kind:"prop"},{framework:"angular",part:"SelectAllCheckbox",name:"indicator",type:"TemplateRef<unknown>",description:"Content drawn into a derived Indicator, when deriving from no content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax.",kind:"prop"},{framework:"vue",part:"SelectAllCheckbox",kind:"slot",name:"indicator",type:"Content projection",description:"indicator content projected by TableSelectAllCheckbox. This framework spells the content customization as a native named slot/snippet on this part; consumers of other wrappers compose the corresponding part or use their documented rendering property."},{framework:"webComponents",part:"RowSelectCheckbox",kind:"event",name:"checked-change",type:"Content projection",description:"Fired with the new `boolean` checked value whenever the checkbox is toggled; an indeterminate box resolves to checked. This element exposes its native/custom bubbling event to addEventListener consumers; other wrappers integrate the corresponding action through callback props or native DOM listeners. This records the element event spelling without inventing an emitted event on the other wrappers."},{framework:"react",part:"RowSelectCheckbox",name:"indicator",type:"React.ReactNode",description:"Renders a derived `CheckboxIndicator` holding this content in place of the default check glyph, ignored when `children` is given. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax."},{framework:"angular",part:"RowSelectCheckbox",name:"indicator",type:"TemplateRef<unknown>",description:"Content drawn into a derived Indicator, when deriving from no content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax."},{framework:"vue",part:"RowSelectCheckbox",kind:"slot",name:"indicator",type:"Content projection",description:"indicator content projected by TableRowSelectCheckbox. This framework spells the content customization as a native named slot/snippet on this part; consumers of other wrappers compose the corresponding part or use their documented rendering property."},{framework:"webComponents",part:"SelectAllCheckbox",kind:"event",name:"checked-change",type:"Content projection",description:"Fired with the new `boolean` checked value whenever the checkbox is toggled; an indeterminate box resolves to checked. This element exposes its native/custom bubbling event to addEventListener consumers; other wrappers integrate the corresponding action through callback props or native DOM listeners. This records the element event spelling without inventing an emitted event on the other wrappers."},{framework:"react",part:"SelectAllCheckbox",name:"indicator",type:"React.ReactNode",description:"Renders a derived `CheckboxIndicator` holding this content in place of the default check glyph, ignored when `children` is given. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax."},{framework:"angular",part:"SelectAllCheckbox",name:"indicator",type:"TemplateRef<unknown>",description:"Content drawn into a derived Indicator, when deriving from no content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax."},{framework:"vue",part:"SelectAllCheckbox",kind:"slot",name:"indicator",type:"Content projection",description:"indicator content projected by TableSelectAllCheckbox. This framework spells the content customization as a native named slot/snippet on this part; consumers of other wrappers compose the corresponding part or use their documented rendering property."}]};export{i as tableContract};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{changeDescription as t,changeDetail as e}from"./change-reason.js";import{ROOT_DATA_ATTRIBUTES as a}from"./styling-hooks.js";var r={name:"Tabs",purpose:"A tabbed interface: one composite root owns the selected value and hands it down to a list of tab triggers and a set of tab panels. Behavior and accessibility only \u2014 layout of the list vs. panels is entirely consumer CSS.",props:[{name:"value",type:"string",required:!1,description:"Selected tab's value, for controlled usage. Pair with the value-change event."},{name:"defaultValue",type:"string",required:!1,description:"Initially selected tab's value, for uncontrolled usage."},{name:"orientation",type:"'horizontal' | 'vertical'",defaultValue:"'horizontal'",required:!1,description:"Layout axis, exposed as data-orientation and used to pick Arrow Left/Right vs Arrow Up/Down for keyboard navigation between triggers."},{name:"activationMode",type:"'automatic' | 'manual'",defaultValue:"'automatic'",required:!1,description:"'automatic' selects a tab on arrow-key focus; 'manual' only on Enter/Space. With 'automatic', expensive panels should set forceMount to avoid remounts during navigation. Selection follows focus only from tablist arrow/Home/End or pointer press, not from restoring focus after a dialog."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables every trigger. OR-ed with each Trigger's own disabled (never overridden)."},{name:"items",type:"ReadonlyArray<{ value: string; label: string; content?: unknown; disabled?: boolean }>",required:!1,description:"The tabs the interface derives from \u2014 one Trigger per entry, one Content panel each. Entry label names its trigger, content fills panel, value is the identity. Hand composition wins when the consumer supplies children."},{name:"renderPanel",type:"(item: TabsItem) => unknown",required:!1,frameworks:["react","svelte","angular","webComponents"],exception:"render-prop",frameworksReason:"Vue's equivalent is a scoped slot, `panel`, receiving the same entry. A function returning renderable nodes is not a Vue prop idiom \u2014 template content reaches a component through its slot mechanism \u2014 and the gate matches member names literally, so a scoped slot cannot be reported as the prop it stands in for.",description:"Renders a derived panel body in place of the entry's `content` string. Panel element (role, ids, hidden handling) stays the library's. Ignored without `items`. **Vue:** `panel` scoped slot receiving entry and index. **Angular:** TemplateRef under this name."},{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether arrow-key navigation wraps from last to first trigger. Forwarded to derived List; hand-composed TabsList sets `loop` on the List itself. On the root because deriving from `items` otherwise hides the prop."}],events:[{name:"value-change",description:t("the selected tab"),detail:e("string")},{name:"value-change-detail",frameworks:["angular"],exception:"event-shape",frameworksReason:"Angular's `valueChange` emits the scalar so `[(value)]` round-trips the value itself; this second output carries the detail object the other four hand to `value-change`.",description:"Fires with valueChange, carrying the previously selected tab and the change reason.",detail:e("string")}],parts:[{name:"List",description:'Container for tab triggers (role="tablist"). Owns roving focus: one trigger in tab order at a time, arrows move between them.',props:[{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether Arrow-key navigation wraps from the last trigger back to the first, and vice versa."}]},{name:"Trigger",description:'One tab button (role="tab"), controlling Content with the same value. Selected on click and on focus in automatic activation mode.',props:[{name:"value",type:"string",required:!0,description:"Identifies this tab. Matched against the root's selected value, and against the Content that this trigger reveals."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Excludes from selection and arrow navigation, keeps out of tab order (tabindex -1). OR-ed with root disabled (never overridden)."}]},{name:"Content",description:"One tab panel (role=tabpanel), labelled by its trigger and shown when its value matches selected tab. Focusable landmark (tabindex 0 by default) for keyboard navigation into panel content.",props:[{name:"value",type:"string",required:!0,description:"Matched against the root's selected value to decide whether this panel is shown."},{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,frameworks:["react","vue","svelte","angular"],exception:"force-mount",frameworksReason:"Web Components never unmounts a closed overlay \u2014 the part hosts the consumer's own adopted light-DOM children and only hides them, so there is no unmount for forceMount to prevent and no exit animation it could rescue.",description:'Keep this panel mounted while inactive ("keepMounted"), hidden via hidden="". For exit animations or to preserve panel state. Not in Web Components \u2014 authored panels are never unmounted.'},{name:"tabIndex",type:"0 | -1",defaultValue:"0",required:!1,description:'Whether the panel itself is a tab stop. APG requires tabindex="0" only when the panel contains no focusable elements. Pass -1 for a panel with focusable content. In Web Components, the native tabindex attribute is the canonical spelling.'}]}],slots:[{name:"default",description:"Root content \u2014 the list and content parts."},{name:"list",description:"Container for the tab triggers (TabsList)."},{name:"trigger",description:"A single tab button, one per TabsTrigger."},{name:"content",description:"A single tab panel, one per TabsContent."}],states:["active","inactive","disabled","focus"],controlledUncontrolled:"Stateless by default (uncontrolled): starts at defaultValue and manages its own state internally. Passing value switches to controlled \u2014 the consumer owns state and must update it from value-change, or the DOM will not change. In Angular the pair is split: `valueChange` emits the scalar for `[(value)]`, `valueChangeDetail` carries the detail.",formBehavior:"Not applicable \u2014 Tabs carries no value that participates in form submission.",validationBehavior:"Not applicable \u2014 Tabs carries no value that participates in validation.",accessibility:{role:"tablist (TabsList) / tab (TabsTrigger) / tabpanel (TabsContent)",keyboard:[{key:"ArrowRight / ArrowLeft",behavior:"Moves focus to the next/previous trigger when orientation is 'horizontal', wrapping if loop is true."},{key:"ArrowDown / ArrowUp",behavior:"Moves focus to the next/previous trigger when orientation is 'vertical', wrapping if loop is true."},{key:"Home / End",behavior:"Moves focus to the first/last enabled trigger."},{key:"Enter / Space",behavior:"Selects the focused trigger. Always active; the only way to select in activationMode='manual'."}],ariaAttributes:["aria-selected on the active TabsTrigger","aria-controls on TabsTrigger to Content (only when panel is in DOM; inactive panels are unmounted by default)","aria-labelledby on TabsContent back to TabsTrigger","aria-orientation on TabsList"],focusManagement:"Roving tabindex in TabsList \u2014 selected trigger (or first enabled if none) is tab stop (tabIndex 0), others -1 via arrows. Disabled triggers always -1. Arrow/Home/End scroll newly focused trigger into view. Each TabsContent is a tab stop (tabIndex 0) for keyboard entry.",namingRequirement:"TabsList should carry an accessible name via aria-label or aria-labelledby."},styling:{cssParts:["list","trigger","content","root"],dataAttributes:[...a,"data-state","data-orientation","data-disabled","data-value",{name:"data-skdx-tabs-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[{name:"setValue",signature:"(value: string, reason?: TabsChangeReason) => void",frameworks:["webComponents"],exception:"imperative",frameworksReason:"Only the custom element publishes it. The other four re-render with a new value prop and never expose a setter; a Web Components consumer holds the element itself, so the same change is made by calling this method on it.",description:"Activates the tab named by value and emits value-change carrying reason."}]};export{r as tabsContract};
|
|
1
|
+
import{changeDescription as t,changeDetail as e}from"./change-reason.js";import{ROOT_DATA_ATTRIBUTES as a}from"./styling-hooks.js";var r={name:"Tabs",purpose:"A tabbed interface: one composite root owns the selected value and hands it down to a list of tab triggers and a set of tab panels. Behavior and accessibility only \u2014 layout of the list vs. panels is entirely consumer CSS.",props:[{name:"value",type:"string",required:!1,description:"Selected tab's value, for controlled usage. Pair with the value-change event."},{name:"defaultValue",type:"string",required:!1,description:"Initially selected tab's value, for uncontrolled usage."},{name:"orientation",type:"'horizontal' | 'vertical'",defaultValue:"'horizontal'",required:!1,description:"Layout axis, exposed as data-orientation and used to pick Arrow Left/Right vs Arrow Up/Down for keyboard navigation between triggers."},{name:"activationMode",type:"'automatic' | 'manual'",defaultValue:"'automatic'",required:!1,description:"'automatic' selects a tab on arrow-key focus; 'manual' only on Enter/Space. With 'automatic', expensive panels should set forceMount to avoid remounts during navigation. Selection follows focus only from tablist arrow/Home/End or pointer press, not from restoring focus after a dialog."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables every trigger. OR-ed with each Trigger's own disabled (never overridden)."},{name:"items",type:"ReadonlyArray<{ value: string; label: string; content?: unknown; disabled?: boolean }>",required:!1,description:"The tabs the interface derives from \u2014 one Trigger per entry, one Content panel each. Entry label names its trigger, content fills panel, value is the identity. Hand composition wins when the consumer supplies children."},{name:"renderPanel",type:"(item: TabsItem) => unknown",required:!1,frameworks:["react","svelte","angular","webComponents"],exception:"render-prop",frameworksReason:"Vue's equivalent is a scoped slot, `panel`, receiving the same entry. A function returning renderable nodes is not a Vue prop idiom \u2014 template content reaches a component through its slot mechanism \u2014 and the gate matches member names literally, so a scoped slot cannot be reported as the prop it stands in for.",description:"Renders a derived panel body in place of the entry's `content` string. Panel element (role, ids, hidden handling) stays the library's. Ignored without `items`. **Vue:** `panel` scoped slot receiving entry and index. **Angular:** TemplateRef under this name."},{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether arrow-key navigation wraps from last to first trigger. Forwarded to derived List; hand-composed TabsList sets `loop` on the List itself. On the root because deriving from `items` otherwise hides the prop."}],events:[{name:"value-change",description:t("the selected tab"),detail:e("string")},{name:"value-change-detail",frameworks:["angular"],exception:"event-shape",frameworksReason:"Angular's `valueChange` emits the scalar so `[(value)]` round-trips the value itself; this second output carries the detail object the other four hand to `value-change`.",description:"Fires with valueChange, carrying the previously selected tab and the change reason.",detail:e("string")}],parts:[{name:"List",description:'Container for tab triggers (role="tablist"). Owns roving focus: one trigger in tab order at a time, arrows move between them.',props:[{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether Arrow-key navigation wraps from the last trigger back to the first, and vice versa."}],slots:[{name:"default",description:"Container for the tab triggers (TabsList)."}]},{name:"Trigger",description:'One tab button (role="tab"), controlling Content with the same value. Selected on click and on focus in automatic activation mode.',props:[{name:"value",type:"string",required:!0,description:"Identifies this tab. Matched against the root's selected value, and against the Content that this trigger reveals."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Excludes from selection and arrow navigation, keeps out of tab order (tabindex -1). OR-ed with root disabled (never overridden)."}],slots:[{name:"default",description:"A single tab button, one per TabsTrigger."}]},{name:"Content",description:"One tab panel (role=tabpanel), labelled by its trigger and shown when its value matches selected tab. Focusable landmark (tabindex 0 by default) for keyboard navigation into panel content.",props:[{name:"value",type:"string",required:!0,description:"Matched against the root's selected value to decide whether this panel is shown."},{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,frameworks:["react","vue","svelte","angular"],exception:"force-mount",frameworksReason:"Web Components never unmounts a closed overlay \u2014 the part hosts the consumer's own adopted light-DOM children and only hides them, so there is no unmount for forceMount to prevent and no exit animation it could rescue.",description:'Keep this panel mounted while inactive ("keepMounted"), hidden via hidden="". For exit animations or to preserve panel state. Not in Web Components \u2014 authored panels are never unmounted.'},{name:"tabIndex",type:"0 | -1",defaultValue:"0",required:!1,description:'Whether the panel itself is a tab stop. APG requires tabindex="0" only when the panel contains no focusable elements. Pass -1 for a panel with focusable content. In Web Components, the native tabindex attribute is the canonical spelling.'}],slots:[{name:"default",description:"A single tab panel, one per TabsContent."}]}],slots:[{name:"default",description:"Root content \u2014 the list and content parts."},{name:"panel",frameworks:["vue"],exception:"render-prop",frameworksReason:"vue expose panel as native content projection for the renderPanel rendering capability. Other frameworks pass the documented renderPanel render prop or template instead of a named slot with this spelling.",description:"Renders a derived panel body in place of the entry's `content` string. Panel element (role, ids, hidden handling) stays the library's. Ignored without `items`. **Vue:** `panel` scoped slot receiving entry and index. **Angular:** TemplateRef under this name."},{name:"render-panel",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose render-panel as native content projection for the renderPanel rendering capability. Other frameworks pass the documented renderPanel render prop or template instead of a named slot with this spelling.",description:"Renders a derived panel body in place of the entry's `content` string. Panel element (role, ids, hidden handling) stays the library's. Ignored without `items`. **Vue:** `panel` scoped slot receiving entry and index. **Angular:** TemplateRef under this name."}],states:["active","inactive","disabled","focus"],controlledUncontrolled:"Stateless by default (uncontrolled): starts at defaultValue and manages its own state internally. Passing value switches to controlled \u2014 the consumer owns state and must update it from value-change, or the DOM will not change. In Angular the pair is split: `valueChange` emits the scalar for `[(value)]`, `valueChangeDetail` carries the detail.",formBehavior:"Not applicable \u2014 Tabs carries no value that participates in form submission.",validationBehavior:"Not applicable \u2014 Tabs carries no value that participates in validation.",accessibility:{role:"tablist (TabsList) / tab (TabsTrigger) / tabpanel (TabsContent)",keyboard:[{key:"ArrowRight / ArrowLeft",behavior:"Moves focus to the next/previous trigger when orientation is 'horizontal', wrapping if loop is true."},{key:"ArrowDown / ArrowUp",behavior:"Moves focus to the next/previous trigger when orientation is 'vertical', wrapping if loop is true."},{key:"Home / End",behavior:"Moves focus to the first/last enabled trigger."},{key:"Enter / Space",behavior:"Selects the focused trigger. Always active; the only way to select in activationMode='manual'."}],ariaAttributes:["aria-selected on the active TabsTrigger","aria-controls on TabsTrigger to Content (only when panel is in DOM; inactive panels are unmounted by default)","aria-labelledby on TabsContent back to TabsTrigger","aria-orientation on TabsList"],focusManagement:"Roving tabindex in TabsList \u2014 selected trigger (or first enabled if none) is tab stop (tabIndex 0), others -1 via arrows. Disabled triggers always -1. Arrow/Home/End scroll newly focused trigger into view. Each TabsContent is a tab stop (tabIndex 0) for keyboard entry.",namingRequirement:"TabsList should carry an accessible name via aria-label or aria-labelledby."},styling:{cssParts:["list","trigger","content","root"],dataAttributes:[...a,"data-state","data-orientation","data-disabled","data-value",{name:"data-skdx-tabs-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[{name:"setValue",signature:"(value: string, reason?: TabsChangeReason) => void",frameworks:["webComponents"],exception:"imperative",frameworksReason:"Only the custom element publishes it. The other four re-render with a new value prop and never expose a setter; a Web Components consumer holds the element itself, so the same change is made by calling this method on it.",description:"Activates the tab named by value and emits value-change carrying reason."}],frameworkExtensions:[{framework:"webComponents",kind:"method",name:"getSelectedValue",type:"() => string | undefined",description:"The currently selected value, resolving controlled vs. uncontrolled. Web Components exposes this documented state/action on its element for native JavaScript and composed elements. Other wrappers coordinate their parts through context, injected state or callback props; this instance helper is separate from the common interaction contract."},{framework:"webComponents",kind:"method",name:"getSelectedValue",type:"() => string | undefined",description:"The currently selected value, resolving controlled vs. uncontrolled. Web Components exposes this documented state/action on its element for native JavaScript and composed elements. Other wrappers coordinate their parts through context, injected state or callback props; this instance helper is separate from the common interaction contract."}]};export{r as tabsContract};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_DATA_ATTRIBUTES as e}from"./styling-hooks.js";var a={name:"TagGroup",purpose:'A keyboard-navigable list of Badges. Renders role="list" and gives the whole group a single Tab stop, with the arrow keys plus Home/End moving between badges (roving tabindex). On removal it moves focus to the following badge, or the preceding one when the removed badge was last, or the group itself when it was the only one \u2014 never the document body. That holds for every route to a removal, not only the ones a Badge initiates: a badge unmounted by a clear-all button, a filter reset or a list replaced from the server hands focus back into the group the same way. It holds no entry data: each Badge owns its own removal.',props:[{name:"orientation",type:"'horizontal' | 'vertical'",defaultValue:"'horizontal'",required:!1,description:'Layout axis for arrow-key navigation between badges, exposed as data-orientation. Mirrored under dir="rtl".'},{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether arrow-key navigation wraps from the last badge back to the first, and vice versa."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables every Badge in the group: none can be removed, each mirrors data-disabled, and arrow-key navigation skips them all."},{name:"tags",type:"ReadonlyArray<{ value: string; label: string; disabled?: boolean }>",required:!1,description:"Optional entries the group renders a Badge from \u2014 one per entry, keyed by value so removed elements hold their place in the tab order. Omitting this prop renders the provided children instead, so recipes and hand-composed anatomy do not collide. The group holds no entry data between renders; remove reports what left rather than mutating the array."},{name:"removable",type:"boolean",defaultValue:"false",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"React, Vue, Svelte and Angular derive this from the onRemove callback presence. Web Components cannot inspect event listeners, so it must be explicit.",description:"Whether each derived Badge gets a delete button. Web Components only, because event listeners are not inspectable there. Only affects badges from the tags prop; hand-composed badges control their own delete."},{name:"density",type:"'comfortable' | 'compact' | (string & {})",required:!1,description:"Vertical rhythm rung, written to data-density on the root; the data-density attribute may be set directly instead."}],events:[{name:"remove",description:"Fired when a Badge is removed without veto. Carries { label, index } \u2014 the removed badge's text and position \u2014 so group-level undo, counters, or announcements use one listener instead of N per-badge callbacks. Fires when focus moves to the neighbour.",detail:"{ label: string; index: number }"}],parts:[{name:"Label",description:"A visible heading for the group. Generates an id and points the list's aria-labelledby at it so the group name stays in sync with the visible text. Rendering it switches the root to wrap [Label, List]."},{name:"List",description:'The <ul role="list"> that holds the badges in labelled compositions. It exists so a heading is not announced as a list item. Rendering a List moves role="list" and the accessible name off the root to it. Optional \u2014 groups without a visible heading keep role="list" on the root.'},{name:"Empty",description:"Content rendered while the group holds no badges, so empty filters say so rather than collapsing. Appears and disappears with badge count, not a separate flag."}],slots:[{name:"default",description:"The group's Badge children, or its Label / List / Empty parts."},{name:"label",description:"The Label part's content \u2014 the group's visible heading."},{name:"list",description:"The List part's content \u2014 the group's Badge children."},{name:"empty",description:"The Empty part's content \u2014 shown only while the group has no badges."}],appearance:[{attribute:"data-density",values:["comfortable","compact"],stylesheet:"tag-group.css"}],states:["default","disabled","empty"],controlledUncontrolled:"Stateless \u2014 the group tracks only which badge holds the Tab stop. The consumer owns the list of entries.",formBehavior:"Not applicable \u2014 TagGroup participates in no form. For a badge list that submits, use TagsInput.",validationBehavior:"Not applicable.",accessibility:{role:"list",keyboard:[{key:"ArrowRight / ArrowDown",behavior:"Moves focus to the next badge, wrapping when loop is set."},{key:"ArrowLeft / ArrowUp",behavior:"Moves focus to the previous badge, wrapping when loop is set."},{key:"Home",behavior:"Moves focus to the first badge."},{key:"End",behavior:"Moves focus to the last badge."},{key:"Tab",behavior:"One tab stop per group: only one badge is in the tab order at a time."}],ariaAttributes:['aria-label or aria-labelledby names the list. role="list" has no implicit name and derives none from contents.'],focusManagement:'Roving tabindex over badges: exactly one carries tabindex="0", the rest "-1". Disabled badges are skipped. The root is tabindex="-1" \u2014 not a tab stop but programmatically focusable so the last removal has somewhere to land rather than the document body. When a badge is removed, focus moves to the next badge, or the previous if it was last, or the root if it was only. This holds for removals from any source \u2014 never pulling focus if the user is elsewhere.',namingRequirement:'The element with role="list" must have an accessible name via aria-label or aria-labelledby. Author-supplied: role="list" has no implicit name. Rendering a Label part generates the id and aria-labelledby for you.'},styling:{cssParts:["root","label","list","empty"],dataAttributes:[...e,"data-orientation","data-disabled","data-density","data-skdx-tag-group","data-skdx-tag",{name:"data-skdx-tag-group-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[]},o="Not adopted: a key set would require the group to know each badge's identity, which the contract deliberately refuses, and per-badge `disabled` already expresses the same subset in a composition model.";export{o as TAG_GROUP_DISABLED_KEYS_DECISION,a as tagGroupContract};
|
|
1
|
+
import{ROOT_DATA_ATTRIBUTES as e}from"./styling-hooks.js";var a={name:"TagGroup",purpose:'A keyboard-navigable list of Badges. Renders role="list" and gives the whole group a single Tab stop, with the arrow keys plus Home/End moving between badges (roving tabindex). On removal it moves focus to the following badge, or the preceding one when the removed badge was last, or the group itself when it was the only one \u2014 never the document body. That holds for every route to a removal, not only the ones a Badge initiates: a badge unmounted by a clear-all button, a filter reset or a list replaced from the server hands focus back into the group the same way. It holds no entry data: each Badge owns its own removal.',props:[{name:"orientation",type:"'horizontal' | 'vertical'",defaultValue:"'horizontal'",required:!1,description:'Layout axis for arrow-key navigation between badges, exposed as data-orientation. Mirrored under dir="rtl".'},{name:"loop",type:"boolean",defaultValue:"true",required:!1,description:"Whether arrow-key navigation wraps from the last badge back to the first, and vice versa."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables every Badge in the group: none can be removed, each mirrors data-disabled, and arrow-key navigation skips them all."},{name:"tags",type:"ReadonlyArray<{ value: string; label: string; disabled?: boolean }>",required:!1,description:"Optional entries the group renders a Badge from \u2014 one per entry, keyed by value so removed elements hold their place in the tab order. Omitting this prop renders the provided children instead, so recipes and hand-composed anatomy do not collide. The group holds no entry data between renders; remove reports what left rather than mutating the array."},{name:"removable",type:"boolean",defaultValue:"false",required:!1,frameworks:["webComponents"],exception:"wc-internals",frameworksReason:"React, Vue, Svelte and Angular derive this from the onRemove callback presence. Web Components cannot inspect event listeners, so it must be explicit.",description:"Whether each derived Badge gets a delete button. Web Components only, because event listeners are not inspectable there. Only affects badges from the tags prop; hand-composed badges control their own delete."},{name:"density",type:"'comfortable' | 'compact' | (string & {})",required:!1,description:"Vertical rhythm rung, written to data-density on the root; the data-density attribute may be set directly instead."}],events:[{name:"remove",description:"Fired when a Badge is removed without veto. Carries { label, index } \u2014 the removed badge's text and position \u2014 so group-level undo, counters, or announcements use one listener instead of N per-badge callbacks. Fires when focus moves to the neighbour.",detail:"{ label: string; index: number }"}],parts:[{name:"Label",description:"A visible heading for the group. Generates an id and points the list's aria-labelledby at it so the group name stays in sync with the visible text. Rendering it switches the root to wrap [Label, List].",slots:[{name:"default",description:"The Label part's content \u2014 the group's visible heading."}]},{name:"List",description:'The <ul role="list"> that holds the badges in labelled compositions. It exists so a heading is not announced as a list item. Rendering a List moves role="list" and the accessible name off the root to it. Optional \u2014 groups without a visible heading keep role="list" on the root.',slots:[{name:"default",description:"The List part's content \u2014 the group's Badge children."}]},{name:"Empty",description:"Content rendered while the group holds no badges, so empty filters say so rather than collapsing. Appears and disappears with badge count, not a separate flag.",slots:[{name:"default",description:"The Empty part's content \u2014 shown only while the group has no badges."}]}],slots:[{name:"default",description:"The group's Badge children, or its Label / List / Empty parts."},{name:"label",description:"The Label part's content \u2014 the group's visible heading.",frameworks:["vue"],exception:"derived-anatomy",frameworksReason:"The root exposes label as content projection in vue. Other wrappers project default content into the Label part or use their separately documented rendering property; they do not accept a root named slot with this spelling."},{name:"list",description:"The List part's content \u2014 the group's Badge children.",frameworks:["vue"],exception:"derived-anatomy",frameworksReason:"The root exposes list as content projection in vue. Other wrappers project default content into the List part or use their separately documented rendering property; they do not accept a root named slot with this spelling."},{name:"empty",description:"The Empty part's content \u2014 shown only while the group has no badges.",frameworks:["vue"],exception:"derived-anatomy",frameworksReason:"The root exposes empty as content projection in vue. Other wrappers project default content into the Empty part or use their separately documented rendering property; they do not accept a root named slot with this spelling."}],appearance:[{attribute:"data-density",values:["comfortable","compact"],stylesheet:"tag-group.css"}],states:["default","disabled","empty"],controlledUncontrolled:"Stateless \u2014 the group tracks only which badge holds the Tab stop. The consumer owns the list of entries.",formBehavior:"Not applicable \u2014 TagGroup participates in no form. For a badge list that submits, use TagsInput.",validationBehavior:"Not applicable.",accessibility:{role:"list",keyboard:[{key:"ArrowRight / ArrowDown",behavior:"Moves focus to the next badge, wrapping when loop is set."},{key:"ArrowLeft / ArrowUp",behavior:"Moves focus to the previous badge, wrapping when loop is set."},{key:"Home",behavior:"Moves focus to the first badge."},{key:"End",behavior:"Moves focus to the last badge."},{key:"Tab",behavior:"One tab stop per group: only one badge is in the tab order at a time."}],ariaAttributes:['aria-label or aria-labelledby names the list. role="list" has no implicit name and derives none from contents.'],focusManagement:'Roving tabindex over badges: exactly one carries tabindex="0", the rest "-1". Disabled badges are skipped. The root is tabindex="-1" \u2014 not a tab stop but programmatically focusable so the last removal has somewhere to land rather than the document body. When a badge is removed, focus moves to the next badge, or the previous if it was last, or the root if it was only. This holds for removals from any source \u2014 never pulling focus if the user is elsewhere.',namingRequirement:'The element with role="list" must have an accessible name via aria-label or aria-labelledby. Author-supplied: role="list" has no implicit name. Rendering a Label part generates the id and aria-labelledby for you.'},styling:{cssParts:["root","label","list","empty"],dataAttributes:[...e,"data-orientation","data-disabled","data-density","data-skdx-tag-group","data-skdx-tag",{name:"data-skdx-tag-group-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[]},o="Not adopted: a key set would require the group to know each badge's identity, which the contract deliberately refuses, and per-badge `disabled` already expresses the same subset in a composition model.";export{o as TAG_GROUP_DISABLED_KEYS_DECISION,a as tagGroupContract};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{changeDetail as e}from"./change-reason.js";import{constraintValidationMethods as t,setCustomValidityMethod as a}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as i}from"./styling-hooks.js";var o={name:"TagsInput",purpose:"A controllable string[] of tags. Delimiter or Enter commits draft; Backspace on empty removes last tag. Pasted text splits and commits in batch. Validator callback gates additions.",props:[{name:"value",type:"string[]",required:!1,description:"Current tags, for controlled usage."},{name:"defaultValue",type:"string[]",defaultValue:"[]",required:!1,description:"Initial tags, for uncontrolled usage."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables adding/removing tags."},{name:"invalid",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field as invalid."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Makes the text field read-only."},{name:"max",type:"number",required:!1,description:"Maximum number of tags; further additions are no-ops once reached."},{name:"name",type:"string",required:!1,description:"Form field name. Every tag is submitted as its own entry under it; without it the field submits nothing."},{name:"required",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field required. valueMissing while there are no tags."},{name:"form",type:"string",required:!1,description:"Id of the <form> this field submits to when it is not nested inside one, exactly like the native form attribute."},{name:"delimiter",type:"string | string[]",defaultValue:"[',', '\\n']",required:!1,description:"Characters that commit draft or split pastes. Array default: paste splits on all entries, typed commit on single-char only (vs KeyboardEvent.key). RegExp not accepted. **Web Components**: array is property-only (attribute is string)."},{name:"blurBehavior",type:"'keep' | 'clear' | 'commit'",defaultValue:"'keep'",required:!1,description:"On blur: keep (leave draft), clear (discard), or commit (as tag via refusal rules)."},{name:"editable",type:"boolean",defaultValue:"false",required:!1,description:"Whether a committed tag can be edited in place. Enter opens ItemInput, Enter commits, Escape cancels. Default false."},{name:"addOnPaste",type:"boolean",defaultValue:"true",required:!1,description:"Commit pasted text as tags (split on delimiter) instead of dropping it into the draft field."},{name:"validator",type:"(tag: string, tags: string[]) => boolean",required:!1,description:"Decides whether a candidate may be added (given trimmed tag and tags earlier in the same paste). Return false=reject, true=accept over built-in duplicate, undefined=built-in rules. Must be pure. **Property-only**: function has no attribute form."},{name:"allowDuplicates",type:"boolean",defaultValue:"false",required:!1,description:"Whether same tag may appear more than once (exact match on trimmed). validator overrides."},{name:"inputValue",type:"string",required:!1,description:"Current draft text in the text field, for controlled usage."},{name:"defaultInputValue",type:"string",defaultValue:"''",required:!1,description:"Initial draft text, for uncontrolled usage."},{name:"placeholder",type:"string",required:!1,description:"Placeholder on draft field. Not a label; use inputLabel for accessible name."},{name:"clearable",type:"boolean",defaultValue:"false",required:!1,description:"Whether to render Clear button. Default false. Disabled while root is disabled or readOnly."},{name:"inputLabel",type:"string",defaultValue:"'Add a tag'",required:!1,description:'Accessible name for draft input (default: "Add a tag"). No visible label; placeholder is not a name.'},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the root; the data-size attribute may be set directly instead."}],events:[{name:"value-change",detail:e("string[]"),description:"Fires with the new tag list whenever it changes (add or remove)."},{name:"input-value-change",description:"Fires with the new draft text whenever it changes \u2014 typing, or the reset to empty after a tag is committed.",detail:"string"},{name:"value-invalid",description:"Fires once for every candidate tag the field refuses, carrying the trimmed candidate and which of the four contracted rules refused it. Without it a refused tag simply vanished: the field looked broken to the user, the application could not tell a rejected paste from an accepted one, and nothing could be announced. Fired once per candidate rather than once per commit, so a pasted batch reports every entry it dropped; a batch that refuses nothing fires nothing. The reasons are exactly the four refusal sites, in the order validationBehavior fixes them in: empty (blank after trimming), max (the list is already full), validator (the consumer predicate returned false) and duplicate (the built-in rule, which allowDuplicates switches off and a validator returning true overrides).",detail:"{ tag: string; reason: 'empty' | 'max' | 'validator' | 'duplicate' }"}],parts:[{name:"Input",description:"The draft field new tags are typed into, sitting after the committed items. Commits on the delimiter or Enter; Backspace while empty reaches back to the last item.",props:[{name:"list",type:"string",required:!1,frameworks:["angular","webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue and Svelte forward `list` to the native <input> through attribute passthrough. Angular and the custom element render the <input> inside their own element, so they declare it to carry it across.",description:"Id of a <datalist> backing the draft field with browser-native suggestions, forwarded to the native input's list attribute."}]},{name:"Item",description:"One committed tag, identified **positionally** (not by value). Allows duplicate text and unambiguous removal.",props:[{name:"index",type:"number",required:!0,description:"This tag's 0-based position in `value`. Required in every package. It is what the roving Tab stop compares against and what the delete button removes, so it must match the index the tag was rendered from \u2014 deriving it from the tag's text would break the moment two tags share text."}]},{name:"ItemDelete",description:'Button to remove one tag. Not a Tab stop (tabindex="-1"): Delete/Backspace on focused tag is keyboard route.',props:[{name:"index",type:"number",required:!0,description:"The position of the tag this button removes \u2014 the same positional identity `Item` carries, and required for the same reason. `removeTag` takes an index."},{name:"getLabel",type:"(tag: string) => string",required:!1,frameworks:["angular"],exception:"attribute-passthrough",frameworksReason:"Angular binds aria-label in template where host attribute cannot beat it. React/Vue/Svelte spread attributes. Web Components: see label below.",description:"Function to build delete button's accessible name from tag (e.g., 'Remove Ruby'). Must name the tag."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"Button is in shadow root; aria-label on host does not reach it. Whole string, per tag.",description:'Accessible name for delete <button> (full string, per tag, e.g., "Remove Ruby").'}]},{name:"ItemInput",lightDom:!0,description:"Text field for editing a tag. Renders nothing unless editable and tag is open. Seeded with tag text, selected on open. Enter commits (refusal rules apply), Escape cancels, blur abandons. Focus returns to tag before editor unmounts.",props:[{name:"index",type:"number",required:!0,description:"The position of the tag this editor edits \u2014 the same positional identity `Item` and `ItemDelete` carry, and required for the same reason: it is what decides whether this editor is the open one, and what the commit writes back to."},{name:"label",type:"string",required:!1,frameworks:["angular","webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue and Svelte let an aria-label written on the editor through by attribute passthrough, so it beats the default without a declared member. Angular binds aria-label in its own template, where a host attribute cannot beat it, and Web Components renders the <input> itself, so both have to take the override as a declared property.",description:'Accessible name for the editing input, replacing the default "Edit <tag>" (full string, per tag).'}]},{name:"Clear",description:'Button to empty whole list in one press (vs. twenty presses). Default aria-label "Clear tags", overridable per port. Disabled while root disabled/readOnly. Carries data-empty while nothing to clear. Focus goes to draft field after clear.'}],slots:[{name:"default",description:"TagsInputItem children plus a TagsInputInput, and optionally a TagsInputClear. Under editable, each TagsInputItem also holds a TagsInputItemInput."},{name:"delete",description:"A TagsInputItem's delete button."}],appearance:[{attribute:"data-size",values:["md","sm","lg"],stylesheet:"tags-input.css"}],states:["default","disabled","invalid","readonly"],controlledUncontrolled:"Supports both: value + onValueChange (controlled) or defaultValue (uncontrolled). The draft text is a second, independent controllable value: inputValue + input-value-change, or defaultInputValue.",formBehavior:'Form-associated: with name, each tag submits as own entry (formData.getAll(name) returns tags). Empty field: submits nothing unless required, where one empty-valued control remains. Four frameworks use visually-hidden native inputs \u2014 never type="hidden" and never readonly. Web Components uses ElementInternals.',validationBehavior:"invalid is presentational; required validators via checkValidity()/reportValidity(). Refusal order (fixed, API): **blank**, **max**, `validator`, **duplicate** \u2014 `allowDuplicates` switches off duplicate; `validator` returning true overrides. Every refusal fires value-invalid (trimmed candidate + reason). Editing uses list without that tag.",accessibility:{role:"generic (root and each tag); the text field is a native <input>",keyboard:[{key:"Enter or a delimiter",behavior:"In draft field: commits as new tag. Single-char delimiter commits; multi-char only splits pastes."},{key:"Backspace",behavior:"On an empty draft, removes the last committed tag."},{key:"ArrowLeft/ArrowRight",behavior:'On focused tag: moves roving Tab stop to previous/next tag; past last tag moves to draft field. Mirrored under dir="rtl".'},{key:"Delete or Backspace",behavior:"On focused tag: removes it (keyboard counterpart of delete button)."},{key:"Enter",behavior:"On focused tag (if editable): opens ItemInput with text selected. Does nothing if root disabled/readOnly."},{key:"Enter (editing)",behavior:"Commits edited text via refusal rules (blank/duplicate refused, reported via value-invalid)."},{key:"Escape (editing)",behavior:"Abandons edit, leaves tag as is. Both Enter/Escape return focus to tag before editor unmounts."}],ariaAttributes:["aria-invalid/aria-readonly on text field",'aria-label on draft field (default: inputLabel "Add a tag")','aria-label on ItemInput (default: "Edit <tag>")','aria-label on Clear button (default: "Clear tags")'],focusManagement:'Draft text on root (inputValue controllable), cleared after commit. Tags navigated by roving DOM focus: one tab stop (tabindex="0"), every delete button is tabindex="-1". Delete hands focus to next tag, else previous, else draft field. Editing: focus moves into ItemInput, returns to tag before editor unmounts. Clear: focus to draft field.'},styling:{cssParts:["tags-input","item","delete","input","item-delete","item-input","clear"],dataAttributes:[...i,"data-disabled","data-invalid","data-readonly","data-editing","data-empty","data-size","data-skdx-tags-input","data-skdx-tags-input-item","data-skdx-tags-input-delete","data-skdx-tags-input-field","data-skdx-tags-input-clear","data-skdx-tags-input-item-input",{name:"data-skdx-tags-input-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[...t,a]};export{o as tagsInputContract};
|
|
1
|
+
import{changeDetail as e}from"./change-reason.js";import{constraintValidationMethods as t,setCustomValidityMethod as a}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as i}from"./styling-hooks.js";var o={name:"TagsInput",purpose:"A controllable string[] of tags. Delimiter or Enter commits draft; Backspace on empty removes last tag. Pasted text splits and commits in batch. Validator callback gates additions.",props:[{name:"value",type:"string[]",required:!1,description:"Current tags, for controlled usage."},{name:"defaultValue",type:"string[]",defaultValue:"[]",required:!1,description:"Initial tags, for uncontrolled usage."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables adding/removing tags."},{name:"invalid",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field as invalid."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Makes the text field read-only."},{name:"max",type:"number",required:!1,description:"Maximum number of tags; further additions are no-ops once reached."},{name:"name",type:"string",required:!1,description:"Form field name. Every tag is submitted as its own entry under it; without it the field submits nothing."},{name:"required",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field required. valueMissing while there are no tags."},{name:"form",type:"string",required:!1,description:"Id of the <form> this field submits to when it is not nested inside one, exactly like the native form attribute."},{name:"delimiter",type:"string | string[]",defaultValue:"[',', '\\n']",required:!1,description:"Characters that commit draft or split pastes. Array default: paste splits on all entries, typed commit on single-char only (vs KeyboardEvent.key). RegExp not accepted. **Web Components**: array is property-only (attribute is string)."},{name:"blurBehavior",type:"'keep' | 'clear' | 'commit'",defaultValue:"'keep'",required:!1,description:"On blur: keep (leave draft), clear (discard), or commit (as tag via refusal rules)."},{name:"editable",type:"boolean",defaultValue:"false",required:!1,description:"Whether a committed tag can be edited in place. Enter opens ItemInput, Enter commits, Escape cancels. Default false."},{name:"addOnPaste",type:"boolean",defaultValue:"true",required:!1,description:"Commit pasted text as tags (split on delimiter) instead of dropping it into the draft field."},{name:"validator",type:"(tag: string, tags: string[]) => boolean",required:!1,description:"Decides whether a candidate may be added (given trimmed tag and tags earlier in the same paste). Return false=reject, true=accept over built-in duplicate, undefined=built-in rules. Must be pure. **Property-only**: function has no attribute form."},{name:"allowDuplicates",type:"boolean",defaultValue:"false",required:!1,description:"Whether same tag may appear more than once (exact match on trimmed). validator overrides."},{name:"inputValue",type:"string",required:!1,description:"Current draft text in the text field, for controlled usage."},{name:"defaultInputValue",type:"string",defaultValue:"''",required:!1,description:"Initial draft text, for uncontrolled usage."},{name:"placeholder",type:"string",required:!1,description:"Placeholder on draft field. Not a label; use inputLabel for accessible name."},{name:"clearable",type:"boolean",defaultValue:"false",required:!1,description:"Whether to render Clear button. Default false. Disabled while root is disabled or readOnly."},{name:"inputLabel",type:"string",defaultValue:"'Add a tag'",required:!1,description:'Accessible name for draft input (default: "Add a tag"). No visible label; placeholder is not a name.'},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the root; the data-size attribute may be set directly instead."}],events:[{name:"value-change",detail:e("string[]"),description:"Fires with the new tag list whenever it changes (add or remove)."},{name:"input-value-change",description:"Fires with the new draft text whenever it changes \u2014 typing, or the reset to empty after a tag is committed.",detail:"string"},{name:"value-invalid",description:"Fires once for every candidate tag the field refuses, carrying the trimmed candidate and which of the four contracted rules refused it. Without it a refused tag simply vanished: the field looked broken to the user, the application could not tell a rejected paste from an accepted one, and nothing could be announced. Fired once per candidate rather than once per commit, so a pasted batch reports every entry it dropped; a batch that refuses nothing fires nothing. The reasons are exactly the four refusal sites, in the order validationBehavior fixes them in: empty (blank after trimming), max (the list is already full), validator (the consumer predicate returned false) and duplicate (the built-in rule, which allowDuplicates switches off and a validator returning true overrides).",detail:"{ tag: string; reason: 'empty' | 'max' | 'validator' | 'duplicate' }"}],parts:[{name:"Input",description:"The draft field new tags are typed into, sitting after the committed items. Commits on the delimiter or Enter; Backspace while empty reaches back to the last item.",props:[{name:"list",type:"string",required:!1,frameworks:["angular","webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue and Svelte forward `list` to the native <input> through attribute passthrough. Angular and the custom element render the <input> inside their own element, so they declare it to carry it across.",description:"Id of a <datalist> backing the draft field with browser-native suggestions, forwarded to the native input's list attribute."}]},{name:"Item",description:"One committed tag, identified **positionally** (not by value). Allows duplicate text and unambiguous removal.",props:[{name:"index",type:"number",required:!0,description:"This tag's 0-based position in `value`. Required in every package. It is what the roving Tab stop compares against and what the delete button removes, so it must match the index the tag was rendered from \u2014 deriving it from the tag's text would break the moment two tags share text."}]},{name:"ItemDelete",description:'Button to remove one tag. Not a Tab stop (tabindex="-1"): Delete/Backspace on focused tag is keyboard route.',props:[{name:"index",type:"number",required:!0,description:"The position of the tag this button removes \u2014 the same positional identity `Item` carries, and required for the same reason. `removeTag` takes an index."},{name:"getLabel",type:"(tag: string) => string",required:!1,frameworks:["angular"],exception:"attribute-passthrough",frameworksReason:"Angular binds aria-label in template where host attribute cannot beat it. React/Vue/Svelte spread attributes. Web Components: see label below.",description:"Function to build delete button's accessible name from tag (e.g., 'Remove Ruby'). Must name the tag."},{name:"label",type:"string",required:!1,frameworks:["webComponents"],exception:"attribute-passthrough",frameworksReason:"Button is in shadow root; aria-label on host does not reach it. Whole string, per tag.",description:'Accessible name for delete <button> (full string, per tag, e.g., "Remove Ruby").'}],slots:[{name:"default",description:"A TagsInputItem's delete button."}]},{name:"ItemInput",lightDom:!0,description:"Text field for editing a tag. Renders nothing unless editable and tag is open. Seeded with tag text, selected on open. Enter commits (refusal rules apply), Escape cancels, blur abandons. Focus returns to tag before editor unmounts.",props:[{name:"index",type:"number",required:!0,description:"The position of the tag this editor edits \u2014 the same positional identity `Item` and `ItemDelete` carry, and required for the same reason: it is what decides whether this editor is the open one, and what the commit writes back to."},{name:"label",type:"string",required:!1,frameworks:["angular","webComponents"],exception:"attribute-passthrough",frameworksReason:"React, Vue and Svelte let an aria-label written on the editor through by attribute passthrough, so it beats the default without a declared member. Angular binds aria-label in its own template, where a host attribute cannot beat it, and Web Components renders the <input> itself, so both have to take the override as a declared property.",description:'Accessible name for the editing input, replacing the default "Edit <tag>" (full string, per tag).'}]},{name:"Clear",description:'Button to empty whole list in one press (vs. twenty presses). Default aria-label "Clear tags", overridable per port. Disabled while root disabled/readOnly. Carries data-empty while nothing to clear. Focus goes to draft field after clear.'}],slots:[{name:"default",description:"TagsInputItem children plus a TagsInputInput, and optionally a TagsInputClear. Under editable, each TagsInputItem also holds a TagsInputItemInput."}],appearance:[{attribute:"data-size",values:["md","sm","lg"],stylesheet:"tags-input.css"}],states:["default","disabled","invalid","readonly"],controlledUncontrolled:"Supports both: value + onValueChange (controlled) or defaultValue (uncontrolled). The draft text is a second, independent controllable value: inputValue + input-value-change, or defaultInputValue.",formBehavior:'Form-associated: with name, each tag submits as own entry (formData.getAll(name) returns tags). Empty field: submits nothing unless required, where one empty-valued control remains. Four frameworks use visually-hidden native inputs \u2014 never type="hidden" and never readonly. Web Components uses ElementInternals.',validationBehavior:"invalid is presentational; required validators via checkValidity()/reportValidity(). Refusal order (fixed, API): **blank**, **max**, `validator`, **duplicate** \u2014 `allowDuplicates` switches off duplicate; `validator` returning true overrides. Every refusal fires value-invalid (trimmed candidate + reason). Editing uses list without that tag.",accessibility:{role:"generic (root and each tag); the text field is a native <input>",keyboard:[{key:"Enter or a delimiter",behavior:"In draft field: commits as new tag. Single-char delimiter commits; multi-char only splits pastes."},{key:"Backspace",behavior:"On an empty draft, removes the last committed tag."},{key:"ArrowLeft/ArrowRight",behavior:'On focused tag: moves roving Tab stop to previous/next tag; past last tag moves to draft field. Mirrored under dir="rtl".'},{key:"Delete or Backspace",behavior:"On focused tag: removes it (keyboard counterpart of delete button)."},{key:"Enter",behavior:"On focused tag (if editable): opens ItemInput with text selected. Does nothing if root disabled/readOnly."},{key:"Enter (editing)",behavior:"Commits edited text via refusal rules (blank/duplicate refused, reported via value-invalid)."},{key:"Escape (editing)",behavior:"Abandons edit, leaves tag as is. Both Enter/Escape return focus to tag before editor unmounts."}],ariaAttributes:["aria-invalid/aria-readonly on text field",'aria-label on draft field (default: inputLabel "Add a tag")','aria-label on ItemInput (default: "Edit <tag>")','aria-label on Clear button (default: "Clear tags")'],focusManagement:'Draft text on root (inputValue controllable), cleared after commit. Tags navigated by roving DOM focus: one tab stop (tabindex="0"), every delete button is tabindex="-1". Delete hands focus to next tag, else previous, else draft field. Editing: focus moves into ItemInput, returns to tag before editor unmounts. Clear: focus to draft field.'},styling:{cssParts:["tags-input","item","delete","input","item-delete","item-input","clear"],dataAttributes:[...i,"data-disabled","data-invalid","data-readonly","data-editing","data-empty","data-size","data-skdx-tags-input","data-skdx-tags-input-item","data-skdx-tags-input-delete","data-skdx-tags-input-field","data-skdx-tags-input-clear","data-skdx-tags-input-item-input",{name:"data-skdx-tags-input-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[...t,a]};export{o as tagsInputContract};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{changeDetail as e}from"./change-reason.js";import{constraintValidationMethods as t,setCustomValidityMethod as a}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as i}from"./styling-hooks.js";var s={name:"TextField",purpose:"A single-line text input with root-owned value and state, plus input and optional slot/clear-button parts. Behavior only \u2014 no visual style.",props:[{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables the field and the wrapped input."},{name:"invalid",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field invalid; sets data-invalid on the root and aria-invalid/data-invalid on the input."},{name:"required",type:"boolean",defaultValue:"false",required:!1,description:"Marks the wrapped input required for native form validation."},{name:"value",type:"string",defaultValue:"''",required:!1,description:"Current value. Root owns this state internally, so binding it (via each framework's native two-way-binding mechanism) makes usage controlled; leaving it unbound is uncontrolled."},{name:"defaultValue",type:"string",defaultValue:"''",required:!1,description:"Initial value for uncontrolled usage, and \u2014 in every package \u2014 the single value a form reset restores, the same role a native input's defaultValue plays. Ignored while value is bound."},{name:"name",type:"string",required:!1,description:"Form field name. Without it the field submits nothing, exactly like a nameless native input."},{name:"form",type:"string",required:!1,description:"Id of the <form> this field submits with, for fields outside the form's DOM tree. React/Vue/Svelte/Angular put it on the <input>; Web Components uses ElementInternals.form."},{name:"clearable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a button that clears the value."},{name:"clearLabel",type:"string",defaultValue:"'Clear'",required:!1,description:"Accessible name for the derived clear button."},{name:"leading",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot (not a prop) \u2014 Vue idiom, Web Components attribute limit. Both slot spellings are under `slots`.",description:"Content rendered before the input, typically an icon or prefix."},{name:"trailing",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot (not a prop) \u2014 Vue idiom, Web Components attribute limit. Both slot spellings are under `slots`.",description:"Content rendered after the input, typically an icon or unit."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text for the derived input. Never a substitute for a label \u2014 the naming requirement below still applies."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Makes the derived input read-only while keeping it focusable and submittable."},{name:"type",type:"string",defaultValue:"'text'",required:!1,description:"Native input type for the derived input, such as 'email', 'search' or 'url'; ignored when children are given."},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the root; the data-size attribute may be set directly instead."},{name:"variant",type:"'filled' | 'ghost' | (string & {})",required:!1,description:"Fill style rung, written to data-variant on the root; the data-variant attribute may be set directly instead."}],events:[{name:"value-change",description:"Fired with the new value whenever it changes, controlled or not (typing, or the clear button).",detail:e("string")}],parts:[{name:"Input",lightDom:!0,description:"The native single-line <input>, driven by the root's value/disabled/invalid/required state. Value/defaultValue are root-owned. Native attributes (readonly, pattern, minlength, maxlength, autocomplete, inputmode, aria-describedby) reach the <input>.",props:[{name:"type",type:"string",defaultValue:"'text'",required:!1,description:"The native <input> type, such as 'email', 'search' or 'url'."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Reflected as the native readonly attribute on the <input>. Not the same as disabled: a read-only field stays focusable, selectable, and submits its value \u2014 only editing is blocked."},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the input; the data-size attribute may be set directly instead."},{name:"variant",type:"'filled' | 'ghost' | (string & {})",required:!1,description:"Fill style rung, written to data-variant on the input; the data-variant attribute may be set directly instead."}]},{name:"Slot",description:"A decorative container for an icon or adornment beside the input. Not focusable and not part of the tab order \u2014 put interactive adornments in their own button instead.",props:[{name:"side",type:"'start' | 'end'",defaultValue:"'start'",required:!1,description:"Which end of the field this slot sits at, exposed as data-side."}]},{name:"ClearButton",description:"A button that resets the root's value to empty. Rendered only while the field has a value, unless forceMount says otherwise.",props:[{name:"label",type:"string",defaultValue:"'Clear'",required:!1,description:"Accessible name for the clear button (no text content). Must be translated."},{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,description:"Keep the button mounted while the field is empty instead of unmounting it, so an animation library can play an exit transition."}]}],slots:[{name:"default",description:"The root's children: a TextFieldInput plus optional TextFieldSlot/TextFieldClearButton parts."},{name:"leading",description:"Content rendered before the input, typically an icon or prefix."},{name:"trailing",description:"Content rendered after the input, typically an icon or unit."}],appearance:[{attribute:"data-size",values:["md","sm","lg"],stylesheet:"text-field.css"},{attribute:"data-variant",values:["filled","ghost"],stylesheet:"text-field.css"}],states:["default","hover","focus","disabled","invalid","readonly"],controlledUncontrolled:"Root owns value internally; binding it (controlled) syncs an external source; leaving it unbound (uncontrolled) works via root's own state.",formBehavior:"Form-associated: with a name, submits its value and mirrors the input's ValidityState (including required). checkValidity()/reportValidity() behave as on a native <input>. A form reset restores `defaultValue` (empty string fallback) in all packages.",validationBehavior:"invalid is a purely presentational flag (aria-invalid/data-invalid) the consumer sets from its own validation result. required marks the input for native constraint validation.",accessibility:{role:"textbox (native <input> element, implicit)",keyboard:[{key:"Standard text-editing keys",behavior:"Arrow keys, selection, and editing behave exactly like a native <input> \u2014 no custom key handling."}],ariaAttributes:["aria-invalid on the input when invalid"],focusManagement:"Focus lands on the native input; the root is not itself focusable.",namingRequirement:"Pair with a Label (pointing at input's id) \u2014 don't rely on placeholder alone. For description or error text, wrap in Field. TextField generates no ids and merges nothing into aria-describedby; Field does that wiring."},styling:{cssParts:["root","input","slot","clear-button"],dataAttributes:[...i,"data-disabled","data-invalid","data-side","data-size","data-variant",{name:"data-skdx-text-field-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[...t,a],contextApi:[{name:"validity",signature:"(): ValidityState | null",description:"The wrapped input's own ValidityState, live. null before the input mounts.",accessors:{react:"ref.current.validity \u2014 a getter on the TextFieldHandle",vue:"templateRef.value.validity \u2014 defineExpose, unwrapped",svelte:"instance.validity() \u2014 export function, reached with bind:this",angular:"component.validity \u2014 a getter on the component instance",webComponents:"el.validity \u2014 a getter on <skdx-text-field>"}},{name:"validationMessage",signature:"(): string",description:"The message the browser would show for the current validity (empty when valid). Available to render in your own error slot.",accessors:{react:"ref.current.validationMessage \u2014 a getter on the TextFieldHandle",vue:"templateRef.value.validationMessage \u2014 defineExpose, unwrapped",svelte:"instance.validationMessage() \u2014 export function, reached with bind:this",angular:"component.validationMessage \u2014 a getter on the component instance",webComponents:"el.validationMessage \u2014 a getter on <skdx-text-field>"}}],frameworkExtensions:[{framework:"webComponents",name:"requiredMessage",type:"string",description:"Replaces the English required message (attribute `required-message`). Web Components only \u2014 the other four packages render an <input> the consumer can override with setCustomValidity()."}]};export{s as textFieldContract};
|
|
1
|
+
import{changeDetail as e}from"./change-reason.js";import{constraintValidationMethods as t,setCustomValidityMethod as n}from"./form-validity.js";import{ROOT_DATA_ATTRIBUTES as i}from"./styling-hooks.js";var s={name:"TextField",purpose:"A single-line text input with root-owned value and state, plus input and optional slot/clear-button parts. Behavior only \u2014 no visual style.",props:[{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:"Disables the field and the wrapped input."},{name:"invalid",type:"boolean",defaultValue:"false",required:!1,description:"Marks the field invalid; sets data-invalid on the root and aria-invalid/data-invalid on the input."},{name:"required",type:"boolean",defaultValue:"false",required:!1,description:"Marks the wrapped input required for native form validation."},{name:"value",type:"string",defaultValue:"''",required:!1,description:"Current value. Root owns this state internally, so binding it (via each framework's native two-way-binding mechanism) makes usage controlled; leaving it unbound is uncontrolled."},{name:"defaultValue",type:"string",defaultValue:"''",required:!1,description:"Initial value for uncontrolled usage, and \u2014 in every package \u2014 the single value a form reset restores, the same role a native input's defaultValue plays. Ignored while value is bound."},{name:"name",type:"string",required:!1,description:"Form field name. Without it the field submits nothing, exactly like a nameless native input."},{name:"form",type:"string",required:!1,description:"Id of the <form> this field submits with, for fields outside the form's DOM tree. React/Vue/Svelte/Angular put it on the <input>; Web Components uses ElementInternals.form."},{name:"clearable",type:"boolean",defaultValue:"false",required:!1,description:"Renders a button that clears the value."},{name:"clearLabel",type:"string",defaultValue:"'Clear'",required:!1,description:"Accessible name for the derived clear button."},{name:"leading",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot (not a prop) \u2014 Vue idiom, Web Components attribute limit. Both slot spellings are under `slots`.",description:"Content rendered before the input, typically an icon or prefix."},{name:"trailing",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot (not a prop) \u2014 Vue idiom, Web Components attribute limit. Both slot spellings are under `slots`.",description:"Content rendered after the input, typically an icon or unit."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text for the derived input. Never a substitute for a label \u2014 the naming requirement below still applies."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Makes the derived input read-only while keeping it focusable and submittable."},{name:"type",type:"string",defaultValue:"'text'",required:!1,description:"Native input type for the derived input, such as 'email', 'search' or 'url'; ignored when children are given."},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the root; the data-size attribute may be set directly instead."},{name:"variant",type:"'filled' | 'ghost' | (string & {})",required:!1,description:"Fill style rung, written to data-variant on the root; the data-variant attribute may be set directly instead."}],events:[{name:"value-change",description:"Fired with the new value whenever it changes, controlled or not (typing, or the clear button).",detail:e("string")}],parts:[{name:"Input",lightDom:!0,description:"The native single-line <input>, driven by the root's value/disabled/invalid/required state. Value/defaultValue are root-owned. Native attributes (readonly, pattern, minlength, maxlength, autocomplete, inputmode, aria-describedby) reach the <input>.",props:[{name:"type",type:"string",defaultValue:"'text'",required:!1,description:"The native <input> type, such as 'email', 'search' or 'url'."},{name:"readOnly",type:"boolean",defaultValue:"false",required:!1,description:"Reflected as the native readonly attribute on the <input>. Not the same as disabled: a read-only field stays focusable, selectable, and submits its value \u2014 only editing is blocked."},{name:"size",type:"'md' | 'sm' | 'lg' | (string & {})",required:!1,description:"Visual size rung, written to data-size on the input; the data-size attribute may be set directly instead."},{name:"variant",type:"'filled' | 'ghost' | (string & {})",required:!1,description:"Fill style rung, written to data-variant on the input; the data-variant attribute may be set directly instead."}]},{name:"Slot",description:"A decorative container for an icon or adornment beside the input. Not focusable and not part of the tab order \u2014 put interactive adornments in their own button instead.",props:[{name:"side",type:"'start' | 'end'",defaultValue:"'start'",required:!1,description:"Which end of the field this slot sits at, exposed as data-side."}]},{name:"ClearButton",description:"A button that resets the root's value to empty. Rendered only while the field has a value, unless forceMount says otherwise.",props:[{name:"label",type:"string",defaultValue:"'Clear'",required:!1,description:"Accessible name for the clear button (no text content). Must be translated."},{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,description:"Keep the button mounted while the field is empty instead of unmounting it, so an animation library can play an exit transition."}]}],slots:[{name:"default",description:"The root's children: a TextFieldInput plus optional TextFieldSlot/TextFieldClearButton parts."},{name:"leading",description:"Content rendered before the input, typically an icon or prefix."},{name:"trailing",description:"Content rendered after the input, typically an icon or unit."}],appearance:[{attribute:"data-size",values:["md","sm","lg"],stylesheet:"text-field.css"},{attribute:"data-variant",values:["filled","ghost"],stylesheet:"text-field.css"}],states:["default","hover","focus","disabled","invalid","readonly"],controlledUncontrolled:"Root owns value internally; binding it (controlled) syncs an external source; leaving it unbound (uncontrolled) works via root's own state.",formBehavior:"Form-associated: with a name, submits its value and mirrors the input's ValidityState (including required). checkValidity()/reportValidity() behave as on a native <input>. A form reset restores `defaultValue` (empty string fallback) in all packages.",validationBehavior:"invalid is a purely presentational flag (aria-invalid/data-invalid) the consumer sets from its own validation result. required marks the input for native constraint validation.",accessibility:{role:"textbox (native <input> element, implicit)",keyboard:[{key:"Standard text-editing keys",behavior:"Arrow keys, selection, and editing behave exactly like a native <input> \u2014 no custom key handling."}],ariaAttributes:["aria-invalid on the input when invalid"],focusManagement:"Focus lands on the native input; the root is not itself focusable.",namingRequirement:"Pair with a Label (pointing at input's id) \u2014 don't rely on placeholder alone. For description or error text, wrap in Field. TextField generates no ids and merges nothing into aria-describedby; Field does that wiring."},styling:{cssParts:["root","input","slot","clear-button"],dataAttributes:[...i,"data-disabled","data-invalid","data-side","data-size","data-variant",{name:"data-skdx-text-field-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[...t,n],contextApi:[{name:"validity",signature:"(): ValidityState | null",description:"The wrapped input's own ValidityState, live. null before the input mounts.",accessors:{react:"ref.current.validity \u2014 a getter on the TextFieldHandle",vue:"templateRef.value.validity \u2014 defineExpose, unwrapped",svelte:"instance.validity() \u2014 export function, reached with bind:this",angular:"component.validity \u2014 a getter on the component instance",webComponents:"el.validity \u2014 a getter on <skdx-text-field>"}},{name:"validationMessage",signature:"(): string",description:"The message the browser would show for the current validity (empty when valid). Available to render in your own error slot.",accessors:{react:"ref.current.validationMessage \u2014 a getter on the TextFieldHandle",vue:"templateRef.value.validationMessage \u2014 defineExpose, unwrapped",svelte:"instance.validationMessage() \u2014 export function, reached with bind:this",angular:"component.validationMessage \u2014 a getter on the component instance",webComponents:"el.validationMessage \u2014 a getter on <skdx-text-field>"}}],frameworkExtensions:[{framework:"webComponents",name:"requiredMessage",type:"string",description:"Replaces the English required message (attribute `required-message`). Web Components only \u2014 the other four packages render an <input> the consumer can override with setCustomValidity()."},{framework:"angular",part:"Input",name:"autocomplete",type:"string",description:"Native <input> autocomplete binding on angular TextFieldInput. Native `<input>` `autocomplete`, e.g. `'username'`, `'current-password'`, `'off'`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"Input",name:"autocomplete",type:"string | undefined",description:"Native <input> autocomplete binding on webComponents TextFieldInput. Native `<input>` `autocomplete`, e.g. `'username'`, `'current-password'`, `'off'`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"Input",name:"maxLength",type:"number",description:"Native <input> max-length binding on angular TextFieldInput. Native `<input>` `maxlength` \u2014 the longest value the field accepts, reported as `tooLong`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"Input",name:"maxLength",type:"number | undefined",description:"Native <input> max-length binding on webComponents TextFieldInput. Native `<input>` `maxlength` \u2014 longest value the field accepts, reported as `tooLong`.\nBrowser caps typing and truncates pastes; only user edits are reported, never code assignments. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"Input",name:"minLength",type:"number",description:"Native <input> min-length binding on angular TextFieldInput. Native `<input>` `minlength` \u2014 the shortest value constraint validation will accept, reported as `tooShort`. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"Input",name:"minLength",type:"number | undefined",description:"Native <input> min-length binding on webComponents TextFieldInput. Native `<input>` `minlength` \u2014 shortest value constraint validation accepts, reported as `tooShort`.\nOnly fires after a user edit; pair with `required` when an empty field must also fail. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"angular",part:"Input",name:"pattern",type:"string",description:"Native <input> pattern binding on angular TextFieldInput. Native `<input>` `pattern` \u2014 a regular expression the value has to match for constraint validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"Input",name:"pattern",type:"string | undefined",description:"Native <input> pattern binding on webComponents TextFieldInput. Native `<input>` `pattern` \u2014 a regular expression the value has to match for constraint validation. This wrapper declares the native binding explicitly; other wrappers inherit native-element attributes rather than duplicate each DOM attribute as a component prop.",kind:"prop"},{framework:"webComponents",part:"Input",name:"inputMode",type:"string",description:"Native `<input>` `inputmode`, which picks the on-screen keyboard.\nOverrides `HTMLElement.inputMode` (which reflects to host, not the element receiving focus). This is documented configuration/state on the native element or its composed part beyond the common component core. It is explicitly recorded as an element adapter rather than falsely requiring the same property binding on every wrapper.",kind:"prop"},{framework:"svelte",kind:"method",name:"validationMessage",type:"() => string",description:"Browser's validation message; empty string when valid. Svelte exports a function through bind:this to read live native input validation state; Vue and Web Components expose the corresponding live property, and native input references provide the platform API."},{framework:"svelte",kind:"method",name:"validity",type:"() => ValidityState | null",description:"Input's `ValidityState` for rendering custom errors, `null` before mount. Svelte exports a function through bind:this to read live native input validation state; Vue and Web Components expose the corresponding live property, and native input references provide the platform API."},{framework:"vue",name:"inputEl",type:"HTMLInputElement | null",description:"The wrapped native input element. This is a reference to the underlying native element for integration with platform APIs; the other wrappers hand off elements through their framework ref/context mechanisms instead of this property spelling.",kind:"prop"},{framework:"webComponents",name:"validationMessage",type:"string",description:"The message the browser would show for the current validity; `''` when valid. This documented getter exposes the native element\u2019s derived live state. Other wrappers expose their state through context or framework refs; the shared component contract does not require identical getter spellings.",kind:"prop"},{framework:"webComponents",name:"validity",type:"ValidityState | null",description:"The control's `ValidityState`, live; use it for custom error rendering\ninstead of parsing the browser message. `null` before any input part mounts. This documented getter exposes the native element\u2019s derived live state. Other wrappers expose their state through context or framework refs; the shared component contract does not require identical getter spellings.",kind:"prop"},{framework:"angular",part:"Input",name:"inputMode",type:"string",description:"Native `<input>` `inputmode`, which picks the on-screen keyboard. Explicit inputmode binding to the native input receiving focus, rather than the custom wrapper host. Other wrappers inherit the platform input attribute through their native input props.",kind:"prop"},{framework:"webComponents",part:"Input",name:"inputMode",type:"string",description:"Native `<input>` `inputmode`, which picks the on-screen keyboard.\nOverrides `HTMLElement.inputMode` (which reflects to host, not the element receiving focus). Explicit inputmode binding to the native input receiving focus, rather than the custom wrapper host. Other wrappers inherit the platform input attribute through their native input props."},{framework:"svelte",kind:"method",name:"validationMessage",type:"() => string",description:"Browser's validation message; empty string when valid. Svelte exports a function through bind:this to read live native input validation state; Vue and Web Components expose the corresponding live property, and native input references provide the platform API."},{framework:"svelte",kind:"method",name:"validity",type:"() => ValidityState | null",description:"Input's `ValidityState` for rendering custom errors, `null` before mount. Svelte exports a function through bind:this to read live native input validation state; Vue and Web Components expose the corresponding live property, and native input references provide the platform API."},{framework:"vue",name:"inputEl",type:"HTMLInputElement | null",description:"The wrapped native input element. This is a reference to the underlying native element for integration with platform APIs; the other wrappers hand off elements through their framework ref/context mechanisms instead of this property spelling."},{framework:"vue",name:"validationMessage",type:"unknown",description:"The message the browser would show for the current validity; `''` when valid. This wrapper exposes the underlying native input validity or validationMessage as a live property; Svelte exposes callable instance accessors and other wrappers provide their native input ref/validation methods.",kind:"prop"},{framework:"webComponents",name:"validationMessage",type:"string",description:"The message the browser would show for the current validity; `''` when valid. This wrapper exposes the underlying native input validity or validationMessage as a live property; Svelte exposes callable instance accessors and other wrappers provide their native input ref/validation methods."},{framework:"vue",name:"validity",type:"unknown",description:"The wrapped input's own live `ValidityState`, or `null` before an input has mounted. This wrapper exposes the underlying native input validity or validationMessage as a live property; Svelte exposes callable instance accessors and other wrappers provide their native input ref/validation methods.",kind:"prop"},{framework:"webComponents",name:"validity",type:"ValidityState | null",description:"The control's `ValidityState`, live; use it for custom error rendering\ninstead of parsing the browser message. `null` before any input part mounts. This wrapper exposes the underlying native input validity or validationMessage as a live property; Svelte exposes callable instance accessors and other wrappers provide their native input ref/validation methods."}]};export{s as textFieldContract};
|