refactor(controls): disable min/max buttons when reached

This commit is contained in:
moklick
2023-05-17 10:49:38 +02:00
parent a1b94f38f0
commit eab39cf1f3
4 changed files with 49 additions and 4 deletions

View File

@@ -39,7 +39,8 @@
},
"dependencies": {
"@reactflow/core": "workspace:*",
"classcat": "^5.0.3"
"classcat": "^5.0.3",
"zustand": "^4.3.1"
},
"peerDependencies": {
"react": ">=17",
@@ -55,7 +56,9 @@
},
"rollup": {
"globals": {
"classcat": "cc"
"classcat": "cc",
"zustand": "Zustand",
"zustand/shallow": "zustandShallow"
},
"name": "ReactFlowControls"
}

View File

@@ -1,5 +1,6 @@
import { memo, useEffect, useState, type FC, type PropsWithChildren } from 'react';
import cc from 'classcat';
import { shallow } from 'zustand/shallow';
import { useStore, useStoreApi, useReactFlow, Panel, type ReactFlowState } from '@reactflow/core';
import PlusIcon from './Icons/Plus';
@@ -11,7 +12,11 @@ import ControlButton from './ControlButton';
import type { ControlProps } from './types';
const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable || s.nodesConnectable || s.elementsSelectable;
const selector = (s: ReactFlowState) => ({
isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
minZoomReached: s.transform[2] <= s.minZoom,
maxZoomReached: s.transform[2] >= s.maxZoom,
});
const Controls: FC<PropsWithChildren<ControlProps>> = ({
style,
@@ -29,7 +34,7 @@ const Controls: FC<PropsWithChildren<ControlProps>> = ({
}) => {
const store = useStoreApi();
const [isVisible, setIsVisible] = useState<boolean>(false);
const isInteractive = useStore(isInteractiveSelector);
const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector, shallow);
const { zoomIn, zoomOut, fitView } = useReactFlow();
useEffect(() => {
@@ -79,6 +84,7 @@ const Controls: FC<PropsWithChildren<ControlProps>> = ({
className="react-flow__controls-zoomin"
title="zoom in"
aria-label="zoom in"
disabled={maxZoomReached}
>
<PlusIcon />
</ControlButton>
@@ -87,6 +93,7 @@ const Controls: FC<PropsWithChildren<ControlProps>> = ({
className="react-flow__controls-zoomout"
title="zoom out"
aria-label="zoom out"
disabled={minZoomReached}
>
<MinusIcon />
</ControlButton>

View File

@@ -24,5 +24,13 @@
max-width: 12px;
max-height: 12px;
}
&:disabled {
pointer-events: none;
svg {
fill-opacity: 0.4;
}
}
}
}

27
pnpm-lock.yaml generated
View File

@@ -132,9 +132,11 @@ importers:
'@types/react': '>=17'
classcat: ^5.0.3
typescript: ^4.9.4
zustand: ^4.3.1
dependencies:
'@reactflow/core': link:../core
classcat: registry.npmjs.org/classcat/5.0.4
zustand: registry.npmjs.org/zustand/4.3.1
devDependencies:
'@reactflow/eslint-config': link:../../tooling/eslint-config
'@reactflow/rollup-config': link:../../tooling/rollup-config
@@ -7445,6 +7447,14 @@ packages:
punycode: registry.npmjs.org/punycode/2.1.1
dev: true
registry.npmjs.org/use-sync-external-store/1.2.0:
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz}
name: use-sync-external-store
version: 1.2.0
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dev: false
registry.npmjs.org/use-sync-external-store/1.2.0_react@18.2.0:
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz}
id: registry.npmjs.org/use-sync-external-store/1.2.0
@@ -7786,6 +7796,23 @@ packages:
engines: {node: '>=10'}
dev: true
registry.npmjs.org/zustand/4.3.1:
resolution: {integrity: sha512-EVyo/eLlOTcJm/X5M00rwtbYFXwRVTaRteSvhtbTZUCQFJkNfIyHPiJ6Ke68MSWzcKHpPzvqNH4gC2ZS/sbNqw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/zustand/-/zustand-4.3.1.tgz}
name: zustand
version: 4.3.1
engines: {node: '>=12.7.0'}
peerDependencies:
immer: '>=9.0'
react: '>=16.8'
peerDependenciesMeta:
immer:
optional: true
react:
optional: true
dependencies:
use-sync-external-store: registry.npmjs.org/use-sync-external-store/1.2.0
dev: false
registry.npmjs.org/zustand/4.3.1_react@18.2.0:
resolution: {integrity: sha512-EVyo/eLlOTcJm/X5M00rwtbYFXwRVTaRteSvhtbTZUCQFJkNfIyHPiJ6Ke68MSWzcKHpPzvqNH4gC2ZS/sbNqw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/zustand/-/zustand-4.3.1.tgz}
id: registry.npmjs.org/zustand/4.3.1