Skip to content

Commit a00bad9

Browse files
committed
body cell wrapper inner
1 parent e04b439 commit a00bad9

File tree

5 files changed

+80
-52
lines changed

5 files changed

+80
-52
lines changed

pages/table/cell-permutations.page.tsx

+49-25
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
FormField,
1313
Header,
1414
Input,
15+
Link,
1516
Slider,
1617
SpaceBetween,
1718
StatusIndicator,
@@ -192,37 +193,60 @@ function TableCellsDemo() {
192193

193194
const columnDefinitions: TableProps.ColumnDefinition<number>[] = columns.map(index => {
194195
const columnId = index.toString();
195-
const cellContent = (item: number) =>
196-
editedValues[`${columnId}:${item}`] ??
197-
`Body cell content ${item}:${index}${index === 1 ? ` (L=${itemLevels[item]})` : ''}${index === 8 ? ' with longer text' : ''}`;
196+
const cellRenderer = (() => {
197+
const getText = (item: number) =>
198+
editedValues[`${columnId}:${item}`] ??
199+
`Body cell content ${item}:${index}${index === 1 ? ` (L=${itemLevels[item]})` : ''}${index === 8 ? ' with longer text' : ''}`;
200+
switch (index) {
201+
case 1:
202+
return { type: 'link', getText, render: (item: number) => <Link>{getText(item)}</Link> };
203+
case 3:
204+
return {
205+
type: 'status',
206+
getText,
207+
render: (item: number) => <StatusIndicator>{getText(item)}</StatusIndicator>,
208+
};
209+
case 4:
210+
return { type: 'right-align', getText, render: () => <Box textAlign="right">{index}</Box> };
211+
case 10:
212+
return {
213+
type: 'actions',
214+
getText,
215+
render: () => <Button variant="icon" iconName="ellipsis" ariaLabel="Actions" />,
216+
};
217+
default:
218+
return { type: 'text', getText, render: getText };
219+
}
220+
})();
198221
return {
199222
id: columnId,
200223
header: `Header cell content ${index}${index === 8 ? ' with longer text' : ''}`,
201224
sortingField: index === 2 ? 'field-1' : index === 3 ? 'field-2' : undefined,
202225
activeSorting: index === 3,
203-
cell: cellContent,
226+
cell: item => cellRenderer.render(item),
204227
verticalAlign: settings.verticalAlign,
205-
editConfig: settings.isEditable
206-
? {
207-
ariaLabel: 'Edit dialog aria label',
208-
editIconAriaLabel: 'Edit icon label',
209-
errorIconAriaLabel: 'Edit error icon label',
210-
validation(_item, value = '') {
211-
if (value.trim() && value.toLowerCase().includes('content')) {
212-
return 'Must not include "content"';
213-
}
214-
},
215-
editingCell(item, { currentValue, setValue }: TableProps.CellContext<string>) {
216-
return (
217-
<Input
218-
autoFocus={true}
219-
value={currentValue ?? cellContent(item)}
220-
onChange={event => setValue(event.detail.value)}
221-
/>
222-
);
223-
},
224-
}
225-
: undefined,
228+
editConfig:
229+
settings.isEditable && cellRenderer.type !== 'link' && cellRenderer.type !== 'actions'
230+
? {
231+
ariaLabel: 'Edit dialog aria label',
232+
editIconAriaLabel: 'Edit icon label',
233+
errorIconAriaLabel: 'Edit error icon label',
234+
validation(_item, value = '') {
235+
if (value.trim() && value.toLowerCase().includes('content')) {
236+
return 'Must not include "content"';
237+
}
238+
},
239+
editingCell(item, { currentValue, setValue }: TableProps.CellContext<string>) {
240+
return (
241+
<Input
242+
autoFocus={true}
243+
value={currentValue ?? cellRenderer.getText(item)}
244+
onChange={event => setValue(event.detail.value)}
245+
/>
246+
);
247+
},
248+
}
249+
: undefined,
226250
};
227251
});
228252

src/table/__tests__/table.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ test('should render table with react content', () => {
298298
];
299299
const { wrapper } = renderTable(<Table columnDefinitions={columns} items={defaultItems} />);
300300
const findCellContent = (row: number, col: number) =>
301-
wrapper.findBodyCell(row, col)!.findByClassName(bodyCellStyles['body-cell-content'])!;
301+
wrapper.findBodyCell(row, col)!.findByClassName(bodyCellStyles['body-cell-content-inner'])!;
302302
expect(wrapper.findColumnHeaders().map(getHeaderHtmlContent)).toEqual(['id', 'name', 'Advanced <span>header</span>']);
303303
expect(wrapper.findRows()).toHaveLength(3);
304304
expect(findCellContent(1, 3)!.getElement().innerHTML).toEqual('<input readonly="" value="Apples">');

src/table/body-cell/styles.scss

+19-23
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ $interactive-column-padding-inline-end: calc(#{$cell-horizontal-padding} + #{aws
2828
$cell-offset: calc(#{awsui.$space-m} + #{awsui.$space-xs});
2929

3030
// Ensuring enough space for absolute-positioned focus outlines of focus-able cell content elements.
31-
$cell-negative-space-vertical: 2px;
31+
$cell-negative-space: 4px;
3232

3333
@mixin cell-focus-outline {
3434
@include styles.focus-highlight(calc(-1 * #{awsui.$space-scaled-xxs}));
@@ -99,20 +99,17 @@ $cell-negative-space-vertical: 2px;
9999
}
100100
@mixin cell-padding-block($padding) {
101101
> .body-cell-content {
102-
padding-block: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width} + #{$cell-negative-space-vertical});
103-
margin-block: calc(-1 * #{$cell-negative-space-vertical});
102+
padding-block: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width});
104103
}
105104
}
106105
@mixin cell-padding-block-start($padding) {
107106
> .body-cell-content {
108-
padding-block-start: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width} + #{$cell-negative-space-vertical});
109-
margin-block-start: calc(-1 * #{$cell-negative-space-vertical});
107+
padding-block-start: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width});
110108
}
111109
}
112110
@mixin cell-padding-block-end($padding) {
113111
> .body-cell-content {
114-
padding-block-end: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width} + #{$cell-negative-space-vertical});
115-
margin-block-end: calc(-1 * #{$cell-negative-space-vertical});
112+
padding-block-end: calc(#{$padding} - 1 * #{awsui.$border-divider-list-width});
116113
}
117114
}
118115

@@ -131,6 +128,21 @@ $cell-negative-space-vertical: 2px;
131128

132129
&-content {
133130
box-sizing: border-box;
131+
block-size: 100%;
132+
margin-block: calc(-1 * $cell-negative-space);
133+
margin-inline: calc(-1 * $cell-negative-space);
134+
display: flex;
135+
align-items: center;
136+
137+
&.body-cell-align-top {
138+
align-items: baseline;
139+
}
140+
}
141+
&-content-inner {
142+
box-sizing: border-box;
143+
inline-size: 100%;
144+
padding-block: $cell-negative-space;
145+
padding-inline: $cell-negative-space;
134146

135147
&:not(.body-cell-wrap) {
136148
white-space: nowrap;
@@ -178,20 +190,10 @@ $cell-negative-space-vertical: 2px;
178190
&:not(.has-selection):not(.body-cell-editable) {
179191
border-inline-start: none;
180192
}
181-
182-
// Give extra space on the edge to allow slight content overflow.
183-
// That is to prevent focus outline on cell content from being cut out.
184-
> .body-cell-content {
185-
padding-inline-start: awsui.$border-divider-list-width;
186-
margin-inline-start: calc(-1 * #{awsui.$border-divider-list-width});
187-
}
188193
}
189194
&:first-child:not(.is-visual-refresh) {
190195
@include cell-padding-inline-start($cell-edge-horizontal-padding);
191196
}
192-
&-align-top {
193-
vertical-align: top;
194-
}
195197
&-first-row {
196198
border-block-start: $border-placeholder;
197199
}
@@ -428,12 +430,6 @@ $cell-negative-space-vertical: 2px;
428430
position: sticky;
429431
}
430432

431-
&.body-cell-edit-active {
432-
> .body-cell-content {
433-
overflow: visible;
434-
}
435-
}
436-
437433
&:not(.body-cell-edit-active) {
438434
cursor: pointer;
439435

src/table/body-cell/td-element.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const TableTdElement = React.forwardRef<HTMLTableCellElement, TableTdElem
102102
const Element = isRowHeader ? 'th' : 'td';
103103
const isVisualRefresh = useVisualRefresh();
104104

105-
resizableStyle = resizableColumns ? resizableStyle : {};
105+
resizableStyle = resizableColumns ? {} : resizableStyle;
106106

107107
nativeAttributes = { ...nativeAttributes, ...getTableCellRoleProps({ tableRole, isRowHeader, colIndex }) };
108108

@@ -139,7 +139,6 @@ export const TableTdElement = React.forwardRef<HTMLTableCellElement, TableTdElem
139139
hasSuccessIcon && styles['body-cell-has-success'],
140140
level !== undefined && styles['body-cell-expandable'],
141141
level !== undefined && styles[`expandable-level-${getLevelClassSuffix(level)}`],
142-
verticalAlign === 'top' && styles['body-cell-align-top'],
143142
stickyStyles.className
144143
)}
145144
onClick={onClick}
@@ -161,7 +160,15 @@ export const TableTdElement = React.forwardRef<HTMLTableCellElement, TableTdElem
161160
</div>
162161
)}
163162

164-
<div className={clsx(styles['body-cell-content'], wrapLines && styles['body-cell-wrap'])}>{children}</div>
163+
<div className={clsx(styles['body-cell-content'], verticalAlign === 'top' && styles['body-cell-align-top'])}>
164+
{isEditing ? (
165+
children
166+
) : (
167+
<div className={clsx(styles['body-cell-content-inner'], wrapLines && styles['body-cell-wrap'])}>
168+
{children}
169+
</div>
170+
)}
171+
</div>
165172
</Element>
166173
);
167174
}

src/table/styles.scss

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
.table {
5555
inline-size: 100%;
56+
block-size: 100%;
5657
border-spacing: 0;
5758
position: relative;
5859
box-sizing: border-box;

0 commit comments

Comments
 (0)