refactor(styling): use css for default styles (#259)

* refactor(minimap): use css for default styles

* refactor(controls): use css for default styles

* refactor(background): use css for default styles

* refactor(edges): add edge type class name

* refactor(nodes): use css for default styles

* refactor(outputnode): add display name

* refactor(wrapnode): cleanup

* refactor(rollup): minimize css for prod build

* refactor(additional-comps): extract css

* test(graphs): adjust for new markup
This commit is contained in:
Moritz
2020-05-29 18:33:29 +02:00
committed by GitHub
parent f2313916b6
commit 714c916121
24 changed files with 131 additions and 143 deletions
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="m376,187l-20,0l0,-40c0,-55 -45,-100 -100,-100c-54.002,23.996 -17.999,27.998 4,31.998c21.999,4 58.002,33.998 58.002,68.002l-0.002,0l0,40l-182,0c-22.002,0 -40,17.998 -40,40l0,200c0,22.002 17.998,40 40,40l240,0c22.002,0 40,-17.998 40,-40l0,-200c0,-22.002 -17.998,-40 -40,-40zm-120,182c-22.002,0 -40,-17.998 -40,-40s17.998,-40 40,-40s40,17.998 40,40s-17.998,40 -40,40z"/></svg> <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m376 187h-20v-40c0-55-45-100-100-100-54.002 23.996-17.999 27.998 4 31.998s58.002 33.998 58.002 68.002h-.002v40h-182c-22.002 0-40 17.998-40 40v200c0 22.002 17.998 40 40 40h240c22.002 0 40-17.998 40-40v-200c0-22.002-17.998-40-40-40zm-120 182c-22.002 0-40-17.998-40-40s17.998-40 40-40 40 17.998 40 40-17.998 40-40 40z"/></svg>

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 394 B

+1 -1
View File
@@ -6,7 +6,7 @@ describe('Basic Graph Rendering', () => {
cy.get('.react-flow-basic-example'); // check if className prop works cy.get('.react-flow-basic-example'); // check if className prop works
cy.get('.react-flow__node').should('have.length', 4); cy.get('.react-flow__node').should('have.length', 4);
cy.get('.react-flow__edge').should('have.length', 2); cy.get('.react-flow__edge').should('have.length', 2);
cy.get('.react-flow__node').children('div').children('.react-flow__handle'); cy.get('.react-flow__node').children('.react-flow__handle');
}); });
it('renders a grid', () => { it('renders a grid', () => {
+1 -1
View File
@@ -5,7 +5,7 @@ describe('Inactive Graph Rendering', () => {
cy.get('.react-flow__renderer'); cy.get('.react-flow__renderer');
cy.get('.react-flow__node').should('have.length', 4); cy.get('.react-flow__node').should('have.length', 4);
cy.get('.react-flow__edge').should('have.length', 2); cy.get('.react-flow__edge').should('have.length', 2);
cy.get('.react-flow__node').children('div').children('.react-flow__handle'); cy.get('.react-flow__node').children('.react-flow__handle');
}); });
it('tries to select a node by click', () => { it('tries to select a node by click', () => {
+3 -5
View File
@@ -2,11 +2,9 @@ import React from 'react';
import { Handle } from 'react-flow-renderer'; import { Handle } from 'react-flow-renderer';
export default ({ data, styles }) => { export default ({ data }) => {
return ( return (
<div <>
style={{ background: '#eee', border: '1px solid #ddd', padding: 10, borderRadius: 5, ...styles }}
>
<Handle <Handle
type="target" type="target"
position="left" position="left"
@@ -27,6 +25,6 @@ export default ({ data, styles }) => {
id="b" id="b"
style={{ bottom: 10, top: 'auto', background: '#fff' }} style={{ bottom: 10, top: 'auto', background: '#fff' }}
/> />
</div> </>
); );
}; };
+1 -1
View File
@@ -37,7 +37,7 @@ const CustomNodeFlow = () => {
setElements([ setElements([
{ id: '1', type: 'input', data: { label: 'An input node' }, position: { x: 0, y: 50 }, sourcePosition: 'right' }, { id: '1', type: 'input', data: { label: 'An input node' }, position: { x: 0, y: 50 }, sourcePosition: 'right' },
{ id: '2', type: 'selectorNode', data: { onChange: onChange, color: initBgColor }, position: { x: 250, y: 50 } }, { id: '2', type: 'selectorNode', data: { onChange: onChange, color: initBgColor }, style: { border: '1px solid #777' }, position: { x: 250, y: 50 } },
{ id: '3', type: 'output', data: { label: 'Output A' }, position: { x: 550, y: 25 }, targetPosition: 'left' }, { id: '3', type: 'output', data: { label: 'Output A' }, position: { x: 550, y: 25 }, targetPosition: 'left' },
{ id: '4', type: 'output', data: { label: 'Output B' }, position: { x: 550, y: 100 }, targetPosition: 'left' }, { id: '4', type: 'output', data: { label: 'Output B' }, position: { x: 550, y: 100 }, targetPosition: 'left' },
+3 -3
View File
@@ -136,9 +136,9 @@ nav a.active:before {
color: #111; color: #111;
} }
.dark-node>div { .dark-node {
background: #333 !important; background: #333;
color: #f8f8f8 !important; color: #f8f8f8;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
+3 -1
View File
@@ -37,7 +37,9 @@ export default [
], ],
plugins: [ plugins: [
bundleSize(), bundleSize(),
postcss(), postcss({
minimize: isProd,
}),
babel({ babel({
exclude: 'node_modules/**', exclude: 'node_modules/**',
}), }),
@@ -1,10 +1,12 @@
import React, { memo, HTMLAttributes, CSSProperties } from 'react'; import React, { memo, HTMLAttributes } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { useStoreState } from '../../store/hooks'; import { useStoreState } from '../../store/hooks';
import { BackgroundVariant } from '../../types'; import { BackgroundVariant } from '../../types';
import { createGridLinesPath, createGridDotsPath } from './utils'; import { createGridLinesPath, createGridDotsPath } from './utils';
import './style.css';
interface BackgroundProps extends HTMLAttributes<SVGElement> { interface BackgroundProps extends HTMLAttributes<SVGElement> {
variant?: BackgroundVariant; variant?: BackgroundVariant;
gap?: number; gap?: number;
@@ -12,19 +14,13 @@ interface BackgroundProps extends HTMLAttributes<SVGElement> {
size?: number; size?: number;
} }
const baseStyles: CSSProperties = {
position: 'absolute',
top: 0,
left: 0,
};
const defaultColors = { const defaultColors = {
[BackgroundVariant.Dots]: '#999', [BackgroundVariant.Dots]: '#999',
[BackgroundVariant.Lines]: '#eee', [BackgroundVariant.Lines]: '#eee',
}; };
const Background = memo( const Background = memo(
({ variant = BackgroundVariant.Dots, gap = 24, size = 0.5, color, style = {}, className = '' }: BackgroundProps) => { ({ variant = BackgroundVariant.Dots, gap = 24, size = 0.5, color, style, className }: BackgroundProps) => {
const width = useStoreState((s) => s.width); const width = useStoreState((s) => s.width);
const height = useStoreState((s) => s.height); const height = useStoreState((s) => s.height);
const [x, y, scale] = useStoreState((s) => s.transform); const [x, y, scale] = useStoreState((s) => s.transform);
@@ -42,7 +38,7 @@ const Background = memo(
const stroke = isLines ? bgColor : 'none'; const stroke = isLines ? bgColor : 'none';
return ( return (
<svg width={width} height={height} style={{ ...baseStyles, ...style }} className={bgClasses}> <svg width={width} height={height} style={style} className={bgClasses}>
<path fill={fill} stroke={stroke} strokeWidth={size} d={path} /> <path fill={fill} stroke={stroke} strokeWidth={size} d={path} />
</svg> </svg>
); );
@@ -0,0 +1,5 @@
.react-flow__background {
position: absolute;
top: 0;
left: 0;
}
+4 -15
View File
@@ -1,4 +1,4 @@
import React, { CSSProperties } from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { fitView, zoomIn, zoomOut } from '../../utils/graph'; import { fitView, zoomIn, zoomOut } from '../../utils/graph';
@@ -10,12 +10,7 @@ import FitviewIcon from '../../../assets/icons/fitview.svg';
import LockIcon from '../../../assets/icons/lock.svg'; import LockIcon from '../../../assets/icons/lock.svg';
import UnlockIcon from '../../../assets/icons/unlock.svg'; import UnlockIcon from '../../../assets/icons/unlock.svg';
const baseStyle: CSSProperties = { import './style.css';
position: 'absolute',
zIndex: 5,
bottom: 10,
left: 10,
};
interface ControlProps extends React.HTMLAttributes<HTMLDivElement> { interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
showZoom?: boolean; showZoom?: boolean;
@@ -26,16 +21,10 @@ interface ControlProps extends React.HTMLAttributes<HTMLDivElement> {
const Controls = ({ style, showZoom = true, showFitView = true, showInteractive = true, className }: ControlProps) => { const Controls = ({ style, showZoom = true, showFitView = true, showInteractive = true, className }: ControlProps) => {
const setInteractive = useStoreActions((actions) => actions.setInteractive); const setInteractive = useStoreActions((actions) => actions.setInteractive);
const isInteractive = useStoreState((s) => s.isInteractive); const isInteractive = useStoreState((s) => s.isInteractive);
const mapClasses: string = classnames('react-flow__controls', className); const mapClasses = classnames('react-flow__controls', className);
return ( return (
<div <div className={mapClasses} style={style}>
className={mapClasses}
style={{
...baseStyle,
...style,
}}
>
{showZoom && ( {showZoom && (
<> <>
<div className="react-flow__controls-button react-flow__controls-zoomin" onClick={zoomIn}> <div className="react-flow__controls-button react-flow__controls-zoomin" onClick={zoomIn}>
@@ -0,0 +1,28 @@
.react-flow__controls {
position: absolute;
z-index: 5;
bottom: 10px;
left: 10px;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);
&-button {
background: #fefefe;
border-bottom: 1px solid #eee;
display: flex;
justify-content: center;
align-items: center;
width: 16px;
height: 16px;
cursor: pointer;
user-select: none;
padding: 5px;
svg {
width: 100%;
}
&:hover {
background: #f4f4f4;
}
}
}
@@ -16,6 +16,7 @@ const MiniMapNode = ({ node, color, borderRadius }: MiniMapNodeProps) => {
} = node.__rg; } = node.__rg;
const { background, backgroundColor } = node.style || {}; const { background, backgroundColor } = node.style || {};
const fill = (background || backgroundColor || color) as string; const fill = (background || backgroundColor || color) as string;
return ( return (
<rect <rect
className="react-flow__minimap-node" className="react-flow__minimap-node"
+8 -20
View File
@@ -1,4 +1,4 @@
import React, { CSSProperties } from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { useStoreState } from '../../store/hooks'; import { useStoreState } from '../../store/hooks';
@@ -6,6 +6,8 @@ import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
import { Node, Rect } from '../../types'; import { Node, Rect } from '../../types';
import MiniMapNode from './MiniMapNode'; import MiniMapNode from './MiniMapNode';
import './style.css';
type StringFunc = (node: Node) => string; type StringFunc = (node: Node) => string;
interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> { interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
@@ -14,14 +16,8 @@ interface MiniMapProps extends React.HTMLAttributes<SVGSVGElement> {
maskColor?: string; maskColor?: string;
} }
const baseStyle: CSSProperties = { const defaultWidth = 200;
position: 'absolute', const defaultHeight = 150;
zIndex: 5,
bottom: 10,
right: 10,
width: 200,
height: 150,
};
const MiniMap = ({ const MiniMap = ({
style = { backgroundColor: '#f8f8f8' }, style = { backgroundColor: '#f8f8f8' },
@@ -36,11 +32,10 @@ const MiniMap = ({
const nodes = useStoreState((s) => s.nodes); const nodes = useStoreState((s) => s.nodes);
const mapClasses = classnames('react-flow__minimap', className); const mapClasses = classnames('react-flow__minimap', className);
const elementWidth = (style.width || baseStyle.width)! as number; const elementWidth = (style.width || defaultWidth)! as number;
const elementHeight = (style.height || baseStyle.height)! as number; const elementHeight = (style.height || defaultHeight)! as number;
const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc; const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc;
const hasNodes = nodes && nodes.length; const hasNodes = nodes && nodes.length;
const bb = getRectOfNodes(nodes); const bb = getRectOfNodes(nodes);
const viewBB: Rect = { const viewBB: Rect = {
x: -tX / tScale, x: -tX / tScale,
@@ -48,17 +43,13 @@ const MiniMap = ({
width: containerWidth / tScale, width: containerWidth / tScale,
height: containerHeight / tScale, height: containerHeight / tScale,
}; };
const boundingRect = hasNodes ? getBoundsofRects(bb, viewBB) : viewBB; const boundingRect = hasNodes ? getBoundsofRects(bb, viewBB) : viewBB;
const scaledWidth = boundingRect.width / elementWidth; const scaledWidth = boundingRect.width / elementWidth;
const scaledHeight = boundingRect.height / elementHeight; const scaledHeight = boundingRect.height / elementHeight;
const viewScale = Math.max(scaledWidth, scaledHeight); const viewScale = Math.max(scaledWidth, scaledHeight);
const viewWidth = viewScale * elementWidth; const viewWidth = viewScale * elementWidth;
const viewHeight = viewScale * elementHeight; const viewHeight = viewScale * elementHeight;
const offset = 5 * viewScale; const offset = 5 * viewScale;
const x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset; const x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset;
const y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset; const y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset;
const width = viewWidth + offset * 2; const width = viewWidth + offset * 2;
@@ -69,10 +60,7 @@ const MiniMap = ({
width={elementWidth} width={elementWidth}
height={elementHeight} height={elementHeight}
viewBox={`${x} ${y} ${width} ${height}`} viewBox={`${x} ${y} ${width} ${height}`}
style={{ style={style}
...baseStyle,
...style,
}}
className={mapClasses} className={mapClasses}
> >
{nodes.map((node) => ( {nodes.map((node) => (
@@ -0,0 +1,6 @@
.react-flow__minimap {
position: absolute;
z-index: 5;
bottom: 10px;
right: 10px;
}
+1 -1
View File
@@ -15,7 +15,7 @@ export default memo(
labelStyle, labelStyle,
labelShowBg, labelShowBg,
labelBgStyle, labelBgStyle,
style = {}, style,
}: EdgeBezierProps) => { }: EdgeBezierProps) => {
const yOffset = Math.abs(targetY - sourceY) / 2; const yOffset = Math.abs(targetY - sourceY) / 2;
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
+1 -1
View File
@@ -4,7 +4,7 @@ import EdgeText from './EdgeText';
import { EdgeProps } from '../../types'; import { EdgeProps } from '../../types';
export default memo( export default memo(
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style = {} }: EdgeProps) => { ({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => {
const yOffset = Math.abs(targetY - sourceY) / 2; const yOffset = Math.abs(targetY - sourceY) / 2;
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
+1 -1
View File
@@ -4,7 +4,7 @@ import EdgeText from './EdgeText';
import { EdgeProps } from '../../types'; import { EdgeProps } from '../../types';
export default memo( export default memo(
({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style = {} }: EdgeProps) => { ({ sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, style }: EdgeProps) => {
const yOffset = Math.abs(targetY - sourceY) / 2; const yOffset = Math.abs(targetY - sourceY) / 2;
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset; const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
+4 -2
View File
@@ -13,8 +13,9 @@ interface EdgeWrapperProps {
labelStyle?: CSSProperties; labelStyle?: CSSProperties;
labelShowBg?: boolean; labelShowBg?: boolean;
labelBgStyle: CSSProperties; labelBgStyle: CSSProperties;
className?: string;
onClick?: (edge: Edge) => void; onClick?: (edge: Edge) => void;
animated: boolean; animated?: boolean;
selected: boolean; selected: boolean;
isInteractive: boolean; isInteractive: boolean;
} }
@@ -34,9 +35,10 @@ export default (EdgeComponent: ComponentType<EdgeCompProps>) => {
labelStyle, labelStyle,
labelShowBg, labelShowBg,
labelBgStyle, labelBgStyle,
className,
...rest ...rest
}: EdgeWrapperProps) => { }: EdgeWrapperProps) => {
const edgeClasses = cx('react-flow__edge', { selected, animated }); const edgeClasses = cx('react-flow__edge', `react-flow__edge-${type}`, className, { selected, animated });
const edgeGroupStyle: CSSProperties = { const edgeGroupStyle: CSSProperties = {
pointerEvents: isInteractive ? 'all' : 'none', pointerEvents: isInteractive ? 'all' : 'none',
}; };
+8 -11
View File
@@ -1,19 +1,16 @@
import React, { CSSProperties } from 'react'; import React from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps, Position } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const DefaultNode = ({ data, targetPosition = Position.Top, sourcePosition = Position.Bottom }: NodeProps) => (
background: '#ff6060', <>
padding: 10,
borderRadius: 5,
width: 150,
};
export default ({ data, targetPosition = Position.Top, sourcePosition = Position.Bottom, style }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}>
<Handle type="target" position={targetPosition} /> <Handle type="target" position={targetPosition} />
{data.label} {data.label}
<Handle type="source" position={sourcePosition} /> <Handle type="source" position={sourcePosition} />
</div> </>
); );
DefaultNode.displayName = 'DefaultNode';
export default DefaultNode;
+8 -11
View File
@@ -1,18 +1,15 @@
import React, { CSSProperties } from 'react'; import React from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps, Position } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const InputNode = ({ data, sourcePosition = Position.Bottom }: NodeProps) => (
background: '#9999ff', <>
padding: 10,
borderRadius: 5,
width: 150,
};
export default ({ data, style, sourcePosition = Position.Bottom }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}>
{data.label} {data.label}
<Handle type="source" position={sourcePosition} /> <Handle type="source" position={sourcePosition} />
</div> </>
); );
InputNode.displayName = 'InputNode';
export default InputNode;
+8 -11
View File
@@ -1,18 +1,15 @@
import React, { CSSProperties } from 'react'; import React from 'react';
import Handle from '../../components/Handle'; import Handle from '../../components/Handle';
import { NodeProps, Position } from '../../types'; import { NodeProps, Position } from '../../types';
const nodeStyles: CSSProperties = { const OutputNode = ({ data, targetPosition = Position.Top }: NodeProps) => (
background: '#55dd99', <>
padding: 10,
borderRadius: 5,
width: 150,
};
export default ({ data, style, targetPosition = Position.Top }: NodeProps) => (
<div style={{ ...nodeStyles, ...style }}>
<Handle type="target" position={targetPosition} /> <Handle type="target" position={targetPosition} />
{data.label} {data.label}
</div> </>
); );
OutputNode.displayName = 'OutputNode';
export default OutputNode;
+4 -12
View File
@@ -158,23 +158,16 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
zIndex: selected ? 10 : 3, zIndex: selected ? 10 : 3,
transform: `translate(${xPos}px,${yPos}px)`, transform: `translate(${xPos}px,${yPos}px)`,
pointerEvents: isInteractive ? 'all' : 'none', pointerEvents: isInteractive ? 'all' : 'none',
}; ...style,
const updateNode = (): void => {
if (!nodeElement.current) {
return;
}
store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current });
}; };
useEffect(() => { useEffect(() => {
if (nodeElement.current) { if (nodeElement.current) {
updateNode(); store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current });
const resizeObserver = new ResizeObserver((entries) => { const resizeObserver = new ResizeObserver((entries) => {
for (let _ of entries) { for (let _ of entries) {
updateNode(); store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current! });
} }
}); });
@@ -188,7 +181,7 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
} }
return; return;
}, []); }, [id]);
return ( return (
<DraggableCore <DraggableCore
@@ -219,7 +212,6 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
id={id} id={id}
data={data} data={data}
type={type} type={type}
style={style}
selected={selected} selected={selected}
sourcePosition={sourcePosition} sourcePosition={sourcePosition}
targetPosition={targetPosition} targetPosition={targetPosition}
+25 -34
View File
@@ -60,6 +60,12 @@
} }
} }
@keyframes dashdraw {
from {
stroke-dashoffset: 10;
}
}
.react-flow__connection { .react-flow__connection {
pointer-events: none; pointer-events: none;
} }
@@ -85,12 +91,6 @@
fill: white; fill: white;
} }
@keyframes dashdraw {
from {
stroke-dashoffset: 10;
}
}
.react-flow__nodes { .react-flow__nodes {
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -110,13 +110,17 @@
pointer-events: all; pointer-events: all;
transform-origin: 0 0; transform-origin: 0 0;
cursor: grab; cursor: grab;
padding: 10px;
border-radius: 5px;
width: 150px;
background: #eee;
&.selected > *, &.selected,
&.selected:hover > * { &.selected:hover {
box-shadow: 0 0 0 2px #555; box-shadow: 0 0 0 2px #555;
} }
&:hover > * { &:hover {
box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08); box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.08);
} }
@@ -125,6 +129,18 @@
} }
} }
.react-flow__node-default {
background: #ff6060;
}
.react-flow__node-input {
background: #9999ff;
}
.react-flow__node-output {
background: #55dd99;
}
.react-flow__handle { .react-flow__handle {
position: absolute; position: absolute;
width: 10px; width: 10px;
@@ -174,28 +190,3 @@
pointer-events: all; pointer-events: all;
} }
} }
.react-flow__controls {
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);
&-button {
background: #fefefe;
border-bottom: 1px solid #eee;
display: flex;
justify-content: center;
align-items: center;
width: 16px;
height: 16px;
cursor: pointer;
user-select: none;
padding: 5px;
svg {
width: 100%;
}
&:hover {
background: #f4f4f4;
}
}
}
-1
View File
@@ -96,7 +96,6 @@ export interface NodeProps {
selected: boolean; selected: boolean;
targetPosition?: Position; targetPosition?: Position;
sourcePosition?: Position; sourcePosition?: Position;
style?: CSSProperties;
} }
export interface NodeComponentProps { export interface NodeComponentProps {