diff --git a/.changeset/twenty-items-invite.md b/.changeset/twenty-items-invite.md new file mode 100644 index 00000000..7252cb31 --- /dev/null +++ b/.changeset/twenty-items-invite.md @@ -0,0 +1,8 @@ +--- +'@reactflow/examples': minor +'@reactflow/core': minor +'@reactflow/minimap': minor +'reactflow': minor +--- + +Feat: Add pan and zoom to mini map diff --git a/examples/vite-app/src/App/index.tsx b/examples/vite-app/src/App/index.tsx index 90339935..25536ebb 100644 --- a/examples/vite-app/src/App/index.tsx +++ b/examples/vite-app/src/App/index.tsx @@ -36,6 +36,7 @@ import Validation from '../examples/Validation'; import UseKeyPress from '../examples/UseKeyPress'; import EdgeRouting from '../examples/EdgeRouting'; import CancelConnection from '../examples/CancelConnection'; +import InteractiveMinimap from '../examples/InteractiveMinimap'; import UseOnSelectionChange from '../examples/UseOnSelectionChange'; interface IRoute { @@ -125,6 +126,11 @@ const routes: IRoute[] = [ path: '/interaction', component: Interaction, }, + { + name: 'Interactive Minimap', + path: '/interactive-minimap', + component: InteractiveMinimap, + }, { name: 'Layouting', path: '/layouting', diff --git a/examples/vite-app/src/examples/InteractiveMinimap/index.tsx b/examples/vite-app/src/examples/InteractiveMinimap/index.tsx new file mode 100644 index 00000000..18fa854a --- /dev/null +++ b/examples/vite-app/src/examples/InteractiveMinimap/index.tsx @@ -0,0 +1,165 @@ +import { MouseEvent, useCallback } from 'react'; +import ReactFlow, { + MiniMap, + Background, + BackgroundVariant, + Controls, + ReactFlowProvider, + Node, + Edge, + useReactFlow, + XYPosition, +} from 'reactflow'; + +const onNodeDrag = (_: MouseEvent, node: Node) => console.log('drag', node); +const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node); +const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); + +const initialNodes: Node[] = [ + { + id: '1', + data: { label: 'Node 1' }, + position: { x: 0, y: 0 }, + }, + { + id: '2', + data: { label: 'Node 2' }, + position: { x: 0, y: 200 }, + }, + { + id: '3', + data: { label: 'Node 3' }, + position: { x: 200, y: 0 }, + }, + + { + id: '4', + data: { label: 'Node 4' }, + position: { x: 1000, y: 0 }, + }, + { + id: '5', + data: { label: 'Node 5' }, + position: { x: 1000, y: 200 }, + }, + { + id: '6', + data: { label: 'Node 6' }, + position: { x: 800, y: 0 }, + }, + + { + id: '7', + data: { label: 'Node 4' }, + position: { x: 0, y: 1000 }, + }, + { + id: '8', + data: { label: 'Node 5' }, + position: { x: 0, y: 800 }, + }, + { + id: '9', + data: { label: 'Node 6' }, + position: { x: 200, y: 1000 }, + }, + + { + id: '10', + data: { label: 'Node 4' }, + position: { x: 1000, y: 1000 }, + }, + { + id: '11', + data: { label: 'Node 5' }, + position: { x: 800, y: 1000 }, + }, + { + id: '12', + data: { label: 'Node 6' }, + position: { x: 1000, y: 800 }, + }, +]; + +const initialEdges: Edge[] = []; + +const defaultEdgeOptions = { zIndex: 0 }; + +const BasicFlow = () => { + const instance = useReactFlow(); + + const updatePos = () => { + instance.setNodes((nodes) => + nodes.map((node) => { + node.position = { + x: Math.random() * 400, + y: Math.random() * 400, + }; + + return node; + }) + ); + }; + + const logToObject = () => console.log(instance.toObject()); + const resetTransform = () => instance.setViewport({ x: 0, y: 0, zoom: 1 }); + + const toggleClassnames = () => { + instance.setNodes((nodes) => + nodes.map((node) => { + node.className = node.className === 'light' ? 'dark' : 'light'; + + return node; + }) + ); + }; + + const onMiniMapClick = useCallback((event: MouseEvent, pos: XYPosition) => { + console.log(pos); + }, []); + + const onMiniMapNodeClick = useCallback((event: MouseEvent, node: Node) => { + console.log(node); + }, []); + + return ( + + + + + +
+ + + + +
+
+ ); +}; + +export default function App() { + return ( + + + + ); +} diff --git a/examples/vite-app/src/examples/NestedNodes/index.tsx b/examples/vite-app/src/examples/NestedNodes/index.tsx index 5e9c80f1..a6c083ce 100644 --- a/examples/vite-app/src/examples/NestedNodes/index.tsx +++ b/examples/vite-app/src/examples/NestedNodes/index.tsx @@ -160,7 +160,7 @@ const NestedFlow = () => { maxZoom={4} onlyRenderVisibleElements={false} > - + diff --git a/packages/core/src/container/ZoomPane/index.tsx b/packages/core/src/container/ZoomPane/index.tsx index cde4ec47..a5783a7a 100644 --- a/packages/core/src/container/ZoomPane/index.tsx +++ b/packages/core/src/container/ZoomPane/index.tsx @@ -173,9 +173,12 @@ const ZoomPane = ({ useEffect(() => { if (d3Zoom) { d3Zoom.on('start', (event: D3ZoomEvent) => { + if (!event.sourceEvent) { + return null; + } + const { onViewportChangeStart } = store.getState(); isZoomingOrPanning.current = true; - if (event.sourceEvent?.type === 'mousedown') { store.setState({ paneDragging: true }); } @@ -194,6 +197,9 @@ const ZoomPane = ({ useEffect(() => { if (d3Zoom) { d3Zoom.on('end', (event: D3ZoomEvent) => { + if (!event.sourceEvent) { + return null; + } const { onViewportChangeEnd } = store.getState(); isZoomingOrPanning.current = false; diff --git a/packages/minimap/package.json b/packages/minimap/package.json index 527aab38..100a12b0 100644 --- a/packages/minimap/package.json +++ b/packages/minimap/package.json @@ -40,7 +40,11 @@ "dependencies": { "@babel/runtime": "^7.18.9", "@reactflow/core": "workspace:*", + "@types/d3-selection": "^3.0.3", + "@types/d3-zoom": "^3.0.1", "classcat": "^5.0.3", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", "zustand": "^4.1.1" }, "peerDependencies": { diff --git a/packages/minimap/src/MiniMap.tsx b/packages/minimap/src/MiniMap.tsx index 05cd8771..f2487f18 100644 --- a/packages/minimap/src/MiniMap.tsx +++ b/packages/minimap/src/MiniMap.tsx @@ -1,8 +1,13 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { memo } from 'react'; +import { memo, useEffect, useRef } from 'react'; +import type { MouseEvent } from 'react'; import cc from 'classcat'; import shallow from 'zustand/shallow'; -import { useStore, getRectOfNodes, getBoundsOfRects, Panel } from '@reactflow/core'; +import { zoom, zoomIdentity } from 'd3-zoom'; +import type { D3ZoomEvent } from 'd3-zoom'; +import { select, pointer } from 'd3-selection'; +import { useStore, getRectOfNodes, Panel, getBoundsOfRects, useStoreApi } from '@reactflow/core'; import type { ReactFlowState, Rect } from '@reactflow/core'; import MiniMapNode from './MiniMapNode'; @@ -37,14 +42,20 @@ const ARIA_LABEL_KEY = 'react-flow__minimap-desc'; function MiniMap({ style, className, - nodeStrokeColor = '#555', - nodeColor = '#fff', + nodeStrokeColor = 'transparent', + nodeColor = '#e2e2e2', nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth = 2, - maskColor = 'rgb(240, 242, 243, 0.7)', + maskColor = 'rgb(240, 240, 240, 0.6)', position = 'bottom-right', + onClick, + onNodeClick, + pannable = false, + zoomable = false, }: MiniMapProps) { + const store = useStoreApi(); + const svg = useRef(null); const { boundingRect, viewBB, nodes, rfId } = useStore(selector, shallow); const elementWidth = (style?.width as number) ?? defaultWidth; const elementHeight = (style?.height as number) ?? defaultHeight; @@ -63,6 +74,75 @@ function MiniMap({ const height = viewHeight + offset * 2; const shapeRendering = typeof window === 'undefined' || !!window.chrome ? 'crispEdges' : 'geometricPrecision'; const labelledBy = `${ARIA_LABEL_KEY}-${rfId}`; + const viewScaleRef = useRef(0); + + viewScaleRef.current = viewScale; + + useEffect(() => { + if (svg.current) { + const selection = select(svg.current as Element); + + const zoomHandler = (event: D3ZoomEvent) => { + const { transform, d3Selection, d3Zoom } = store.getState(); + + if (event.sourceEvent.type !== 'wheel' || !d3Selection || !d3Zoom) { + return; + } + + const pinchDelta = + -event.sourceEvent.deltaY * + (event.sourceEvent.deltaMode === 1 ? 0.05 : event.sourceEvent.deltaMode ? 1 : 0.002) * + 10; + const zoom = transform[2] * Math.pow(2, pinchDelta); + + d3Zoom.scaleTo(d3Selection, zoom); + }; + + const panHandler = (event: D3ZoomEvent) => { + const { transform, d3Selection, d3Zoom } = store.getState(); + + if (event.sourceEvent.type !== 'mousemove' || !d3Selection || !d3Zoom) { + return; + } + + // @TODO: how to calculate the correct next position? Math.max(1, transform[2]) is a workaround. + const position = { + x: transform[0] - event.sourceEvent.movementX * viewScaleRef.current * Math.max(1, transform[2]), + y: transform[1] - event.sourceEvent.movementY * viewScaleRef.current * Math.max(1, transform[2]), + }; + + const nextTransform = zoomIdentity.translate(position.x, position.y).scale(transform[2]); + + d3Zoom.transform(d3Selection, nextTransform); + }; + + const zoomAndPanHandler = zoom() + // @ts-ignore + .on('zoom', pannable ? panHandler : null) + // @ts-ignore + .on('zoom.wheel', zoomable ? zoomHandler : null); + + selection.call(zoomAndPanHandler); + + return () => { + selection.on('zoom', null); + }; + } + }, [pannable, zoomable]); + + const onSvgClick = onClick + ? (event: MouseEvent) => { + const rfCoord = pointer(event); + onClick(event, { x: rfCoord[0], y: rfCoord[1] }); + } + : undefined; + + const onSvgNodeClick = onNodeClick + ? (event: MouseEvent, nodeId: string) => { + const node = store.getState().nodeInternals.get(nodeId)!; + onNodeClick(event, node); + } + : undefined; return ( @@ -72,6 +152,8 @@ function MiniMap({ viewBox={`${x} ${y} ${width} ${height}`} role="img" aria-labelledby={labelledBy} + ref={svg} + onClick={onSvgClick} > React Flow mini map {nodes.map((node) => { @@ -89,6 +171,8 @@ function MiniMap({ strokeColor={nodeStrokeColorFunc(node)} strokeWidth={nodeStrokeWidth} shapeRendering={shapeRendering} + onClick={onSvgNodeClick} + id={node.id} /> ); })} diff --git a/packages/minimap/src/MiniMapNode.tsx b/packages/minimap/src/MiniMapNode.tsx index 111c7ee0..ae000d02 100644 --- a/packages/minimap/src/MiniMapNode.tsx +++ b/packages/minimap/src/MiniMapNode.tsx @@ -1,8 +1,9 @@ import { memo } from 'react'; -import type { CSSProperties } from 'react'; +import type { CSSProperties, MouseEvent } from 'react'; import cc from 'classcat'; interface MiniMapNodeProps { + id: string; x: number; y: number; width: number; @@ -14,9 +15,11 @@ interface MiniMapNodeProps { strokeColor: string; strokeWidth: number; style?: CSSProperties; + onClick?: (event: MouseEvent, id: string) => void; } const MiniMapNode = ({ + id, x, y, width, @@ -28,6 +31,7 @@ const MiniMapNode = ({ className, borderRadius, shapeRendering, + onClick, }: MiniMapNodeProps) => { const { background, backgroundColor } = style || {}; const fill = (color || background || backgroundColor) as string; @@ -45,6 +49,7 @@ const MiniMapNode = ({ stroke={strokeColor} strokeWidth={strokeWidth} shapeRendering={shapeRendering} + onClick={onClick ? (event) => onClick(event, id) : undefined} /> ); }; diff --git a/packages/minimap/src/types.ts b/packages/minimap/src/types.ts index 4fed29ba..63d8c6d9 100644 --- a/packages/minimap/src/types.ts +++ b/packages/minimap/src/types.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { HTMLAttributes } from 'react'; -import type { Node, PanelPosition } from '@reactflow/core'; +import type { HTMLAttributes, MouseEvent } from 'react'; +import type { Node, PanelPosition, XYPosition } from '@reactflow/core'; export type GetMiniMapNodeAttribute = (node: Node) => string; -export type MiniMapProps = HTMLAttributes & { +export type MiniMapProps = Omit, 'onClick'> & { nodeColor?: string | GetMiniMapNodeAttribute; nodeStrokeColor?: string | GetMiniMapNodeAttribute; nodeClassName?: string | GetMiniMapNodeAttribute; @@ -12,4 +12,8 @@ export type MiniMapProps = HTMLAttributes & { nodeStrokeWidth?: number; maskColor?: string; position?: PanelPosition; + onClick?: (event: MouseEvent, position: XYPosition) => void; + onNodeClick?: (event: MouseEvent, node: Node) => void; + pannable?: boolean; + zoomable?: boolean; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78749f21..7220fd5e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,15 +32,15 @@ importers: '@changesets/changelog-github': registry.npmjs.org/@changesets/changelog-github/0.4.7 '@changesets/cli': registry.npmjs.org/@changesets/cli/2.25.0 '@preconstruct/cli': registry.npmjs.org/@preconstruct/cli/2.2.1 - '@typescript-eslint/eslint-plugin': registry.npmjs.org/@typescript-eslint/eslint-plugin/5.39.0_jdrczqv3ll7udvbunca43w7rz4 - '@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.39.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/eslint-plugin': registry.npmjs.org/@typescript-eslint/eslint-plugin/5.42.0_dcn2ddfkdgyby36a3kmqplwxkq + '@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.42.0_irgkl5vooow2ydyo6aokmferha autoprefixer: registry.npmjs.org/autoprefixer/10.4.9_postcss@8.4.16 concurrently: registry.npmjs.org/concurrently/7.4.0 cypress: registry.npmjs.org/cypress/10.7.0 eslint: registry.npmjs.org/eslint/8.23.1 eslint-config-prettier: registry.npmjs.org/eslint-config-prettier/8.5.0_eslint@8.23.1 eslint-plugin-prettier: registry.npmjs.org/eslint-plugin-prettier/4.2.1_cabrci5exjdaojcvd6xoxgeowu - eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.31.9_eslint@8.23.1 + eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.31.10_eslint@8.23.1 postcss: registry.npmjs.org/postcss/8.4.16 postcss-cli: registry.npmjs.org/postcss-cli/10.0.0_postcss@8.4.16 postcss-combine-duplicated-selectors: registry.npmjs.org/postcss-combine-duplicated-selectors/10.0.3_postcss@8.4.16 @@ -185,16 +185,24 @@ importers: '@reactflow/eslint-config': workspace:^0.0.0 '@reactflow/rollup-config': workspace:* '@reactflow/tsconfig': workspace:* + '@types/d3-selection': ^3.0.3 + '@types/d3-zoom': ^3.0.1 '@types/node': ^18.7.16 '@types/react': ^18.0.19 classcat: ^5.0.3 + d3-selection: ^3.0.0 + d3-zoom: ^3.0.0 react: ^18.2.0 typescript: ^4.8.3 zustand: ^4.1.1 dependencies: '@babel/runtime': registry.npmjs.org/@babel/runtime/7.19.0 '@reactflow/core': link:../core + '@types/d3-selection': registry.npmjs.org/@types/d3-selection/3.0.3 + '@types/d3-zoom': registry.npmjs.org/@types/d3-zoom/3.0.1 classcat: registry.npmjs.org/classcat/5.0.4 + d3-selection: registry.npmjs.org/d3-selection/3.0.0 + d3-zoom: registry.npmjs.org/d3-zoom/3.0.0 zustand: registry.npmjs.org/zustand/4.1.1_react@18.2.0 devDependencies: '@reactflow/eslint-config': link:../../tooling/eslint-config @@ -242,7 +250,7 @@ importers: eslint: registry.npmjs.org/eslint/8.23.1 eslint-config-prettier: registry.npmjs.org/eslint-config-prettier/8.5.0_eslint@8.23.1 eslint-config-turbo: registry.npmjs.org/eslint-config-turbo/0.0.4_eslint@8.23.1 - eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.31.8_eslint@8.23.1 + eslint-plugin-react: registry.npmjs.org/eslint-plugin-react/7.31.10_eslint@8.23.1 tooling/rollup-config: specifiers: @@ -1682,6 +1690,12 @@ packages: version: 6.2.3 dev: true + registry.npmjs.org/@types/semver/7.3.13: + resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz} + name: '@types/semver' + version: 7.3.13 + dev: true + registry.npmjs.org/@types/sinonjs__fake-timers/8.1.1: resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz} name: '@types/sinonjs__fake-timers' @@ -1704,11 +1718,11 @@ packages: dev: true optional: true - registry.npmjs.org/@typescript-eslint/eslint-plugin/5.39.0_jdrczqv3ll7udvbunca43w7rz4: - resolution: {integrity: sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz} - id: registry.npmjs.org/@typescript-eslint/eslint-plugin/5.39.0 + registry.npmjs.org/@typescript-eslint/eslint-plugin/5.42.0_dcn2ddfkdgyby36a3kmqplwxkq: + resolution: {integrity: sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.0.tgz} + id: registry.npmjs.org/@typescript-eslint/eslint-plugin/5.42.0 name: '@typescript-eslint/eslint-plugin' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1718,13 +1732,14 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.39.0_irgkl5vooow2ydyo6aokmferha - '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.39.0 - '@typescript-eslint/type-utils': registry.npmjs.org/@typescript-eslint/type-utils/5.39.0_irgkl5vooow2ydyo6aokmferha - '@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.39.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/parser': registry.npmjs.org/@typescript-eslint/parser/5.42.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.42.0 + '@typescript-eslint/type-utils': registry.npmjs.org/@typescript-eslint/type-utils/5.42.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.42.0_irgkl5vooow2ydyo6aokmferha debug: registry.npmjs.org/debug/4.3.4 eslint: registry.npmjs.org/eslint/8.23.1 ignore: registry.npmjs.org/ignore/5.2.0 + natural-compare-lite: registry.npmjs.org/natural-compare-lite/1.4.0 regexpp: registry.npmjs.org/regexpp/3.2.0 semver: registry.npmjs.org/semver/7.3.8 tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.8.3 @@ -1733,11 +1748,11 @@ packages: - supports-color dev: true - registry.npmjs.org/@typescript-eslint/parser/5.39.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz} - id: registry.npmjs.org/@typescript-eslint/parser/5.39.0 + registry.npmjs.org/@typescript-eslint/parser/5.42.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.0.tgz} + id: registry.npmjs.org/@typescript-eslint/parser/5.42.0 name: '@typescript-eslint/parser' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1746,9 +1761,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.39.0 - '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.39.0 - '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.39.0_typescript@4.8.3 + '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.42.0 + '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.42.0 + '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.3 debug: registry.npmjs.org/debug/4.3.4 eslint: registry.npmjs.org/eslint/8.23.1 typescript: registry.npmjs.org/typescript/4.8.3 @@ -1756,21 +1771,21 @@ packages: - supports-color dev: true - registry.npmjs.org/@typescript-eslint/scope-manager/5.39.0: - resolution: {integrity: sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz} + registry.npmjs.org/@typescript-eslint/scope-manager/5.42.0: + resolution: {integrity: sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz} name: '@typescript-eslint/scope-manager' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.39.0 - '@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.39.0 + '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.42.0 + '@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.42.0 dev: true - registry.npmjs.org/@typescript-eslint/type-utils/5.39.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz} - id: registry.npmjs.org/@typescript-eslint/type-utils/5.39.0 + registry.npmjs.org/@typescript-eslint/type-utils/5.42.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.0.tgz} + id: registry.npmjs.org/@typescript-eslint/type-utils/5.42.0 name: '@typescript-eslint/type-utils' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1779,8 +1794,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.39.0_typescript@4.8.3 - '@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.39.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.3 + '@typescript-eslint/utils': registry.npmjs.org/@typescript-eslint/utils/5.42.0_irgkl5vooow2ydyo6aokmferha debug: registry.npmjs.org/debug/4.3.4 eslint: registry.npmjs.org/eslint/8.23.1 tsutils: registry.npmjs.org/tsutils/3.21.0_typescript@4.8.3 @@ -1789,18 +1804,18 @@ packages: - supports-color dev: true - registry.npmjs.org/@typescript-eslint/types/5.39.0: - resolution: {integrity: sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz} + registry.npmjs.org/@typescript-eslint/types/5.42.0: + resolution: {integrity: sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz} name: '@typescript-eslint/types' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - registry.npmjs.org/@typescript-eslint/typescript-estree/5.39.0_typescript@4.8.3: - resolution: {integrity: sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz} - id: registry.npmjs.org/@typescript-eslint/typescript-estree/5.39.0 + registry.npmjs.org/@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.3: + resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz} + id: registry.npmjs.org/@typescript-eslint/typescript-estree/5.42.0 name: '@typescript-eslint/typescript-estree' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -1808,8 +1823,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.39.0 - '@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.39.0 + '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.42.0 + '@typescript-eslint/visitor-keys': registry.npmjs.org/@typescript-eslint/visitor-keys/5.42.0 debug: registry.npmjs.org/debug/4.3.4 globby: registry.npmjs.org/globby/11.1.0 is-glob: registry.npmjs.org/is-glob/4.0.3 @@ -1820,34 +1835,36 @@ packages: - supports-color dev: true - registry.npmjs.org/@typescript-eslint/utils/5.39.0_irgkl5vooow2ydyo6aokmferha: - resolution: {integrity: sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz} - id: registry.npmjs.org/@typescript-eslint/utils/5.39.0 + registry.npmjs.org/@typescript-eslint/utils/5.42.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz} + id: registry.npmjs.org/@typescript-eslint/utils/5.42.0 name: '@typescript-eslint/utils' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': registry.npmjs.org/@types/json-schema/7.0.11 - '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.39.0 - '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.39.0 - '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.39.0_typescript@4.8.3 + '@types/semver': registry.npmjs.org/@types/semver/7.3.13 + '@typescript-eslint/scope-manager': registry.npmjs.org/@typescript-eslint/scope-manager/5.42.0 + '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.42.0 + '@typescript-eslint/typescript-estree': registry.npmjs.org/@typescript-eslint/typescript-estree/5.42.0_typescript@4.8.3 eslint: registry.npmjs.org/eslint/8.23.1 eslint-scope: registry.npmjs.org/eslint-scope/5.1.1 eslint-utils: registry.npmjs.org/eslint-utils/3.0.0_eslint@8.23.1 + semver: registry.npmjs.org/semver/7.3.8 transitivePeerDependencies: - supports-color - typescript dev: true - registry.npmjs.org/@typescript-eslint/visitor-keys/5.39.0: - resolution: {integrity: sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz} + registry.npmjs.org/@typescript-eslint/visitor-keys/5.42.0: + resolution: {integrity: sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz} name: '@typescript-eslint/visitor-keys' - version: 5.39.0 + version: 5.42.0 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.39.0 + '@typescript-eslint/types': registry.npmjs.org/@typescript-eslint/types/5.42.0 eslint-visitor-keys: registry.npmjs.org/eslint-visitor-keys/3.3.0 dev: true @@ -3370,37 +3387,11 @@ packages: prettier-linter-helpers: registry.npmjs.org/prettier-linter-helpers/1.0.0 dev: true - registry.npmjs.org/eslint-plugin-react/7.31.8_eslint@8.23.1: - resolution: {integrity: sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz} - id: registry.npmjs.org/eslint-plugin-react/7.31.8 + registry.npmjs.org/eslint-plugin-react/7.31.10_eslint@8.23.1: + resolution: {integrity: sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz} + id: registry.npmjs.org/eslint-plugin-react/7.31.10 name: eslint-plugin-react - version: 7.31.8 - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - array-includes: registry.npmjs.org/array-includes/3.1.5 - array.prototype.flatmap: registry.npmjs.org/array.prototype.flatmap/1.3.0 - doctrine: registry.npmjs.org/doctrine/2.1.0 - eslint: registry.npmjs.org/eslint/8.23.1 - estraverse: registry.npmjs.org/estraverse/5.3.0 - jsx-ast-utils: registry.npmjs.org/jsx-ast-utils/3.3.3 - minimatch: registry.npmjs.org/minimatch/3.1.2 - object.entries: registry.npmjs.org/object.entries/1.1.5 - object.fromentries: registry.npmjs.org/object.fromentries/2.0.5 - object.hasown: registry.npmjs.org/object.hasown/1.1.1 - object.values: registry.npmjs.org/object.values/1.1.5 - prop-types: registry.npmjs.org/prop-types/15.8.1 - resolve: registry.npmjs.org/resolve/2.0.0-next.4 - semver: registry.npmjs.org/semver/6.3.0 - string.prototype.matchall: registry.npmjs.org/string.prototype.matchall/4.0.7 - dev: true - - registry.npmjs.org/eslint-plugin-react/7.31.9_eslint@8.23.1: - resolution: {integrity: sha512-vrVJwusIw4L99lyfXjtCw8HWdloajsiYslMavogrBe2Gl8gr95TJsJnOMRasN4b4N24I3XuJf6aAV6MhyGmjqw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.9.tgz} - id: registry.npmjs.org/eslint-plugin-react/7.31.9 - name: eslint-plugin-react - version: 7.31.9 + version: 7.31.10 engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 @@ -5174,6 +5165,12 @@ packages: hasBin: true dev: true + registry.npmjs.org/natural-compare-lite/1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz} + name: natural-compare-lite + version: 1.4.0 + dev: true + registry.npmjs.org/natural-compare/1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz} name: natural-compare