feat(node-toolbar): change isActive to isVisible and implement default behavior

This commit is contained in:
Christopher Möller
2022-11-16 13:49:15 +01:00
parent 20a6653577
commit edbf894350
4 changed files with 17 additions and 6 deletions
@@ -1,10 +1,10 @@
import { memo, FC } from 'react'; import { memo, FC } from 'react';
import { Handle, Position, NodeProps, NodeToolbar } from 'reactflow'; import { Handle, Position, NodeProps, NodeToolbar } from 'reactflow';
const CustomNode: FC<NodeProps> = ({ id, data, selected }) => { const CustomNode: FC<NodeProps> = ({ id, data }) => {
return ( return (
<> <>
<NodeToolbar isActive={selected} nodeId={id} position={data.toolbarPosition}> <NodeToolbar nodeId={id} isVisible={data.toolbarVisible} position={data.toolbarPosition}>
<button>delete</button> <button>delete</button>
<button>copy</button> <button>copy</button>
<button>expand</button> <button>expand</button>
@@ -20,7 +20,7 @@ const initialNodes: Node[] = [
id: '1', id: '1',
type: 'custom', type: 'custom',
data: { label: 'toolbar top', toolbarPosition: Position.Top }, data: { label: 'toolbar top', toolbarPosition: Position.Top },
position: { x: 0, y: 100 }, position: { x: 0, y: 0 },
className: 'react-flow__node-default', className: 'react-flow__node-default',
}, },
{ {
@@ -44,6 +44,13 @@ const initialNodes: Node[] = [
position: { x: 400, y: 200 }, position: { x: 400, y: 200 },
className: 'react-flow__node-default', className: 'react-flow__node-default',
}, },
{
id: '5',
type: 'custom',
data: { label: 'toolbar always open', toolbarPosition: Position.Top, toolbarVisible: true },
position: { x: 0, y: 150 },
className: 'react-flow__node-default',
},
]; ];
const initialEdges: Edge[] = [ const initialEdges: Edge[] = [
+6 -2
View File
@@ -25,7 +25,9 @@ const nodeEqualityFn = (a: SelectedNode, b: SelectedNode) =>
a?.selected === b?.selected && a?.selected === b?.selected &&
a?.[internalsSymbol]?.z === b?.[internalsSymbol]?.z; a?.[internalsSymbol]?.z === b?.[internalsSymbol]?.z;
const transformSelector = (state: ReactFlowState) => state.transform; const transformSelector = (state: ReactFlowState): Transform => state.transform;
const selectedNodesCountSelector = (state: ReactFlowState): number =>
Array.from(state.nodeInternals.values()).filter((node) => node.selected).length;
function getTransform(nodeRect: Rect, transform: Transform, position: Position, offset: number): string { function getTransform(nodeRect: Rect, transform: Transform, position: Position, offset: number): string {
// position === Position.Top // position === Position.Top
@@ -61,7 +63,7 @@ function NodeToolbar({
children, children,
className, className,
style, style,
isActive, isVisible,
position = Position.Top, position = Position.Top,
offset = 10, offset = 10,
...rest ...rest
@@ -69,6 +71,8 @@ function NodeToolbar({
const nodeSelector = useCallback((state: ReactFlowState): SelectedNode => state.nodeInternals.get(nodeId), [nodeId]); const nodeSelector = useCallback((state: ReactFlowState): SelectedNode => state.nodeInternals.get(nodeId), [nodeId]);
const node = useStore(nodeSelector, nodeEqualityFn); const node = useStore(nodeSelector, nodeEqualityFn);
const transform = useStore(transformSelector, shallow); const transform = useStore(transformSelector, shallow);
const selectedNodesCount = useStore(selectedNodesCountSelector);
const isActive = typeof isVisible === 'boolean' ? isVisible : node?.selected && selectedNodesCount === 1;
if (!isActive || !node) { if (!isActive || !node) {
return null; return null;
+1 -1
View File
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'react';
export type NodeToolbarProps = HTMLAttributes<HTMLDivElement> & { export type NodeToolbarProps = HTMLAttributes<HTMLDivElement> & {
nodeId: string; nodeId: string;
isActive?: boolean; isVisible?: boolean;
position?: Position; position?: Position;
offset?: number; offset?: number;
}; };