feat(onFocus): pan nodes into the viewport on tab
This commit is contained in:
@@ -155,6 +155,19 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onFocus = () => {
|
||||||
|
const { panZoom } = store.getState();
|
||||||
|
const zoom = panZoom?.getViewport().zoom ?? 1;
|
||||||
|
panZoom?.setViewport(
|
||||||
|
{
|
||||||
|
x: -(internals.positionAbsolute.x + nodeDimensions.width / 2) * zoom + window.innerWidth / 2,
|
||||||
|
y: -(internals.positionAbsolute.y + nodeDimensions.height / 2) * zoom + window.innerHeight / 2,
|
||||||
|
zoom: zoom,
|
||||||
|
},
|
||||||
|
{ duration: 100 }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cc([
|
className={cc([
|
||||||
@@ -192,6 +205,7 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
onDoubleClick={onDoubleClickHandler}
|
onDoubleClick={onDoubleClickHandler}
|
||||||
onKeyDown={isFocusable ? onKeyDown : undefined}
|
onKeyDown={isFocusable ? onKeyDown : undefined}
|
||||||
tabIndex={isFocusable ? 0 : undefined}
|
tabIndex={isFocusable ? 0 : undefined}
|
||||||
|
onFocus={isFocusable ? onFocus : undefined}
|
||||||
role={isFocusable ? 'button' : undefined}
|
role={isFocusable ? 'button' : undefined}
|
||||||
aria-describedby={disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`}
|
aria-describedby={disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`}
|
||||||
aria-label={node.ariaLabel}
|
aria-label={node.ariaLabel}
|
||||||
|
|||||||
@@ -196,6 +196,27 @@
|
|||||||
store.moveSelectedNodes(arrowKeyDiffs[event.key], event.shiftKey ? 4 : 1);
|
store.moveSelectedNodes(arrowKeyDiffs[event.key], event.shiftKey ? 4 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onFocus() {
|
||||||
|
if (store.disableKeyboardA11y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const zoom = store.panZoom?.getViewport().zoom ?? 1;
|
||||||
|
|
||||||
|
// Get node dimensions
|
||||||
|
const nodeWidth = nodeRef?.offsetWidth || 0;
|
||||||
|
const nodeHeight = nodeRef?.offsetHeight || 0;
|
||||||
|
|
||||||
|
store.panZoom?.setViewport(
|
||||||
|
{
|
||||||
|
x: -(positionX + nodeWidth / 2) * zoom + window.innerWidth / 2,
|
||||||
|
y: -(positionY + nodeHeight / 2) * zoom + window.innerHeight / 2,
|
||||||
|
zoom: zoom,
|
||||||
|
},
|
||||||
|
{ duration: 100 }
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !hidden}
|
{#if !hidden}
|
||||||
@@ -251,6 +272,7 @@
|
|||||||
? (event) => onnodecontextmenu({ node: userNode, event })
|
? (event) => onnodecontextmenu({ node: userNode, event })
|
||||||
: undefined}
|
: undefined}
|
||||||
onkeydown={focusable ? onKeyDown : undefined}
|
onkeydown={focusable ? onKeyDown : undefined}
|
||||||
|
onfocus={focusable ? onFocus : undefined}
|
||||||
tabIndex={focusable ? 0 : undefined}
|
tabIndex={focusable ? 0 : undefined}
|
||||||
role={focusable ? 'button' : undefined}
|
role={focusable ? 'button' : undefined}
|
||||||
aria-describedby={store.disableKeyboardA11y
|
aria-describedby={store.disableKeyboardA11y
|
||||||
|
|||||||
Reference in New Issue
Block a user