diff --git a/.changeset/petite-toys-greet.md b/.changeset/petite-toys-greet.md new file mode 100644 index 00000000000..b085079cfa0 --- /dev/null +++ b/.changeset/petite-toys-greet.md @@ -0,0 +1,87 @@ +--- +"@spectrum-css/table": major +--- + +### S2 table migration + +Compared to the S1 table, this component has updated corner rounding, updated color tokens, some updated spacing, and an overall refreshed look. + +#### Net-new features + +- The S2 table supports an empty state, rendering an illustrated message component. +- As data is loading to the table, this component will render a progress circle during the loading state. +- There are 2 selection modes: single-select and multi-select. Multi-select tables (`selectionMode: "multiple"`) render an indeterminate checkbox in the `thead`/`div` equivalent. Single-select tables (`selectionMode: "single"`) do not render the indeterminate checkbox in the header row. (Note: the `selectionMode` arg is disabled and will not render in the Storybook control table.) +- For tables with sortable column, there are three new S2 icons used: `Sort` to indicate "general" sorting, `SortUp` for ascending sort direction, `SortDown` for descending sort direction. +- Tables support thumbnail, avatar, and icon components as content within a cell. +- Focus indicators for entire rows have been updated for rows to include a side focus indicator. + +#### Description of other S2 table work + +T-shirt sizing for tables is not technically supported, so t-shirt size classes (i.e. `.spectrum-Table--sizeS`), have been removed across all density variants. + +The `.spectrum-Table-cell--alignRight` class has been renamed to `.spectrum-Table-cell--alignEnd` to reflect the preference for "logical" positioning. The `.spectrum-Table-cell--alignCenter` class has been refactored to `.spectrum-Table-cell--alignStart`. + +In S1, the CSS table component only supported thumbnails. Because the S2 table supports thumbnails, as well as avatars and icons, most of the language regarding thumbnails has also changed. For instance, the `showThumbnail` storybook arg was refactored to `visualElement`. The following CSS classes have been removed or refactored to remove the thumbnail language in favor of "visual" instead: + +- `.spectrum-Table-thumbnailInner` >> `.spectrum-Table-visualInner` + +- `.spectrum-Table-row--thumbnail` >> **removed** +- `.spectrum-Table-cell--thumbnail` >> **removed** +- `.spectrum-Table-thumbnailInner` >> **removed** +- `.spectrum-Table-thumbnailContent` >> **removed** +- `.spectrum-Table-thumbnailInner` >> **removed** + +The drop zones have been refactored to approach the drop zone indicators as pseudo elements, as opposed to `outline` properties. + +Because there are multiple sort icons in the S2 table, `.spectrum-Table-sortedIcon` has been renamed to `.spectrum-Table-sortIcon`. + +Individual cell focus rings have rounded corners. + +The outer table border extends all the way around the `thead`/`div` equivalent. + +In Storybook, several new stories have been added to the docs page and the testing grid for Chromatic. These stories include `EmptyState`, `LoadingState`, `SingleSelect`, `NumericalData`, `TableStates`, `Sortable`. Documentation has been added for each of these stories, as well as expanded in other stories. + +#### Mods + +##### Renamed Modifiers + +| Old Modifier | New modifier | +| -------------------------------------------------- | ------------------------------------------------- | +| `--mod-table-border-radius--quiet` | `--mod-table-border-radius-quiet` | +| `--mod-table-header-top-to-text` | `--mod-table-header-row-top-to-text` | +| `--mod-table-header-bottom-to-text` | `--mod-table-header-row-bottom-to-text` | +| `--mod-table-cell-inline-space` | `--mod-table-cell-inline-spacing` | +| `--mod-table-checkbox-to-text` | `--mod-table-checkbox-to-cell-content` | +| `--mod-table-header-background-color--quiet` | `--mod-table-header-background-color-quiet` | +| `--mod-table-header-bottom-to-text` | `--mod-table-header-row-bottom-to-text` | +| `--mod-table-header-top-to-text` | `--mod-table-header-row-top-to-text` | +| `--mod-table-min-row-height--compact` | `--mod-table-min-row-height-compact` | +| `--mod-table-min-row-height--spacious` | `--mod-table-min-row-height-spacious` | +| `--mod-table-outer-border-inline-width--quiet` | `--mod-table-outer-border-inline-width-quiet` | +| `--mod-table-row-background-color--quiet` | `--mod-table-row-background-color-quiet` | +| `--mod-table-row-checkbox-block-spacing--compact` | `--mod-table-row-checkbox-block-spacing-compact` | +| `--mod-table-row-checkbox-block-spacing--spacious` | `--mod-table-row-checkbox-block-spacing-spacious` | +| `--mod-table-thumbnail-to-text` | `--mod-table-visual-to-text` | + +##### New Modifiers + +- `--mod-table-avatar-size` +- `--mod-table-avatar-size-compact` +- `--mod-table-avatar-size-spacious` +- `--mod-table-section-header-inline-start-spacing` +- `--mod-table-summary-row-bottom-to-text` +- `--mod-table-summary-row-min-height` +- `--mod-table-summary-row-top-to-text` + +##### Removed Modifiers + +- `--mod-table-edge-to-content` +- `--mod-table-header-row-checkbox-block-spacing` +- `--mod-table-avatar-size-spacious` +- `--mod-table-row-bottom-to-text--compact` +- `--mod-table-row-bottom-to-text--spacious` +- `--mod-table-row-top-to-text--compact` +- `--mod-table-row-top-to-text--spacious` +- `--mod-table-thumbnail-block-spacing"` +- `--mod-table-thumbnail-block-spacing-compact` +- `--mod-table-thumbnail-block-spacing-spacious` diff --git a/components/table/dist/metadata.json b/components/table/dist/metadata.json index 26a601ce86e..277dc9d978c 100644 --- a/components/table/dist/metadata.json +++ b/components/table/dist/metadata.json @@ -3,19 +3,9 @@ "selectors": [ ".spectrum-Table", ".spectrum-Table--compact", - ".spectrum-Table--compact.spectrum-Table--sizeL", - ".spectrum-Table--compact.spectrum-Table--sizeS", - ".spectrum-Table--compact.spectrum-Table--sizeXL", ".spectrum-Table--emphasized", ".spectrum-Table--quiet", - ".spectrum-Table--sizeL", - ".spectrum-Table--sizeM", - ".spectrum-Table--sizeS", - ".spectrum-Table--sizeXL", ".spectrum-Table--spacious", - ".spectrum-Table--spacious.spectrum-Table--sizeL", - ".spectrum-Table--spacious.spectrum-Table--sizeS", - ".spectrum-Table--spacious.spectrum-Table--sizeXL", ".spectrum-Table-body", ".spectrum-Table-body .spectrum-Table-row .spectrum-Table-cell:first-child", ".spectrum-Table-body .spectrum-Table-row .spectrum-Table-cell:last-child", @@ -24,19 +14,19 @@ ".spectrum-Table-body.is-drop-target", ".spectrum-Table-body.is-drop-target .spectrum-Table-row", ".spectrum-Table-body.is-drop-target .spectrum-Table-row .spectrum-Table-checkbox .spectrum-Checkbox-box:before", + ".spectrum-Table-body.is-drop-target:after", ".spectrum-Table-cell", - ".spectrum-Table-cell--alignCenter", - ".spectrum-Table-cell--alignRight", + ".spectrum-Table-cell--alignEnd", + ".spectrum-Table-cell--alignStart", ".spectrum-Table-cell--collapsible", ".spectrum-Table-cell--divider", ".spectrum-Table-cell.is-focused", + ".spectrum-Table-cell.is-focused:after", ".spectrum-Table-cell:focus-visible", + ".spectrum-Table-cell:focus-visible:after", ".spectrum-Table-checkboxCell", ".spectrum-Table-checkboxCell .spectrum-Table-checkbox", - ".spectrum-Table-checkboxCell.spectrum-Table-cell .spectrum-Table-checkbox", - ".spectrum-Table-checkboxCell.spectrum-Table-headCell .spectrum-Table-checkbox", ".spectrum-Table-collapseInner", - ".spectrum-Table-collapseInner .spectrum-Table-collapseContent", ".spectrum-Table-columnTitle", ".spectrum-Table-disclosureIcon.spectrum-Table-disclosureIcon", ".spectrum-Table-disclosureIcon.spectrum-Table-disclosureIcon.is-keyboardFocused", @@ -50,22 +40,42 @@ ".spectrum-Table-head", ".spectrum-Table-head [role=\"row\"]", ".spectrum-Table-headCell", - ".spectrum-Table-headCell .spectrum-Table-menuIcon", - ".spectrum-Table-headCell .spectrum-Table-sortedIcon", ".spectrum-Table-headCell.is-focused", + ".spectrum-Table-headCell.is-focused:after", ".spectrum-Table-headCell.is-sortable", + ".spectrum-Table-headCell.is-sortable .spectrum-Table-sortButton .spectrum-Icon", + ".spectrum-Table-headCell.is-sortable .spectrum-Table-sortButton:after", ".spectrum-Table-headCell.is-sortable.is-keyboardFocused", ".spectrum-Table-headCell.is-sortable:active", ".spectrum-Table-headCell.is-sortable:focus", ".spectrum-Table-headCell.is-sortable:focus-visible", ".spectrum-Table-headCell.is-sortable:focus:hover", ".spectrum-Table-headCell.is-sortable:hover", - ".spectrum-Table-headCell.is-sorted-asc .spectrum-Table-sortedIcon", - ".spectrum-Table-headCell.is-sorted-desc .spectrum-Table-sortedIcon", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton .spectrum-Table-sortButton", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton .spectrum-Table-sortButton .spectrum-Button-label", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton .spectrum-Table-sortButton .spectrum-Button-label:after", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton .spectrum-Table-sortButton .spectrum-Icon", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton .spectrum-Table-sortButton:after", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton.is-keyboardFocused", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton:active", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton:focus", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton:focus-visible", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton:focus:hover", + ".spectrum-Table-headCell.spectrum-Table-hasMenuButton:hover", ".spectrum-Table-headCell:focus-visible", + ".spectrum-Table-headCell:focus-visible:after", + ".spectrum-Table-headRow .spectrum-ActionButton:after", + ".spectrum-Table-headRow .spectrum-Table-checkboxCell", + ".spectrum-Table-headRow .spectrum-Table-checkboxCell .spectrum-Table-checkbox", + ".spectrum-Table-headRow .spectrum-Table-headCell", + ".spectrum-Table-headRow .spectrum-Table-headCell.is-sortable", + ".spectrum-Table-headRow:first-child .spectrum-Table-headCell:first-child", + ".spectrum-Table-headRow:last-child .spectrum-Table-headCell:last-child", ".spectrum-Table-main", - ".spectrum-Table-menuIcon", ".spectrum-Table-row", + ".spectrum-Table-row .is-emphasized", + ".spectrum-Table-row .spectrum-Table-cell", ".spectrum-Table-row--collapsible", ".spectrum-Table-row--collapsible .spectrum-Table-checkboxCell", ".spectrum-Table-row--collapsible .spectrum-Table-disclosureIcon", @@ -83,15 +93,18 @@ ".spectrum-Table-row--sectionHeader:hover", ".spectrum-Table-row--summary", ".spectrum-Table-row--summary .spectrum-Table-cell", - ".spectrum-Table-row--thumbnail", - ".spectrum-Table-row--thumbnail .spectrum-Table-cell", - ".spectrum-Table-row--thumbnail .spectrum-Table-cell--thumbnail", - ".spectrum-Table-row--thumbnail.spectrum-Table-row--collapsible", ".spectrum-Table-row.is-drop-target", ".spectrum-Table-row.is-drop-target .spectrum-Table-cell", ".spectrum-Table-row.is-drop-target .spectrum-Table-checkbox .spectrum-Checkbox-box:before", ".spectrum-Table-row.is-focused", + ".spectrum-Table-row.is-focused .spectrum-Table-cell", + ".spectrum-Table-row.is-focused .spectrum-Table-cell:first-child", + ".spectrum-Table-row.is-focused .spectrum-Table-cell:first-child:before", + ".spectrum-Table-row.is-focused .spectrum-Table-cell:last-child", ".spectrum-Table-row.is-focused .spectrum-Table-checkbox .spectrum-Checkbox-box:before", + ".spectrum-Table-row.is-focused:first-child .spectrum-Table-cell", + ".spectrum-Table-row.is-focused:last-child .spectrum-Table-cell", + ".spectrum-Table-row.is-focused:last-child .spectrum-Table-cell:first-child:before", ".spectrum-Table-row.is-selected", ".spectrum-Table-row.is-selected .spectrum-Table-checkbox .spectrum-Checkbox-box:before", ".spectrum-Table-row.is-selected.is-focused", @@ -99,12 +112,26 @@ ".spectrum-Table-row.is-selected:hover", ".spectrum-Table-row:active", ".spectrum-Table-row:first-child", - ".spectrum-Table-row:first-child .spectrum-Table-cell:first-child", ".spectrum-Table-row:first-child .spectrum-Table-cell:last-child", ".spectrum-Table-row:focus", + ".spectrum-Table-row:focus .spectrum-Table-cell", + ".spectrum-Table-row:focus .spectrum-Table-cell:first-child", + ".spectrum-Table-row:focus .spectrum-Table-cell:first-child:before", + ".spectrum-Table-row:focus .spectrum-Table-cell:last-child", ".spectrum-Table-row:focus-visible", + ".spectrum-Table-row:focus-visible .spectrum-Table-cell", + ".spectrum-Table-row:focus-visible .spectrum-Table-cell:first-child", + ".spectrum-Table-row:focus-visible .spectrum-Table-cell:first-child:before", + ".spectrum-Table-row:focus-visible .spectrum-Table-cell:last-child", ".spectrum-Table-row:focus-visible .spectrum-Table-checkbox .spectrum-Checkbox-box:before", + ".spectrum-Table-row:focus-visible:first-child .spectrum-Table-cell", + ".spectrum-Table-row:focus-visible:last-child .spectrum-Table-cell", + ".spectrum-Table-row:focus-visible:last-child .spectrum-Table-cell:first-child:before", + ".spectrum-Table-row:focus:first-child .spectrum-Table-cell", + ".spectrum-Table-row:focus:last-child .spectrum-Table-cell", + ".spectrum-Table-row:focus:last-child .spectrum-Table-cell:first-child:before", ".spectrum-Table-row:hover", + ".spectrum-Table-row:hover .spectrum-Table-cell:first-child:before", ".spectrum-Table-row:hover .spectrum-Table-checkbox .spectrum-Checkbox-box:before", ".spectrum-Table-row:last-child", ".spectrum-Table-row:last-child .spectrum-Table-cell:first-child", @@ -115,23 +142,26 @@ ".spectrum-Table-scroller .spectrum-Table-body .spectrum-Table-row:first-child .spectrum-Table-cell", ".spectrum-Table-scroller .spectrum-Table-body .spectrum-Table-row:last-child .spectrum-Table-cell", ".spectrum-Table-scroller .spectrum-Table-head", - ".spectrum-Table-scroller .spectrum-Table-headCell", + ".spectrum-Table-scroller .spectrum-Table-headRow:first-child .spectrum-Table-headCell", ".spectrum-Table-scroller.spectrum-Table--quiet", - ".spectrum-Table-sortedIcon", - ".spectrum-Table-thumbnailInner", - ".spectrum-Table-thumbnailInner .spectrum-Table-thumbnailContent", - ".spectrum-Table-thumbnailInner .spectrum-Thumbnail", + ".spectrum-Table-visualInner", + ".spectrum-Table-visualInner .spectrum-Avatar", + ".spectrum-Table-visualInner .spectrum-Icon", + ".spectrum-Table-visualInner .spectrum-Thumbnail", ".spectrum-Table:dir(rtl)", ".spectrum-Table:not(.spectrum-Table-scroller)", "[dir=\"rtl\"] .spectrum-Table" ], "modifiers": [ + "--mod-table-avatar-size", + "--mod-table-avatar-size-compact", + "--mod-table-avatar-size-spacious", "--mod-table-border-color", "--mod-table-border-radius", - "--mod-table-border-radius--quiet", + "--mod-table-border-radius-quiet", "--mod-table-border-width", - "--mod-table-cell-inline-space", - "--mod-table-checkbox-to-text", + "--mod-table-cell-inline-spacing", + "--mod-table-checkbox-to-cell-content", "--mod-table-collapsible-disclosure-inline-spacing", "--mod-table-collapsible-icon-animation-duration", "--mod-table-current-header-height", @@ -144,21 +174,20 @@ "--mod-table-divider-color", "--mod-table-drop-zone-background-color", "--mod-table-drop-zone-outline-color", - "--mod-table-edge-to-content", "--mod-table-focus-indicator-color", "--mod-table-focus-indicator-thickness", "--mod-table-header-background-color", - "--mod-table-header-background-color--quiet", + "--mod-table-header-background-color-quiet", "--mod-table-header-background-color-scrollable", - "--mod-table-header-bottom-to-text", - "--mod-table-header-checkbox-block-spacing", "--mod-table-header-font-family", "--mod-table-header-font-size", "--mod-table-header-font-weight", "--mod-table-header-line-height", + "--mod-table-header-row-bottom-to-text", + "--mod-table-header-row-checkbox-block-spacing", + "--mod-table-header-row-top-to-text", "--mod-table-header-text-color", "--mod-table-header-text-transform", - "--mod-table-header-top-to-text", "--mod-table-header-vertical-align", "--mod-table-icon-color-active", "--mod-table-icon-color-default", @@ -166,30 +195,25 @@ "--mod-table-icon-color-focus-hover", "--mod-table-icon-color-hover", "--mod-table-icon-color-key-focus", - "--mod-table-icon-to-text", "--mod-table-min-header-height", "--mod-table-min-row-height", - "--mod-table-min-row-height--compact", - "--mod-table-min-row-height--spacious", + "--mod-table-min-row-height-compact", + "--mod-table-min-row-height-spacious", "--mod-table-outer-border-inline-width", - "--mod-table-outer-border-inline-width--quiet", + "--mod-table-outer-border-inline-width-quiet", "--mod-table-row-active-color", "--mod-table-row-background-color", - "--mod-table-row-background-color--quiet", "--mod-table-row-background-color-hover", + "--mod-table-row-background-color-quiet", "--mod-table-row-bottom-to-text", - "--mod-table-row-bottom-to-text--compact", - "--mod-table-row-bottom-to-text--spacious", "--mod-table-row-checkbox-block-spacing", - "--mod-table-row-checkbox-block-spacing--compact", - "--mod-table-row-checkbox-block-spacing--spacious", + "--mod-table-row-checkbox-block-spacing-compact", + "--mod-table-row-checkbox-block-spacing-spacious", "--mod-table-row-font-size", "--mod-table-row-font-weight", "--mod-table-row-line-height", "--mod-table-row-text-color", "--mod-table-row-top-to-text", - "--mod-table-row-top-to-text--compact", - "--mod-table-row-top-to-text--spacious", "--mod-table-section-header-background-color", "--mod-table-section-header-block-end-spacing", "--mod-table-section-header-block-start-spacing", @@ -197,6 +221,7 @@ "--mod-table-section-header-font-size", "--mod-table-section-header-font-style", "--mod-table-section-header-font-weight", + "--mod-table-section-header-inline-start-spacing", "--mod-table-section-header-line-height", "--mod-table-section-header-min-height", "--mod-table-section-header-text-color", @@ -204,43 +229,37 @@ "--mod-table-selected-row-background-color-focus", "--mod-table-selected-row-background-color-non-emphasized", "--mod-table-selected-row-background-color-non-emphasized-focus", - "--mod-table-sort-icon-inline-end-spacing", - "--mod-table-sort-icon-inline-start-spacing", "--mod-table-summary-row-background-color", + "--mod-table-summary-row-bottom-to-text", "--mod-table-summary-row-font-family", "--mod-table-summary-row-font-size", "--mod-table-summary-row-font-style", "--mod-table-summary-row-font-weight", "--mod-table-summary-row-line-height", + "--mod-table-summary-row-min-height", "--mod-table-summary-row-text-color", - "--mod-table-thumbnail-block-spacing", - "--mod-table-thumbnail-block-spacing-compact", - "--mod-table-thumbnail-block-spacing-spacious", + "--mod-table-summary-row-top-to-text", "--mod-table-thumbnail-size", "--mod-table-thumbnail-size-compact", "--mod-table-thumbnail-size-spacious", - "--mod-table-thumbnail-to-text", - "--mod-table-transition-duration" + "--mod-table-transition-duration", + "--mod-table-visual-to-text" ], "component": [ + "--spectrum-table-avatar-size", "--spectrum-table-border-color", "--spectrum-table-border-divider-width", "--spectrum-table-border-radius", "--spectrum-table-border-width", "--spectrum-table-cell-background-color", - "--spectrum-table-cell-inline-space", + "--spectrum-table-cell-inline-spacing", + "--spectrum-table-checkbox-to-cell-content", "--spectrum-table-checkbox-to-text", "--spectrum-table-collapsible-disclosure-inline-spacing", "--spectrum-table-collapsible-icon-animation-duration", "--spectrum-table-collapsible-tier-indent", - "--spectrum-table-column-header-row-bottom-to-text-extra-large", - "--spectrum-table-column-header-row-bottom-to-text-large", "--spectrum-table-column-header-row-bottom-to-text-medium", - "--spectrum-table-column-header-row-bottom-to-text-small", - "--spectrum-table-column-header-row-top-to-text-extra-large", - "--spectrum-table-column-header-row-top-to-text-large", "--spectrum-table-column-header-row-top-to-text-medium", - "--spectrum-table-column-header-row-top-to-text-small", "--spectrum-table-default-vertical-align", "--spectrum-table-disclosure-icon-size", "--spectrum-table-divider-color", @@ -249,17 +268,14 @@ "--spectrum-table-edge-to-content", "--spectrum-table-focus-indicator-color", "--spectrum-table-focus-indicator-thickness", + "--spectrum-table-focused-cell-border-radius", "--spectrum-table-header-background-color", - "--spectrum-table-header-bottom-to-text", - "--spectrum-table-header-checkbox-block-spacing", "--spectrum-table-header-font-weight", - "--spectrum-table-header-row-checkbox-to-top-extra-large", - "--spectrum-table-header-row-checkbox-to-top-large", + "--spectrum-table-header-row-bottom-to-text", + "--spectrum-table-header-row-checkbox-block-spacing", "--spectrum-table-header-row-checkbox-to-top-medium", - "--spectrum-table-header-row-checkbox-to-top-small", + "--spectrum-table-header-row-top-to-text", "--spectrum-table-header-text-color", - "--spectrum-table-header-top-to-text", - "--spectrum-table-header-vertical-align", "--spectrum-table-icon-color", "--spectrum-table-icon-color-active", "--spectrum-table-icon-color-default", @@ -267,82 +283,43 @@ "--spectrum-table-icon-color-focus-hover", "--spectrum-table-icon-color-hover", "--spectrum-table-icon-color-key-focus", - "--spectrum-table-icon-to-text", - "--spectrum-table-min-header-height", + "--spectrum-table-min-header-row-height", "--spectrum-table-min-row-height", "--spectrum-table-outer-border-inline-width", "--spectrum-table-row-active-color", "--spectrum-table-row-background-color", "--spectrum-table-row-background-color-hover", "--spectrum-table-row-bottom-to-text", - "--spectrum-table-row-bottom-to-text-extra-large-compact", - "--spectrum-table-row-bottom-to-text-extra-large-regular", - "--spectrum-table-row-bottom-to-text-extra-large-spacious", - "--spectrum-table-row-bottom-to-text-large-compact", - "--spectrum-table-row-bottom-to-text-large-regular", - "--spectrum-table-row-bottom-to-text-large-spacious", + "--spectrum-table-row-bottom-to-text-medium", "--spectrum-table-row-bottom-to-text-medium-compact", - "--spectrum-table-row-bottom-to-text-medium-regular", "--spectrum-table-row-bottom-to-text-medium-spacious", - "--spectrum-table-row-bottom-to-text-small-compact", - "--spectrum-table-row-bottom-to-text-small-regular", - "--spectrum-table-row-bottom-to-text-small-spacious", "--spectrum-table-row-checkbox-block-spacing", - "--spectrum-table-row-checkbox-to-top-extra-large-compact", - "--spectrum-table-row-checkbox-to-top-extra-large-regular", - "--spectrum-table-row-checkbox-to-top-extra-large-spacious", - "--spectrum-table-row-checkbox-to-top-large-compact", - "--spectrum-table-row-checkbox-to-top-large-regular", - "--spectrum-table-row-checkbox-to-top-large-spacious", + "--spectrum-table-row-checkbox-to-top-medium", "--spectrum-table-row-checkbox-to-top-medium-compact", - "--spectrum-table-row-checkbox-to-top-medium-regular", "--spectrum-table-row-checkbox-to-top-medium-spacious", - "--spectrum-table-row-checkbox-to-top-small-compact", - "--spectrum-table-row-checkbox-to-top-small-regular", - "--spectrum-table-row-checkbox-to-top-small-spacious", "--spectrum-table-row-down-opacity", + "--spectrum-table-row-focus-indicator-width", "--spectrum-table-row-font-family", "--spectrum-table-row-font-size", "--spectrum-table-row-font-style", "--spectrum-table-row-font-weight", - "--spectrum-table-row-height-extra-large-compact", - "--spectrum-table-row-height-extra-large-regular", - "--spectrum-table-row-height-extra-large-spacious", - "--spectrum-table-row-height-large-compact", - "--spectrum-table-row-height-large-regular", - "--spectrum-table-row-height-large-spacious", + "--spectrum-table-row-height-medium", "--spectrum-table-row-height-medium-compact", - "--spectrum-table-row-height-medium-regular", "--spectrum-table-row-height-medium-spacious", - "--spectrum-table-row-height-small-compact", - "--spectrum-table-row-height-small-regular", - "--spectrum-table-row-height-small-spacious", "--spectrum-table-row-hover-opacity", "--spectrum-table-row-line-height", "--spectrum-table-row-text-color", "--spectrum-table-row-tier", "--spectrum-table-row-top-to-text", - "--spectrum-table-row-top-to-text-extra-large-compact", - "--spectrum-table-row-top-to-text-extra-large-regular", - "--spectrum-table-row-top-to-text-extra-large-spacious", - "--spectrum-table-row-top-to-text-large-compact", - "--spectrum-table-row-top-to-text-large-regular", - "--spectrum-table-row-top-to-text-large-spacious", + "--spectrum-table-row-top-to-text-medium", "--spectrum-table-row-top-to-text-medium-compact", - "--spectrum-table-row-top-to-text-medium-regular", "--spectrum-table-row-top-to-text-medium-spacious", - "--spectrum-table-row-top-to-text-small-compact", - "--spectrum-table-row-top-to-text-small-regular", - "--spectrum-table-row-top-to-text-small-spacious", "--spectrum-table-section-header-background-color", "--spectrum-table-section-header-block-end-spacing", "--spectrum-table-section-header-block-start-spacing", "--spectrum-table-section-header-font-weight", "--spectrum-table-section-header-min-height", - "--spectrum-table-section-header-row-height-extra-large", - "--spectrum-table-section-header-row-height-large", "--spectrum-table-section-header-row-height-medium", - "--spectrum-table-section-header-row-height-small", "--spectrum-table-selected-cell-background-color", "--spectrum-table-selected-cell-background-color-focus", "--spectrum-table-selected-row-background-color", @@ -355,61 +332,36 @@ "--spectrum-table-selected-row-background-opacity-non-emphasized-hover", "--spectrum-table-summary-row-background-color", "--spectrum-table-summary-row-font-weight", - "--spectrum-table-thumbnail-block-spacing", - "--spectrum-table-thumbnail-cell-block-spacing", - "--spectrum-table-thumbnail-inner-content-block-spacing", - "--spectrum-table-thumbnail-inner-minimum-block-spacing", "--spectrum-table-thumbnail-size", - "--spectrum-table-thumbnail-to-text", - "--spectrum-table-thumbnail-to-top-minimum-extra-large-compact", - "--spectrum-table-thumbnail-to-top-minimum-extra-large-regular", - "--spectrum-table-thumbnail-to-top-minimum-extra-large-spacious", - "--spectrum-table-thumbnail-to-top-minimum-large-compact", - "--spectrum-table-thumbnail-to-top-minimum-large-regular", - "--spectrum-table-thumbnail-to-top-minimum-large-spacious", - "--spectrum-table-thumbnail-to-top-minimum-medium-compact", - "--spectrum-table-thumbnail-to-top-minimum-medium-regular", - "--spectrum-table-thumbnail-to-top-minimum-medium-spacious", - "--spectrum-table-thumbnail-to-top-minimum-small-compact", - "--spectrum-table-thumbnail-to-top-minimum-small-regular", - "--spectrum-table-thumbnail-to-top-minimum-small-spacious", - "--spectrum-table-transition-duration" + "--spectrum-table-transition-duration", + "--spectrum-table-visual-to-text" ], "global": [ "--spectrum-accent-visual-color", "--spectrum-animation-duration-100", + "--spectrum-avatar-size-100", + "--spectrum-avatar-size-50", + "--spectrum-avatar-size-75", "--spectrum-background-layer-1-color", "--spectrum-blue-900-rgb", "--spectrum-body-color", "--spectrum-bold-font-weight", "--spectrum-checkbox-control-size-small", "--spectrum-component-bottom-to-text-100", - "--spectrum-component-bottom-to-text-200", - "--spectrum-component-bottom-to-text-300", - "--spectrum-component-bottom-to-text-75", "--spectrum-component-height-100", - "--spectrum-component-height-200", - "--spectrum-component-height-300", - "--spectrum-component-height-75", "--spectrum-component-top-to-text-100", - "--spectrum-component-top-to-text-200", - "--spectrum-component-top-to-text-300", - "--spectrum-component-top-to-text-75", - "--spectrum-corner-radius-100", + "--spectrum-corner-radius-medium-size-extra-small", + "--spectrum-corner-radius-small-default", "--spectrum-default-font-style", "--spectrum-drop-zone-background-color-opacity", "--spectrum-drop-zone-background-color-rgb", "--spectrum-focus-indicator-color", "--spectrum-focus-indicator-thickness", "--spectrum-font-size-100", - "--spectrum-font-size-200", - "--spectrum-font-size-300", - "--spectrum-font-size-75", "--spectrum-gray-100", "--spectrum-gray-200", "--spectrum-gray-25", "--spectrum-gray-300", - "--spectrum-gray-50", "--spectrum-gray-700-rgb", "--spectrum-gray-75", "--spectrum-gray-900-rgb", @@ -422,23 +374,40 @@ "--spectrum-neutral-subdued-content-color-key-focus", "--spectrum-regular-font-weight", "--spectrum-sans-font-family-stack", + "--spectrum-side-focus-indicator", "--spectrum-spacing-300", - "--spectrum-text-to-visual-100", - "--spectrum-text-to-visual-200", "--spectrum-text-to-visual-300", + "--spectrum-thumbnail-size-100", "--spectrum-thumbnail-size-200", - "--spectrum-thumbnail-size-300", - "--spectrum-thumbnail-size-50", - "--spectrum-thumbnail-size-500", - "--spectrum-thumbnail-size-700", - "--spectrum-thumbnail-size-800", + "--spectrum-thumbnail-size-75", "--spectrum-transparent-white-100", "--spectrum-transparent-white-25" ], - "passthroughs": ["--mod-checkbox-spacing", "--mod-thumbnail-size"], + "passthroughs": [ + "--mod-avatar-block-size", + "--mod-avatar-inline-size", + "--mod-button-background-color-default", + "--mod-button-background-color-down", + "--mod-button-background-color-focus", + "--mod-button-background-color-hover", + "--mod-button-border-radius", + "--mod-button-content-color-default", + "--mod-button-content-color-down", + "--mod-button-content-color-focus", + "--mod-button-content-color-hover", + "--mod-button-edge-to-text", + "--mod-button-focus-ring-border-radius", + "--mod-button-font-family", + "--mod-button-font-size", + "--mod-button-font-weight", + "--mod-button-height", + "--mod-button-line-height", + "--mod-button-padding-label-to-icon", + "--mod-checkbox-margin-block", + "--mod-thumbnail-size" + ], "high-contrast": [ "--highcontrast-table-border-color", - "--highcontrast-table-cell-focus-extra-offset", "--highcontrast-table-cell-focus-indicator-color", "--highcontrast-table-divider-color", "--highcontrast-table-focus-indicator-color", diff --git a/components/table/index.css b/components/table/index.css index 7ffbacf046a..3fd1f5f836b 100644 --- a/components/table/index.css +++ b/components/table/index.css @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Adobe. All rights reserved. + * Copyright 2025 Adobe. All rights reserved. * * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy @@ -12,404 +12,263 @@ */ .spectrum-Table { + /* Animation */ + --spectrum-table-transition-duration: var(--spectrum-animation-duration-100); + + /* Background colors */ --spectrum-table-header-background-color: var(--spectrum-transparent-white-25); - --spectrum-table-border-color: var(--spectrum-gray-200); - --spectrum-table-divider-color: var(--spectrum-gray-200); --spectrum-table-row-background-color: var(--spectrum-gray-25); - --spectrum-table-summary-row-background-color: var(--spectrum-gray-100); + /* @todo Refactor or remove these properties once the RGB stripped value is available. */ + --spectrum-table-row-background-color-hover: rgb(var(--spectrum-gray-900-rgb), var(--spectrum-table-row-hover-opacity)); + --spectrum-table-summary-row-background-color: var(--spectrum-gray-200); --spectrum-table-section-header-background-color: var(--spectrum-gray-100); - --spectrum-table-icon-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); - --spectrum-table-icon-color-focus-hover: var(--spectrum-neutral-subdued-content-color-hover); -} - -.spectrum-Table--quiet { - --spectrum-table-header-background-color: var(--spectrum-transparent-white-25); - --spectrum-table-row-background-color: var(--spectrum-transparent-white-25); -} - -/********* HIGH CONTRAST *********/ -@media (forced-colors: active) { - .spectrum-Table { - --highcontrast-table-row-background-color: Canvas; - --highcontrast-table-row-text-color: CanvasText; - --highcontrast-table-divider-color: CanvasText; - --highcontrast-table-border-color: CanvasText; - --highcontrast-table-icon-color: CanvasText; - --highcontrast-table-icon-color-focus: Highlight; - - --highcontrast-table-selected-row-background-color: Highlight; - --highcontrast-table-selected-row-text-color: HighlightText; + --spectrum-table-selected-row-background-color: rgb(var(--spectrum-blue-900-rgb), var(--spectrum-table-selected-row-background-opacity)); + --spectrum-table-selected-row-background-color-non-emphasized: rgb(var(--spectrum-gray-700-rgb), var(--spectrum-table-selected-row-background-opacity-non-emphasized)); + --spectrum-table-selected-row-background-color-focus: rgb(var(--spectrum-blue-900-rgb), var(--spectrum-table-selected-row-background-opacity-hover)); + --spectrum-table-selected-row-background-color-non-emphasized-focus: rgb(var(--spectrum-gray-700-rgb), var(--spectrum-table-selected-row-background-opacity-non-emphasized-hover)); - @supports (color: SelectedItem) { - --highcontrast-table-selected-row-background-color: SelectedItem; - --highcontrast-table-selected-row-text-color: SelectedItemText; - } - - --highcontrast-table-selected-row-background-color-focus: Highlight; - --highcontrast-table-selected-row-text-color-focus: HighlightText; - --highcontrast-table-row-background-color-hover: Highlight; - --highcontrast-table-row-text-color-hover: HighlightText; + --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color, var(--mod-table-row-background-color, var(--spectrum-table-row-background-color))); + --spectrum-table-selected-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-selected-row-background-color-non-emphasized, var(--spectrum-table-selected-row-background-color-non-emphasized))); - --highcontrast-table-section-header-text-color: Canvas; - --highcontrast-table-section-header-background-color: CanvasText; + --spectrum-table-drop-zone-background-color: rgb(var(--spectrum-drop-zone-background-color-rgb), var(--spectrum-drop-zone-background-color-opacity)); + --spectrum-table-drop-zone-outline-color: var(--spectrum-accent-visual-color); - --highcontrast-table-focus-indicator-color: Highlight; - --highcontrast-table-transition-duration: 0; - } + /* Row Selection */ + --spectrum-table-row-active-color: rgb(var(--spectrum-gray-900-rgb), var(--spectrum-table-row-down-opacity)); /* active/down state background color */ - .spectrum-Table-cell { - /* Removes unstylable readability backplate. */ - forced-color-adjust: none; - } + /* Border */ + --spectrum-table-border-color: var(--spectrum-gray-300); + --spectrum-table-border-radius: var(--spectrum-corner-radius-medium-size-extra-small); + --spectrum-table-border-width: var(--spectrum-table-border-divider-width); + --spectrum-table-outer-border-inline-width: var(--spectrum-table-border-divider-width); - .spectrum-Table-row { - &:hover, - &:focus-visible, - &.is-focused { - .spectrum-Table-checkbox .spectrum-Checkbox-box::before { - outline: var(--highcontrast-table-row-text-color-hover) 1px solid; - } - } - } + /* Divider */ + --spectrum-table-divider-color: var(--spectrum-gray-300); - .spectrum-Table-row.is-selected, - .spectrum-Table-row.is-drop-target, - .spectrum-Table-body.is-drop-target .spectrum-Table-row { - /* Ensure negative offset outline contrasts on top of SelectedItem background. */ - --highcontrast-table-cell-focus-indicator-color: var(--highcontrast-table-selected-row-text-color); - --highcontrast-table-cell-focus-extra-offset: 1px; + /* Focus indicators */ + --spectrum-table-focus-indicator-thickness: var(--spectrum-focus-indicator-thickness); + --spectrum-table-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-table-row-focus-indicator-width: var(--spectrum-side-focus-indicator); - .spectrum-Table-checkbox .spectrum-Checkbox-box::before { - outline: var(--highcontrast-table-selected-row-text-color) 1px solid; - } - } -} + /* Individual focused table cells still have a border-radius */ + --spectrum-table-focused-cell-border-radius: var(--spectrum-corner-radius-small-default); -.spectrum-Table { - --spectrum-table-cell-inline-space: var(--spectrum-table-edge-to-content); + --spectrum-table-selected-cell-background-color-focus: var(--highcontrast-table-selected-row-background-color-focus, var(--mod-table-selected-row-background-color-non-emphasized-focus, var(--spectrum-table-selected-row-background-color-non-emphasized-focus))); - --spectrum-table-border-radius: var(--spectrum-corner-radius-100); - --spectrum-table-border-width: var(--spectrum-table-border-divider-width); - --spectrum-table-outer-border-inline-width: var(--spectrum-table-border-divider-width); + /* Visual (avatar, icons, thumbnails) */ + --spectrum-table-icon-color-default: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-table-icon-color-hover: var(--spectrum-neutral-subdued-content-color-hover); + --spectrum-table-icon-color-active: var(--spectrum-neutral-subdued-content-color-down); + --spectrum-table-icon-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-table-icon-color-focus-hover: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-table-icon-color-key-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + --spectrum-table-disclosure-icon-size: var(--spectrum-component-height-100); + --spectrum-table-icon-color: var(--highcontrast-table-icon-color, var(--mod-table-icon-color-default, var(--spectrum-table-icon-color-default))); - --spectrum-table-default-vertical-align: top; - --spectrum-table-header-vertical-align: middle; + /* Alignment */ + --spectrum-table-default-vertical-align: middle; + /* Font */ --spectrum-table-header-font-weight: var(--spectrum-bold-font-weight); + --spectrum-table-header-text-color: var(--spectrum-body-color); --spectrum-table-row-font-family: var(--spectrum-sans-font-family-stack); --spectrum-table-row-font-weight: var(--spectrum-regular-font-weight); --spectrum-table-row-font-style: var(--spectrum-default-font-style); --spectrum-table-row-line-height: var(--spectrum-line-height-100); - - --spectrum-table-border-color: var(--spectrum-gray-300); - --spectrum-table-divider-color: var(--spectrum-gray-300); - --spectrum-table-header-background-color: var(--spectrum-transparent-white-100); - --spectrum-table-header-text-color: var(--spectrum-body-color); - --spectrum-table-row-background-color: var(--spectrum-gray-50); --spectrum-table-row-text-color: var(--spectrum-neutral-content-color-default); + --spectrum-table-row-font-size: var(--spectrum-font-size-100); - /* @todo Refactor or remove these properties once the RGB stripped value is available. */ - --spectrum-table-selected-row-background-color: rgba(var(--spectrum-blue-900-rgb), var(--spectrum-table-selected-row-background-opacity)); - --spectrum-table-selected-row-background-color-non-emphasized: rgba(var(--spectrum-gray-700-rgb), var(--spectrum-table-selected-row-background-opacity-non-emphasized)); - --spectrum-table-row-background-color-hover: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-table-row-hover-opacity)); - --spectrum-table-row-active-color: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-table-row-down-opacity)); - --spectrum-table-selected-row-background-color-focus: rgba(var(--spectrum-blue-900-rgb), var(--spectrum-table-selected-row-background-opacity-hover)); - --spectrum-table-selected-row-background-color-non-emphasized-focus: rgba(var(--spectrum-gray-700-rgb), var(--spectrum-table-selected-row-background-opacity-non-emphasized-hover)); + --spectrum-table-summary-row-font-weight: var(--spectrum-bold-font-weight); + --spectrum-table-section-header-font-weight: var(--spectrum-bold-font-weight); - --spectrum-table-icon-color-default: var(--spectrum-neutral-subdued-content-color-default); - --spectrum-table-icon-color-hover: var(--spectrum-neutral-subdued-content-color-hover); - --spectrum-table-icon-color-active: var(--spectrum-neutral-subdued-content-color-down); - --spectrum-table-icon-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); - --spectrum-table-icon-color-focus-hover: var(--spectrum-neutral-subdued-content-color-key-focus); - --spectrum-table-icon-color-key-focus: var(--spectrum-neutral-subdued-content-color-key-focus); + /* Size and Spacing */ + --spectrum-table-min-header-row-height: var(--spectrum-component-height-100); + --spectrum-table-header-row-top-to-text: var(--spectrum-table-column-header-row-top-to-text-medium); + --spectrum-table-header-row-bottom-to-text: var(--spectrum-table-column-header-row-bottom-to-text-medium); - --spectrum-table-focus-indicator-thickness: var(--spectrum-focus-indicator-thickness); - --spectrum-table-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-table-min-row-height: var(--spectrum-table-row-height-medium); + --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-medium); + --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-medium); - --spectrum-table-drop-zone-background-color: rgba(var(--spectrum-drop-zone-background-color-rgb), var(--spectrum-drop-zone-background-color-opacity)); - --spectrum-table-drop-zone-outline-color: var(--spectrum-accent-visual-color); + --spectrum-table-header-row-checkbox-block-spacing: var(--spectrum-table-header-row-checkbox-to-top-medium); + --spectrum-table-row-checkbox-block-spacing: var(--spectrum-table-row-checkbox-to-top-medium); - --spectrum-table-transition-duration: var(--spectrum-animation-duration-100); + --spectrum-table-section-header-min-height: var(--spectrum-table-section-header-row-height-medium); + --spectrum-table-section-header-block-start-spacing: var(--spectrum-component-top-to-text-100); + --spectrum-table-section-header-block-end-spacing: var(--spectrum-component-bottom-to-text-100); - /* Summary Row and Section Header Row */ - --spectrum-table-summary-row-font-weight: var(--spectrum-bold-font-weight); - --spectrum-table-summary-row-background-color: var(--spectrum-gray-200); + --spectrum-table-visual-to-text: var(--spectrum-text-to-visual-300); + --spectrum-table-thumbnail-size: var(--spectrum-thumbnail-size-100); + --spectrum-table-avatar-size: var(--spectrum-avatar-size-75); - --spectrum-table-section-header-font-weight: var(--spectrum-bold-font-weight); - --spectrum-table-section-header-background-color: var(--spectrum-gray-200); + --spectrum-table-cell-inline-spacing: var(--spectrum-table-edge-to-content); + --spectrum-table-checkbox-to-cell-content: var(--spectrum-table-checkbox-to-text); - /* Collapsible and thumbnails */ --spectrum-table-collapsible-tier-indent: var(--spectrum-spacing-300); --spectrum-table-collapsible-disclosure-inline-spacing: 0px; --spectrum-table-collapsible-icon-animation-duration: var(--spectrum-animation-duration-100); - --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color, var(--mod-table-row-background-color, var(--spectrum-table-row-background-color))); - --spectrum-table-selected-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-selected-row-background-color-non-emphasized, var(--spectrum-table-selected-row-background-color-non-emphasized))); - --spectrum-table-selected-cell-background-color-focus: var(--highcontrast-table-selected-row-background-color-focus, var(--mod-table-selected-row-background-color-non-emphasized-focus, var(--spectrum-table-selected-row-background-color-non-emphasized-focus))); - /* @passthrough */ --mod-thumbnail-size: var(--mod-table-thumbnail-size, var(--spectrum-table-thumbnail-size)); + --mod-avatar-block-size: var(--mod-table-avatar-size, var(--spectrum-table-avatar-size)); + --mod-avatar-inline-size: var(--mod-table-avatar-size, var(--spectrum-table-avatar-size)); + + /* Button for menus in header cells */ + --mod-button-border-radius: 0; + --mod-button-font-weight: var(--spectrum-table-header-font-weight); + --mod-button-font-size: var(--spectrum-table-row-font-size); + --mod-button-font-family: var(--spectrum-table-row-font-family); + --mod-button-line-height: var(--spectrum-table-row-line-height); + --mod-button-background-color-default: transparent; + --mod-button-background-color-hover: transparent; + --mod-button-background-color-focus: transparent; + --mod-button-background-color-down: transparent; + --mod-button-content-color-default: var(--spectrum-table-header-text-color); + --mod-button-content-color-hover: var(--spectrum-table-header-text-color); + --mod-button-content-color-focus: var(--spectrum-table-header-text-color); + --mod-button-content-color-down: var(--spectrum-table-header-text-color); + --mod-button-edge-to-text: var(--spectrum-table-cell-inline-spacing); + --mod-button-padding-label-to-icon: var(--spectrum-table-visual-to-text); + --mod-button-height: var(--spectrum-table-min-header-row-height); + --mod-button-focus-ring-border-radius: var(--spectrum-table-focused-cell-border-radius); &:dir(rtl) { --spectrum-logical-rotation: matrix(-1, 0, 0, 1, 0, 0); } } -.spectrum-Table, -.spectrum-Table--sizeM { - --spectrum-table-min-header-height: var(--spectrum-component-height-100); - --spectrum-table-header-top-to-text: var(--spectrum-table-column-header-row-top-to-text-medium); - --spectrum-table-header-bottom-to-text: var(--spectrum-table-column-header-row-bottom-to-text-medium); - - --spectrum-table-min-row-height: var(--spectrum-table-row-height-medium-regular); - --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-medium-regular); - --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-medium-regular); - - --spectrum-table-icon-to-text: var(--spectrum-text-to-visual-100); - - /* Typography */ - --spectrum-table-row-font-size: var(--spectrum-font-size-100); - - /* Row Selection */ - --spectrum-table-header-checkbox-block-spacing: var(--spectrum-table-header-row-checkbox-to-top-medium); - --spectrum-table-row-checkbox-block-spacing: var(--spectrum-table-row-checkbox-to-top-medium-regular); - - /* Summary Row and Section Header Row */ - --spectrum-table-section-header-min-height: var(--spectrum-table-section-header-row-height-medium); - --spectrum-table-section-header-block-start-spacing: var(--spectrum-component-top-to-text-100); - --spectrum-table-section-header-block-end-spacing: var(--spectrum-component-bottom-to-text-100); - - /* Collapsible and Thumbnails */ - --spectrum-table-disclosure-icon-size: var(--spectrum-component-height-100); - - --spectrum-table-thumbnail-block-spacing: var(--spectrum-table-thumbnail-to-top-minimum-medium-regular); - --spectrum-table-thumbnail-to-text: var(--spectrum-text-to-visual-100); - --spectrum-table-thumbnail-size: var(--spectrum-thumbnail-size-300); -} - -.spectrum-Table--sizeS { +/********* VARIANTS *********/ +.spectrum-Table--compact { /* Size and Spacing */ - --spectrum-table-min-header-height: var(--spectrum-component-height-100); - --spectrum-table-header-top-to-text: var(--spectrum-table-column-header-row-top-to-text-small); - --spectrum-table-header-bottom-to-text: var(--spectrum-table-column-header-row-bottom-to-text-small); - - --spectrum-table-min-row-height: var(--spectrum-table-row-height-small-regular); - --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-small-regular); - --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-small-regular); - - --spectrum-table-icon-to-text: var(--spectrum-text-to-visual-100); - - /* Typography */ - --spectrum-table-row-font-size: var(--spectrum-font-size-75); + --spectrum-table-min-row-height: var(--mod-table-min-row-height-compact, var(--spectrum-table-row-height-medium-compact)); + --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-medium-compact); + --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-medium-compact); /* Row Selection */ - --spectrum-table-header-checkbox-block-spacing: var(--spectrum-table-header-row-checkbox-to-top-small); - --spectrum-table-row-checkbox-block-spacing: var(--spectrum-table-row-checkbox-to-top-small-regular); + --spectrum-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing-compact, var(--spectrum-table-row-checkbox-to-top-medium-compact)); - /* Summary Row and Section Header Row */ - --spectrum-table-section-header-min-height: var(--spectrum-table-section-header-row-height-small); - --spectrum-table-section-header-block-start-spacing: var(--spectrum-component-top-to-text-75); - --spectrum-table-section-header-block-end-spacing: var(--spectrum-component-bottom-to-text-75); - - /* Collapsible and Thumbnails */ - --spectrum-table-disclosure-icon-size: var(--spectrum-component-height-75); - - --spectrum-table-thumbnail-block-spacing: var(--spectrum-table-thumbnail-to-top-minimum-small-regular); - --spectrum-table-thumbnail-to-text: var(--spectrum-text-to-visual-100); - --spectrum-table-thumbnail-size: var(--spectrum-thumbnail-size-200); + /* Visuals */ + --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-compact, var(--spectrum-thumbnail-size-75)); + --mod-table-avatar-size: var(--mod-table-avatar-size-compact, var(--spectrum-avatar-size-50)); } -.spectrum-Table--sizeL { +.spectrum-Table--spacious { /* Size and Spacing */ - --spectrum-table-min-header-height: var(--spectrum-component-height-200); - --spectrum-table-header-top-to-text: var(--spectrum-table-column-header-row-top-to-text-large); - --spectrum-table-header-bottom-to-text: var(--spectrum-table-column-header-row-bottom-to-text-large); - - --spectrum-table-min-row-height: var(--spectrum-table-row-height-large-regular); - --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-large-regular); - --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-large-regular); - - --spectrum-table-icon-to-text: var(--spectrum-text-to-visual-200); - - /* Typography */ - --spectrum-table-row-font-size: var(--spectrum-font-size-200); + --spectrum-table-min-row-height: var(--mod-table-min-row-height-spacious, var(--spectrum-table-row-height-medium-spacious)); + --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-medium-spacious); + --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-medium-spacious); /* Row Selection */ - --spectrum-table-header-checkbox-block-spacing: var(--spectrum-table-header-row-checkbox-to-top-large); - --spectrum-table-row-checkbox-block-spacing: var(--spectrum-table-row-checkbox-to-top-large-regular); - - /* Summary Row and Section Header Row */ - --spectrum-table-section-header-min-height: var(--spectrum-table-section-header-row-height-large); - --spectrum-table-section-header-block-start-spacing: var(--spectrum-component-top-to-text-200); - --spectrum-table-section-header-block-end-spacing: var(--spectrum-component-bottom-to-text-200); + --spectrum-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing-spacious, var(--spectrum-table-row-checkbox-to-top-medium-spacious)); - /* Collapsible and Thumbnails */ - --spectrum-table-disclosure-icon-size: var(--spectrum-component-height-200); - - --spectrum-table-thumbnail-block-spacing: var(--spectrum-table-thumbnail-to-top-minimum-large-regular); - --spectrum-table-thumbnail-to-text: var(--spectrum-text-to-visual-200); - --spectrum-table-thumbnail-size: var(--spectrum-thumbnail-size-500); + /* Visuals */ + --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-spacious, var(--spectrum-thumbnail-size-200)); + --mod-table-avatar-size: var(--mod-table-avatar-size-spacious, var(--spectrum-avatar-size-100)); } -.spectrum-Table--sizeXL { - /* Size and Spacing */ - --spectrum-table-min-header-height: var(--spectrum-component-height-300); - --spectrum-table-header-top-to-text: var(--spectrum-table-column-header-row-top-to-text-extra-large); - --spectrum-table-header-bottom-to-text: var(--spectrum-table-column-header-row-bottom-to-text-extra-large); - - --spectrum-table-min-row-height: var(--spectrum-table-row-height-extra-large-regular); - --spectrum-table-row-top-to-text: var(--spectrum-table-row-top-to-text-extra-large-regular); - --spectrum-table-row-bottom-to-text: var(--spectrum-table-row-bottom-to-text-extra-large-regular); - - --spectrum-table-icon-to-text: var(--spectrum-text-to-visual-300); - - /* Typography */ - --spectrum-table-row-font-size: var(--spectrum-font-size-300); - - /* Row Selection */ - --spectrum-table-header-checkbox-block-spacing: var(--spectrum-table-header-row-checkbox-to-top-extra-large); - --spectrum-table-row-checkbox-block-spacing: var(--spectrum-table-row-checkbox-to-top-extra-large-regular); - - /* Summary Row and Section Header Row */ - --spectrum-table-section-header-min-height: var(--spectrum-table-section-header-row-height-extra-large); - --spectrum-table-section-header-block-start-spacing: var(--spectrum-component-top-to-text-300); - --spectrum-table-section-header-block-end-spacing: var(--spectrum-component-bottom-to-text-300); - - /* Collapsible and Thumbnails */ - --spectrum-table-disclosure-icon-size: var(--spectrum-component-height-300); - - --spectrum-table-thumbnail-block-spacing: var(--spectrum-table-thumbnail-to-top-minimum-extra-large-regular); - --spectrum-table-thumbnail-to-text: var(--spectrum-text-to-visual-300); - --spectrum-table-thumbnail-size: var(--spectrum-thumbnail-size-700); +.spectrum-Table--emphasized, +.spectrum-Table-row .is-emphasized { + --spectrum-table-selected-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-selected-row-background-color, var(--spectrum-table-selected-row-background-color))); + --spectrum-table-selected-cell-background-color-focus: var(--highcontrast-table-selected-row-background-color-focus, var(--mod-table-selected-row-background-color-focus, var(--spectrum-table-selected-row-background-color-focus))); } -/********* VARIANTS *********/ -.spectrum-Table--compact { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--compact, var(--spectrum-table-row-height-medium-compact)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--compact, var(--spectrum-table-row-top-to-text-medium-compact)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--compact, var(--spectrum-table-row-bottom-to-text-medium-compact)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--compact, var(--spectrum-table-row-checkbox-to-top-medium-compact)); - - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-compact, var(--spectrum-table-thumbnail-to-top-minimum-medium-compact)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-compact, var(--spectrum-thumbnail-size-200)); - - &.spectrum-Table--sizeS { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--compact, var(--spectrum-table-row-height-small-compact)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--compact, var(--spectrum-table-row-top-to-text-small-compact)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--compact, var(--spectrum-table-row-bottom-to-text-small-compact)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--compact, var(--spectrum-table-row-checkbox-to-top-small-compact)); +.spectrum-Table--quiet { + --spectrum-table-border-radius: var(--mod-table-border-radius-quiet, 0px); + --spectrum-table-outer-border-inline-width: var(--mod-table-outer-border-inline-width-quiet, 0px); + --spectrum-table-header-background-color: var(--mod-table-header-background-color-quiet, var(--spectrum-transparent-white-100)); + --spectrum-table-row-background-color: var(--mod-table-row-background-color-quiet, var(--spectrum-transparent-white-100)); + --spectrum-table-border-color: transparent; +} - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-compact, var(--spectrum-table-thumbnail-to-top-minimum-small-compact)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-compact, var(--spectrum-thumbnail-size-50)); +.spectrum-Table-row { + &:hover, + &:focus-visible, + &.is-focused { + --highcontrast-table-row-text-color: var(--highcontrast-table-row-text-color-hover); + --highcontrast-table-icon-color: var(--highcontrast-table-row-text-color-hover); + --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color-hover, var(--mod-table-row-background-color-hover, var(--spectrum-table-row-background-color-hover))); } - &.spectrum-Table--sizeL { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--compact, var(--spectrum-table-row-height-large-compact)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--compact, var(--spectrum-table-row-top-to-text-large-compact)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--compact, var(--spectrum-table-row-bottom-to-text-large-compact)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--compact, var(--spectrum-table-row-checkbox-to-top-large-compact)); - - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-compact, var(--spectrum-table-thumbnail-to-top-minimum-large-compact)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-compact, var(--spectrum-thumbnail-size-300)); + &:active { + --highcontrast-table-row-text-color: var(--highcontrast-table-row-text-color-hover); + --highcontrast-table-icon-color: var(--highcontrast-table-row-text-color-hover); + --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color-hover, var(--mod-table-row-active-color, var(--spectrum-table-row-active-color))); } - &.spectrum-Table--sizeXL { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--compact, var(--spectrum-table-row-height-extra-large-compact)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--compact, var(--spectrum-table-row-top-to-text-extra-large-compact)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--compact, var(--spectrum-table-row-bottom-to-text-extra-large-compact)); + &.is-selected { + --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color); + --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color); + --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--spectrum-table-selected-cell-background-color)); - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--compact, var(--spectrum-table-row-checkbox-to-top-extra-large-compact)); + &:hover, + &:focus-visible, + &.is-focused { + --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color-focus); + --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color-focus); + --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color-focus, var(--spectrum-table-selected-cell-background-color-focus)); + } + } - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-compact, var(--spectrum-table-thumbnail-to-top-minimum-extra-large-compact)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-compact, var(--spectrum-thumbnail-size-500)); + &.is-drop-target, + .spectrum-Table-body.is-drop-target & { + --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color); + --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color); + --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-drop-zone-background-color, var(--spectrum-table-drop-zone-background-color))); } } -.spectrum-Table--spacious { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--spacious, var(--spectrum-table-row-height-medium-spacious)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--spacious, var(--spectrum-table-row-top-to-text-medium-spacious)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--spacious, var(--spectrum-table-row-bottom-to-text-medium-spacious)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--spacious, var(--spectrum-table-row-checkbox-to-top-medium-spacious)); +.spectrum-Table-headCell { + &.is-sortable, + &.spectrum-Table-hasMenuButton { + &:hover { + --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-hover, var(--spectrum-table-icon-color-hover))); + } - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-spacious, var(--spectrum-table-thumbnail-to-top-minimum-medium-spacious)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-spacious, var(--spectrum-thumbnail-size-500)); + &:active { + --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-active, var(--spectrum-table-icon-color-active))); + } - &.spectrum-Table--sizeS { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--spacious, var(--spectrum-table-row-height-small-spacious)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--spacious, var(--spectrum-table-row-top-to-text-small-spacious)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--spacious, var(--spectrum-table-row-bottom-to-text-small-spacious)); + &:focus { + --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-focus, var(--spectrum-table-icon-color-focus))); + } - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--spacious, var(--spectrum-table-row-checkbox-to-top-small-spacious)); + &:focus:hover { + --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-focus-hover, var(--spectrum-table-icon-color-focus-hover))); + } - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-spacious, var(--spectrum-table-thumbnail-to-top-minimum-small-spacious)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-spacious, var(--spectrum-thumbnail-size-300)); + &:focus-visible, + &.is-keyboardFocused { + --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-key-focus, var(--spectrum-table-icon-color-key-focus))); + } } - &.spectrum-Table--sizeL { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--spacious, var(--spectrum-table-row-height-large-spacious)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--spacious, var(--spectrum-table-row-top-to-text-large-spacious)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--spacious, var(--spectrum-table-row-bottom-to-text-large-spacious)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--spacious, var(--spectrum-table-row-checkbox-to-top-large-spacious)); - - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-spacious, var(--spectrum-table-thumbnail-to-top-minimum-large-spacious)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-spacious, var(--spectrum-thumbnail-size-700)); + /* These styles get applied to the headCell when the headCell has the --hasMenuButton class. */ + &.spectrum-Table-hasMenuButton { + --spectrum-table-cell-inline-spacing: 0; + --spectrum-table-header-row-top-to-text: 0; + --spectrum-table-header-row-bottom-to-text: 0; } +} - &.spectrum-Table--sizeXL { - /* Size and Spacing */ - --mod-table-min-row-height: var(--mod-table-min-row-height--spacious, var(--spectrum-table-row-height-extra-large-spacious)); - --mod-table-row-top-to-text: var(--mod-table-row-top-to-text--spacious, var(--spectrum-table-row-top-to-text-extra-large-spacious)); - --mod-table-row-bottom-to-text: var(--mod-table-row-bottom-to-text--spacious, var(--spectrum-table-row-bottom-to-text-extra-large-spacious)); - - /* Row Selection */ - --mod-table-row-checkbox-block-spacing: var(--mod-table-row-checkbox-block-spacing--spacious, var(--spectrum-table-row-checkbox-to-top-extra-large-spacious)); - - /* Collapsible and Thumbnails */ - --mod-table-thumbnail-block-spacing: var(--mod-table-thumbnail-block-spacing-spacious, var(--spectrum-table-thumbnail-to-top-minimum-extra-large-spacious)); - --mod-table-thumbnail-size: var(--mod-table-thumbnail-size-spacious, var(--spectrum-thumbnail-size-800)); - } +.spectrum-Table-scroller { + --spectrum-table-header-background-color: var(--mod-table-header-background-color-scrollable, var(--spectrum-background-layer-1-color, var(--spectrum-gray-75))); } -.spectrum-Table--emphasized { - --spectrum-table-selected-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-selected-row-background-color, var(--spectrum-table-selected-row-background-color))); - --spectrum-table-selected-cell-background-color-focus: var(--highcontrast-table-selected-row-background-color-focus, var(--mod-table-selected-row-background-color-focus, var(--spectrum-table-selected-row-background-color-focus))); +.spectrum-Table-row--summary { + --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color, var(--mod-table-summary-row-background-color, var(--spectrum-table-summary-row-background-color))); } -.spectrum-Table--quiet { - --mod-table-border-radius: var(--mod-table-border-radius--quiet, 0px); - --mod-table-outer-border-inline-width: var(--mod-table-outer-border-inline-width--quiet, 0px); - --mod-table-header-background-color: var(--mod-table-header-background-color--quiet, var(--spectrum-transparent-white-100)); - --mod-table-row-background-color: var(--mod-table-row-background-color--quiet, var(--spectrum-transparent-white-100)); +.spectrum-Table-row--sectionHeader { + --spectrum-table-cell-background-color: var(--highcontrast-table-section-header-background-color, var(--mod-table-section-header-background-color, var(--spectrum-table-section-header-background-color))); + + &:hover { + --highcontrast-table-row-text-color: var(--highcontrast-table-section-header-text-color); + --spectrum-table-cell-background-color: var(--highcontrast-table-section-header-background-color, var(--mod-table-section-header-background-color, var(--spectrum-table-section-header-background-color))); + } } -/********* REGULAR / DEFAULT *********/ +/********* REGULAR / DEFAULT TABLE *********/ .spectrum-Table:not(.spectrum-Table-scroller), .spectrum-Table-main { border-collapse: separate; @@ -417,124 +276,179 @@ display: table; } -.spectrum-Table-sortedIcon { - display: none; - vertical-align: baseline; - margin-inline-start: var(--mod-table-sort-icon-inline-start-spacing, 0); - margin-inline-end: var(--mod-table-sort-icon-inline-end-spacing, var(--mod-table-icon-to-text, var(--spectrum-table-icon-to-text))); - transition: transform var(--highcontrast-table-transition-duration, var(--mod-table-transition-duration, var(--spectrum-table-transition-duration))) ease-in-out; -} +/********* HEAD CELLS *********/ +.spectrum-Table-headRow { + .spectrum-Table-headCell { + box-sizing: border-box; + text-align: start; + vertical-align: var(--mod-table-header-vertical-align, var(--spectrum-table-default-vertical-align)); -.spectrum-Table-menuIcon { - vertical-align: middle; - margin-inline-start: var(--mod-table-icon-to-text, var(--spectrum-table-icon-to-text)); -} + font-family: var(--mod-table-header-font-family, var(--spectrum-table-row-font-family)); + font-size: var(--mod-table-header-font-size, var(--spectrum-table-row-font-size)); + font-weight: var(--mod-table-header-font-weight, var(--spectrum-table-header-font-weight)); + line-height: var(--mod-table-header-line-height, var(--spectrum-table-row-line-height)); + text-transform: var(--mod-table-header-text-transform, none); -.spectrum-Table-headCell { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color, var(--mod-table-icon-color-default, var(--spectrum-table-icon-color-default))); + /* block-size functions as min-block-size when using display table-cell. */ + block-size: var(--mod-table-min-header-height, var(--spectrum-table-min-header-row-height)); - box-sizing: border-box; - text-align: start; - vertical-align: var(--mod-table-header-vertical-align, var(--spectrum-table-header-vertical-align)); + padding-block: var(--mod-table-header-row-top-to-text, var(--spectrum-table-header-row-top-to-text)) var(--mod-table-header-row-bottom-to-text, var(--spectrum-table-header-row-bottom-to-text)); + padding-inline: var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing)); - font-family: var(--mod-table-header-font-family, var(--spectrum-table-row-font-family)); - font-size: var(--mod-table-header-font-size, var(--spectrum-table-row-font-size)); - font-weight: var(--mod-table-header-font-weight, var(--spectrum-table-header-font-weight)); - line-height: var(--mod-table-header-line-height, var(--spectrum-table-row-line-height)); - text-transform: var(--mod-table-header-text-transform, none); + color: var(--mod-table-header-text-color, var(--spectrum-table-header-text-color)); + background-color: var(--mod-table-header-background-color, var(--spectrum-table-header-background-color)); + border-block-start: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-border-color, var(--spectrum-table-border-color))); - /* block-size functions as min-block-size when using display table-cell. */ - block-size: var(--mod-table-min-header-height, var(--spectrum-table-min-header-height)); + transition: color var(--highcontrast-table-transition-duration, var(--mod-table-transition-duration, var(--spectrum-table-transition-duration))) ease-in-out; + cursor: var(--mod-table-cursor-header-default, initial); + outline: 0; - padding-block: var(--mod-table-header-top-to-text, var(--spectrum-table-header-top-to-text)) var(--mod-table-header-bottom-to-text, var(--spectrum-table-header-bottom-to-text)); - padding-inline: var(--mod-table-cell-inline-space, var(--spectrum-table-cell-inline-space)); + &.is-sortable { + cursor: var(--mod-table-cursor-header-sortable, pointer); + } + } - color: var(--mod-table-header-text-color, var(--spectrum-table-header-text-color)); - background-color: var(--mod-table-header-background-color, var(--spectrum-table-header-background-color)); + /* Places the focus indicator above the table cell borders. */ + .spectrum-ActionButton::after { + z-index: 1; + } - border-radius: 0; - transition: color var(--highcontrast-table-transition-duration, var(--mod-table-transition-duration, var(--spectrum-table-transition-duration))) ease-in-out; - cursor: var(--mod-table-cursor-header-default, initial); - outline: 0; + &:first-child .spectrum-Table-headCell:first-child { + border-start-start-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border-inline-start: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-border-color, var(--spectrum-table-border-color))); + } - .spectrum-Table-sortedIcon, - .spectrum-Table-menuIcon { - color: var(--spectrum-table-icon-color); + &:last-child .spectrum-Table-headCell:last-child { + border-start-end-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border-inline-end: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-border-color, var(--spectrum-table-border-color))); } - &.is-sortable { - cursor: var(--mod-table-cursor-header-sortable, pointer); + /* Checkbox cell in header row */ + .spectrum-Table-checkboxCell { + padding-inline-start: calc(var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing)) - var(--mod-table-outer-border-inline-width, var(--spectrum-table-outer-border-inline-width))); - &:hover { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-hover, var(--spectrum-table-icon-color-hover))); - } + /* the calc subtraction is because the --spectrum-table-checkbox-to-text spacing value + includes the inline start padding in the adjacent cell. */ + padding-inline-end: calc(var(--mod-table-checkbox-to-cell-content, var(--spectrum-table-checkbox-to-cell-content)) - var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing))); + padding-block: var(--mod-table-header-row-checkbox-block-spacing, var(--spectrum-table-header-row-checkbox-block-spacing)); - &:active { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-active, var(--spectrum-table-icon-color-active))); - } + .spectrum-Table-checkbox { + --mod-checkbox-margin-block: 0px; - &:focus { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-focus, var(--spectrum-table-icon-color-focus))); + min-block-size: initial; } + } +} - &:focus:hover { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-focus-hover, var(--spectrum-table-icon-color-focus-hover))); +/********* ICONS- SORT, DISCLOSURE/MENU *********/ +/* Head cell column text */ +.spectrum-Table-columnTitle { + display: inline-block; + vertical-align: middle; +} + +/* A "sortable-only" head cell has no padding around its button. */ +.spectrum-Table-headCell.is-sortable { + padding: 0; + + /* Focus indicator- brings the focus indicator above the border and matches the table cell dimensions. */ + .spectrum-Table-sortButton::after { + inset: calc(3 * var(--mod-table-border-width, var(--spectrum-table-border-width))); + z-index: 1; + } + + .spectrum-Table-sortButton .spectrum-Icon { + color: var(--spectrum-table-icon-color); + transition: transform var(--highcontrast-table-transition-duration, var(--mod-table-transition-duration, var(--spectrum-table-transition-duration))) ease-in-out; + } +} + +/* Head cell column text in the button that opens the menu */ +.spectrum-Table-headCell.spectrum-Table-hasMenuButton { + .spectrum-Table-sortButton { + min-block-size: calc(var(--spectrum-table-min-header-row-height) + var(--mod-table-border-width, var(--spectrum-table-border-width))); + + /* Focus indicator- brings the focus indicator above the border and matches the table cell dimensions. */ + &::after { + /* Multiply by 3 to account for the borders on the top, side and bottom of the table cell. */ + inset: calc(3 * var(--mod-table-border-width, var(--spectrum-table-border-width))); + z-index: 1; } - &:focus-visible, - &.is-keyboardFocused { - --spectrum-table-icon-color: var(--highcontrast-table-icon-color-focus, var(--mod-table-icon-color-key-focus, var(--spectrum-table-icon-color-key-focus))); + .spectrum-Button-label { + vertical-align: middle; + display: inline-block; } - } - &.is-sorted-asc, - &.is-sorted-desc { - .spectrum-Table-sortedIcon { + .spectrum-Button-label::after { + content: ""; display: inline-block; + mask-image: url('data:image/svg+xml,'); + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + + block-size: 10px; + inline-size: 10px; + background-color: var(--spectrum-table-icon-color); + transform: rotate(90deg); + vertical-align: middle; + margin-inline-start: var(--mod-table-visual-to-text, var(--spectrum-table-visual-to-text)); } - } - &.is-sorted-asc { - .spectrum-Table-sortedIcon { - transform: rotateZ(-90deg); + & .spectrum-Icon { + transition: transform var(--highcontrast-table-transition-duration, var(--mod-table-transition-duration, var(--spectrum-table-transition-duration))) ease-in-out; + color: var(--spectrum-table-icon-color); } } } -.spectrum-Table-columnTitle { - display: inline-block; -} - -.spectrum-Table-cell--alignCenter { - text-align: center; +/********* TEXT ALIGNMENT *********/ +.spectrum-Table-cell--alignStart { + text-align: start; } -.spectrum-Table-cell--alignRight { +.spectrum-Table-cell--alignEnd { text-align: end; } +/********* TABLE BODY *********/ .spectrum-Table-body { position: relative; border: none; - border-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border-end-start-radius: calc(var(--mod-table-border-radius, var(--spectrum-table-border-radius)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); + border-end-end-radius: calc(var(--mod-table-border-radius, var(--spectrum-table-border-radius)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); display: table-row-group; &.is-drop-target { - /* Make sure negative offset outline is not covered by borders. */ + /* Make sure borders are not visible behind the pseudo-element */ --mod-table-border-color: transparent; - outline-width: var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness)); - outline-style: solid; - outline-color: var(--highcontrast-table-focus-indicator-color, var(--mod-table-drop-zone-outline-color, var(--spectrum-table-drop-zone-outline-color))); + /* Remove the outline since we'll replace it with an ::after pseudo-element */ + outline: none; + position: relative; + z-index: 0; + + &::after { + content: ""; + position: absolute; + inset: 0; + border-end-start-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border-end-end-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border: var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness)) solid var(--highcontrast-table-focus-indicator-color, var(--mod-table-drop-zone-outline-color, var(--spectrum-table-drop-zone-outline-color))); + pointer-events: none; + z-index: 1; + } } } -/* Outside border, row divider lines, and rounded corners: +/********* CELLS *********/ +.spectrum-Table-cell { + /* Outside border, row divider lines, and rounded corners: The tbody tag doesn't allow setting a border or border-radius. To make them work, border styles are instead applied to the individual cells around the outside, while using border-collapse: separate. */ -/* Row divider lines */ -.spectrum-Table-cell { + /* Row divider lines */ border-block-start: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-divider-color, var(--mod-table-divider-color, var(--spectrum-table-divider-color))); /* Cells within table body */ @@ -551,13 +465,44 @@ padding-block-start: calc(var(--mod-table-row-top-to-text, var(--spectrum-table-row-top-to-text)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); padding-block-end: var(--mod-table-row-bottom-to-text, var(--spectrum-table-row-bottom-to-text)); - padding-inline: calc(var(--mod-table-edge-to-content, var(--spectrum-table-edge-to-content)) - var(--mod-table-outer-border-inline-width, var(--spectrum-table-outer-border-inline-width))); + padding-inline: calc(var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing)) - var(--mod-table-outer-border-inline-width, var(--spectrum-table-outer-border-inline-width))); } -/* Outside border */ +/* Focus Indicator (Ring) */ +.spectrum-Table-cell, +.spectrum-Table-headCell { + position: relative; + display: table-cell; + + &:focus-visible, + &.is-focused { + position: relative; + + /* Remove the outline since we'll replace it with an ::after pseudo-element */ + outline: none; + z-index: 1; /* Ensure cell focus indicator appears above row focus indicator */ + + &::after { + content: ""; + position: absolute; + inset: calc(-1 * var(--mod-table-border-width, var(--spectrum-table-border-width))); + border-radius: calc(var(--mod-table-border-radius, var(--spectrum-table-focused-cell-border-radius)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); + border: var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness)) solid var(--highcontrast-table-cell-focus-indicator-color, var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color)))); + pointer-events: none; + } + } +} + +/* Cells that display a column divider (vertical border). */ +.spectrum-Table-cell--divider { + border-inline-end: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-divider-color, var(--mod-table-divider-color, var(--spectrum-table-divider-color))); +} + +/********* ROWS *********/ +/* Outside border (the table's border) */ .spectrum-Table-body .spectrum-Table-row { &:first-child .spectrum-Table-cell { - border-block-start: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-border-color, var(--spectrum-table-border-color))); + border-block-start: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-divider-color, var(--spectrum-table-divider-color))); } &:last-child .spectrum-Table-cell { @@ -581,18 +526,22 @@ cursor: var(--mod-table-cursor-row-default, pointer); border-block-start: none; - &:first-child .spectrum-Table-cell:first-child { - border-start-start-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + /* most cells within the table body have no border-radius */ + .spectrum-Table-cell { + border-radius: 0; } + /* first cell of first row in table body */ &:first-child .spectrum-Table-cell:last-child { - border-start-end-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + border-radius: 0; } + /* first cell of last row in table body */ &:last-child .spectrum-Table-cell:first-child { border-end-start-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); } + /* last cell of last row in table body */ &:last-child .spectrum-Table-cell:last-child { border-end-end-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); } @@ -608,48 +557,58 @@ border-end-end-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); } - &:focus { - outline: 0; - } - - &:hover, + /* Row focus indicator */ + &.is-focused, &:focus-visible, - &.is-focused { - --highcontrast-table-row-text-color: var(--highcontrast-table-row-text-color-hover); - --highcontrast-table-icon-color: var(--highcontrast-table-row-text-color-hover); - --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color-hover, var(--mod-table-row-background-color-hover, var(--spectrum-table-row-background-color-hover))); - } + &:focus { + outline: none; - &:active { - --highcontrast-table-row-text-color: var(--highcontrast-table-row-text-color-hover); - --highcontrast-table-icon-color: var(--highcontrast-table-row-text-color-hover); - --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color-hover, var(--mod-table-row-active-color, var(--spectrum-table-row-active-color))); - } + /* First cell of focused rows need fancy new focus indicator borders & no border-radius, and the thicker row focus indicator */ + .spectrum-Table-cell:first-child { + position: relative; + border-inline-start: 0; + border-block: var(--spectrum-table-border-width) solid var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color))); + + /* Because the ::before element technically removes the table's inline border, the first cell needs the entire cell padding to avoid horizontal layout shift when a row is focused. */ + padding-inline-start: var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing)); + + /* The side row focus indicator line */ + &::before { + content: ""; + position: absolute; + inset-block-start: 0; + inset-block-end: 0; + inset-inline-start: 0; + inline-size: var(--spectrum-table-row-focus-indicator-width); + background-color: var(--spectrum-table-focus-indicator-color); + z-index: 1; + } + } - &.is-selected { - --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color); - --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color); - --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--spectrum-table-selected-cell-background-color)); + /* All other cells in focused rows (including the first rows after the header row and last rows in the table) need the focus indicator border */ + &:first-child .spectrum-Table-cell, + &:last-child .spectrum-Table-cell, + .spectrum-Table-cell { + border-block: var(--spectrum-table-border-width) solid var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color))); + } - &:hover, - &:focus-visible, - &.is-focused { - --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color-focus); - --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color-focus); - --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color-focus, var(--spectrum-table-selected-cell-background-color-focus)); + /* Last cell of focused row needs the fancy new focus indicator borders at the end */ + .spectrum-Table-cell:last-child { + border-inline-end: var(--spectrum-table-border-width) solid var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color))); + border-block-end: var(--spectrum-table-border-width) solid var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color))); } - } - &.is-drop-target, - .spectrum-Table-body.is-drop-target & { - --highcontrast-table-row-text-color: var(--highcontrast-table-selected-row-text-color); - --highcontrast-table-icon-color: var(--highcontrast-table-selected-row-text-color); - --spectrum-table-cell-background-color: var(--highcontrast-table-selected-row-background-color, var(--mod-table-drop-zone-background-color, var(--spectrum-table-drop-zone-background-color))); + /* In a focused row that is last in the table, the first cell needs rounded corners at the bottom of the row focus indicator line */ + &:last-child .spectrum-Table-cell:first-child::before { + border-end-start-radius: var(--mod-table-border-radius, var(--spectrum-table-border-radius)); + } } &.is-drop-target { /* Make sure negative offset outline is not covered by borders. */ --mod-table-border-color: var(--highcontrast-table-focus-indicator-color, transparent); + border-start-start-radius: 0; + border-start-end-radius: 0; outline-width: var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness)); outline-style: solid; @@ -662,33 +621,15 @@ } } -/* Focus Indicator (Ring) */ -.spectrum-Table-cell, -.spectrum-Table-headCell { - position: relative; - display: table-cell; - - &:focus-visible, - &.is-focused { - outline-width: var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness)); - outline-style: solid; - outline-color: var(--highcontrast-table-cell-focus-indicator-color, var(--highcontrast-table-focus-indicator-color, var(--mod-table-focus-indicator-color, var(--spectrum-table-focus-indicator-color)))); - outline-offset: calc((-1 * var(--mod-table-focus-indicator-thickness, var(--spectrum-table-focus-indicator-thickness))) - var(--highcontrast-table-cell-focus-extra-offset, 0px)); - } -} - -/* Cells that display a column divider (vertical border). */ -.spectrum-Table-cell--divider { - border-inline-end: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-divider-color, var(--mod-table-divider-color, var(--spectrum-table-divider-color))); -} - .spectrum-Table-row--summary { - --spectrum-table-cell-background-color: var(--highcontrast-table-row-background-color, var(--mod-table-summary-row-background-color, var(--spectrum-table-summary-row-background-color))); - .spectrum-Table-cell { font-weight: var(--mod-table-summary-row-font-weight, var(--spectrum-table-summary-row-font-weight)); - /* Make unique summary row mods available to these default row styles: */ + /* Summary rows are typically the same dimensions as other non-header rows, but we make + mods available to override the default row styles */ + block-size: var(--mod-table-summary-row-min-height, var(--spectrum-table-min-row-height)); + padding-block-start: calc(var(--mod-table-summary-row-top-to-text, var(--spectrum-table-row-top-to-text)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); + padding-block-end: var(--mod-table-summary-row-bottom-to-text, var(--spectrum-table-row-bottom-to-text)); font-size: var(--mod-table-summary-row-font-size, var(--spectrum-table-row-font-size)); font-family: var(--mod-table-summary-row-font-family, var(--spectrum-table-row-font-family)); font-style: var(--mod-table-summary-row-font-style, var(--spectrum-table-row-font-style)); @@ -698,7 +639,6 @@ } .spectrum-Table-row--sectionHeader { - --spectrum-table-cell-background-color: var(--highcontrast-table-section-header-background-color, var(--mod-table-section-header-background-color, var(--spectrum-table-section-header-background-color))); cursor: var(--mod-table-cursor-section-header, initial); .spectrum-Table-cell { @@ -709,48 +649,35 @@ block-size: var(--mod-table-section-header-min-height, var(--spectrum-table-section-header-min-height)); padding-block-start: calc(var(--mod-table-section-header-block-start-spacing, var(--spectrum-table-section-header-block-start-spacing)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); - padding-block-end: calc(var(--mod-table-section-header-block-end-spacing, var(--spectrum-table-section-header-block-end-spacing)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); + padding-block-end: var(--mod-table-section-header-block-end-spacing, var(--spectrum-table-section-header-block-end-spacing)); /* Make unique section header mods available to these default row styles: */ + padding-inline-start: calc(var(--mod-table-section-header-inline-start-spacing, var(--spectrum-table-cell-inline-spacing)) - var(--mod-table-outer-border-inline-width, var(--spectrum-table-outer-border-inline-width))); font-size: var(--mod-table-section-header-font-size, var(--spectrum-table-row-font-size)); font-family: var(--mod-table-section-header-font-family, var(--spectrum-table-row-font-family)); font-style: var(--mod-table-section-header-font-style, var(--spectrum-table-row-font-style)); line-height: var(--mod-table-section-header-line-height, var(--spectrum-table-row-line-height)); color: var(--highcontrast-table-section-header-text-color, var(--mod-table-section-header-text-color, var(--spectrum-table-row-text-color))); } - - &:hover { - --highcontrast-table-row-text-color: var(--highcontrast-table-section-header-text-color); - --spectrum-table-cell-background-color: var(--highcontrast-table-section-header-background-color, var(--mod-table-section-header-background-color, var(--spectrum-table-section-header-background-color))); - } } +/* Checkbox cell styles are further down the cascade to override some of the checkbox styles for collapsible tables. */ +/********* CHECKBOX CELLS *********/ .spectrum-Table-checkboxCell { /* Prevent width expansion with 100% width table. */ inline-size: var(--spectrum-checkbox-control-size-small); /* The calc subtraction is because the --spectrum-table-checkbox-to-text spacing value includes the inline start padding in the adjacent cell. */ - padding-inline-end: calc(var(--mod-table-checkbox-to-text, var(--spectrum-table-checkbox-to-text)) - var(--mod-table-edge-to-content, var(--spectrum-table-edge-to-content))); - - /* Block spacing must be moved to calculated margin on the checkbox element. */ - padding-block: 0; + padding-inline-end: calc(var(--mod-table-checkbox-to-cell-content, var(--spectrum-table-checkbox-to-cell-content)) - var(--mod-table-cell-inline-spacing, var(--spectrum-table-cell-inline-spacing))); + padding-block-start: calc(var(--mod-table-row-checkbox-block-spacing, var(--spectrum-table-row-checkbox-block-spacing)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); + padding-block-end: var(--mod-table-row-checkbox-block-spacing, var(--spectrum-table-row-checkbox-block-spacing)); .spectrum-Table-checkbox { - --mod-checkbox-spacing: 0px; + --mod-checkbox-margin-block: 0px; min-block-size: initial; } - - &.spectrum-Table-cell .spectrum-Table-checkbox { - margin-block-start: calc(var(--mod-table-row-checkbox-block-spacing, var(--spectrum-table-row-checkbox-block-spacing)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); - margin-block-end: var(--mod-table-row-checkbox-block-spacing, var(--spectrum-table-row-checkbox-block-spacing)); - } - - &.spectrum-Table-headCell .spectrum-Table-checkbox { - margin-block-start: calc(var(--mod-table-header-checkbox-block-spacing, var(--spectrum-table-header-checkbox-block-spacing)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); - margin-block-end: var(--mod-table-header-checkbox-block-spacing, var(--spectrum-table-header-checkbox-block-spacing)); - } } /********* DIVS *********/ @@ -767,8 +694,6 @@ /********* SCROLLABLE *********/ /* Wrapper that allows a scrollable body and sticky column header. */ .spectrum-Table-scroller { - --spectrum-table-header-background-color: var(--mod-table-header-background-color-scrollable, var(--spectrum-background-layer-1-color, var(--spectrum-gray-75))); - box-sizing: border-box; display: inline-block; position: relative; @@ -780,7 +705,7 @@ /* Make sure shift-tab reverse keyboard navigation keeps the whole cell in focus. --mod-table-current-header-height should be dynamically updated with JS to match the table header height. */ - scroll-padding-top: var(--mod-table-current-header-height, calc((var(--mod-table-header-line-height, var(--spectrum-table-row-line-height)) * var(--mod-table-header-font-size, var(--spectrum-table-row-font-size))) + var(--mod-table-header-top-to-text, var(--spectrum-table-header-top-to-text)) + var(--mod-table-header-bottom-to-text, var(--spectrum-table-header-bottom-to-text)) + var(--mod-table-border-width, var(--spectrum-table-border-width)))); + scroll-padding-top: var(--mod-table-current-header-height, calc((var(--mod-table-header-line-height, var(--spectrum-table-row-line-height)) * var(--mod-table-header-font-size, var(--spectrum-table-row-font-size))) + var(--mod-table-header-row-top-to-text, var(--spectrum-table-header-row-top-to-text)) + var(--mod-table-header-row-bottom-to-text, var(--spectrum-table-header-row-bottom-to-text)) + var(--mod-table-border-width, var(--spectrum-table-border-width)))); &.spectrum-Table--quiet { border-block-start: none; @@ -792,11 +717,14 @@ z-index: 2; } - .spectrum-Table-headCell { + /* Remove borders that have been replaced by borders on scroller wrapper or pseudo elements. */ + .spectrum-Table-headRow:first-child .spectrum-Table-headCell { border-block-end: var(--mod-table-border-width, var(--spectrum-table-border-width)) solid var(--highcontrast-table-border-color, var(--mod-table-border-color, var(--spectrum-table-border-color))); + border-block-start: 0; + border-inline: 0; + border-radius: 0; } - /* Remove borders that have been replaced by borders on wrapper or pseudo elements. */ .spectrum-Table-body .spectrum-Table-row { &:first-child .spectrum-Table-cell { border-block-start: none; @@ -873,7 +801,6 @@ .spectrum-Table-cell--collapsible { padding-inline-start: calc(var(--spectrum-table-row-tier, 0px) * var(--spectrum-table-collapsible-tier-indent)); - padding-block: 0; } .spectrum-Table-collapseInner { @@ -881,12 +808,7 @@ flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; - align-items: flex-start; - - .spectrum-Table-collapseContent { - padding-block-start: calc(var(--mod-table-row-top-to-text, var(--spectrum-table-row-top-to-text)) - var(--mod-table-border-width, var(--spectrum-table-border-width))); - padding-block-end: var(--mod-table-row-bottom-to-text, var(--spectrum-table-row-bottom-to-text)); - } + align-items: center; } .spectrum-Table-disclosureIcon.spectrum-Table-disclosureIcon { @@ -940,45 +862,95 @@ } } -/********* THUMBNAILS *********/ -.spectrum-Table-row--thumbnail { - --spectrum-table-thumbnail-cell-block-spacing: var(--mod-table-thumbnail-block-spacing, var(--spectrum-table-thumbnail-block-spacing)); - --spectrum-table-thumbnail-inner-content-block-spacing: max(0px, calc((var(--mod-table-thumbnail-size, var(--spectrum-table-thumbnail-size)) - (var(--mod-table-row-line-height, var(--spectrum-table-row-line-height)) * var(--mod-table-header-font-size, var(--spectrum-table-row-font-size)))) / 2)); - - /* Cell that does not have a thumbnail, within a row that has a thumbnail. */ - .spectrum-Table-cell { - padding-block: calc(var(--spectrum-table-thumbnail-cell-block-spacing) + var(--spectrum-table-thumbnail-inner-content-block-spacing)); - } - - /* Cell that does have a thumbnail has its padding moved within the "Inner" and "Content" alignment wrappers. */ - .spectrum-Table-cell--thumbnail { - padding-block: 0; - } - - /* Sometimes the padding must be larger to match any extra space created by the disclosure icon (e.g. compact + large ). */ - &.spectrum-Table-row--collapsible { - --spectrum-table-thumbnail-inner-minimum-block-spacing: max(0px, calc((var(--mod-table-disclosure-icon-size, var(--spectrum-table-disclosure-icon-size)) - var(--mod-table-thumbnail-size, var(--spectrum-table-thumbnail-size))) / 2)); - --spectrum-table-thumbnail-cell-block-spacing: max(var(--mod-table-thumbnail-block-spacing, var(--spectrum-table-thumbnail-block-spacing)), var(--spectrum-table-thumbnail-inner-minimum-block-spacing)); - } -} - -.spectrum-Table-thumbnailInner { +/********* VISUALS- THUMBNAILS, AVATARS, ICONS *********/ +.spectrum-Table-visualInner { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; - align-items: flex-start; - padding-block: var(--spectrum-table-thumbnail-cell-block-spacing); + align-items: center; + gap: var(--spectrum-table-visual-to-text); - .spectrum-Thumbnail { + .spectrum-Thumbnail, + .spectrum-Icon, + .spectrum-Avatar { flex-grow: 0; flex-shrink: 0; - margin-inline-end: var(--mod-table-thumbnail-to-text, var(--spectrum-table-thumbnail-to-text)); + margin-inline-end: var(--mod-table-visual-to-text, var(--spectrum-table-visual-to-text)); line-height: var(--mod-table-row-line-height, var(--spectrum-table-row-line-height)); } +} + +/********* HIGH CONTRAST *********/ +@media (forced-colors: active) { + .spectrum-Table { + --highcontrast-table-row-background-color: Canvas; + --highcontrast-table-row-text-color: CanvasText; + --highcontrast-table-divider-color: CanvasText; + --highcontrast-table-border-color: CanvasText; + --highcontrast-table-icon-color: CanvasText; + --highcontrast-table-icon-color-focus: Highlight; + + --highcontrast-table-selected-row-background-color: Highlight; + --highcontrast-table-selected-row-text-color: HighlightText; + + @supports (color: SelectedItem) { + --highcontrast-table-selected-row-background-color: SelectedItem; + --highcontrast-table-selected-row-text-color: SelectedItemText; + } + + --highcontrast-table-selected-row-background-color-focus: Highlight; + --highcontrast-table-selected-row-text-color-focus: HighlightText; + --highcontrast-table-row-background-color-hover: Highlight; + --highcontrast-table-row-text-color-hover: HighlightText; + + --highcontrast-table-section-header-text-color: Canvas; + --highcontrast-table-section-header-background-color: CanvasText; + + --highcontrast-table-focus-indicator-color: Highlight; + --highcontrast-table-transition-duration: 0; + } + + .spectrum-Table-cell { + /* Removes unstylable readability backplate. */ + forced-color-adjust: none; + + &:focus-visible, + &.is-focused { + &::after { + border-color: Highlight; + } + } + } + + .spectrum-Table-row { + &:hover, + &:focus-visible, + &.is-focused { + .spectrum-Table-checkbox .spectrum-Checkbox-box::before { + outline: var(--highcontrast-table-row-text-color-hover) 1px solid; + } - .spectrum-Table-thumbnailContent { - /* Vertically centers text with the middle of the thumbnail. */ - padding-block: var(--spectrum-table-thumbnail-inner-content-block-spacing); + /* corresponds to the row focus indicator with a ::before pseudo element */ + .spectrum-Table-cell:first-child::before { + background-color: Highlight; + } + + /* Make sure border colors are visible in high contrast mode */ + /* .spectrum-Table-cell { + border-color: Highlight; + } */ + } + } + + .spectrum-Table-row.is-selected, + .spectrum-Table-row.is-drop-target, + .spectrum-Table-body.is-drop-target .spectrum-Table-row { + /* Ensure negative offset outline contrasts on top of SelectedItem background. */ + --highcontrast-table-cell-focus-indicator-color: var(--highcontrast-table-selected-row-text-color); + + .spectrum-Table-checkbox .spectrum-Checkbox-box::before { + outline: var(--highcontrast-table-selected-row-text-color) 1px solid; + } } } diff --git a/components/table/stories/table.stories.js b/components/table/stories/table.stories.js index 834a90f4630..ff16c7518bb 100644 --- a/components/table/stories/table.stories.js +++ b/components/table/stories/table.stories.js @@ -1,6 +1,5 @@ -import { Sizes } from "@spectrum-css/preview/decorators"; import { disableDefaultModes } from "@spectrum-css/preview/modes"; -import { isEmphasized, isQuiet, size } from "@spectrum-css/preview/types"; +import { isEmphasized, isLoading, isQuiet } from "@spectrum-css/preview/types"; import metadata from "../dist/metadata.json"; import packageJson from "../package.json"; import { TableGroup } from "./table.test.js"; @@ -13,7 +12,6 @@ export default { title: "Table", component: "Table", argTypes: { - size: size(["s", "m", "l", "xl"]), density: { name: "Density", table: { @@ -24,11 +22,15 @@ export default { control: "select", }, isQuiet, - isEmphasized, + isEmphasized: { + ...isEmphasized, + description: "Emphasized styling on the table affects colors of selected rows and any checkboxes." + }, + isLoading, useDivs: { name: "Use divs for markup", description: - "Use 'div' elements for all of the table markup instead of the 'table' element.", + "Use `div` elements for all of the table markup instead of the `table` element.", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -47,10 +49,21 @@ export default { }, control: "boolean", }, - showThumbnails: { - name: "Show thumbnails in content", - description: - "Uses the thumbnail component at the start of the first column's cells.", + selectionMode: { + name: "Selection mode", + description: "Determines whether items in the table can be selected, and if users can select only one or multiple items.", + type: { name: "string", required: true }, + table: { + type: { summary: "string" }, + category: "Selection", + disable: true, + }, + options: ["none", "single", "multiple"], + control: "select", + }, + hasColumnDividers: { + name: "Show dividers between columns", + description: "Sets dividers between table columns.", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -58,9 +71,9 @@ export default { }, control: "boolean", }, - hasColumnDividers: { - name: "Show dividers between columns", - description: "Sets dividers between table columns.", + hasMenu: { + name: "Has a menu", + description: "Adds an action button to header cell to indicate that the column has a hidden menu.", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -68,12 +81,35 @@ export default { }, control: "boolean", }, + isSortable: { + name: "Enable sortable columns", + description: "Table columns can be sortable and are indicated by appropriate sort icons.", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Component", + }, + control: "boolean", + }, + sortIcon: { + name: "Sort icon", + description: "Sort icons are used to indicate the sort direction of a column. The `none` option is used to indicate that the column is not sorted.", + type: { name: "string" }, + table: { + type: { summary: "string" }, + category: "Component", + }, + options: ["Sort", "SortUp", "SortDown"], + control: "select", + if: { arg: "isSortable", eq: true }, + }, isDropTarget: { name: "Dropzone (drop target)", type: { name: "boolean" }, table: { type: { summary: "boolean" }, category: "State", + disable: true, }, control: "boolean", }, @@ -83,15 +119,18 @@ export default { }, args: { rootClass: "spectrum-Table", - size: "m", - density: "standard", + density: "regular", isQuiet: false, + isLoading: false, isEmphasized: true, + selectionMode: "none", useDivs: false, - showThumbnails: false, isDropTarget: false, useScroller: false, hasColumnDividers: false, + hasMenu: false, + isSortable: false, + sortIcon: "Sort", rowItems: [ { cellContent: "Row item alpha", @@ -117,9 +156,14 @@ export default { }, packageJson, metadata, + status: { + type: "migrated" + }, }, + tags: ["migrated"], }; + const ExampleRowItems = [ { cellContent: ["Table row alpha", "Alpha", "Table row alpha"], @@ -127,7 +171,7 @@ const ExampleRowItems = [ }, { cellContent: [ - "Table row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + "Selected row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "Bravo", "Table row bravo. Lorem ipsum dolor sit amet.", ], @@ -135,7 +179,7 @@ const ExampleRowItems = [ isSelected: true, }, { - cellContent: "Table row charlie", + cellContent: "Selected row charlie", showCheckbox: true, isSelected: true, }, @@ -154,29 +198,52 @@ const ExampleRowItems = [ ]; /** - * The medium size is the default and recommended option. The default table also uses the regular density. + * The default table also uses the regular density. Similar to a paragraph of text, textual data is always start-aligned within a table. Never use center alignment. */ export const Default = TableGroup.bind({}); Default.args = {}; // ********* DOCS ONLY ********* // /** - * Tables come in four different sizes: small, medium, large, and extra-large. The medium size is the default and recommended option. + * The empty state variant displays an [illustrated message](/docs/components-illustrated-message--docs) when there is no data to display. + */ +export const EmptyState = Template.bind({}); +EmptyState.args = { + rowItems: [], +}; +EmptyState.parameters = { + chromatic: { disableSnapshot: true }, +}; +EmptyState.storyName = "Empty state"; +EmptyState.argTypes = { + isEmphasized: { table: { disable: true } }, + isQuiet: { table: { disable: true } }, + isLoading: { table: { disable: true } }, + hasColumnDividers: { table: { disable: true } }, + hasMenu: { table: { disable: true } }, + isSortable: { table: { disable: true } }, + sortIcon: { table: { disable: true } }, + isDropTarget: { table: { disable: true } }, + useDivs: { table: { disable: true } }, + useScroller: { table: { disable: true } }, +}; + +/** + * A table may render a [progress circle](/docs/components-progress-circle--docs) while populating data. */ -export const Sizing = (args, context) => Sizes({ - Template, - withHeading: false, - withBorder: false, - ...args, -}, context); -Sizing.args = {}; -Sizing.tags = ["!dev"]; -Sizing.parameters = { +export const LoadingState = Template.bind({}); +LoadingState.args = { + ...Default.args, + isLoading: true, +}; +LoadingState.tags = ["!dev"]; +LoadingState.parameters = { chromatic: { disableSnapshot: true }, }; +LoadingState.storyName = "Loading state"; /** - * The compact variant decreases the spacing used within the table. + * The compact variant decreases the spacing used within the table rows, except for the header row. */ export const Compact = Template.bind({}); Compact.args = { @@ -190,7 +257,7 @@ Compact.parameters = { Compact.storyName = "Density - compact"; /** - * The spacious variant increases the spacing used within the table. + * The spacious variant increases the spacing used within the table rows, except for the header row. */ export const Spacious = Template.bind({}); Spacious.args = { @@ -204,22 +271,62 @@ Spacious.parameters = { Spacious.storyName = "Density - spacious"; /** - * The standard multi-select table includes a column of checkboxes used for selecting rows. + * The standard multi-select table includes a column of checkboxes used for selecting rows. When the selection mode + * is set to `multiple`, users may select more than one table row. Typically, an [indeterminate checkbox](/docs/components-checkbox--docs) + * is used to indicate that ability. */ export const MultiSelect = Template.bind({}); -MultiSelect.storyName = "Multi-select"; +MultiSelect.storyName = "Selection mode: multiple"; MultiSelect.args = { rowItems: ExampleRowItems, + selectionMode: "multiple", }; MultiSelect.parameters = { chromatic: { disableSnapshot: true }, }; +/** + * When the selection mode is set to `single`, users may select only one table row. + */ +export const SingleSelect = Template.bind({}); +SingleSelect.storyName = "Selection mode: single"; +SingleSelect.args = { + selectionMode: "single", + rowItems: [ + { + cellContent: ["Pikachu", "Electric", "35"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + isSelected: true, + isChecked: true, + }, + { + cellContent: ["Charmander", "Fire", "39"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + }, + { + cellContent: ["Mew", "Psychic", "100"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + } + ], +}; +SingleSelect.parameters = { + chromatic: { disableSnapshot: true }, +}; + /** * Excluding the `.spectrum-Table--emphasized` class will change the style of selected rows. */ export const NonEmphasizedMultiSelect = Template.bind({}); -NonEmphasizedMultiSelect.storyName = "Non-emphasized multi-select"; +NonEmphasizedMultiSelect.storyName = "Selection mode: multiple, non-emphasized styling"; NonEmphasizedMultiSelect.args = { ...MultiSelect.args, isEmphasized: false, @@ -230,7 +337,83 @@ NonEmphasizedMultiSelect.parameters = { }; /** - * The quiet table has a transparent background and no borders on the left and right. + * Numerical data should generally be end-aligned for the ease of scanning and comparing. Numerical data should only be start-aligned when numbers are arbitrary identifiers, known as “nominal numbers,” which means they can’t be compared or combined arithmetically (e.g., ZIP codes, IP addresses, phone numbers). + * + * Column headers follow the alignment of the data, so for end-aligned numerical data, implementations should add the `.spectrum-Table-headCell--alignEnd` class to affected header cells (not shown below). + */ +export const NumericalData = Template.bind({}); +NumericalData.args = { + rowItems: [ + { + cellContent: ["Pikachu", "Electric", "35"], + textAlignment: { + 2: "end" + } + }, + { + cellContent: ["Charmander", "Fire", "39"], + textAlignment: { + 2: "end" + } + }, + { + cellContent: ["Mew", "Psychic", "100"], + textAlignment: { + 2: "end" + } + } + ], +}; +NumericalData.storyName = "Numerical data"; +NumericalData.parameters = { + chromatic: { disableSnapshot: true }, +}; + +/** + * The cells and rows within the table have different states based on selection and focus. Implementations should add appropriate tab stops to indicate focus on a row correctly. + */ +export const TableStates = Template.bind({}); +TableStates.args = { + rowItems: [ + { + cellContent: "Focused selected row, no rounded corners", + isFocused: true, + isSelected: true, + }, + { + cellContent: "Table row bravo", + }, + { + cellContent: "Selected unfocused row, no rounded corners", + isSelected: true, + }, + { + cellContent: "Focused unselected row, no rounded corners", + isFocused: true, + }, + { + cellContent: ["Table row with a focused cell", "Focused cell", "Unfocused cell"], + cellCustomClasses: { + 1: ["is-focused"] + } + }, + { + cellContent: "Table row echo", + }, + { + cellContent: "Focused selected row, with rounded corners", + isFocused: true, + isSelected: true, + } + ], +}; +TableStates.storyName = "Row and cell states"; +TableStates.parameters = { + chromatic: { disableSnapshot: true }, +}; + +/** + * Quiet tables are for when a table is meant to be supplementary, subtle, or lightweight. The quiet table utilizes the `.spectrum-Table--quiet` class and has a transparent background and no borders on the left and right. */ export const Quiet = Template.bind({}); Quiet.args = { @@ -242,6 +425,43 @@ Quiet.parameters = { chromatic: { disableSnapshot: true }, }; +/** + * Tables with enabled column sorting can show different states of sorting: unsorted, ascending, and descending. The content of the header cell is an [button](/docs/components-button--docs), that has a class of `.spectrum-Table-sortButton`, which should contain the sorting icon, as well as the header label. + * + * When a column is sorted in ascending order, use the `SortUp` icon, as seen below. If sorted in descending order, use the `SortDown` icon. If the sort is undefined, use the more general `Sort` icon. + * + * The `aria-sort` attribute should be set on the `.spectrum-Table-headCell .is-sortable` element for the column that is currently sorted, and when sorting is active. `aria-sort` should not be set on more than one column at a time. + * + * Implementations will develop their own sorting functionality. The `aria-sort` attribute should be removed from a column header when the column is not sorted. + */ +export const Sortable = Template.bind({}); +Sortable.args = { + ...Default.args, + isSortable: true, + sortIcon: "Sort", +}; +Sortable.parameters = { + chromatic: { disableSnapshot: true }, +}; +Sortable.storyName = "Sortable columns"; +Sortable.tags = ["!dev"]; + +/** + * Tables can have additional actions in the header cells that could trigger a menu, as indicated by the chevron. Oftentimes, the menu is used to show users the available sorting options. The content of the header cell is an [button](/docs/components-button--docs), that has a class of `.spectrum-Table-sortButton`, which should contain the sorting icon when applicable, as well as the header label. + * + * The `aria-sort` attribute should be set on the `.spectrum-Table-hasMenuButton` element for the column that is currently sorted, and when sorting is active. + */ +export const WithMenuButton = Template.bind({}); +WithMenuButton.args = { + ...Default.args, + hasMenu: true, +}; +WithMenuButton.storyName = "Sortable columns: with menu button"; +WithMenuButton.parameters = { + chromatic: { disableSnapshot: true }, +}; +WithMenuButton.tags = ["!dev"]; + /** * A quiet multi-select table has emphasized styling by default, but excluding the `.spectrum-Table--emphasized` class will change the style of selected rows. */ @@ -249,15 +469,18 @@ export const QuietMultiSelect = Template.bind({}); QuietMultiSelect.args = { ...MultiSelect.args, isQuiet: true, + selectionMode: "multiple", }; QuietMultiSelect.tags = ["!dev"]; -QuietMultiSelect.storyName = "Quiet multi-select"; +QuietMultiSelect.storyName = "Selection mode: multiple, quiet styling"; QuietMultiSelect.parameters = { chromatic: { disableSnapshot: true }, }; /** - * The standard table can display column dividers by including the `.spectrum-Table-cell--divider` class with `.spectrum-Table-cell`. Use sparingly to group related content. + * Column dividers are for organizing table content and aid the user in parsing related data. These are optional; use them carefully to group related content. + * + * The standard table can display column dividers by including the `.spectrum-Table-cell--divider` class with `.spectrum-Table-cell`. */ export const WithColumnDividers = Template.bind({}); WithColumnDividers.args = { @@ -276,6 +499,10 @@ WithColumnDividers.parameters = { export const SummaryAndSelected = Template.bind({}); SummaryAndSelected.args = { rowItems: [ + { + cellContent: "Summary row", + isSummaryRow: true, + }, { cellContent: "Table row alpha", }, @@ -283,19 +510,15 @@ SummaryAndSelected.args = { cellContent: "Table row bravo", }, { - cellContent: "Table row charlie", + cellContent: "Selected row charlie", isSelected: true, }, { cellContent: "Table row delta", }, - { - cellContent: "Summary row", - isSummaryRow: true, - }, ], }; -SummaryAndSelected.storyName = "Summary and selected"; +SummaryAndSelected.storyName = "Summary and selected rows"; SummaryAndSelected.parameters = { chromatic: { disableSnapshot: true }, }; @@ -331,7 +554,7 @@ SectionHeader.args = { }, ], }; -SectionHeader.storyName = "Section header"; +SectionHeader.storyName = "Section headers"; SectionHeader.parameters = { chromatic: { disableSnapshot: true }, }; @@ -341,13 +564,13 @@ SectionHeaderQuiet.args = { ...SectionHeader.args, isQuiet: true, }; -SectionHeaderQuiet.storyName = "Section header: quiet"; +SectionHeaderQuiet.storyName = "Section headers: quiet styling"; SectionHeaderQuiet.parameters = { chromatic: { disableSnapshot: true }, }; +SectionHeaderQuiet.tags = ["!dev"]; /** - * * A table can be wrapped in a fixed height `div` with the `.spectrum-Table-scroller` class. This allows scrolling of the table body and makes the column headers sticky (i.e. fixed to the top on scroll). * * When using the scrollable wrapper, the column headers must have a solid background color set. This can be customized to match the parent background with the custom property `--mod-table-header-background-color-scrollable`. @@ -367,7 +590,7 @@ Scrollable.args = { cellContent: "Table row bravo", }, { - cellContent: "Table row charlie", + cellContent: "Selected row charlie", isSelected: true, }, { @@ -391,20 +614,47 @@ Scrollable.parameters = { }; /** - * A table can also be made up of `div` tags if needed, instead of a ``. This example uses both the div markup, and the scrollable wrapper. + * A table can also be made up of `div` tags if needed, instead of a `
`. This example uses both the `div` markup, and the scrollable wrapper. */ export const DivsScrollable = Template.bind({}); -DivsScrollable.storyName = "Scrollable with divs"; +DivsScrollable.storyName = "Scrollable table with divs"; DivsScrollable.args = { ...Scrollable.args, useDivs: true, - rowItems: ExampleRowItems, }; DivsScrollable.tags = ["!dev"]; DivsScrollable.parameters = { chromatic: { disableSnapshot: true }, }; + +/** + * Thumbnails, avatars, and other icons can be used in the table content, with some additional markup and classes for alignment. + */ +export const Visuals = Template.bind({}); +Visuals.args = { + rowItems: [ + { + cellContent: "Avatar example", + visualElement: "avatar", + }, + { + cellContent: "Icon example", + visualElement: "icon", + }, + { + cellContent: "Thumbnail example", + visualElement: "thumbnail", + }, + ], +}; +Visuals.parameters = { + chromatic: { disableSnapshot: true }, +}; +Visuals.storyName = "With visuals"; + + +// TODO: The design team doesn't have support for collapsible rows in the table component, so they are removed from the docs page for now. /** * In a table with collapsible rows, all child items must have columns that match the parent items. If they don’t, consider using multiple drill-in tables, [Miller columns](/docs/components-miller-columns--docs), or [breadcrumbs](/docs/components-breadcrumbs--docs) instead. */ @@ -421,7 +671,7 @@ Collapsible.args = { }, { cellContent: - "Table row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + "Table row bravo. There is actually another collapsed row here that's not visible. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", isCollapsible: true, tier: 1, ariaControls: "table-cr-charlie", @@ -439,7 +689,7 @@ Collapsible.args = { id: "table-cr-charlie", }, { - cellContent: "Table row delta", + cellContent: "Selected row delta", isSelected: true, isCollapsible: true, isExpanded: true, @@ -470,10 +720,13 @@ Collapsible.args = { Collapsible.parameters = { chromatic: { disableSnapshot: true }, }; +Collapsible.storyName = "Collapsible rows"; +Collapsible.tags = ["!autodocs", "!dev"]; export const CollapsibleMultiSelect = Template.bind({}); -CollapsibleMultiSelect.storyName = "Collapsible multi-select"; +CollapsibleMultiSelect.storyName = "Selection mode: multiple, collapsible rows"; CollapsibleMultiSelect.args = { + selectionMode: "multiple", rowItems: [ { showCheckbox: true, @@ -487,7 +740,7 @@ CollapsibleMultiSelect.args = { { showCheckbox: true, cellContent: - "Table row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + "Table row bravo. There is actually another collapsed row here that's not visible. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", isCollapsible: true, tier: 1, ariaControls: "table-cr-charlie", @@ -507,7 +760,7 @@ CollapsibleMultiSelect.args = { }, { showCheckbox: true, - cellContent: "Table row delta", + cellContent: "Selected row delta", isSelected: true, isCollapsible: true, isExpanded: true, @@ -541,73 +794,66 @@ CollapsibleMultiSelect.args = { CollapsibleMultiSelect.parameters = { chromatic: { disableSnapshot: true }, }; +CollapsibleMultiSelect.tags = ["!autodocs", "!dev"]; /** - * Thumbnails can be used in the table content, with some additional markup and classes for alignment. - */ -export const Thumbnails = Template.bind({}); -Thumbnails.args = { - showThumbnails: true, - rowItems: [ - { - cellContent: ["Table row alpha", "Test", "2"], - }, - { - cellContent: ["Table row bravo", "Test", "28"], - }, - { - cellContent: [ - "Table row charlie. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", - "Test", - "23", - ], - }, - { - cellContent: ["Table row delta", "Test", "7"], - }, - ], -}; -Thumbnails.tags = ["!dev"]; -Thumbnails.parameters = { - chromatic: { disableSnapshot: true }, -}; - -/** - * The thumbnail table variant can also be combined with collapsible rows. + * The table can also combine visuals with collapsible rows. */ -export const ThumbnailsCollapsible = Template.bind({}); -ThumbnailsCollapsible.args = { - showThumbnails: true, +export const VisualsCollapsible = Template.bind({}); +VisualsCollapsible.args = { rowItems: [ { cellContent: "Table row alpha", isCollapsible: true, isExpanded: true, tier: 0, - ariaControls: "table-cr-bravo", + ariaControls: "table-cr-bravo table-cr-delta", id: "table-cr-alpha", }, { cellContent: - "Table row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + "Table row bravo. There is actually another collapsed row here that's not visible. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", isCollapsible: true, tier: 1, ariaControls: "table-cr-charlie", id: "table-cr-bravo", + visualElement: "avatar", }, { - cellContent: "Table row charlie", + cellContent: [ + "Table row charlie", + "Default not visible", + "Default not visible", + ], + isCollapsible: true, + isHidden: true, + tier: 2, + id: "table-cr-charlie", + }, + { + cellContent: "Selected row delta", + isSelected: true, + isCollapsible: true, + isExpanded: true, + tier: 1, + ariaControls: "table-cr-echo table-cr-foxtrot", + id: "table-cr-delta", + visualElement: "icon", + }, + { + cellContent: "Table row echo", tier: 2, isLastTier: true, isCollapsible: true, - id: "table-cr-charlie", + id: "table-cr-echo", + visualElement: "thumbnail", }, { - cellContent: "Table row delta", + cellContent: "Table row foxtrot", tier: 2, isLastTier: true, isCollapsible: true, - id: "table-cr-delta", + id: "table-cr-foxtrot", }, { cellContent: "Summary row", @@ -615,19 +861,22 @@ ThumbnailsCollapsible.args = { }, ], }; -ThumbnailsCollapsible.storyName = "Thumbnails: collapsible"; -ThumbnailsCollapsible.parameters = { +VisualsCollapsible.tags = ["!autodocs", "!dev"]; +VisualsCollapsible.storyName = "With visuals: collapsible rows"; +VisualsCollapsible.parameters = { chromatic: { disableSnapshot: true }, }; +// TODO: The design team doesn't have dropzones in the table component, so they are removed from the docs page for now. /** * The table body can accept dropped content. */ export const BodyDropZone = Template.bind({}); BodyDropZone.args = { + ...Default.args, isDropTarget: true, }; -BodyDropZone.tags = ["!dev"]; +BodyDropZone.tags = ["!autodocs", "!dev"]; BodyDropZone.storyName = "Dropzone: body"; BodyDropZone.parameters = { chromatic: { disableSnapshot: true }, @@ -662,6 +911,7 @@ RowDropZone.args = { }, ], }; +RowDropZone.tags = ["!autodocs", "!dev"]; RowDropZone.storyName = "Dropzone: row"; RowDropZone.parameters = { chromatic: { disableSnapshot: true }, @@ -672,7 +922,7 @@ RowDropZoneQuiet.args = { ...RowDropZone.args, isQuiet: true, }; -RowDropZoneQuiet.tags = ["!dev"]; +RowDropZoneQuiet.tags = ["!autodocs", "!dev"]; RowDropZoneQuiet.storyName = "Dropzone: row, quiet"; RowDropZoneQuiet.parameters = { chromatic: { disableSnapshot: true }, diff --git a/components/table/stories/table.test.js b/components/table/stories/table.test.js index 73022af599f..3d0eba27f69 100644 --- a/components/table/stories/table.test.js +++ b/components/table/stories/table.test.js @@ -133,22 +133,61 @@ export const TableGroup = Variants({ hasColumnDividers: true, }, { - testHeading: "Summary: selected", + testHeading: "Empty state", + rowItems: [], + }, + { + testHeading: "Loading state", + isLoading: true, + }, + { + testHeading: "Summary and selected rows", rowItems: ExampleSummarySelectedContent, }, { - testHeading: "Multi-select: emphasized", + testHeading: "Selection mode: multiple, emphasized", rowItems: ExampleMultiSelectContent, + selectionMode: "multiple", }, { - testHeading: "Multi-select: non-emphasized", - isEmphasized: false, + testHeading: "Selection mode: single, emphasized", + rowItems: [ + { + cellContent: ["Pikachu", "Electric", "35"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + isSelected: true, + isChecked: true, + }, + { + cellContent: ["Charmander", "Fire", "39"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + }, + { + cellContent: ["Mew", "Psychic", "100"], + textAlignment: { + 2: "end" + }, + showCheckbox: true, + } + ], + }, + { + testHeading: "Selection mode: multiple, non-emphasized", rowItems: ExampleMultiSelectContent, + isEmphasized: false, + selectionMode: "multiple", }, { - testHeading: "Quiet multi-select: emphasized", + testHeading: "Selection mode: multiple, quiet, emphasized", isQuiet: true, rowItems: ExampleMultiSelectContent, + selectionMode: "multiple", }, { testHeading: "Scrollable", @@ -161,6 +200,14 @@ export const TableGroup = Variants({ useScroller: true, rowItems: ExampleMultiSelectContent, }, + { + testHeading: "Sortable columns", + isSortable: true, + }, + { + testHeading: "Head cell with menu button", + hasMenu: true, + }, { testHeading: "Section headers", rowItems: ExampleSectionHeadersContent, @@ -230,7 +277,8 @@ export const TableGroup = Variants({ ], }, { - testHeading: "Collapsible: multi-select", + testHeading: "Selection mode: multiple, collapsible", + selectionMode: "multiple", rowItems: [ { showCheckbox: true, @@ -296,60 +344,100 @@ export const TableGroup = Variants({ ], }, { - testHeading: "Thumbnails", - showThumbnails: true, + testHeading: "End-alignment for numerical data", rowItems: [ { - cellContent: ["Table row alpha", "Test", "2"], + cellContent: ["Pikachu", "Electric", "35"], + textAlignment: { + 2: "end" + } }, { - cellContent: ["Table row bravo", "Test", "28"], + cellContent: ["Charmander", "Fire", "39"], + textAlignment: { + 2: "end" + } }, { - cellContent: [ - "Table row charlie. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", - "Test", - "23", - ], + cellContent: ["Mew", "Psychic", "100"], + textAlignment: { + 2: "end" + } + }, + ], + }, + { + testHeading: "Visual elements", + rowItems: [ + { + cellContent: "Avatar example", + visualElement: "avatar", }, { - cellContent: ["Table row delta", "Test", "7"], + cellContent: "Icon example", + visualElement: "icon", + }, + { + cellContent: "Thumbnail example", + visualElement: "thumbnail", }, ], }, { - testHeading: "Thumbnail: collapsible", - showThumbnails: true, + testHeading: "Visual elements: collapsible", rowItems: [ { cellContent: "Table row alpha", isCollapsible: true, isExpanded: true, tier: 0, - ariaControls: "table-cr-bravo", + ariaControls: "table-cr-bravo table-cr-delta", id: "table-cr-alpha", }, { cellContent: - "Table row bravo. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + "Table row bravo. There is actually another collapsed row here that's not visible. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", isCollapsible: true, tier: 1, ariaControls: "table-cr-charlie", id: "table-cr-bravo", + visualElement: "avatar", }, { - cellContent: "Table row charlie", + cellContent: [ + "Table row charlie", + "Default not visible", + "Default not visible", + ], + isCollapsible: true, + isHidden: true, + tier: 2, + id: "table-cr-charlie", + }, + { + cellContent: "Selected row delta", + isSelected: true, + isCollapsible: true, + isExpanded: true, + tier: 1, + ariaControls: "table-cr-echo table-cr-foxtrot", + id: "table-cr-delta", + visualElement: "icon", + }, + { + cellContent: "Table row echo", tier: 2, isLastTier: true, isCollapsible: true, - id: "table-cr-charlie", + id: "table-cr-echo", + visualElement: "thumbnail", }, { - cellContent: "Table row delta", + cellContent: "Table row foxtrot", tier: 2, isLastTier: true, isCollapsible: true, - id: "table-cr-delta", + id: "table-cr-foxtrot", }, { cellContent: "Summary row", @@ -370,5 +458,40 @@ export const TableGroup = Variants({ testHeading: "Body drop target", isDropTarget: true, }, + { + testHeading: "Focus, selected states for rows and cells", + rowItems: [ + { + cellContent: "Focused selected row, no rounded corners", + isFocused: true, + isSelected: true, + }, + { + cellContent: "Table row bravo", + }, + { + cellContent: "Selected unfocused row, no rounded corners", + isSelected: true, + }, + { + cellContent: "Focused unselected row, no rounded corners", + isFocused: true, + }, + { + cellContent: ["Table row with a focused cell", "Focused cell", "Unfocused cell"], + cellCustomClasses: { + 1: ["is-focused"] + } + }, + { + cellContent: "Table row echo", + }, + { + cellContent: "Focused selected row, with rounded corners", + isFocused: true, + isSelected: true, + } + ], + } ], }); diff --git a/components/table/stories/template.js b/components/table/stories/template.js index 8487cca716d..f90d4e1e0e8 100644 --- a/components/table/stories/template.js +++ b/components/table/stories/template.js @@ -1,7 +1,10 @@ +import { Template as Avatar } from "@spectrum-css/avatar/stories/template.js"; import { Template as Button } from "@spectrum-css/button/stories/template.js"; import { Template as Checkbox } from "@spectrum-css/checkbox/stories/template.js"; import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; +import { Template as IllustratedMessage } from "@spectrum-css/illustratedmessage/stories/template.js"; import { getRandomId } from "@spectrum-css/preview/decorators"; +import { Template as ProgressCircle } from "@spectrum-css/progresscircle/stories/template.js"; import { Template as Thumbnail } from "@spectrum-css/thumbnail/stories/template.js"; import { classMap } from "lit/directives/class-map.js"; import { ifDefined } from "lit/directives/if-defined.js"; @@ -15,23 +18,26 @@ export const TableRowItem = ({ cellContent = "Row Item Text", showCheckbox = false, isSelected = false, + isFocused = false, isSummaryRow = false, isSectionHeader = false, - tableIsEmphasized = true, + isEmphasized = true, isCollapsible = false, isExpanded = false, isHidden = false, hasColumnDividers = false, + density = "regular", tier, isLastTier = false, useDivs = false, - showThumbnails = false, + visualElement, + textAlignment, isDropTarget = false, ariaControls, customClasses = [], - size = "m", + cellCustomClasses = {}, } = {}, context = {}) => { - const useThumbnail = showThumbnails && !isSummaryRow && !isSectionHeader; + const useVisuals = visualElement !== undefined && !isSummaryRow && !isSectionHeader; const useColumnDividers = hasColumnDividers && !isSummaryRow && !isSectionHeader; // Use Table tags or Div tags. @@ -44,15 +50,37 @@ export const TableRowItem = ({ const content = Array.isArray(cellContent) ? cellContent[columnIndex] : cellContent; - if (useThumbnail && columnIndex < 2) { + + if (useVisuals && columnIndex < 2) { return html` -
- ${Thumbnail({ - size: "300", - imageURL: "example-card-landscape.png", - isCover: true, - }, context)} -
${content}
+
+ ${visualElement === "thumbnail" ? + Thumbnail({ + size: ({ + compact: "75", + regular: "100", + spacious: "200", + }[density] || "100"), + imageURL: "example-card-landscape.png", + isCover: true, + }, context) + : visualElement === "avatar" ? + Avatar({ + size: ({ + compact: "50", + regular: "75", + spacious: "100", + }[density] || "75"), + imageURL: "example-card-landscape.png", + isCover: true, + }, context) + : visualElement === "icon" ? + Icon({ + iconName: "Image", + setName: "workflow", + }, context) + : null} +
${content}
`; } @@ -61,6 +89,11 @@ export const TableRowItem = ({ } }; + // For each column, apply the text alignment specified in textAlignment + const getTextAlignment = (columnIndex) => { + return textAlignment?.[columnIndex] || "start"; + }; + return html` <${rowTag} class=${classMap({ @@ -68,9 +101,9 @@ export const TableRowItem = ({ [`${rootClass}-row--summary`]: isSummaryRow, [`${rootClass}-row--sectionHeader`]: isSectionHeader, [`${rootClass}-row--collapsible`]: isCollapsible, - [`${rootClass}-row--thumbnail`]: useThumbnail, [`${rootClass}-cell--divider`]: useColumnDividers, ["is-selected"]: isSelected, + ["is-focused"]: isFocused, ["is-expanded"]: isExpanded, ["is-last-tier"]: isLastTier, ["is-drop-target"]: isDropTarget, @@ -87,12 +120,14 @@ export const TableRowItem = ({ class=${classMap({ [`${rootClass}-cell`]: true, [`${rootClass}-checkboxCell`]: true, + [`${rootClass}-cell--alignEnd`]: getTextAlignment(0) === "end", + ...cellCustomClasses?.[0]?.reduce((a, c) => ({ ...a, [c]: true }), {}), })} > ${when(!isSummaryRow, () => Checkbox({ - size, - isEmphasized: tableIsEmphasized, + size: "m", + isEmphasized, isChecked: isSelected, customClasses: [`${rootClass}-checkbox`], }, context) @@ -101,41 +136,47 @@ export const TableRowItem = ({ )} ${isCollapsible - ? html` - <${cellTag} - role=${ifDefined(showCheckbox ? "gridcell" : useDivs ? "cell" : undefined)} - class=${classMap({ - [`${rootClass}-cell`]: true, - [`${rootClass}-cell--collapsible`]: true, - [`${rootClass}-cell--thumbnail`]: useThumbnail, - [`${rootClass}-cell--divider`]: useColumnDividers, - })} - > -
- ${when(!isLastTier, () => - Button({ - size, - iconName: "ChevronRight100", - iconSet: "ui", - hideLabel: true, - customClasses: [`${rootClass}-disclosureIcon`], - ariaExpanded: isExpanded, - ariaControls, - }, context) - )} - ${useThumbnail ? getCellContent(0) : html`
${getCellContent(0)}
`} -
- ` - : html` - <${cellTag} - role=${ifDefined(showCheckbox ? "gridcell" : useDivs ? "cell" : undefined)} - class=${classMap({ - [`${rootClass}-cell`]: true, - [`${rootClass}-cell--thumbnail`]: useThumbnail, - [`${rootClass}-cell--divider`]: useColumnDividers, - })} - colspan=${ifDefined(isSectionHeader && showCheckbox ? "4" : isSectionHeader ? "3" : undefined)} - >${getCellContent(0)}` + ? html` + <${cellTag} + role=${ifDefined(showCheckbox ? "gridcell" : useDivs ? "cell" : undefined)} + class=${classMap({ + [`${rootClass}-cell`]: true, + [`${rootClass}-cell--collapsible`]: true, + [`${rootClass}-cell--visual`]: useVisuals, + [`${rootClass}-cell--divider`]: useColumnDividers, + [`${rootClass}-cell--alignEnd`]: getTextAlignment(0) === "end", + ...cellCustomClasses?.[showCheckbox ? 1 : 0]?.reduce((a, c) => ({ ...a, [c]: true }), {}), + })} + > +
+ ${when(!isLastTier, () => + Button({ + size: "m", + iconName: "ChevronRight100", + iconSet: "ui", + hideLabel: true, + customClasses: [`${rootClass}-disclosureIcon`], + ariaExpanded: isExpanded, + ariaControls, + }, context) + )} + ${useVisuals ? getCellContent(0) : html`
${getCellContent(0)}
`} +
+ ` + : html` + <${cellTag} + role=${ifDefined(showCheckbox ? "gridcell" : useDivs ? "cell" : undefined)} + class=${classMap({ + [`${rootClass}-cell`]: true, + [`${rootClass}-cell--visual`]: useVisuals, + [`${rootClass}-cell--divider`]: useColumnDividers, + [`${rootClass}-cell--alignEnd`]: getTextAlignment(0) === "end", + ...cellCustomClasses?.[showCheckbox ? 1 : 0]?.reduce((a, c) => ({ ...a, [c]: true }), {}), + })} + colspan=${ifDefined(isSectionHeader && showCheckbox ? "4" : isSectionHeader ? "3" : undefined)} + > + ${getCellContent(0)} + ` } ${when(!isSectionHeader, () => html` @@ -143,8 +184,10 @@ export const TableRowItem = ({ role=${ifDefined(showCheckbox ? "gridcell" : useDivs ? "cell" : undefined)} class=${classMap({ [`${rootClass}-cell`]: true, - [`${rootClass}-cell--thumbnail`]: useThumbnail, + [`${rootClass}-cell--visual`]: useVisuals, [`${rootClass}-cell--divider`]: useColumnDividers, + [`${rootClass}-cell--alignEnd`]: getTextAlignment(1) === "end", + ...cellCustomClasses?.[showCheckbox ? 2 : 1]?.reduce((a, c) => ({ ...a, [c]: true }), {}), })} >${getCellContent(1)} @@ -153,6 +196,8 @@ export const TableRowItem = ({ class=${classMap({ [`${rootClass}-cell`]: true, [`${rootClass}-cell--divider`]: useColumnDividers, + [`${rootClass}-cell--alignEnd`]: getTextAlignment(2) === "end", + ...cellCustomClasses?.[showCheckbox ? 3 : 2]?.reduce((a, c) => ({ ...a, [c]: true }), {}), })} >${getCellContent(2)}` )} @@ -162,20 +207,54 @@ export const TableRowItem = ({ export const Template = ({ rootClass = "spectrum-Table", - size = "m", - density = "standard", + density = "regular", isQuiet = false, isEmphasized = true, + isLoading = false, useDivs = false, + selectionMode = "none", useScroller = false, - showThumbnails = false, + visualElement, isDropTarget = false, hasColumnDividers = false, + isSortable = false, + sortIcon = "Sort", + hasMenu = false, rowItems = [], customClasses = [], id = getRandomId("table"), } = {}, context = {}) => { - if (!rowItems || !rowItems.length) return html``; + + // Empty state + if (!rowItems || !rowItems.length) return html` + ${IllustratedMessage({ + illustration: "NoData", + illustrationSet: "workflow", + title: "Empty state title", + description: "No data to display. Description of status. Give more information about what a user can do or expect, or how to make items appear here.", + isHorizontal: true, + hasButtons: true, + size: ({ + "compact": "s", + "regular": "m", + "spacious": "l", + }[density] || "regular"), + }, context)} + `; + + // Loading state + if (isLoading) { + return html` + ${ProgressCircle({ + size: ({ + "compact": "s", + "regular": "m", + "spacious": "l", + }[density] || "regular"), + isIndeterminate: true, + }, context)} + `; + } // Use Table tags or Div tags. const tableTag = useDivs ? literal`div` : literal`table`; @@ -185,7 +264,6 @@ export const Template = ({ const thTag = useDivs ? literal`div` : literal`th`; const rootClassMapVariants = { - [`${rootClass}--size${size?.toUpperCase()}`]: typeof size !== "undefined", [`${rootClass}--${density}`]: density !== "standard", [`${rootClass}--quiet`]: isQuiet, [`${rootClass}--emphasized`]: isEmphasized, @@ -193,6 +271,7 @@ export const Template = ({ }; const useCheckboxCell = rowItems.some((item) => item.showCheckbox === true); + const ariaSortValue = sortIcon === "SortUp" ? "ascending" : sortIcon === "SortDown" ? "descending" : "none"; const tableHtml = html` <${tableTag} @@ -203,8 +282,7 @@ export const Template = ({ })} id=${ifDefined(id)} role=${ifDefined(useCheckboxCell ? "grid" : useDivs ? "table" : undefined)} - aria-multiselectable=${ifDefined(useCheckboxCell ? "true" : undefined)} - style="max-width: 800px;" + aria-multiselectable=${ifDefined(selectionMode === "multiple" ? "true" : undefined)} > <${theadTag} class="${rootClass}-head" @@ -212,57 +290,67 @@ export const Template = ({ > <${rowTag} role=${ifDefined(useDivs ? "row" : undefined)} + class="${rootClass}-headRow" > ${when(useCheckboxCell, () => html` <${thTag} class="spectrum-Table-headCell spectrum-Table-checkboxCell" role=${ifDefined(useDivs ? "columnheader" : undefined)} > - ${Checkbox({ - size, - isEmphasized: isEmphasized, - isChecked: false, - isIndeterminate: true, - customClasses: [`${rootClass}-checkbox`], + ${when(selectionMode === "multiple", () => html` + ${Checkbox({ + size: "m", + isEmphasized: isEmphasized, + isChecked: false, + isIndeterminate: true, + customClasses: [`${rootClass}-checkbox`], }, context)} - ` + `)} + `, )} <${thTag} - class="${rootClass}-headCell is-sortable is-sorted-desc" + class=${classMap({ + [`${rootClass}-headCell`]: true, + ["is-sortable"]: isSortable, + ["is-sorted-asc"]: sortIcon === "SortUp", + ["is-sorted-desc"]: sortIcon === "SortDown", + [`${rootClass}-hasMenuButton`]: hasMenu, + })} role=${ifDefined(useDivs ? "columnheader" : undefined)} - aria-sort="descending" - tabindex="0" + aria-sort=${ifDefined(isSortable || hasMenu ? ariaSortValue : undefined)} > - ${Icon({ - iconName: "ArrowDown100", - setName: "ui", - size, - customClasses: [`${rootClass}-sortedIcon`], - }, context)}Column title${ - Icon({ - iconName: "ChevronDown100", - setName: "ui", - size, - customClasses: [`${rootClass}-menuIcon`], - }, context)} + ${when(hasMenu || isSortable, () => html` + ${when(isSortable, () => Button({ + size: "m", + iconName: sortIcon, + iconSet: "workflow", + label: "Column title", + customClasses: [`${rootClass}-sortButton`], + }, context) + )} + ${when(!isSortable, () => Button({ + size: "m", + iconName: "SortUp", + iconSet: "workflow", + label: "Column title", + customClasses: [`${rootClass}-sortButton`], + }, context) + )} + `, () => html`Column title` + )} <${thTag} - class="${rootClass}-headCell is-sortable" + class="${rootClass}-headCell" role=${ifDefined(useDivs ? "columnheader" : undefined)} - aria-sort="none" - tabindex="0" > - ${Icon({ - iconName: "ArrowDown100", - setName: "ui", - size, - customClasses: [`${rootClass}-sortedIcon`], - }, context)}Column title + Column title <${thTag} class="${rootClass}-headCell" role=${ifDefined(useDivs ? "columnheader" : undefined)} - >Column title + > + Column title + <${tbodyTag} @@ -275,11 +363,12 @@ export const Template = ({ ${rowItems.map((item) => TableRowItem({ rootClass, - size, + density, useDivs, - showThumbnails, + visualElement, hasColumnDividers, - tableIsEmphasized: isEmphasized, + hasMenu, + isEmphasized, ...item, }, context) )}