chore(labelconfig): cleanup
This commit is contained in:
@@ -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 />
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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 && (
|
||||
<>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
|
||||
@@ -112,7 +112,8 @@ export {
|
||||
type ResizeParamsWithDirection,
|
||||
type ResizeDragEvent,
|
||||
type IsValidConnection,
|
||||
type NodeConnection
|
||||
type NodeConnection,
|
||||
type LabelConfig
|
||||
} from '@xyflow/system';
|
||||
|
||||
// system utils
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user