Skip to content

Commit

Permalink
refactor: Refactors table body cell styles (#2954)
Browse files Browse the repository at this point in the history
Co-authored-by: Avinash Dwarapu <[email protected]>
  • Loading branch information
pan-kot and avinashbot authored Nov 5, 2024
1 parent d8edc99 commit 638ea3b
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 63 deletions.
2 changes: 1 addition & 1 deletion pages/table/expandable-rows-performance.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type PageContext = React.Context<
}>
>;

const columnDefinitions = createColumns();
const columnDefinitions = createColumns({ terminationReasons: new Map() });

export default function App() {
const { urlParams, setUrlParams } = useContext(AppContext as PageContext);
Expand Down
12 changes: 10 additions & 2 deletions pages/table/expandable-rows-test.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,22 @@ type PageContext = React.Context<
export default () => {
const settings = usePageSettings();
const [toolsOpen, setToolsOpen] = useState(true);
const [terminationReasons, setTerminationReasons] = useState(() => new Map<string, string>());
const [preferences, setPreferences] = useState<CollectionPreferencesProps.Preferences>({
wrapLines: true,
stickyColumns: { first: 0, last: 0 },
});

const tableData = useTableData();

const columnDefinitions = createColumns();
const columnDefinitions = createColumns({ terminationReasons });

const handleSubmit: TableProps.SubmitEditFunction<Instance> = (currentItem, column, newValue) => {
if (column.id === 'termination-reason' && typeof newValue === 'string') {
setTerminationReasons(prev => new Map(prev).set(currentItem.name, newValue));
}
return Promise.resolve();
};

return (
<I18nProvider messages={[messages]} locale="en">
Expand All @@ -95,7 +103,7 @@ export default () => {
pagination={settings.usePagination && <Pagination {...tableData.paginationProps} />}
columnDisplay={preferences.contentDisplay}
preferences={createPreferences({ preferences, setPreferences })}
submitEdit={() => {}}
submitEdit={handleSubmit}
variant="full-page"
renderAriaLive={renderAriaLive}
loading={tableData.loading}
Expand Down
12 changes: 8 additions & 4 deletions pages/table/expandable-rows/expandable-rows-configs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import { contentDisplayPreferenceI18nStrings } from '../../common/i18n-strings';
import { columnLabel } from '../shared-configs';
import { Instance } from './common';

export function createColumns(): TableProps.ColumnDefinition<Instance>[] {
export function createColumns(props: {
terminationReasons: Map<string, string>;
}): TableProps.ColumnDefinition<Instance>[] {
return [
{
id: 'name',
Expand Down Expand Up @@ -105,20 +107,22 @@ export function createColumns(): TableProps.ColumnDefinition<Instance>[] {
{
id: 'termination-reason',
header: 'Termination reason',
cell: item => item.terminationReason || '-',
cell: item => props.terminationReasons.get(item.name) ?? (item.terminationReason || '-'),
editConfig: {
ariaLabel: 'Edit termination reason',
editIconAriaLabel: 'editable',
errorIconAriaLabel: 'Edit cell error',
editingCell: (item, { currentValue, setValue }) => (
<Input
autoFocus={true}
value={currentValue ?? item.terminationReason}
value={currentValue ?? props.terminationReasons.get(item.name) ?? item.terminationReason}
onChange={event => setValue(event.detail.value)}
/>
),
disabledReason: item =>
item.terminationReason?.includes('automatically') ? 'Cannot edit automatically added description' : '',
!props.terminationReasons.has(item.name) && item.terminationReason?.includes('automatically')
? 'Cannot edit automatically added description'
: '',
},
minWidth: 250,
},
Expand Down
5 changes: 0 additions & 5 deletions pages/table/inline-editor.permutations.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const unevenOptions = [

interface PermutationProps extends TableProps.EditConfig<unknown> {
isEditing: boolean;
interactiveCell: boolean;
successfulEdit?: boolean;
disabledReason?: () => string;
}
Expand All @@ -49,7 +48,6 @@ const editPermutations = createPermutations<PermutationProps>([
constraintText: [undefined, 'This requirement needs to be met.'],
validation: [undefined, () => 'There was an error!'],
isEditing: [true],
interactiveCell: [false],
},
{
ariaLabel: ['Editable column'],
Expand All @@ -59,7 +57,6 @@ const editPermutations = createPermutations<PermutationProps>([
constraintText: [undefined],
validation: [undefined],
isEditing: [false],
interactiveCell: [false, true],
successfulEdit: [false, true],
},
{
Expand All @@ -70,7 +67,6 @@ const editPermutations = createPermutations<PermutationProps>([
constraintText: [undefined],
validation: [undefined],
isEditing: [false],
interactiveCell: [false, true],
disabledReason: [() => 'Disabled reason popover content'],
},
// Select overflow permutation
Expand All @@ -92,7 +88,6 @@ const editPermutations = createPermutations<PermutationProps>([
constraintText: [undefined],
validation: [undefined],
isEditing: [true],
interactiveCell: [false],
},
]);

Expand Down
7 changes: 2 additions & 5 deletions src/table/body-cell/disabled-inline-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export function DisabledInlineEditor<ItemType>({
onEditEnd,
editDisabledReason,
isVisualRefresh,
interactiveCell = true,
resizableColumns = false,
...rest
}: DisabledInlineEditorProps<ItemType>) {
Expand All @@ -45,7 +44,7 @@ export function DisabledInlineEditor<ItemType>({
const [hasHover, setHasHover] = useState(false);
const [hasFocus, setHasFocus] = useState(false);
// When a cell is both expandable and editable the icon is always shown.
const showIcon = hasHover || hasFocus || isEditing || !interactiveCell;
const showIcon = hasHover || hasFocus || isEditing;

const iconRef = useRef(null);
const buttonRef = useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -76,12 +75,11 @@ export function DisabledInlineEditor<ItemType>({
className={clsx(
className,
styles['body-cell-editable'],
interactiveCell && styles['body-cell-interactive'],
resizableColumns && styles['resizable-columns'],
isEditing && styles['body-cell-edit-disabled-popover'],
isVisualRefresh && styles['is-visual-refresh']
)}
onClick={interactiveCell && !isEditing ? onClick : undefined}
onClick={!isEditing ? onClick : undefined}
onMouseEnter={() => setHasHover(true)}
onMouseLeave={() => setHasHover(false)}
ref={clickAwayRef}
Expand All @@ -96,7 +94,6 @@ export function DisabledInlineEditor<ItemType>({
aria-label={ariaLabels?.activateEditLabel?.(column, item)}
aria-haspopup="dialog"
aria-disabled="true"
onClick={!interactiveCell && !isEditing ? onClick : undefined}
onFocus={() => setHasFocus(true)}
onBlur={() => setHasFocus(false)}
onKeyDown={handleEscape}
Expand Down
8 changes: 2 additions & 6 deletions src/table/body-cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export interface TableBodyCellProps<ItemType> extends TableTdElementProps {
onEditEnd: (cancelled: boolean) => void;
submitEdit?: TableProps.SubmitEditFunction<ItemType>;
ariaLabels: TableProps['ariaLabels'];
interactiveCell?: boolean;
}

function TableCellEditable<ItemType>({
Expand All @@ -44,7 +43,6 @@ function TableCellEditable<ItemType>({
isVisualRefresh,
resizableColumns = false,
successfulEdit = false,
interactiveCell = true,
...rest
}: TableBodyCellProps<ItemType>) {
const i18n = useInternalI18n('table');
Expand All @@ -64,7 +62,7 @@ function TableCellEditable<ItemType>({
const [hasHover, setHasHover] = useState(false);
const [hasFocus, setHasFocus] = useState(false);
// When a cell is both expandable and editable the icon is always shown.
const showIcon = hasHover || hasFocus || !interactiveCell;
const showIcon = hasHover || hasFocus;

const prevSuccessfulEdit = usePrevious(successfulEdit);
const prevHasFocus = usePrevious(hasFocus);
Expand All @@ -90,13 +88,12 @@ function TableCellEditable<ItemType>({
className={clsx(
className,
styles['body-cell-editable'],
interactiveCell && styles['body-cell-interactive'],
resizableColumns && styles['resizable-columns'],
isEditing && styles['body-cell-edit-active'],
showSuccessIcon && showIcon && styles['body-cell-has-success'],
isVisualRefresh && styles['is-visual-refresh']
)}
onClick={interactiveCell && !isEditing ? onEditStart : undefined}
onClick={!isEditing ? onEditStart : undefined}
onMouseEnter={() => setHasHover(true)}
onMouseLeave={() => setHasHover(false)}
>
Expand Down Expand Up @@ -141,7 +138,6 @@ function TableCellEditable<ItemType>({
className={styles['body-cell-editor']}
aria-label={ariaLabels?.activateEditLabel?.(column, item)}
ref={editActivateRef}
onClick={!interactiveCell && !isEditing ? onEditStart : undefined}
onFocus={() => setHasFocus(true)}
onBlur={() => setHasFocus(false)}
tabIndex={editActivateTabIndex}
Expand Down
59 changes: 19 additions & 40 deletions src/table/body-cell/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ $cell-negative-space-vertical: 2px;
.body-cell {
box-sizing: border-box;
border-block-start: awsui.$border-divider-list-width solid transparent;
word-wrap: break-word;
border-block-end: awsui.$border-divider-list-width solid awsui.$color-border-divider-secondary;
word-wrap: break-word;
font-weight: inherit;
text-align: start;

Expand All @@ -147,7 +147,7 @@ $cell-negative-space-vertical: 2px;
&.is-visual-refresh:first-child {
&:not(.has-striped-rows) {
@include cell-padding-inline-start(awsui.$space-xxxs);
&:not(.body-cell-edit-active).body-cell-interactive.body-cell-editable:hover {
&:not(.body-cell-edit-active).body-cell-editable:hover {
@include cell-padding-inline-start(calc(#{awsui.$space-xxxs} + #{awsui.$border-divider-list-width}));
}
}
Expand Down Expand Up @@ -431,19 +431,14 @@ $cell-negative-space-vertical: 2px;
> .body-cell-content {
overflow: visible;
}
&.sticky-cell {
position: sticky;
}
}

&:not(.body-cell-edit-active) {
&.body-cell-interactive {
cursor: pointer;
cursor: pointer;

// Include interactive padding even when a cell is not hovered to prevent jittering when resizableColumns=false.
&:not(.resizable-columns) {
@include cell-padding-inline-end($interactive-column-padding-inline-end);
}
// Include interactive padding even when a cell is not hovered to prevent jittering when resizableColumns=false.
&:not(.resizable-columns) {
@include cell-padding-inline-end($interactive-column-padding-inline-end);
}

@mixin focused-editor-styles {
Expand All @@ -466,18 +461,10 @@ $cell-negative-space-vertical: 2px;
// These edit buttons are special because they are visually hidden (opacity: 0), but exposed to assistive technology.
// It's therefore important to display the focus outline, even when a keyboard use wasn't detected.
// For example, when an edit button is selected from the VoiceOver rotor menu.
&.body-cell-interactive:focus-within {
&:focus-within {
@include cell-focus-outline;
}
// When a cell is not interactive the focus outline must be present for the editor button.
&:not(.body-cell-interactive) > .body-cell-editor-wrapper > .body-cell-editor,
&:not(.body-cell-interactive) > .expandable-cell-content > .body-cell-editor-wrapper > .body-cell-editor {
@include focus-visible.when-visible {
@include styles.focus-highlight(awsui.$space-button-inline-icon-focus-outline-gutter);
}
}

&:not(.body-cell-interactive),
&:focus-within:focus-within,
&.body-cell-edit-disabled-popover {
&.body-cell-has-success {
Expand All @@ -492,15 +479,25 @@ $cell-negative-space-vertical: 2px;
}
}

&.body-cell-interactive:hover {
&:hover:hover {
position: relative;

background-color: awsui.$color-background-dropdown-item-hover;
border-block: awsui.$border-divider-list-width solid awsui.$color-border-editable-cell-hover;
border-inline: awsui.$border-divider-list-width solid awsui.$color-border-editable-cell-hover;
inset-inline: calc(-1 * #{awsui.$border-divider-list-width});
position: relative;
&.sticky-cell {
position: sticky;
}

&:first-child {
inset-inline: 0;
border-start-start-radius: awsui.$border-radius-item;
border-end-start-radius: awsui.$border-radius-item;
}
&:last-child {
border-start-end-radius: awsui.$border-radius-item;
border-end-end-radius: awsui.$border-radius-item;
}

& > .body-cell-editor-wrapper,
Expand All @@ -527,28 +524,10 @@ $cell-negative-space-vertical: 2px;
&.body-cell-first-row:not(.body-cell-selected) {
@include cell-padding-block(calc(#{$cell-vertical-padding} - calc(#{awsui.$border-divider-list-width})));
}
&.sticky-cell {
position: sticky;
}
@include focused-editor-styles;
}
}
}
&-editable.is-visual-refresh:not(.body-cell-edit-active).body-cell-interactive:hover {
&:first-child {
border-start-start-radius: awsui.$border-radius-item;
border-end-start-radius: awsui.$border-radius-item;
}
&:last-child {
border-start-end-radius: awsui.$border-radius-item;
border-end-end-radius: awsui.$border-radius-item;
}
&.body-cell-first-row > .body-cell-success,
&.body-cell-first-row > .body-cell-editor-wrapper,
&.body-cell-first-row > .expandable-cell-content > .body-cell-editor-wrapper {
@include cell-padding-block-start(awsui.$border-divider-list-width);
}
}

@include focus-visible.when-visible {
@include cell-focus-outline;
Expand Down

0 comments on commit 638ea3b

Please sign in to comment.