chore(a11y): add ariaLiveMessage to label config

This commit is contained in:
Abbey Yacoe
2025-05-22 15:58:31 +02:00
parent 21e25d698c
commit 1fb7a5c98a
5 changed files with 22 additions and 9 deletions
@@ -63,6 +63,8 @@ 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.',
'a11yDescription.ariaLiveMessage': (node: string, x: number, y: number) =>
`Custom Moved selected node ${node}. New position, x: ${x}, y: ${y}`,
'controls.ariaLabel': 'Custom Controls Aria Label', 'controls.ariaLabel': 'Custom Controls Aria Label',
'controls.zoomin.title': 'Custom Zoom in', 'controls.zoomin.title': 'Custom Zoom in',
'controls.zoomout.title': 'Custom Zoom Out', 'controls.zoomout.title': 'Custom Zoom Out',
@@ -15,7 +15,8 @@
position: { x: 0, y: 0 }, position: { x: 0, y: 0 },
data: { label: 'A' }, data: { label: 'A' },
}, },
{ id: 'B', position: { x: -100, y: 150 }, data: { label: '<ul> Node' }, as: 'ul' }, // You need to explicitly pass the as type
{ id: 'B', position: { x: -100, y: 150 }, data: { label: '<ul> Node' }, as: "ul" as "ul" },
{ id: 'C', position: { x: 100, y: 150 }, data: { label: 'C' } }, { id: 'C', position: { x: 100, y: 150 }, data: { label: 'C' } },
{ id: 'D', position: { x: 0, y: 260 }, data: { label: 'D' } } { id: 'D', position: { x: 0, y: 260 }, data: { label: 'D' } }
]); ]);
@@ -36,6 +37,8 @@
'a11yDescription.node.default': 'Svelte Custom Node Desc.', 'a11yDescription.node.default': 'Svelte Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Svelte Custom Keyboard Desc.', 'a11yDescription.node.keyboardDisabled': 'Svelte Custom Keyboard Desc.',
'a11yDescription.edge.default': 'Svelte Custom Edge Desc.', 'a11yDescription.edge.default': 'Svelte Custom Edge Desc.',
'a11yDescription.ariaLiveMessage': (node: string, x: number, y: number) =>
`Custom Moved selected node ${node}. New position, x: ${x}, y: ${y}`,
'controls.ariaLabel': 'Svelte Custom Control Aria Label', 'controls.ariaLabel': 'Svelte Custom Control Aria Label',
'controls.zoomin.title': 'Svelte Custom Zoom in', 'controls.zoomin.title': 'Svelte Custom Zoom in',
'controls.zoomout.title': 'Svelte Custom Zoom Out', 'controls.zoomout.title': 'Svelte Custom Zoom Out',
@@ -40,7 +40,7 @@ export function NodeWrapper<NodeType extends Node>({
nodeClickDistance, nodeClickDistance,
onError, onError,
}: NodeWrapperProps<NodeType>) { }: NodeWrapperProps<NodeType>) {
const { node, internals, isParent } = useStore((s) => { const { node, internals, isParent, labelConfig } = useStore((s) => {
const node = s.nodeLookup.get(id)! as InternalNode<NodeType>; const node = s.nodeLookup.get(id)! as InternalNode<NodeType>;
const isParent = s.parentLookup.has(id); const isParent = s.parentLookup.has(id);
@@ -48,6 +48,7 @@ export function NodeWrapper<NodeType extends Node>({
node, node,
internals: node.internals, internals: node.internals,
isParent, isParent,
labelConfig: s.labelConfig,
}; };
}, shallow); }, shallow);
@@ -151,9 +152,12 @@ export function NodeWrapper<NodeType extends Node>({
event.preventDefault(); event.preventDefault();
store.setState({ store.setState({
ariaLiveMessage: `Moved selected node ${event.key ariaLiveMessage:
.replace('Arrow', '') labelConfig['a11yDescription.ariaLiveMessage']?.(
.toLowerCase()}. New position, x: ${~~internals.positionAbsolute.x}, y: ${~~internals.positionAbsolute.y}`, event.key.replace('Arrow', '').toLowerCase(),
~~internals.positionAbsolute.x,
~~internals.positionAbsolute.y
) || '',
}); });
moveSelectedNodes({ moveSelectedNodes({
@@ -89,6 +89,7 @@
let prevTargetPosition: Position | undefined = targetPosition; let prevTargetPosition: Position | undefined = targetPosition;
let NodeComponent = $derived(store.nodeTypes[type] ?? DefaultNode); let NodeComponent = $derived(store.nodeTypes[type] ?? DefaultNode);
let labelConfig = $derived(store.labelConfig);
let connectableContext: ConnectableContext = { let connectableContext: ConnectableContext = {
get value() { get value() {
@@ -192,10 +193,11 @@
) { ) {
// prevent default scrolling behavior on arrow key press when node is moved // prevent default scrolling behavior on arrow key press when node is moved
event.preventDefault(); event.preventDefault();
store.ariaLiveMessage = labelConfig['a11yDescription.ariaLiveMessage'](
store.ariaLiveMessage = `Moved selected node ${event.key event.key.replace('Arrow', '').toLowerCase(),
.replace('Arrow', '') ~~node.internals.positionAbsolute.x,
.toLowerCase()}. New position, x: ${node.internals.positionAbsolute.x}, y: ${node.internals.positionAbsolute.y}`; ~~node.internals.positionAbsolute.y
) || '';
store.moveSelectedNodes(arrowKeyDiffs[event.key], event.shiftKey ? 4 : 1); store.moveSelectedNodes(arrowKeyDiffs[event.key], event.shiftKey ? 4 : 1);
} }
+2
View File
@@ -44,6 +44,8 @@ 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.',
'a11yDescription.ariaLiveMessage': (node: string, x: number, y: number) =>
`Moved selected node ${node}. New position, x: ${x}, y: ${y}`,
// Control elements // Control elements
'controls.ariaLabel': 'Control Panel', 'controls.ariaLabel': 'Control Panel',