chore(a11y): add controls to LabelConfig

This commit is contained in:
Abbey Yacoe
2025-05-21 16:50:48 +02:00
parent 91ecfe73cc
commit 3858d3b08b
3 changed files with 20 additions and 10 deletions
@@ -65,6 +65,10 @@ const A11y = () => {
'a11yDescription.node.default': 'Custom Node Desc.', 'a11yDescription.node.default': 'Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Custom Keyboard Desc.', 'a11yDescription.node.keyboardDisabled': 'Custom Keyboard Desc.',
'a11yDescription.edge.default': 'Custom Edge Desc.', 'a11yDescription.edge.default': 'Custom Edge Desc.',
'controls.zoomin.title': 'Custom Zoom in',
'controls.zoomout.title': 'Custom Zoom Out',
'controls.fitview.title': 'Custom Fit View',
'controls.interactive.title': 'Custom Toggle Interactivity',
}} }}
> >
<Background variant={BackgroundVariant.Dots} /> <Background variant={BackgroundVariant.Dots} />
@@ -19,6 +19,7 @@ const selector = (s: ReactFlowState) => ({
isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable, isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
minZoomReached: s.transform[2] <= s.minZoom, minZoomReached: s.transform[2] <= s.minZoom,
maxZoomReached: s.transform[2] >= s.maxZoom, maxZoomReached: s.transform[2] >= s.maxZoom,
labelConfig: s.labelConfig,
}); });
function ControlsComponent({ function ControlsComponent({
@@ -38,7 +39,7 @@ function ControlsComponent({
'aria-label': ariaLabel = 'React Flow controls', 'aria-label': ariaLabel = 'React Flow controls',
}: ControlProps) { }: ControlProps) {
const store = useStoreApi(); const store = useStoreApi();
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector, shallow); const { isInteractive, minZoomReached, maxZoomReached, labelConfig } = useStore(selector, shallow);
const { zoomIn, zoomOut, fitView } = useReactFlow(); const { zoomIn, zoomOut, fitView } = useReactFlow();
const onZoomInHandler = () => { const onZoomInHandler = () => {
@@ -67,7 +68,6 @@ function ControlsComponent({
}; };
const orientationClass = orientation === 'horizontal' ? 'horizontal' : 'vertical'; const orientationClass = orientation === 'horizontal' ? 'horizontal' : 'vertical';
return ( return (
<Panel <Panel
className={cc(['react-flow__controls', orientationClass, className])} className={cc(['react-flow__controls', orientationClass, className])}
@@ -81,8 +81,8 @@ function ControlsComponent({
<ControlButton <ControlButton
onClick={onZoomInHandler} onClick={onZoomInHandler}
className="react-flow__controls-zoomin" className="react-flow__controls-zoomin"
title="zoom in" title={labelConfig['controls.zoomin.title']}
aria-label="zoom in" aria-label={labelConfig['controls.zoomin.title']}
disabled={maxZoomReached} disabled={maxZoomReached}
> >
<PlusIcon /> <PlusIcon />
@@ -90,8 +90,8 @@ function ControlsComponent({
<ControlButton <ControlButton
onClick={onZoomOutHandler} onClick={onZoomOutHandler}
className="react-flow__controls-zoomout" className="react-flow__controls-zoomout"
title="zoom out" title={labelConfig['controls.zoomout.title']}
aria-label="zoom out" aria-label={labelConfig['controls.zoomout.title']}
disabled={minZoomReached} disabled={minZoomReached}
> >
<MinusIcon /> <MinusIcon />
@@ -102,8 +102,8 @@ function ControlsComponent({
<ControlButton <ControlButton
className="react-flow__controls-fitview" className="react-flow__controls-fitview"
onClick={onFitViewHandler} onClick={onFitViewHandler}
title="fit view" title={labelConfig['controls.fitview.title']}
aria-label="fit view" aria-label={labelConfig['controls.fitview.title']}
> >
<FitViewIcon /> <FitViewIcon />
</ControlButton> </ControlButton>
@@ -112,8 +112,8 @@ function ControlsComponent({
<ControlButton <ControlButton
className="react-flow__controls-interactive" className="react-flow__controls-interactive"
onClick={onToggleInteractivity} onClick={onToggleInteractivity}
title="toggle interactivity" title={labelConfig['controls.interactive.title']}
aria-label="toggle interactivity" aria-label={labelConfig['controls.interactive.title']}
> >
{isInteractive ? <UnlockIcon /> : <LockIcon />} {isInteractive ? <UnlockIcon /> : <LockIcon />}
</ControlButton> </ControlButton>
+6
View File
@@ -44,6 +44,12 @@ export const defaultLabelConfig = {
'Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.', 'Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.',
'a11yDescription.edge.default': 'a11yDescription.edge.default':
'Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.', 'Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.',
// Control elements
'controls.zoomin.title': 'Zoom In',
'controls.zoomout.title': 'Zoom Out',
'controls.fitview.title': 'Fit View',
'controls.interactive.title': 'Toggle Interactivity',
}; };
export type LabelConfig = Partial<typeof defaultLabelConfig>; export type LabelConfig = Partial<typeof defaultLabelConfig>;