panelui-native 0.63.0 → 0.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/lib/module/components/badge/index.js +1 -1
- package/lib/module/components/badge/index.js.map +1 -1
- package/lib/module/components/bar-chart/index.js +39 -2
- package/lib/module/components/bar-chart/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +2 -2
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/button/index.js +19 -9
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/carousel/index.js +28 -14
- package/lib/module/components/carousel/index.js.map +1 -1
- package/lib/module/components/checkbox/index.js +2 -3
- package/lib/module/components/checkbox/index.js.map +1 -1
- package/lib/module/components/dialog/index.js +2 -2
- package/lib/module/components/dialog/index.js.map +1 -1
- package/lib/module/components/drawer/index.js +2 -2
- package/lib/module/components/drawer/index.js.map +1 -1
- package/lib/module/components/fab/index.js +4 -3
- package/lib/module/components/fab/index.js.map +1 -1
- package/lib/module/components/field/index.js +41 -6
- package/lib/module/components/field/index.js.map +1 -1
- package/lib/module/components/flow/flow-accessibility.js +84 -0
- package/lib/module/components/flow/flow-accessibility.js.map +1 -0
- package/lib/module/components/flow/index.js +100 -39
- package/lib/module/components/flow/index.js.map +1 -1
- package/lib/module/components/form/use-form.js +93 -66
- package/lib/module/components/form/use-form.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +2 -2
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +2 -2
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/kpi/index.js +3 -1
- package/lib/module/components/kpi/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +3 -3
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/map/index.js +71 -8
- package/lib/module/components/map/index.js.map +1 -1
- package/lib/module/components/map/map-accessibility.js +20 -0
- package/lib/module/components/map/map-accessibility.js.map +1 -0
- package/lib/module/components/map/maplibre.js.map +1 -1
- package/lib/module/components/menu/index.js +4 -1
- package/lib/module/components/menu/index.js.map +1 -1
- package/lib/module/components/number-input/index.js +1 -23
- package/lib/module/components/number-input/index.js.map +1 -1
- package/lib/module/components/number-input/number-input-math.js +44 -0
- package/lib/module/components/number-input/number-input-math.js.map +1 -0
- package/lib/module/components/plot/index.js +2 -2
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/radio-group/index.js +1 -2
- package/lib/module/components/radio-group/index.js.map +1 -1
- package/lib/module/components/sortable/index.js +5 -55
- package/lib/module/components/sortable/index.js.map +1 -1
- package/lib/module/components/sortable/reorder.js +63 -0
- package/lib/module/components/sortable/reorder.js.map +1 -0
- package/lib/module/components/swipe/index.js +4 -4
- package/lib/module/components/swipe/index.js.map +1 -1
- package/lib/module/components/switch/index.js +36 -3
- package/lib/module/components/switch/index.js.map +1 -1
- package/lib/module/components/time-picker/accessibility.js +21 -0
- package/lib/module/components/time-picker/accessibility.js.map +1 -0
- package/lib/module/components/time-picker/index.js +34 -8
- package/lib/module/components/time-picker/index.js.map +1 -1
- package/lib/module/components/waterfall-chart/index.js +1325 -0
- package/lib/module/components/waterfall-chart/index.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/primitives/modal-isolation-store.js +29 -0
- package/lib/module/primitives/modal-isolation-store.js.map +1 -0
- package/lib/module/primitives/portal.js +36 -4
- package/lib/module/primitives/portal.js.map +1 -1
- package/lib/module/providers/panel-ui-provider.js +27 -6
- package/lib/module/providers/panel-ui-provider.js.map +1 -1
- package/lib/typescript/src/components/badge/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bar-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/carousel/index.d.ts +1 -1
- package/lib/typescript/src/components/carousel/index.d.ts.map +1 -1
- package/lib/typescript/src/components/checkbox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/fab/index.d.ts.map +1 -1
- package/lib/typescript/src/components/field/index.d.ts +8 -1
- package/lib/typescript/src/components/field/index.d.ts.map +1 -1
- package/lib/typescript/src/components/flow/flow-accessibility.d.ts +49 -0
- package/lib/typescript/src/components/flow/flow-accessibility.d.ts.map +1 -0
- package/lib/typescript/src/components/flow/index.d.ts +14 -2
- package/lib/typescript/src/components/flow/index.d.ts.map +1 -1
- package/lib/typescript/src/components/form/use-form.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/kpi/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/index.d.ts +13 -5
- package/lib/typescript/src/components/map/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/map-accessibility.d.ts +19 -0
- package/lib/typescript/src/components/map/map-accessibility.d.ts.map +1 -0
- package/lib/typescript/src/components/map/maplibre.d.ts +2 -0
- package/lib/typescript/src/components/map/maplibre.d.ts.map +1 -1
- package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
- package/lib/typescript/src/components/number-input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/number-input/number-input-math.d.ts +9 -0
- package/lib/typescript/src/components/number-input/number-input-math.d.ts.map +1 -0
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/sortable/index.d.ts.map +1 -1
- package/lib/typescript/src/components/sortable/reorder.d.ts +14 -0
- package/lib/typescript/src/components/sortable/reorder.d.ts.map +1 -0
- package/lib/typescript/src/components/swipe/index.d.ts.map +1 -1
- package/lib/typescript/src/components/switch/index.d.ts +3 -3
- package/lib/typescript/src/components/switch/index.d.ts.map +1 -1
- package/lib/typescript/src/components/time-picker/accessibility.d.ts +10 -0
- package/lib/typescript/src/components/time-picker/accessibility.d.ts.map +1 -0
- package/lib/typescript/src/components/time-picker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/waterfall-chart/index.d.ts +379 -0
- package/lib/typescript/src/components/waterfall-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/primitives/modal-isolation-store.d.ts +10 -0
- package/lib/typescript/src/primitives/modal-isolation-store.d.ts.map +1 -0
- package/lib/typescript/src/primitives/portal.d.ts +6 -0
- package/lib/typescript/src/primitives/portal.d.ts.map +1 -1
- package/lib/typescript/src/providers/panel-ui-provider.d.ts.map +1 -1
- package/package.json +5 -2
- package/src/components/badge/index.tsx +4 -1
- package/src/components/bar-chart/index.tsx +40 -3
- package/src/components/bottom-sheet/index.tsx +3 -3
- package/src/components/button/index.tsx +15 -21
- package/src/components/carousel/index.tsx +42 -20
- package/src/components/checkbox/index.tsx +1 -2
- package/src/components/dialog/index.tsx +3 -3
- package/src/components/drawer/index.tsx +3 -3
- package/src/components/fab/index.tsx +8 -12
- package/src/components/field/index.tsx +52 -10
- package/src/components/flow/flow-accessibility.ts +109 -0
- package/src/components/flow/index.tsx +162 -50
- package/src/components/form/use-form.ts +101 -65
- package/src/components/heatmap-chart/index.tsx +2 -3
- package/src/components/hex-chart/index.tsx +2 -3
- package/src/components/kpi/index.tsx +3 -1
- package/src/components/line-chart/index.tsx +3 -2
- package/src/components/map/index.tsx +110 -7
- package/src/components/map/map-accessibility.ts +41 -0
- package/src/components/map/maplibre.ts +2 -0
- package/src/components/menu/index.tsx +4 -1
- package/src/components/number-input/index.tsx +1 -26
- package/src/components/number-input/number-input-math.ts +50 -0
- package/src/components/plot/index.tsx +2 -1
- package/src/components/radio-group/index.tsx +1 -2
- package/src/components/sortable/index.tsx +12 -64
- package/src/components/sortable/reorder.ts +88 -0
- package/src/components/swipe/index.tsx +7 -4
- package/src/components/switch/index.tsx +42 -6
- package/src/components/time-picker/accessibility.ts +24 -0
- package/src/components/time-picker/index.tsx +48 -2
- package/src/components/waterfall-chart/index.tsx +1589 -0
- package/src/index.ts +23 -0
- package/src/primitives/modal-isolation-store.ts +31 -0
- package/src/primitives/portal.tsx +34 -4
- package/src/providers/panel-ui-provider.tsx +41 -9
- package/theme.css +30 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export const FLOW_MOVE_ACTIONS = [{
|
|
4
|
+
name: 'flow-move-up',
|
|
5
|
+
label: 'Move up',
|
|
6
|
+
dx: 0,
|
|
7
|
+
dy: -1
|
|
8
|
+
}, {
|
|
9
|
+
name: 'flow-move-right',
|
|
10
|
+
label: 'Move right',
|
|
11
|
+
dx: 1,
|
|
12
|
+
dy: 0
|
|
13
|
+
}, {
|
|
14
|
+
name: 'flow-move-down',
|
|
15
|
+
label: 'Move down',
|
|
16
|
+
dx: 0,
|
|
17
|
+
dy: 1
|
|
18
|
+
}, {
|
|
19
|
+
name: 'flow-move-left',
|
|
20
|
+
label: 'Move left',
|
|
21
|
+
dx: -1,
|
|
22
|
+
dy: 0
|
|
23
|
+
}];
|
|
24
|
+
export const FLOW_DELETE_ACTION = {
|
|
25
|
+
name: 'flow-delete',
|
|
26
|
+
label: 'Delete node'
|
|
27
|
+
};
|
|
28
|
+
/** Keep pointer and assistive-technology movement inside the same group bounds. */
|
|
29
|
+
export function clampNodePosition(rect, bounds, position) {
|
|
30
|
+
'worklet';
|
|
31
|
+
|
|
32
|
+
if (!bounds) return position;
|
|
33
|
+
return {
|
|
34
|
+
x: Math.min(Math.max(position.x, bounds.x), bounds.x + bounds.width - rect.width),
|
|
35
|
+
y: Math.min(Math.max(position.y, bounds.y), bounds.y + bounds.height - rect.height)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function moveNodePosition(rect, bounds, actionName, step) {
|
|
39
|
+
const action = FLOW_MOVE_ACTIONS.find(entry => entry.name === actionName);
|
|
40
|
+
if (!action) return undefined;
|
|
41
|
+
return clampNodePosition(rect, bounds, {
|
|
42
|
+
x: rect.x + action.dx * Math.max(1, step),
|
|
43
|
+
y: rect.y + action.dy * Math.max(1, step)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Build connection choices from the same registered nodes and handles used by drag hit-testing. */
|
|
48
|
+
export function getFlowConnectionActions(sourceNode, nodes, handles) {
|
|
49
|
+
const sources = handles.filter(handle => handle.node === sourceNode && handle.type !== 'target');
|
|
50
|
+
if (sources.length === 0) return [];
|
|
51
|
+
const actions = [];
|
|
52
|
+
for (const source of sources) {
|
|
53
|
+
for (const targetNode of nodes) {
|
|
54
|
+
if (targetNode.id === sourceNode) continue;
|
|
55
|
+
const targets = handles.filter(handle => handle.node === targetNode.id && handle.type !== 'source');
|
|
56
|
+
if (targets.length === 0) {
|
|
57
|
+
actions.push({
|
|
58
|
+
name: `flow-connect:${source.key}->${targetNode.id}`,
|
|
59
|
+
label: `Connect ${source.label} to ${targetNode.label}`,
|
|
60
|
+
connection: {
|
|
61
|
+
source: sourceNode,
|
|
62
|
+
sourceHandle: source.id,
|
|
63
|
+
target: targetNode.id
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const target of targets) {
|
|
69
|
+
actions.push({
|
|
70
|
+
name: `flow-connect:${source.key}->${target.key}`,
|
|
71
|
+
label: `Connect ${source.label} to ${targetNode.label}, ${target.label}`,
|
|
72
|
+
connection: {
|
|
73
|
+
source: sourceNode,
|
|
74
|
+
sourceHandle: source.id,
|
|
75
|
+
target: target.node,
|
|
76
|
+
targetHandle: target.id
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return actions;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=flow-accessibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["FLOW_MOVE_ACTIONS","name","label","dx","dy","FLOW_DELETE_ACTION","clampNodePosition","rect","bounds","position","x","Math","min","max","width","y","height","moveNodePosition","actionName","step","action","find","entry","undefined","getFlowConnectionActions","sourceNode","nodes","handles","sources","filter","handle","node","type","length","actions","source","targetNode","id","targets","push","key","connection","sourceHandle","target","targetHandle"],"sourceRoot":"../../../../src","sources":["components/flow/flow-accessibility.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* They are nested gesture detectors rather than one gesture doing three jobs,
|
|
45
45
|
* so the innermost thing under the finger wins, which is what a finger expects.
|
|
46
46
|
*/
|
|
47
|
-
import { createContext, Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
47
|
+
import { createContext, Fragment, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
48
48
|
import { StyleSheet, View } from 'react-native';
|
|
49
49
|
import { useCSSVariable } from 'uniwind';
|
|
50
50
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
@@ -56,6 +56,7 @@ import { AnimatedPressable } from "../../primitives/animated-pressable.js";
|
|
|
56
56
|
import { Text, textChildren } from "../../primitives/text.js";
|
|
57
57
|
import { cn } from "../../utils/cn.js";
|
|
58
58
|
import { anchorOf, arrivalDirection, arrowHeadPath, autoSides, edgePath, standOff } from "./flow-paths.js";
|
|
59
|
+
import { clampNodePosition, FLOW_DELETE_ACTION, FLOW_MOVE_ACTIONS, getFlowConnectionActions, moveNodePosition } from "./flow-accessibility.js";
|
|
59
60
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
60
61
|
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
61
62
|
const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
|
@@ -172,7 +173,7 @@ function FlowRoot({
|
|
|
172
173
|
height: 0
|
|
173
174
|
});
|
|
174
175
|
const [locked, setLocked] = useState(false);
|
|
175
|
-
const [
|
|
176
|
+
const [nodes, setNodes] = useState([]);
|
|
176
177
|
const [groupIds, setGroupIds] = useState([]);
|
|
177
178
|
const [handles, setHandles] = useState([]);
|
|
178
179
|
const [edges, setEdges] = useState([]);
|
|
@@ -277,11 +278,14 @@ function FlowRoot({
|
|
|
277
278
|
zoom: z
|
|
278
279
|
});
|
|
279
280
|
}, []);
|
|
280
|
-
const registerNode = useCallback(id => {
|
|
281
|
-
|
|
281
|
+
const registerNode = useCallback((id, label = id) => {
|
|
282
|
+
setNodes(current => [...current.filter(entry => entry.id !== id), {
|
|
283
|
+
id,
|
|
284
|
+
label
|
|
285
|
+
}]);
|
|
282
286
|
}, []);
|
|
283
287
|
const unregisterNode = useCallback(id => {
|
|
284
|
-
|
|
288
|
+
setNodes(current => current.filter(entry => entry.id !== id));
|
|
285
289
|
}, []);
|
|
286
290
|
const registerGroup = useCallback(id => {
|
|
287
291
|
setGroupIds(current => current.includes(id) ? current : [...current, id]);
|
|
@@ -307,6 +311,14 @@ function FlowRoot({
|
|
|
307
311
|
const unregisterEdge = useCallback(key => {
|
|
308
312
|
setEdges(current => current.filter(edge => edge.key !== key));
|
|
309
313
|
}, []);
|
|
314
|
+
const connectRef = useRef(onConnect);
|
|
315
|
+
connectRef.current = onConnect;
|
|
316
|
+
const validConnectionRef = useRef(isValidConnection);
|
|
317
|
+
validConnectionRef.current = isValidConnection;
|
|
318
|
+
const connectNodes = useCallback(next => {
|
|
319
|
+
if (validConnectionRef.current && !validConnectionRef.current(next)) return;
|
|
320
|
+
connectRef.current?.(next);
|
|
321
|
+
}, []);
|
|
310
322
|
const fitView = useCallback(() => {
|
|
311
323
|
const {
|
|
312
324
|
width,
|
|
@@ -359,10 +371,10 @@ function FlowRoot({
|
|
|
359
371
|
// mount has nothing to fit to yet. One frame later they do.
|
|
360
372
|
const fitOnMount = useRef(fitViewOnMount);
|
|
361
373
|
useEffect(() => {
|
|
362
|
-
if (!fitOnMount.current ||
|
|
374
|
+
if (!fitOnMount.current || nodes.length === 0) return;
|
|
363
375
|
const timer = setTimeout(fitView, 32);
|
|
364
376
|
return () => clearTimeout(timer);
|
|
365
|
-
}, [fitView,
|
|
377
|
+
}, [fitView, nodes.length]);
|
|
366
378
|
const panStart = useSharedValue({
|
|
367
379
|
x: 0,
|
|
368
380
|
y: 0
|
|
@@ -448,7 +460,7 @@ function FlowRoot({
|
|
|
448
460
|
maxZoom,
|
|
449
461
|
locked,
|
|
450
462
|
setLocked,
|
|
451
|
-
|
|
463
|
+
nodes,
|
|
452
464
|
groupIds,
|
|
453
465
|
handles,
|
|
454
466
|
edges,
|
|
@@ -460,12 +472,12 @@ function FlowRoot({
|
|
|
460
472
|
unregisterHandle,
|
|
461
473
|
registerEdge,
|
|
462
474
|
unregisterEdge,
|
|
463
|
-
|
|
464
|
-
|
|
475
|
+
connectNodes,
|
|
476
|
+
canConnect: Boolean(onConnect),
|
|
465
477
|
onNodeDragEnd,
|
|
466
478
|
fitView,
|
|
467
479
|
zoomBy
|
|
468
|
-
}), [boxes, setNodeRect, dropNodeRect, box, layer, origin, connection, edges, fitView, handles, registerEdge, unregisterEdge,
|
|
480
|
+
}), [boxes, setNodeRect, dropNodeRect, box, layer, origin, connection, edges, fitView, handles, registerEdge, unregisterEdge, connectNodes, locked, maxZoom, minZoom, nodes, groupIds, onConnect, onNodeDragEnd, rects, registerGroup, registerHandle, registerNode, size, translateX, translateY, unregisterGroup, unregisterHandle, unregisterNode, zoom, zoomBy]);
|
|
469
481
|
const onLayout = useCallback(event => {
|
|
470
482
|
const {
|
|
471
483
|
width,
|
|
@@ -610,7 +622,7 @@ function FlowBackground({
|
|
|
610
622
|
const token = useCSSVariable('--color-muted-foreground');
|
|
611
623
|
const tint = color ?? (typeof token === 'string' ? token : '#737373');
|
|
612
624
|
// A pattern is referenced by id, and two canvases on one screen would collide.
|
|
613
|
-
const id =
|
|
625
|
+
const id = `panelui-flow-${useId().replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
614
626
|
|
|
615
627
|
/*
|
|
616
628
|
* The grid is a tile that follows the viewport in whole-cell steps.
|
|
@@ -716,7 +728,11 @@ function FlowNode({
|
|
|
716
728
|
pinned = false,
|
|
717
729
|
selected = false,
|
|
718
730
|
onPress,
|
|
731
|
+
onDelete,
|
|
732
|
+
accessibilityMoveStep = 24,
|
|
719
733
|
accessibilityLabel,
|
|
734
|
+
accessibilityActions,
|
|
735
|
+
onAccessibilityAction,
|
|
720
736
|
children,
|
|
721
737
|
...props
|
|
722
738
|
}) {
|
|
@@ -733,7 +749,11 @@ function FlowNode({
|
|
|
733
749
|
unregisterNode,
|
|
734
750
|
registerGroup,
|
|
735
751
|
unregisterGroup,
|
|
736
|
-
onNodeDragEnd
|
|
752
|
+
onNodeDragEnd,
|
|
753
|
+
nodes,
|
|
754
|
+
handles,
|
|
755
|
+
connectNodes,
|
|
756
|
+
canConnect
|
|
737
757
|
} = flow;
|
|
738
758
|
|
|
739
759
|
/*
|
|
@@ -743,13 +763,13 @@ function FlowNode({
|
|
|
743
763
|
* layer both need to know it is a container and not a card.
|
|
744
764
|
*/
|
|
745
765
|
useEffect(() => {
|
|
746
|
-
registerNode(id);
|
|
766
|
+
registerNode(id, accessibilityLabel ?? id);
|
|
747
767
|
registerGroup(id);
|
|
748
768
|
return () => {
|
|
749
769
|
unregisterNode(id);
|
|
750
770
|
unregisterGroup(id);
|
|
751
771
|
};
|
|
752
|
-
}, [id, registerGroup, registerNode, unregisterGroup, unregisterNode]);
|
|
772
|
+
}, [accessibilityLabel, id, registerGroup, registerNode, unregisterGroup, unregisterNode]);
|
|
753
773
|
|
|
754
774
|
// Writing on every render would fight the drag, snapping a node back to the
|
|
755
775
|
// position it was first given. Only an actual change to the prop moves it.
|
|
@@ -798,6 +818,48 @@ function FlowNode({
|
|
|
798
818
|
const pressRef = useRef(onPress);
|
|
799
819
|
pressRef.current = onPress;
|
|
800
820
|
const press = useCallback(() => pressRef.current?.(), []);
|
|
821
|
+
const moveNode = useCallback(actionName => {
|
|
822
|
+
const rect = rects.value[id];
|
|
823
|
+
if (!rect) return;
|
|
824
|
+
const bounds = confine && group ? rects.value[group] : undefined;
|
|
825
|
+
const next = moveNodePosition(rect, bounds, actionName, accessibilityMoveStep);
|
|
826
|
+
if (!next) return;
|
|
827
|
+
setNodeRect(id, next);
|
|
828
|
+
dragEnd(next.x, next.y);
|
|
829
|
+
}, [accessibilityMoveStep, confine, dragEnd, group, id, rects, setNodeRect]);
|
|
830
|
+
const connectionActions = useMemo(() => canConnect && !locked ? getFlowConnectionActions(id, nodes, handles) : [], [canConnect, handles, id, locked, nodes]);
|
|
831
|
+
const connectionByAction = useMemo(() => new Map(connectionActions.map(entry => [entry.name, entry.connection])), [connectionActions]);
|
|
832
|
+
const movable = draggable && !pinned && !locked;
|
|
833
|
+
const nodeActions = useMemo(() => [...(onPress ? [{
|
|
834
|
+
name: 'activate'
|
|
835
|
+
}] : []), ...(movable ? FLOW_MOVE_ACTIONS : []), ...connectionActions.map(({
|
|
836
|
+
name,
|
|
837
|
+
label
|
|
838
|
+
}) => ({
|
|
839
|
+
name,
|
|
840
|
+
label
|
|
841
|
+
})), ...(onDelete ? [FLOW_DELETE_ACTION] : []), ...(accessibilityActions ?? [])], [accessibilityActions, connectionActions, movable, onDelete, onPress]);
|
|
842
|
+
const handleAccessibilityAction = useCallback(event => {
|
|
843
|
+
const action = event.nativeEvent.actionName;
|
|
844
|
+
if (action === 'activate' && onPress) {
|
|
845
|
+
press();
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
if (movable && FLOW_MOVE_ACTIONS.some(entry => entry.name === action)) {
|
|
849
|
+
moveNode(action);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
const nextConnection = connectionByAction.get(action);
|
|
853
|
+
if (nextConnection) {
|
|
854
|
+
connectNodes(nextConnection);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (action === FLOW_DELETE_ACTION.name && onDelete) {
|
|
858
|
+
onDelete();
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
onAccessibilityAction?.(event);
|
|
862
|
+
}, [connectNodes, connectionByAction, movable, moveNode, onAccessibilityAction, onDelete, onPress, press]);
|
|
801
863
|
const drag = useMemo(() => Gesture.Pan()
|
|
802
864
|
// A pinned node takes no drag at all: it is part of its container, and
|
|
803
865
|
// the container is what moves.
|
|
@@ -825,13 +887,12 @@ function FlowNode({
|
|
|
825
887
|
* would leave the edges drawn to a position the node never reached.
|
|
826
888
|
*/
|
|
827
889
|
if (confine && group) {
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}
|
|
890
|
+
const next = clampNodePosition(rect, rects.value[group], {
|
|
891
|
+
x,
|
|
892
|
+
y
|
|
893
|
+
});
|
|
894
|
+
x = next.x;
|
|
895
|
+
y = next.y;
|
|
835
896
|
}
|
|
836
897
|
rects.value = {
|
|
837
898
|
...rects.value,
|
|
@@ -886,6 +947,8 @@ function FlowNode({
|
|
|
886
947
|
accessibilityState: {
|
|
887
948
|
selected
|
|
888
949
|
},
|
|
950
|
+
accessibilityActions: nodeActions,
|
|
951
|
+
onAccessibilityAction: handleAccessibilityAction,
|
|
889
952
|
...props,
|
|
890
953
|
children: textChildren(children)
|
|
891
954
|
})
|
|
@@ -912,6 +975,7 @@ function FlowHandle({
|
|
|
912
975
|
type = 'both',
|
|
913
976
|
offset = 0.5,
|
|
914
977
|
className,
|
|
978
|
+
accessibilityLabel,
|
|
915
979
|
hidden = false
|
|
916
980
|
}) {
|
|
917
981
|
const flow = useFlow('Flow.Handle');
|
|
@@ -926,7 +990,8 @@ function FlowHandle({
|
|
|
926
990
|
handles,
|
|
927
991
|
locked,
|
|
928
992
|
registerHandle,
|
|
929
|
-
unregisterHandle
|
|
993
|
+
unregisterHandle,
|
|
994
|
+
connectNodes
|
|
930
995
|
} = flow;
|
|
931
996
|
const key = `${node}.${id}`;
|
|
932
997
|
useEffect(() => {
|
|
@@ -934,26 +999,21 @@ function FlowHandle({
|
|
|
934
999
|
key,
|
|
935
1000
|
node,
|
|
936
1001
|
id,
|
|
1002
|
+
label: accessibilityLabel ?? id,
|
|
937
1003
|
side: position,
|
|
938
1004
|
offset,
|
|
939
1005
|
type
|
|
940
1006
|
});
|
|
941
1007
|
return () => unregisterHandle(key);
|
|
942
|
-
}, [id, key, node, offset, position, registerHandle, type, unregisterHandle]);
|
|
943
|
-
const connectRef = useRef(flow.onConnect);
|
|
944
|
-
connectRef.current = flow.onConnect;
|
|
945
|
-
const validRef = useRef(flow.isValidConnection);
|
|
946
|
-
validRef.current = flow.isValidConnection;
|
|
1008
|
+
}, [accessibilityLabel, id, key, node, offset, position, registerHandle, type, unregisterHandle]);
|
|
947
1009
|
const land = useCallback((target, targetHandle) => {
|
|
948
|
-
|
|
1010
|
+
connectNodes({
|
|
949
1011
|
source: node,
|
|
950
1012
|
sourceHandle: id,
|
|
951
1013
|
target,
|
|
952
1014
|
targetHandle
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
connectRef.current?.(payload);
|
|
956
|
-
}, [id, node]);
|
|
1015
|
+
});
|
|
1016
|
+
}, [connectNodes, id, node]);
|
|
957
1017
|
|
|
958
1018
|
// A snapshot of what a drag can land on, rebuilt only when handles come and
|
|
959
1019
|
// go — the drop test runs on the UI thread and cannot read React state.
|
|
@@ -1067,8 +1127,7 @@ function FlowHandle({
|
|
|
1067
1127
|
children: /*#__PURE__*/_jsx(View, {
|
|
1068
1128
|
collapsable: false,
|
|
1069
1129
|
hitSlop: 12,
|
|
1070
|
-
|
|
1071
|
-
accessibilityLabel: `${position} connection point`,
|
|
1130
|
+
accessible: false,
|
|
1072
1131
|
style: placement,
|
|
1073
1132
|
className: flowVariants().handle({
|
|
1074
1133
|
className
|
|
@@ -1301,9 +1360,9 @@ function FlowGroup({
|
|
|
1301
1360
|
onNodeDragEnd
|
|
1302
1361
|
} = flow;
|
|
1303
1362
|
useEffect(() => {
|
|
1304
|
-
registerNode(id);
|
|
1363
|
+
registerNode(id, label ?? id);
|
|
1305
1364
|
return () => unregisterNode(id);
|
|
1306
|
-
}, [id, registerNode, unregisterNode]);
|
|
1365
|
+
}, [id, label, registerNode, unregisterNode]);
|
|
1307
1366
|
useEffect(() => {
|
|
1308
1367
|
setNodeRect(id, {
|
|
1309
1368
|
x: position.x,
|
|
@@ -1553,7 +1612,7 @@ function FlowMiniMap({
|
|
|
1553
1612
|
}) {
|
|
1554
1613
|
const {
|
|
1555
1614
|
rects,
|
|
1556
|
-
|
|
1615
|
+
nodes,
|
|
1557
1616
|
groupIds,
|
|
1558
1617
|
translateX,
|
|
1559
1618
|
translateY,
|
|
@@ -1640,7 +1699,9 @@ function FlowMiniMap({
|
|
|
1640
1699
|
children: /*#__PURE__*/_jsxs(Svg, {
|
|
1641
1700
|
width: width,
|
|
1642
1701
|
height: height,
|
|
1643
|
-
children: [
|
|
1702
|
+
children: [nodes.map(({
|
|
1703
|
+
id
|
|
1704
|
+
}) => {
|
|
1644
1705
|
const group = groups.has(id);
|
|
1645
1706
|
return /*#__PURE__*/_jsx(MiniMapNode, {
|
|
1646
1707
|
id: id,
|