Skip to content

Commit 508f8b9

Browse files
committed
chore: Minor design updates
1 parent 43bfcbd commit 508f8b9

File tree

5 files changed

+35
-20
lines changed

5 files changed

+35
-20
lines changed

src/table/__tests__/column-grouping-utils.test.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,18 @@ describe('column-grouping-utils', () => {
418418

419419
expect(result?.maxDepth).toBe(3);
420420

421-
console.log(JSON.stringify(result?.rows));
422-
423-
// Row 0: metrics and config
421+
// Row 0: metrics and a hidden placeholder for config (config had rowspan=2, now expanded)
424422
expect(result?.rows[0].columns.map(c => c.id)).toEqual(['metrics', 'config']);
425-
426-
// Row 1: perf only (config's children in row 2)
427-
expect(result?.rows[1].columns.map(c => c.id)).toEqual(['perf']);
423+
const configRow0 = result?.rows[0].columns.find(c => c.id === 'config');
424+
expect(configRow0?.isHidden).toBe(true);
425+
expect(configRow0?.rowspan).toBe(1);
426+
427+
// Row 1: perf and the real config (dropped down from row 0)
428+
expect(result?.rows[1].columns.map(c => c.id)).toEqual(['perf', 'config']);
429+
const configRow1 = result?.rows[1].columns.find(c => c.id === 'config');
430+
expect(configRow1?.isHidden).toBe(false);
431+
expect(configRow1?.isGroup).toBe(true);
432+
expect(configRow1?.rowspan).toBe(1);
428433

429434
// Row 2: both leaf columns
430435
expect(result?.rows[2].columns.map(c => c.id)).toEqual(['cpu', 'type']);

src/table/column-grouping-utils.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,6 @@ function expandRowspansToHiddenNodes<T>(node: TableHeaderNode<T>): void {
312312
return;
313313
}
314314

315-
// Only expand leaf columns — groups keep their natural HTML rowspan
316-
if (node.isGroup) {
317-
return;
318-
}
319-
320315
const originalRowspan = node.rowspan;
321316
const originalRowIndex = node.rowIndex;
322317
const parentNode = node.parentNode!;

src/table/header-cell/hidden-header-cell.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import React, { useRef } from 'react';
44

55
import { useMergeRefs } from '@cloudscape-design/component-toolkit/internal';
6+
import { useSingleTabStopNavigation } from '@cloudscape-design/component-toolkit/internal';
67

78
import { ColumnWidthStyle } from '../column-widths-utils';
89
import { TableProps } from '../interfaces';
@@ -63,6 +64,9 @@ export function TableHiddenHeaderCell({
6364
const cellRefObject = useRef<HTMLElement>(null);
6465
const cellRefCombined = useMergeRefs(cellRef, cellRefObject);
6566

67+
const focusableRef = useRef<HTMLDivElement>(null);
68+
const { tabIndex: focusableTabIndex } = useSingleTabStopNavigation(focusableRef, { tabIndex });
69+
6670
return (
6771
<TableThElement
6872
resizableStyle={resizableStyle}
@@ -83,8 +87,13 @@ export function TableHiddenHeaderCell({
8387
scope="col"
8488
ariaLabel=""
8589
>
86-
{/* Empty content — this is a hidden placeholder cell */}
87-
<div className={styles['header-cell-hidden-content']} aria-hidden="true" />
90+
{/* Empty but focusable content — allows keyboard navigation through placeholder cells */}
91+
<div
92+
ref={focusableRef}
93+
className={styles['header-cell-hidden-content']}
94+
tabIndex={focusableTabIndex}
95+
data-focus-id={`header-hidden-${columnId}`}
96+
/>
8897
{resizableColumns ? (
8998
<Resizer
9099
tabIndex={tabIndex}

src/table/header-cell/styles.scss

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ $cell-horizontal-padding: awsui.$space-scaled-l;
9595
// is the table-level visibility prop (for the measurement thead), not our placeholder concept.
9696
&:has(.header-cell-hidden-content) {
9797
border-block-end-color: transparent;
98+
}
9899

99-
// Complete divider styles for hidden placeholder cells.
100-
// The normal divider rule `th:not(:last-child) > .divider` fails when hidden cells
101-
// end up as :last-child (due to rowspan siblings not being in the same <tr>).
102-
// We replicate the full divider positioning here with the same block-gap
103-
// to keep divider heights visually consistent with normal header cells.
100+
// Divider styles for hidden placeholder cells (only when NOT the last cell in the row).
101+
// The normal divider rule `th:not(:last-child) > .divider` doesn't apply here because
102+
// hidden cells use `.resize-divider` instead of `.divider`. We replicate the positioning
103+
// with the same block-gap to keep divider heights visually consistent.
104+
&:not(:last-child):has(.header-cell-hidden-content) {
104105
> .resize-divider {
105106
position: absolute;
106107
outline: none;
@@ -111,7 +112,8 @@ $cell-horizontal-padding: awsui.$space-scaled-l;
111112
min-block-size: awsui.$line-height-heading-xs;
112113
// Use the same block-gap as normal dividers (from resizer/styles.scss)
113114
// to keep divider heights visually consistent across the header row.
114-
max-block-size: calc(100% - 2 * #{awsui.$space-xs} - #{awsui.$space-xxxs});
115+
// stylelint-disable-next-line custom-property-pattern
116+
max-block-size: calc(100% - var(--awsui-table-resizer-block-gap, 0px));
115117
margin-block: auto;
116118
margin-inline: auto;
117119
border-inline-start: awsui.$border-item-width solid awsui.$color-border-divider-default;
@@ -156,6 +158,7 @@ $cell-horizontal-padding: awsui.$space-scaled-l;
156158
box-shadow: awsui.$shadow-sticky-column-first;
157159
clip-path: inset(0px -24px 0px 0px);
158160

161+
// stylelint-disable-next-line no-descending-specificity
159162
& > .resize-divider {
160163
display: none;
161164
}

src/table/resizer/styles.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
$handle-width: awsui.$space-xl;
1717
$active-separator-width: 2px;
18-
$block-gap: calc(2 * #{awsui.$space-xs} + #{awsui.$space-xxxs});
18+
// $block-gap: calc(2 * #{awsui.$space-xs} + #{awsui.$space-xxxs});
19+
// Use a CSS custom property so the gap can be overridden at runtime (demo/playground for designers).
20+
// stylelint-disable-next-line custom-property-pattern
21+
$block-gap: var(--awsui-table-resizer-block-gap, 0px);
1922

2023
.resizer-wrapper {
2124
inset-block: 0;

0 commit comments

Comments
 (0)