#5201 chore(A11yDescriptions): add static support for localization
This commit is contained in:
@@ -235,6 +235,11 @@ const OverviewFlow = () => {
|
||||
onBeforeDelete={onBeforeDelete}
|
||||
onDelete={onDelete}
|
||||
onPaneMouseMove={onPaneMouseMove}
|
||||
a11yMessages={{
|
||||
'a11yDescription.node.default': 'Custom Node Desc.',
|
||||
'a11yDescription.node.keyboardDisabled': 'Custom Keyboard Desc.',
|
||||
'a11yDescription.edge.default': 'Custom Edge Desc.',
|
||||
}}
|
||||
>
|
||||
<MiniMap nodeBorderRadius={2} />
|
||||
<Controls orientation="horizontal" />
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CSSProperties } from 'react';
|
||||
|
||||
import { useStore } from '../../hooks/useStore';
|
||||
import type { ReactFlowState } from '../../types';
|
||||
import type { a11yMessages } from '@xyflow/system';
|
||||
|
||||
const style: CSSProperties = { display: 'none' };
|
||||
const ariaLiveStyle: CSSProperties = {
|
||||
@@ -20,6 +21,15 @@ export const ARIA_NODE_DESC_KEY = 'react-flow__node-desc';
|
||||
export const ARIA_EDGE_DESC_KEY = 'react-flow__edge-desc';
|
||||
export const ARIA_LIVE_MESSAGE = 'react-flow__aria-live';
|
||||
|
||||
const defaultA11yMessages: Required<a11yMessages> = {
|
||||
'a11yDescription.node.default':
|
||||
'Press enter or space to select a node. Press delete to remove it and escape to cancel.',
|
||||
'a11yDescription.node.keyboardDisabled':
|
||||
'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':
|
||||
'Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.',
|
||||
};
|
||||
|
||||
const selector = (s: ReactFlowState) => s.ariaLiveMessage;
|
||||
|
||||
function AriaLiveMessage({ rfId }: { rfId: string }) {
|
||||
@@ -32,16 +42,28 @@ function AriaLiveMessage({ rfId }: { rfId: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function A11yDescriptions({ rfId, disableKeyboardA11y }: { rfId: string; disableKeyboardA11y: boolean }) {
|
||||
export function A11yDescriptions({
|
||||
rfId,
|
||||
disableKeyboardA11y,
|
||||
a11yMessages = {},
|
||||
}: {
|
||||
rfId: string;
|
||||
disableKeyboardA11y: boolean;
|
||||
a11yMessages?: a11yMessages;
|
||||
}) {
|
||||
const nodeDesc = disableKeyboardA11y
|
||||
? a11yMessages['a11yDescription.node.default'] || defaultA11yMessages['a11yDescription.node.default']
|
||||
: a11yMessages['a11yDescription.node.keyboardDisabled'] ||
|
||||
defaultA11yMessages['a11yDescription.node.keyboardDisabled'];
|
||||
const edgeDesc = a11yMessages['a11yDescription.edge.default'] || defaultA11yMessages['a11yDescription.edge.default'];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id={`${ARIA_NODE_DESC_KEY}-${rfId}`} style={style}>
|
||||
Press enter or space to select a node.
|
||||
{!disableKeyboardA11y && 'You can then use the arrow keys to move the node around.'} Press delete to remove it
|
||||
and escape to cancel.{' '}
|
||||
{nodeDesc}
|
||||
</div>
|
||||
<div id={`${ARIA_EDGE_DESC_KEY}-${rfId}`} style={style}>
|
||||
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
|
||||
{edgeDesc}
|
||||
</div>
|
||||
{!disableKeyboardA11y && <AriaLiveMessage rfId={rfId} />}
|
||||
</>
|
||||
|
||||
@@ -145,6 +145,7 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||
colorMode = 'light',
|
||||
debug,
|
||||
onScroll,
|
||||
a11yMessages,
|
||||
...rest
|
||||
}: ReactFlowProps<NodeType, EdgeType>,
|
||||
ref: ForwardedRef<HTMLDivElement>
|
||||
@@ -309,7 +310,7 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
|
||||
<SelectionListener<NodeType, EdgeType> onSelectionChange={onSelectionChange} />
|
||||
{children}
|
||||
<Attribution proOptions={proOptions} position={attributionPosition} />
|
||||
<A11yDescriptions rfId={rfId} disableKeyboardA11y={disableKeyboardA11y} />
|
||||
<A11yDescriptions rfId={rfId} disableKeyboardA11y={disableKeyboardA11y} a11yMessages={a11yMessages} />
|
||||
</Wrapper>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -21,6 +21,7 @@ import type {
|
||||
ColorMode,
|
||||
SnapGrid,
|
||||
OnReconnect,
|
||||
a11yMessages,
|
||||
} from '@xyflow/system';
|
||||
|
||||
import type {
|
||||
@@ -666,4 +667,9 @@ export interface ReactFlowProps<NodeType extends Node = Node, EdgeType extends E
|
||||
* @default false
|
||||
*/
|
||||
debug?: boolean;
|
||||
/**
|
||||
* Custom accessibility messages for screen readers and a11y features.
|
||||
* Allows localization and customization of ARIA descriptions.
|
||||
*/
|
||||
a11yMessages?: a11yMessages;
|
||||
}
|
||||
|
||||
@@ -313,3 +313,9 @@ export type OnBeforeDeleteBase<NodeType extends NodeBase = NodeBase, EdgeType ex
|
||||
nodes: NodeType[];
|
||||
edges: EdgeType[];
|
||||
}) => Promise<boolean | { nodes: NodeType[]; edges: EdgeType[] }>;
|
||||
|
||||
export type a11yMessages = {
|
||||
'a11yDescription.node.default'?: string;
|
||||
'a11yDescription.node.keyboardDisabled'?: string;
|
||||
'a11yDescription.edge.default'?: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user