chore(labelconfig): cleanup

This commit is contained in:
moklick
2025-06-03 13:36:16 +02:00
parent 220cb7f8a3
commit 6543ddc31c
11 changed files with 59 additions and 65 deletions

View File

@@ -9,6 +9,7 @@ import {
Node,
Edge,
OnNodeDrag,
LabelConfig,
} from '@xyflow/react';
const onNodeDrag: OnNodeDrag = (_, node: Node, nodes: Node[]) => console.log('drag', node, nodes);
@@ -43,6 +44,20 @@ const initialEdges: Edge[] = [
{ id: 'e1-3', source: '1', target: '3' },
];
const labelConfig: Partial<LabelConfig> = {
'a11yDescription.node.default': 'Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Custom Keyboard Desc.',
'a11yDescription.edge.default': 'Custom Edge Desc.',
'a11yDescription.ariaLiveMessage': ({ direction, x, y }) =>
`Custom Moved selected node ${direction}. New position, x: ${x}, y: ${y}`,
'controls.ariaLabel': 'Custom Controls Aria Label',
'controls.zoomin.title': 'Custom Zoom in',
'controls.zoomout.title': 'Custom Zoom Out',
// 'controls.fitview.title': 'Custom Fit View',
'controls.interactive.title': 'Custom Toggle Interactivity',
'minimap.ariaLabel': 'Custom Aria Label',
};
const A11y = () => {
return (
<ReactFlow
@@ -61,19 +76,7 @@ const A11y = () => {
elevateEdgesOnSelect
elevateNodesOnSelect={false}
nodeDragThreshold={0}
labelConfig={{
'a11yDescription.node.default': 'Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Custom Keyboard 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.zoomin.title': 'Custom Zoom in',
'controls.zoomout.title': 'Custom Zoom Out',
// 'controls.fitview.title': 'Custom Fit View',
'controls.interactive.title': 'Custom Toggle Interactivity',
'minimap.ariaLabel': 'Custom Aria Label',
}}
labelConfig={labelConfig}
>
<Background variant={BackgroundVariant.Dots} />
<MiniMap />

View File

@@ -1,24 +1,17 @@
<script lang="ts">
import {
SvelteFlow,
Controls,
Background,
MiniMap,
} from '@xyflow/svelte';
import { SvelteFlow, Controls, Background, MiniMap } from '@xyflow/svelte';
import '@xyflow/svelte/dist/style.css';
let nodes = $state.raw([
{
id: 'A',
position: { x: 0, y: 0 },
data: { label: 'A' },
data: { label: 'A' }
},
{ id: 'B', position: { x: -100, y: 150 }, data: { label: 'B' } },
{ id: 'C', position: { x: 100, y: 150 }, data: { label: 'C' } },
{ id: 'D', position: { x: 0, y: 260 }, data: { label: 'D' } }
{ id: 'C', position: { x: 100, y: 150 }, data: { label: 'C' } },
{ id: 'D', position: { x: 0, y: 260 }, data: { label: 'D' } }
]);
let edges = $state.raw([
@@ -26,25 +19,24 @@
{ id: 'A-C', source: 'A', target: 'C' },
{ id: 'A-D', source: 'A', target: 'D' }
]);
</script>
<SvelteFlow
bind:nodes
bind:edges
fitView
<SvelteFlow
bind:nodes
bind:edges
fitView
labelConfig={{
'a11yDescription.node.default': 'Svelte Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Svelte Custom Keyboard 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.zoomin.title': 'Svelte Custom Zoom in',
'controls.zoomout.title': 'Svelte Custom Zoom Out',
// 'controls.fitview.title': 'Svelte Custom Fit View',
'controls.interactive.title': 'Svelte Custom Toggle Interactivity',
'minimap.ariaLabel': 'Svelte Custom Minimap',
'a11yDescription.node.default': 'Svelte Custom Node Desc.',
'a11yDescription.node.keyboardDisabled': 'Svelte Custom Keyboard Desc.',
'a11yDescription.edge.default': 'Svelte Custom Edge Desc.',
'a11yDescription.ariaLiveMessage': ({ direction, x, y }) =>
`Custom Moved selected node ${direction}. New position, x: ${x}, y: ${y}`,
'controls.ariaLabel': 'Svelte Custom Control Aria Label',
'controls.zoomin.title': 'Svelte Custom Zoom in',
'controls.zoomout.title': 'Svelte Custom Zoom Out',
// 'controls.fitview.title': 'Svelte Custom Fit View',
'controls.interactive.title': 'Svelte Custom Toggle Interactivity',
'minimap.ariaLabel': 'Svelte Custom Minimap'
}}
>
<Controls />

View File

@@ -41,7 +41,6 @@ function ControlsComponent({
const store = useStoreApi();
const { isInteractive, minZoomReached, maxZoomReached, labelConfig } = useStore(selector, shallow);
const { zoomIn, zoomOut, fitView } = useReactFlow();
const effectiveAriaLabel = ariaLabel ?? labelConfig['controls.ariaLabel'];
const onZoomInHandler = () => {
zoomIn();
@@ -75,7 +74,7 @@ function ControlsComponent({
position={position}
style={style}
data-testid="rf__controls"
aria-label={effectiveAriaLabel}
aria-label={ariaLabel ?? labelConfig['controls.ariaLabel']}
>
{showZoom && (
<>

View File

@@ -133,7 +133,7 @@ function MiniMapComponent<NodeType extends Node = Node>({
}, [])
: undefined;
const effectiveAriaLabel = ariaLabel ?? labelConfig['minimap.ariaLabel'];
const _ariaLabel = ariaLabel ?? labelConfig['minimap.ariaLabel'];
return (
<Panel
@@ -164,7 +164,7 @@ function MiniMapComponent<NodeType extends Node = Node>({
ref={svg}
onClick={onSvgClick}
>
{effectiveAriaLabel && <title id={labelledBy}>{effectiveAriaLabel}</title>}
{_ariaLabel && <title id={labelledBy}>{_ariaLabel}</title>}
<MiniMapNodes<NodeType>
onClick={onSvgNodeClick}

View File

@@ -144,11 +144,11 @@ export function NodeWrapper<NodeType extends Node>({
event.preventDefault();
store.setState({
ariaLiveMessage: labelConfig['a11yDescription.ariaLiveMessage'](
event.key.replace('Arrow', '').toLowerCase(),
~~internals.positionAbsolute.x,
~~internals.positionAbsolute.y
),
ariaLiveMessage: labelConfig['a11yDescription.ariaLiveMessage']({
direction: event.key.replace('Arrow', '').toLowerCase(),
x: ~~internals.positionAbsolute.x,
y: ~~internals.positionAbsolute.y,
}),
});
moveSelectedNodes({

View File

@@ -108,6 +108,7 @@ export {
type NoConnection,
type NodeConnection,
type OnReconnect,
type LabelConfig,
} from '@xyflow/system';
// we need this workaround to prevent a duplicate identifier error

View File

@@ -1,5 +1,4 @@
<script lang="ts" generics="NodeType extends Node = Node, EdgeType extends Edge = Edge">
import { derived } from 'svelte/store';
import type { SvelteFlowStore } from '$lib/store/types';
import type { Node, Edge } from '$lib/types';
import { ARIA_EDGE_DESC_KEY, ARIA_LIVE_MESSAGE, ARIA_NODE_DESC_KEY } from '.';
@@ -8,12 +7,12 @@
</script>
<div id={`${ARIA_NODE_DESC_KEY}-${store.flowId}`} class="a11y-hidden">
{store.disableKeyboardA11y
? store.labelConfig['a11yDescription.node.default']
: store.labelConfig['a11yDescription.node.keyboardDisabled']}
{store.disableKeyboardA11y
? store.labelConfig['a11yDescription.node.default']
: store.labelConfig['a11yDescription.node.keyboardDisabled']}
</div>
<div id={`${ARIA_EDGE_DESC_KEY}-${store.flowId}`} class="a11y-hidden">
{store.labelConfig['a11yDescription.edge.default']}
{store.labelConfig['a11yDescription.edge.default']}
</div>
{#if !store.disableKeyboardA11y}

View File

@@ -189,12 +189,11 @@
) {
// prevent default scrolling behavior on arrow key press when node is moved
event.preventDefault();
store.ariaLiveMessage = labelConfig['a11yDescription.ariaLiveMessage'](
event.key.replace('Arrow', '').toLowerCase(),
~~node.internals.positionAbsolute.x,
~~node.internals.positionAbsolute.y
),
store.ariaLiveMessage = labelConfig['a11yDescription.ariaLiveMessage']({
direction: event.key.replace('Arrow', '').toLowerCase(),
x: ~~node.internals.positionAbsolute.x,
y: ~~node.internals.positionAbsolute.y
});
store.moveSelectedNodes(arrowKeyDiffs[event.key], event.shiftKey ? 4 : 1);
}
}

View File

@@ -476,5 +476,5 @@ export type SvelteFlowProps<
* Configuration for customizable labels, descriptions, and UI text. Provided keys will override the corresponding defaults.
* Allows localization, customization of ARIA descriptions, control labels, minimap labels, and other UI strings.
*/
labelConfig?: LabelConfig;
labelConfig?: Partial<LabelConfig>;
};

View File

@@ -112,7 +112,8 @@ export {
type ResizeParamsWithDirection,
type ResizeDragEvent,
type IsValidConnection,
type NodeConnection
type NodeConnection,
type LabelConfig
} from '@xyflow/system';
// system utils

View File

@@ -44,8 +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.',
'a11yDescription.edge.default':
'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}`,
'a11yDescription.ariaLiveMessage': ({ direction, x, y }: { direction: string; x: number; y: number }) =>
`Moved selected node ${direction}. New position, x: ${x}, y: ${y}`,
// Control elements
'controls.ariaLabel': 'Control Panel',
@@ -61,4 +61,4 @@ export const defaultLabelConfig = {
'handle.ariaLabel': 'Handle',
};
export type LabelConfig = Required<typeof defaultLabelConfig>;
export type LabelConfig = typeof defaultLabelConfig;