Skip to content

Commit

Permalink
fix: Click outside focus handling on table inline edit
Browse files Browse the repository at this point in the history
When editing a table cell and clicking somewhere outside, the edit mode ended and the edited cell kept focus by purpose. Now, if a focusable element got clicked outside, it will receive the focus - the focus handling does not get intercepted anymore.
  • Loading branch information
Johannes Weber authored and johannes-weber committed Aug 28, 2023
1 parent 3507cce commit 334a015
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
13 changes: 13 additions & 0 deletions src/table/__integ__/inline-editing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,16 @@ test(
await page.waitForAssertion(() => expect(page.isFocused(cellInputField$)).resolves.toBe(true));
})
);

test(
'click focusable element outside when editing cancels editing and focuses clicked element',
setupTest(async page => {
// Edit a cell
await page.click(cellEditButton$);
await expect(page.isFocused(cellInputField$)).resolves.toBe(true);

// Click on the input element outside, it should get focused.
await page.click('[data-testid="focus"]');
await expect(page.isFocused('[data-testid="focus"]')).resolves.toBe(true);
})
);
6 changes: 3 additions & 3 deletions src/table/body-cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ function TableCellEditable<ItemType>({
ariaLabels={ariaLabels}
column={column}
item={item}
onEditEnd={e => {
onEditEnd={options => {
setShowSuccessIcon(false);
isFocusMoveNeededRef.current = true;
onEditEnd(e);
isFocusMoveNeededRef.current = options.refocusCell;
onEditEnd(options.cancelled);
}}
submitEdit={submitEdit ?? submitHandlerFallback}
/>
Expand Down
21 changes: 13 additions & 8 deletions src/table/body-cell/inline-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ import { useInternalI18n } from '../../i18n/context';
// A function that does nothing
const noop = () => undefined;

interface OnEditEndOptions {
cancelled: boolean;
refocusCell: boolean;
}

interface InlineEditorProps<ItemType> {
ariaLabels: TableProps['ariaLabels'];
column: TableProps.ColumnDefinition<ItemType>;
item: ItemType;
onEditEnd: (cancelled: boolean) => void;
onEditEnd: (options: OnEditEndOptions) => void;
submitEdit: TableProps.SubmitEditFunction<ItemType>;
__onRender?: () => void;
}
Expand All @@ -43,11 +48,11 @@ export function InlineEditor<ItemType>({
setValue: setCurrentEditValue,
};

function finishEdit(cancel = false) {
if (!cancel) {
function finishEdit({ cancelled = false, refocusCell = true }: Partial<OnEditEndOptions> = {}) {
if (!cancelled) {
setCurrentEditValue(undefined);
}
onEditEnd(cancel);
onEditEnd({ cancelled, refocusCell: refocusCell });
}

async function onSubmitClick(evt: React.FormEvent) {
Expand All @@ -68,11 +73,11 @@ export function InlineEditor<ItemType>({
}
}

function onCancel() {
function onCancel({ reFocusEditedCell = true } = {}) {
if (currentEditLoading) {
return;
}
finishEdit(true);
finishEdit({ cancelled: true, refocusCell: reFocusEditedCell });
}

function handleEscape(event: React.KeyboardEvent): void {
Expand All @@ -81,7 +86,7 @@ export function InlineEditor<ItemType>({
}
}

const clickAwayRef = useClickAway(onCancel);
const clickAwayRef = useClickAway(() => onCancel({ reFocusEditedCell: false }));

useEffect(() => {
if (__onRender) {
Expand Down Expand Up @@ -127,7 +132,7 @@ export function InlineEditor<ItemType>({
formAction="none"
iconName="close"
variant="inline-icon"
onClick={onCancel}
onClick={() => onCancel()}
/>
) : null}
<Button
Expand Down

0 comments on commit 334a015

Please sign in to comment.