Merge pull request #2464 from wbkd/refactor/a11y

Refactor: make keyboard a11y better configurable
This commit is contained in:
Moritz Klack
2022-10-03 14:48:17 +02:00
committed by GitHub
25 changed files with 134 additions and 36 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@reactflow/examples", "name": "@reactflow/examples",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.2",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --port 3000 --open", "dev": "vite --port 3000 --open",
@@ -92,7 +92,7 @@ const BasicFlow = () => {
defaultEdgeOptions={defaultEdgeOptions} defaultEdgeOptions={defaultEdgeOptions}
selectNodesOnDrag={false} selectNodesOnDrag={false}
> >
<Background variant={BackgroundVariant.Lines} /> <Background variant={BackgroundVariant.Dots} />
<MiniMap /> <MiniMap />
<Controls /> <Controls />
+9
View File
@@ -1,5 +1,14 @@
# @reactflow/background # @reactflow/background
## 11.0.1
### Patch Changes
- [`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab) Thanks [@moklick](https://github.com/moklick)! - default gap = 20
- Updated dependencies [[`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab), [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4)]:
- @reactflow/core@11.1.0
## 11.0.0 ## 11.0.0
### Major Changes ### Major Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/background", "name": "@reactflow/background",
"version": "11.0.0", "version": "11.0.1",
"description": "Background component with different variants for React Flow", "description": "Background component with different variants for React Flow",
"keywords": [ "keywords": [
"react", "react",
+1 -1
View File
@@ -22,7 +22,7 @@ const selector = (s: ReactFlowState) => ({ transform: s.transform, rfId: s.rfId
function Background({ function Background({
variant = BackgroundVariant.Dots, variant = BackgroundVariant.Dots,
gap = 25, gap = 20,
// only used for dots and cross // only used for dots and cross
size, size,
// only used for lines and cross // only used for lines and cross
+7
View File
@@ -1,5 +1,12 @@
# @reactflow/controls # @reactflow/controls
## 11.0.1
### Patch Changes
- Updated dependencies [[`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab), [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4)]:
- @reactflow/core@11.1.0
## 11.0.0 ## 11.0.0
### Major Changes ### Major Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/controls", "name": "@reactflow/controls",
"version": "11.0.0", "version": "11.0.1",
"description": "Component to control the viewport of a React Flow instance", "description": "Component to control the viewport of a React Flow instance",
"keywords": [ "keywords": [
"react", "react",
+10
View File
@@ -1,5 +1,15 @@
# @reactflow/core # @reactflow/core
## 11.1.0
### Minor Changes
- [`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab) Thanks [@moklick](https://github.com/moklick)! - New props: nodesFocusable and edgesFocusable
### Patch Changes
- [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4) Thanks [@moklick](https://github.com/moklick)! - Make nopan class name overwritable with class name option
## 11.0.0 ## 11.0.0
### Major Changes ### Major Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/core", "name": "@reactflow/core",
"version": "11.0.0", "version": "11.1.0",
"description": "Core components and util functions of React Flow.", "description": "Core components and util functions of React Flow.",
"keywords": [ "keywords": [
"react", "react",
@@ -51,7 +51,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
markerStart, markerStart,
rfId, rfId,
ariaLabel, ariaLabel,
disableKeyboardA11y, isFocusable,
pathOptions, pathOptions,
interactionWidth, interactionWidth,
}: WrapEdgeProps): JSX.Element | null => { }: WrapEdgeProps): JSX.Element | null => {
@@ -158,12 +158,12 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
onMouseEnter={onEdgeMouseEnter} onMouseEnter={onEdgeMouseEnter}
onMouseMove={onEdgeMouseMove} onMouseMove={onEdgeMouseMove}
onMouseLeave={onEdgeMouseLeave} onMouseLeave={onEdgeMouseLeave}
onKeyDown={disableKeyboardA11y ? undefined : onKeyDown} onKeyDown={isFocusable ? onKeyDown : undefined}
tabIndex={disableKeyboardA11y ? undefined : 0} tabIndex={isFocusable ? 0 : undefined}
role={disableKeyboardA11y ? undefined : 'button'} role={isFocusable ? 'button' : undefined}
data-testid={`rf__edge-${id}`} data-testid={`rf__edge-${id}`}
aria-label={ariaLabel === null ? undefined : ariaLabel ? ariaLabel : `Edge from ${source} to ${target}`} aria-label={ariaLabel === null ? undefined : ariaLabel ? ariaLabel : `Edge from ${source} to ${target}`}
aria-describedby={disableKeyboardA11y ? undefined : `${ARIA_EDGE_DESC_KEY}-${rfId}`} aria-describedby={isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : undefined}
ref={edgeRef} ref={edgeRef}
> >
{!updating && ( {!updating && (
+30 -11
View File
@@ -11,10 +11,10 @@ import { NodeProps, WrapNodeProps, XYPosition } from '../../types';
import { elementSelectionKeys } from '../../utils'; import { elementSelectionKeys } from '../../utils';
export const arrowKeyDiffs: Record<string, XYPosition> = { export const arrowKeyDiffs: Record<string, XYPosition> = {
ArrowUp: { x: 0, y: -10 }, ArrowUp: { x: 0, y: -1 },
ArrowDown: { x: 0, y: 10 }, ArrowDown: { x: 0, y: 1 },
ArrowLeft: { x: -10, y: 0 }, ArrowLeft: { x: -1, y: 0 },
ArrowRight: { x: 10, y: 0 }, ArrowRight: { x: 1, y: 0 },
}; };
export default (NodeComponent: ComponentType<NodeProps>) => { export default (NodeComponent: ComponentType<NodeProps>) => {
@@ -38,6 +38,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
isDraggable, isDraggable,
isSelectable, isSelectable,
isConnectable, isConnectable,
isFocusable,
selectNodesOnDrag, selectNodesOnDrag,
sourcePosition, sourcePosition,
targetPosition, targetPosition,
@@ -82,6 +83,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
}; };
const onKeyDown = (event: KeyboardEvent) => { const onKeyDown = (event: KeyboardEvent) => {
const { snapGrid, snapToGrid } = store.getState();
if (elementSelectionKeys.includes(event.key) && isSelectable) { if (elementSelectionKeys.includes(event.key) && isSelectable) {
const unselect = event.key === 'Escape'; const unselect = event.key === 'Escape';
if (unselect) { if (unselect) {
@@ -92,14 +94,28 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
store, store,
unselect, unselect,
}); });
} else if (selected && Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)) { } else if (
!disableKeyboardA11y &&
isDraggable &&
selected &&
Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)
) {
store.setState({ store.setState({
ariaLiveMessage: `Moved selected node ten pixels ${event.key ariaLiveMessage: `Moved selected node ${event.key
.replace('Arrow', '') .replace('Arrow', '')
.toLowerCase()}. New position, x: ${~~xPos}, y: ${~~yPos}`, .toLowerCase()}. New position, x: ${~~xPos}, y: ${~~yPos}`,
}); });
updatePositions(arrowKeyDiffs[event.key]); // by default a node moves 5px on each key press, or 20px if shift is pressed
// if snap grid is enabled, we use that for the velocity.
const xVelo = snapToGrid ? snapGrid[0] : 5;
const yVelo = snapToGrid ? snapGrid[1] : 5;
const factor = event.shiftKey ? 4 : 1;
updatePositions({
x: arrowKeyDiffs[event.key].x * xVelo * factor,
y: arrowKeyDiffs[event.key].y * yVelo * factor,
});
} }
}; };
@@ -151,13 +167,16 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
className={cc([ className={cc([
'react-flow__node', 'react-flow__node',
`react-flow__node-${type}`, `react-flow__node-${type}`,
{
// this is overwritable by passing `nopan` as a class name
[noPanClassName]: isDraggable,
},
className, className,
{ {
selected, selected,
selectable: isSelectable, selectable: isSelectable,
parent: isParent, parent: isParent,
dragging, dragging,
[noPanClassName]: isDraggable,
}, },
])} ])}
ref={nodeRef} ref={nodeRef}
@@ -176,9 +195,9 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
onContextMenu={onContextMenuHandler} onContextMenu={onContextMenuHandler}
onClick={onSelectNodeHandler} onClick={onSelectNodeHandler}
onDoubleClick={onDoubleClickHandler} onDoubleClick={onDoubleClickHandler}
onKeyDown={disableKeyboardA11y ? undefined : onKeyDown} onKeyDown={isFocusable ? onKeyDown : undefined}
tabIndex={disableKeyboardA11y ? undefined : 0} tabIndex={isFocusable ? 0 : undefined}
role={disableKeyboardA11y ? undefined : 'button'} role={isFocusable ? 'button' : undefined}
aria-describedby={disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`} aria-describedby={disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`}
aria-label={ariaLabel} aria-label={ariaLabel}
> >
@@ -18,6 +18,8 @@ type StoreUpdaterProps = Pick<
| 'onClickConnectEnd' | 'onClickConnectEnd'
| 'nodesDraggable' | 'nodesDraggable'
| 'nodesConnectable' | 'nodesConnectable'
| 'nodesFocusable'
| 'edgesFocusable'
| 'minZoom' | 'minZoom'
| 'maxZoom' | 'maxZoom'
| 'nodeExtent' | 'nodeExtent'
@@ -89,6 +91,8 @@ const StoreUpdater = ({
onClickConnectEnd, onClickConnectEnd,
nodesDraggable, nodesDraggable,
nodesConnectable, nodesConnectable,
nodesFocusable,
edgesFocusable,
minZoom, minZoom,
maxZoom, maxZoom,
nodeExtent, nodeExtent,
@@ -145,6 +149,8 @@ const StoreUpdater = ({
useDirectStoreUpdater('onClickConnectEnd', onClickConnectEnd, store.setState); useDirectStoreUpdater('onClickConnectEnd', onClickConnectEnd, store.setState);
useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState); useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState);
useDirectStoreUpdater('nodesConnectable', nodesConnectable, store.setState); useDirectStoreUpdater('nodesConnectable', nodesConnectable, store.setState);
useDirectStoreUpdater('nodesFocusable', nodesFocusable, store.setState);
useDirectStoreUpdater('edgesFocusable', edgesFocusable, store.setState);
useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState); useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState);
useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState); useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState);
useDirectStoreUpdater('snapGrid', snapGrid, store.setState); useDirectStoreUpdater('snapGrid', snapGrid, store.setState);
@@ -46,6 +46,7 @@ const selector = (s: ReactFlowState) => ({
connectionNodeId: s.connectionNodeId, connectionNodeId: s.connectionNodeId,
connectionHandleType: s.connectionHandleType, connectionHandleType: s.connectionHandleType,
nodesConnectable: s.nodesConnectable, nodesConnectable: s.nodesConnectable,
edgesFocusable: s.edgesFocusable,
elementsSelectable: s.elementsSelectable, elementsSelectable: s.elementsSelectable,
width: s.width, width: s.width,
height: s.height, height: s.height,
@@ -58,6 +59,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
connectionNodeId, connectionNodeId,
connectionHandleType, connectionHandleType,
nodesConnectable, nodesConnectable,
edgesFocusable,
elementsSelectable, elementsSelectable,
width, width,
height, height,
@@ -119,6 +121,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
const targetHandle = getHandle(targetNodeHandles!, edge.targetHandle || null); const targetHandle = getHandle(targetNodeHandles!, edge.targetHandle || null);
const sourcePosition = sourceHandle?.position || Position.Bottom; const sourcePosition = sourceHandle?.position || Position.Bottom;
const targetPosition = targetHandle?.position || Position.Top; const targetPosition = targetHandle?.position || Position.Top;
const isFocusable = !!(edge.focusable || (edgesFocusable && typeof edge.focusable === 'undefined'));
if (!sourceHandle || !targetHandle) { if (!sourceHandle || !targetHandle) {
devWarn( devWarn(
@@ -181,7 +184,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
onEdgeUpdateEnd={props.onEdgeUpdateEnd} onEdgeUpdateEnd={props.onEdgeUpdateEnd}
rfId={props.rfId} rfId={props.rfId}
ariaLabel={edge.ariaLabel} ariaLabel={edge.ariaLabel}
disableKeyboardA11y={props.disableKeyboardA11y} isFocusable={isFocusable}
pathOptions={'pathOptions' in edge ? edge.pathOptions : undefined} pathOptions={'pathOptions' in edge ? edge.pathOptions : undefined}
interactionWidth={edge.interactionWidth} interactionWidth={edge.interactionWidth}
/> />
@@ -31,12 +31,16 @@ type NodeRendererProps = Pick<
const selector = (s: ReactFlowState) => ({ const selector = (s: ReactFlowState) => ({
nodesDraggable: s.nodesDraggable, nodesDraggable: s.nodesDraggable,
nodesConnectable: s.nodesConnectable, nodesConnectable: s.nodesConnectable,
nodesFocusable: s.nodesFocusable,
elementsSelectable: s.elementsSelectable, elementsSelectable: s.elementsSelectable,
updateNodeDimensions: s.updateNodeDimensions, updateNodeDimensions: s.updateNodeDimensions,
}); });
const NodeRenderer = (props: NodeRendererProps) => { const NodeRenderer = (props: NodeRendererProps) => {
const { nodesDraggable, nodesConnectable, elementsSelectable, updateNodeDimensions } = useStore(selector, shallow); const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, updateNodeDimensions } = useStore(
selector,
shallow
);
const nodes = useVisibleNodes(props.onlyRenderVisibleElements); const nodes = useVisibleNodes(props.onlyRenderVisibleElements);
const resizeObserverRef = useRef<ResizeObserver>(); const resizeObserverRef = useRef<ResizeObserver>();
@@ -82,6 +86,8 @@ const NodeRenderer = (props: NodeRendererProps) => {
const isDraggable = !!(node.draggable || (nodesDraggable && typeof node.draggable === 'undefined')); const isDraggable = !!(node.draggable || (nodesDraggable && typeof node.draggable === 'undefined'));
const isSelectable = !!(node.selectable || (elementsSelectable && typeof node.selectable === 'undefined')); const isSelectable = !!(node.selectable || (elementsSelectable && typeof node.selectable === 'undefined'));
const isConnectable = !!(node.connectable || (nodesConnectable && typeof node.connectable === 'undefined')); const isConnectable = !!(node.connectable || (nodesConnectable && typeof node.connectable === 'undefined'));
const isFocusable = !!(node.focusable || (nodesFocusable && typeof node.focusable === 'undefined'));
const clampedPosition = props.nodeExtent const clampedPosition = props.nodeExtent
? clampPosition(node.positionAbsolute, props.nodeExtent) ? clampPosition(node.positionAbsolute, props.nodeExtent)
: node.positionAbsolute; : node.positionAbsolute;
@@ -122,6 +128,7 @@ const NodeRenderer = (props: NodeRendererProps) => {
isDraggable={isDraggable} isDraggable={isDraggable}
isSelectable={isSelectable} isSelectable={isSelectable}
isConnectable={isConnectable} isConnectable={isConnectable}
isFocusable={isFocusable}
resizeObserver={resizeObserver} resizeObserver={resizeObserver}
dragHandle={node.dragHandle} dragHandle={node.dragHandle}
zIndex={node[internalsSymbol]?.z ?? 0} zIndex={node[internalsSymbol]?.z ?? 0}
@@ -108,7 +108,9 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
selectNodesOnDrag = true, selectNodesOnDrag = true,
nodesDraggable, nodesDraggable,
nodesConnectable, nodesConnectable,
nodesFocusable,
nodeOrigin = initNodeOrigin, nodeOrigin = initNodeOrigin,
edgesFocusable,
elementsSelectable, elementsSelectable,
defaultViewport = initDefaultViewport, defaultViewport = initDefaultViewport,
minZoom = 0.5, minZoom = 0.5,
@@ -245,6 +247,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
onClickConnectEnd={onClickConnectEnd} onClickConnectEnd={onClickConnectEnd}
nodesDraggable={nodesDraggable} nodesDraggable={nodesDraggable}
nodesConnectable={nodesConnectable} nodesConnectable={nodesConnectable}
nodesFocusable={nodesFocusable}
edgesFocusable={edgesFocusable}
elementsSelectable={elementsSelectable} elementsSelectable={elementsSelectable}
minZoom={minZoom} minZoom={minZoom}
maxZoom={maxZoom} maxZoom={maxZoom}
@@ -9,17 +9,19 @@ function useUpdateNodePositions() {
const store = useStoreApi(); const store = useStoreApi();
const updatePositions = useCallback((positionDiff: XYPosition) => { const updatePositions = useCallback((positionDiff: XYPosition) => {
const { nodeInternals, nodeExtent, updateNodePositions } = store.getState(); const { nodeInternals, nodeExtent, updateNodePositions, snapToGrid, snapGrid } = store.getState();
const selectedNodes = Array.from(nodeInternals.values()).filter((n) => n.selected); const selectedNodes = Array.from(nodeInternals.values()).filter((n) => n.selected);
const nodeUpdates = selectedNodes.map((n) => { const nodeUpdates = selectedNodes.map((n) => {
if (n.positionAbsolute) { if (n.positionAbsolute) {
const updatedPos = calcNextPosition( const nextPosition = { x: n.positionAbsolute.x + positionDiff.x, y: n.positionAbsolute.y + positionDiff.y };
n,
{ x: n.positionAbsolute.x + positionDiff.x, y: n.positionAbsolute.y + positionDiff.y }, if (snapToGrid) {
nodeInternals, nextPosition.x = snapGrid[0] * Math.round(nextPosition.x / snapGrid[0]);
nodeExtent nextPosition.y = snapGrid[1] * Math.round(nextPosition.y / snapGrid[1]);
); }
const updatedPos = calcNextPosition(n, nextPosition, nodeInternals, nodeExtent);
n.position = updatedPos.position; n.position = updatedPos.position;
n.positionAbsolute = updatedPos.positionAbsolute; n.positionAbsolute = updatedPos.positionAbsolute;
+2
View File
@@ -40,6 +40,8 @@ const initialState: ReactFlowStore = {
nodesDraggable: true, nodesDraggable: true,
nodesConnectable: true, nodesConnectable: true,
nodesFocusable: true,
edgesFocusable: true,
elementsSelectable: true, elementsSelectable: true,
fitViewOnInit: false, fitViewOnInit: false,
fitViewOnInitDone: false, fitViewOnInitDone: false,
@@ -92,7 +92,9 @@ export interface ReactFlowProps extends HTMLAttributes<HTMLDivElement> {
onlyRenderVisibleElements?: boolean; onlyRenderVisibleElements?: boolean;
nodesDraggable?: boolean; nodesDraggable?: boolean;
nodesConnectable?: boolean; nodesConnectable?: boolean;
nodesFocusable?: boolean;
nodeOrigin?: NodeOrigin; nodeOrigin?: NodeOrigin;
edgesFocusable?: boolean;
initNodeOrigin?: NodeOrigin; initNodeOrigin?: NodeOrigin;
elementsSelectable?: boolean; elementsSelectable?: boolean;
selectNodesOnDrag?: boolean; selectNodesOnDrag?: boolean;
+2 -1
View File
@@ -33,6 +33,7 @@ type DefaultEdge<T = any> = {
zIndex?: number; zIndex?: number;
ariaLabel?: string; ariaLabel?: string;
interactionWidth?: number; interactionWidth?: number;
focusable?: boolean;
}; };
export type SmoothStepPathOptions = { export type SmoothStepPathOptions = {
@@ -132,7 +133,7 @@ export type WrapEdgeProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHandl
onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge, handleType: HandleType) => void; onEdgeUpdateStart?: (event: React.MouseEvent, edge: Edge, handleType: HandleType) => void;
onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge, handleType: HandleType) => void; onEdgeUpdateEnd?: (event: MouseEvent, edge: Edge, handleType: HandleType) => void;
rfId?: string; rfId?: string;
disableKeyboardA11y: boolean; isFocusable: boolean;
pathOptions?: BezierPathOptions | SmoothStepPathOptions; pathOptions?: BezierPathOptions | SmoothStepPathOptions;
}; };
+2
View File
@@ -167,6 +167,8 @@ export type ReactFlowStore = {
nodesDraggable: boolean; nodesDraggable: boolean;
nodesConnectable: boolean; nodesConnectable: boolean;
nodesFocusable: boolean;
edgesFocusable: boolean;
elementsSelectable: boolean; elementsSelectable: boolean;
multiSelectionActive: boolean; multiSelectionActive: boolean;
+2
View File
@@ -31,6 +31,7 @@ export interface Node<T = any> {
expandParent?: boolean; expandParent?: boolean;
positionAbsolute?: XYPosition; positionAbsolute?: XYPosition;
ariaLabel?: string; ariaLabel?: string;
focusable?: boolean;
// only used internally // only used internally
[internalsSymbol]?: { [internalsSymbol]?: {
@@ -73,6 +74,7 @@ export interface WrapNodeProps<T = any> {
initialized: boolean; initialized: boolean;
isSelectable: boolean; isSelectable: boolean;
isDraggable: boolean; isDraggable: boolean;
isFocusable: boolean;
selectNodesOnDrag: boolean; selectNodesOnDrag: boolean;
onClick?: NodeMouseHandler; onClick?: NodeMouseHandler;
onDoubleClick?: NodeMouseHandler; onDoubleClick?: NodeMouseHandler;
+7 -1
View File
@@ -1,5 +1,12 @@
# @reactflow/minimap # @reactflow/minimap
## 11.0.1
### Patch Changes
- Updated dependencies [[`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab), [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4)]:
- @reactflow/core@11.1.0
## 11.0.0 ## 11.0.0
### Major Changes ### Major Changes
@@ -29,7 +36,6 @@
- @reactflow/controls - @reactflow/controls
- @reactflow/minimap - @reactflow/minimap
### Patch Changes ### Patch Changes
- Updated dependencies: - Updated dependencies:
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@reactflow/minimap", "name": "@reactflow/minimap",
"version": "11.0.0", "version": "11.0.1",
"description": "Minimap component for React Flow.", "description": "Minimap component for React Flow.",
"keywords": [ "keywords": [
"react", "react",
+17 -1
View File
@@ -1,9 +1,25 @@
# reactflow # reactflow
## 11.1.0
### Minor Changes
- [`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab) Thanks [@moklick](https://github.com/moklick)! - New props: nodesFocusable and edgesFocusable
### Patch Changes
- [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4) Thanks [@moklick](https://github.com/moklick)! - Make nopan class name overwritable with class name option
- Updated dependencies [[`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab), [`def11008`](https://github.com/wbkd/react-flow/commit/def11008d88749fec40e6fcba8bc41eea2511bab), [`d00faa6b`](https://github.com/wbkd/react-flow/commit/d00faa6b3e77388bfd655d4c02e9a5375bc515e4)]:
- @reactflow/background@11.0.1
- @reactflow/core@11.1.0
- @reactflow/controls@11.0.1
- @reactflow/minimap@11.0.1
## 11.0.0 ## 11.0.0
Finally it's here! A new version that comes with lots of improvements and the new package name `reactflow`. Finally it's here! A new version that comes with lots of improvements and the new package name `reactflow`.
From now on you can install it via `npm install reactflow`. From now on you can install it via `npm install reactflow`.
## Major Changes ## Major Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "reactflow", "name": "reactflow",
"version": "11.0.0", "version": "11.1.0",
"description": "A highly customizable React library for building node-based editors and interactive flow charts", "description": "A highly customizable React library for building node-based editors and interactive flow charts",
"keywords": [ "keywords": [
"react", "react",