M: Update GraphUI
This commit is contained in:
parent
82731be327
commit
a63af2b5cf
36
rsconcept/frontend/src/components/ui/Flow/DynamicEdge.tsx
Normal file
36
rsconcept/frontend/src/components/ui/Flow/DynamicEdge.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { EdgeProps, getStraightPath } from 'reactflow';
|
||||||
|
|
||||||
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
|
const RADIUS = PARAMETER.graphNodeRadius + PARAMETER.graphNodePadding;
|
||||||
|
|
||||||
|
function DynamicEdge({ id, markerEnd, style, ...props }: EdgeProps) {
|
||||||
|
const sourceY = props.sourceY - PARAMETER.graphNodeRadius - PARAMETER.graphHandleSize;
|
||||||
|
const targetY = props.targetY + PARAMETER.graphNodeRadius + PARAMETER.graphHandleSize;
|
||||||
|
|
||||||
|
const dx = props.targetX - props.sourceX;
|
||||||
|
const dy = targetY - sourceY;
|
||||||
|
const distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||||
|
|
||||||
|
if (distance <= 2 * RADIUS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ux = dx / distance;
|
||||||
|
const uy = dy / distance;
|
||||||
|
|
||||||
|
const [path] = getStraightPath({
|
||||||
|
sourceX: props.sourceX + ux * RADIUS,
|
||||||
|
sourceY: sourceY + uy * RADIUS,
|
||||||
|
targetX: props.targetX - ux * RADIUS,
|
||||||
|
targetY: targetY - uy * RADIUS
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<path id={id} className='react-flow__edge-path' d={path} markerEnd={markerEnd} style={style} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DynamicEdge;
|
|
@ -13,9 +13,10 @@ interface ASTFlowProps {
|
||||||
data: SyntaxTree;
|
data: SyntaxTree;
|
||||||
onNodeEnter: (node: Node) => void;
|
onNodeEnter: (node: Node) => void;
|
||||||
onNodeLeave: (node: Node) => void;
|
onNodeLeave: (node: Node) => void;
|
||||||
|
onChangeDragging: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ASTFlow({ data, onNodeEnter, onNodeLeave }: ASTFlowProps) {
|
function ASTFlow({ data, onNodeEnter, onNodeLeave, onChangeDragging }: ASTFlowProps) {
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||||
const [edges, setEdges] = useEdgesState([]);
|
const [edges, setEdges] = useEdgesState([]);
|
||||||
|
|
||||||
|
@ -59,6 +60,8 @@ function ASTFlow({ data, onNodeEnter, onNodeLeave }: ASTFlowProps) {
|
||||||
nodesFocusable={false}
|
nodesFocusable={false}
|
||||||
onNodeMouseEnter={(_, node) => onNodeEnter(node)}
|
onNodeMouseEnter={(_, node) => onNodeEnter(node)}
|
||||||
onNodeMouseLeave={(_, node) => onNodeLeave(node)}
|
onNodeMouseLeave={(_, node) => onNodeLeave(node)}
|
||||||
|
onNodeDragStart={() => onChangeDragging(true)}
|
||||||
|
onNodeDragStop={() => onChangeDragging(false)}
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
nodeTypes={ASTNodeTypes}
|
nodeTypes={ASTNodeTypes}
|
||||||
edgeTypes={ASTEdgeTypes}
|
edgeTypes={ASTEdgeTypes}
|
||||||
|
|
|
@ -25,6 +25,8 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
const handleHoverIn = useCallback((node: Node) => setHoverID(Number(node.id)), []);
|
const handleHoverIn = useCallback((node: Node) => setHoverID(Number(node.id)), []);
|
||||||
const handleHoverOut = useCallback(() => setHoverID(undefined), []);
|
const handleHoverOut = useCallback(() => setHoverID(undefined), []);
|
||||||
|
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
readonly
|
readonly
|
||||||
|
@ -37,8 +39,8 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
className='px-2 py-1 rounded-2xl cc-blur max-w-[60ch] text-lg text-center'
|
className='px-2 py-1 rounded-2xl cc-blur max-w-[60ch] text-lg text-center'
|
||||||
style={{ backgroundColor: colors.bgBlur }}
|
style={{ backgroundColor: colors.bgBlur }}
|
||||||
>
|
>
|
||||||
{!hoverNode ? expression : null}
|
{!hoverNode || isDragging ? expression : null}
|
||||||
{hoverNode ? (
|
{!isDragging && hoverNode ? (
|
||||||
<div>
|
<div>
|
||||||
<span>{expression.slice(0, hoverNode.start)}</span>
|
<span>{expression.slice(0, hoverNode.start)}</span>
|
||||||
<span className='clr-selected'>{expression.slice(hoverNode.start, hoverNode.finish)}</span>
|
<span className='clr-selected'>{expression.slice(hoverNode.start, hoverNode.finish)}</span>
|
||||||
|
@ -47,7 +49,12 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
) : null}
|
) : null}
|
||||||
</Overlay>
|
</Overlay>
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<ASTFlow data={syntaxTree} onNodeEnter={handleHoverIn} onNodeLeave={handleHoverOut} />
|
<ASTFlow
|
||||||
|
data={syntaxTree}
|
||||||
|
onNodeEnter={handleHoverIn}
|
||||||
|
onNodeLeave={handleHoverOut}
|
||||||
|
onChangeDragging={setIsDragging}
|
||||||
|
/>
|
||||||
</ReactFlowProvider>
|
</ReactFlowProvider>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
import { EdgeProps, getStraightPath } from 'reactflow';
|
|
||||||
|
|
||||||
const NODE_RADIUS = 20;
|
|
||||||
const EDGE_RADIUS = 25;
|
|
||||||
|
|
||||||
function ASTEdge({ id, markerEnd, style, ...props }: EdgeProps) {
|
|
||||||
const scale =
|
|
||||||
EDGE_RADIUS /
|
|
||||||
Math.sqrt(
|
|
||||||
Math.pow(props.sourceX - props.targetX, 2) +
|
|
||||||
Math.pow(Math.abs(props.sourceY - props.targetY) + 2 * NODE_RADIUS, 2)
|
|
||||||
);
|
|
||||||
|
|
||||||
const [path] = getStraightPath({
|
|
||||||
sourceX: props.sourceX - (props.sourceX - props.targetX) * scale,
|
|
||||||
sourceY: props.sourceY - (props.sourceY - props.targetY - 2 * NODE_RADIUS) * scale - NODE_RADIUS,
|
|
||||||
targetX: props.targetX + (props.sourceX - props.targetX) * scale,
|
|
||||||
targetY: props.targetY + (props.sourceY - props.targetY - 2 * NODE_RADIUS) * scale + NODE_RADIUS
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<path id={id} className='react-flow__edge-path' d={path} markerEnd={markerEnd} style={style} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ASTEdge;
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { EdgeTypes } from 'reactflow';
|
import { EdgeTypes } from 'reactflow';
|
||||||
|
|
||||||
import ASTEdge from './ASTEdge';
|
import DynamicEdge from '@/components/ui/Flow/DynamicEdge';
|
||||||
|
|
||||||
export const ASTEdgeTypes: EdgeTypes = {
|
export const ASTEdgeTypes: EdgeTypes = {
|
||||||
dynamic: ASTEdge
|
dynamic: DynamicEdge
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,23 +2,19 @@ import dagre from '@dagrejs/dagre';
|
||||||
import { Edge, Node } from 'reactflow';
|
import { Edge, Node } from 'reactflow';
|
||||||
|
|
||||||
import { ISyntaxTreeNode } from '@/models/rslang';
|
import { ISyntaxTreeNode } from '@/models/rslang';
|
||||||
|
import { PARAMETER } from '@/utils/constants';
|
||||||
const NODE_WIDTH = 44;
|
|
||||||
const NODE_HEIGHT = 44;
|
|
||||||
const HOR_SEPARATION = 40;
|
|
||||||
const VERT_SEPARATION = 40;
|
|
||||||
|
|
||||||
export function applyLayout(nodes: Node<ISyntaxTreeNode>[], edges: Edge[]) {
|
export function applyLayout(nodes: Node<ISyntaxTreeNode>[], edges: Edge[]) {
|
||||||
const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
|
const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
|
||||||
dagreGraph.setGraph({
|
dagreGraph.setGraph({
|
||||||
rankdir: 'TB',
|
rankdir: 'TB',
|
||||||
ranksep: VERT_SEPARATION,
|
ranksep: 40,
|
||||||
nodesep: HOR_SEPARATION,
|
nodesep: 40,
|
||||||
ranker: 'network-simplex',
|
ranker: 'network-simplex',
|
||||||
align: undefined
|
align: undefined
|
||||||
});
|
});
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
dagreGraph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT });
|
dagreGraph.setNode(node.id, { width: 2 * PARAMETER.graphNodeRadius, height: 2 * PARAMETER.graphNodeRadius });
|
||||||
});
|
});
|
||||||
|
|
||||||
edges.forEach(edge => {
|
edges.forEach(edge => {
|
||||||
|
@ -29,7 +25,7 @@ export function applyLayout(nodes: Node<ISyntaxTreeNode>[], edges: Edge[]) {
|
||||||
|
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
const nodeWithPosition = dagreGraph.node(node.id);
|
const nodeWithPosition = dagreGraph.node(node.id);
|
||||||
node.position.x = nodeWithPosition.x - NODE_WIDTH / 2;
|
node.position.x = nodeWithPosition.x - PARAMETER.graphNodeRadius;
|
||||||
node.position.y = nodeWithPosition.y - NODE_HEIGHT / 2;
|
node.position.y = nodeWithPosition.y - PARAMETER.graphNodeRadius;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ interface ASTNodeInternal {
|
||||||
id: string;
|
id: string;
|
||||||
data: ISyntaxTreeNode;
|
data: ISyntaxTreeNode;
|
||||||
dragging: boolean;
|
dragging: boolean;
|
||||||
|
selected: boolean;
|
||||||
xPos: number;
|
xPos: number;
|
||||||
yPos: number;
|
yPos: number;
|
||||||
}
|
}
|
||||||
|
@ -32,10 +33,18 @@ function ASTNode(node: ASTNodeInternal) {
|
||||||
/>
|
/>
|
||||||
<Handle type='source' position={Position.Bottom} style={{ opacity: 0 }} />
|
<Handle type='source' position={Position.Bottom} style={{ opacity: 0 }} />
|
||||||
<div
|
<div
|
||||||
className='font-math mt-1 w-fit px-1 text-center translate-x-[calc(-50%+20px)]'
|
className='font-math mt-1 w-fit text-center translate-x-[calc(-50%+20px)]'
|
||||||
style={{ backgroundColor: colors.bgDefault, fontSize: label.length > 3 ? 12 : 14 }}
|
style={{ fontSize: label.length > 3 ? 12 : 14 }}
|
||||||
>
|
>
|
||||||
{label}
|
<div className='absolute top-0 left-0 text-center w-full'>{label}</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
WebkitTextStrokeWidth: 2,
|
||||||
|
WebkitTextStrokeColor: colors.bgDefault
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -61,7 +61,9 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
const [edges, setEdges] = useEdgesState([]);
|
const [edges, setEdges] = useEdgesState([]);
|
||||||
const flow = useReactFlow();
|
const flow = useReactFlow();
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
|
const { addSelectedNodes } = store.getState();
|
||||||
|
|
||||||
|
const [showParamsDialog, setShowParamsDialog] = useState(false);
|
||||||
const [filterParams, setFilterParams] = useLocalStorage<GraphFilterParams>(storage.rsgraphFilter, {
|
const [filterParams, setFilterParams] = useLocalStorage<GraphFilterParams>(storage.rsgraphFilter, {
|
||||||
noHermits: true,
|
noHermits: true,
|
||||||
noTemplates: false,
|
noTemplates: false,
|
||||||
|
@ -81,16 +83,13 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
allowConstant: true,
|
allowConstant: true,
|
||||||
allowTheorem: true
|
allowTheorem: true
|
||||||
});
|
});
|
||||||
const [showParamsDialog, setShowParamsDialog] = useState(false);
|
|
||||||
const [focusCst, setFocusCst] = useState<IConstituenta | undefined>(undefined);
|
|
||||||
const filteredGraph = useGraphFilter(controller.schema, filterParams, focusCst);
|
|
||||||
|
|
||||||
const [hidden, setHidden] = useState<ConstituentaID[]>([]);
|
|
||||||
|
|
||||||
const [coloring, setColoring] = useLocalStorage<GraphColoring>(storage.rsgraphColoring, 'type');
|
const [coloring, setColoring] = useLocalStorage<GraphColoring>(storage.rsgraphColoring, 'type');
|
||||||
|
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [focusCst, setFocusCst] = useState<IConstituenta | undefined>(undefined);
|
||||||
|
const filteredGraph = useGraphFilter(controller.schema, filterParams, focusCst);
|
||||||
|
const [hidden, setHidden] = useState<ConstituentaID[]>([]);
|
||||||
|
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const [hoverID, setHoverID] = useState<ConstituentaID | undefined>(undefined);
|
const [hoverID, setHoverID] = useState<ConstituentaID | undefined>(undefined);
|
||||||
const hoverCst = useMemo(() => {
|
const hoverCst = useMemo(() => {
|
||||||
return hoverID && controller.schema?.cstByID.get(hoverID);
|
return hoverID && controller.schema?.cstByID.get(hoverID);
|
||||||
|
@ -100,8 +99,6 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
|
|
||||||
const [toggleResetView, setToggleResetView] = useState(false);
|
const [toggleResetView, setToggleResetView] = useState(false);
|
||||||
|
|
||||||
const { addSelectedNodes } = store.getState();
|
|
||||||
|
|
||||||
const onSelectionChange = useCallback(
|
const onSelectionChange = useCallback(
|
||||||
({ nodes }: { nodes: Node[] }) => {
|
({ nodes }: { nodes: Node[] }) => {
|
||||||
const ids = nodes.map(node => Number(node.id));
|
const ids = nodes.map(node => Number(node.id));
|
||||||
|
@ -299,6 +296,8 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
const handleNodeClick = useCallback(
|
const handleNodeClick = useCallback(
|
||||||
(event: CProps.EventMouse, cstID: ConstituentaID) => {
|
(event: CProps.EventMouse, cstID: ConstituentaID) => {
|
||||||
if (event.altKey) {
|
if (event.altKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
handleSetFocus(cstID);
|
handleSetFocus(cstID);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -445,7 +444,7 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
hideZero
|
hideZero
|
||||||
totalCount={controller.schema?.stats?.count_all ?? 0}
|
totalCount={controller.schema?.stats?.count_all ?? 0}
|
||||||
selectedCount={controller.selected.length}
|
selectedCount={controller.selected.length}
|
||||||
position='top-[4.3rem] sm:top-[2rem] left-0'
|
position='top-[4.3rem] left-0'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!isDragging && hoverCst && hoverCstDebounced && hoverCst === hoverCstDebounced ? (
|
{!isDragging && hoverCst && hoverCstDebounced && hoverCst === hoverCstDebounced ? (
|
||||||
|
@ -465,7 +464,7 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
|
||||||
</Overlay>
|
</Overlay>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Overlay position='top-[8.15rem] sm:top-[5.9rem] left-0' className='flex gap-1'>
|
<Overlay position='top-[6.15rem] sm:top-[5.9rem] left-0' className='flex gap-1'>
|
||||||
<div className='flex flex-col ml-2 w-[13.5rem]'>
|
<div className='flex flex-col ml-2 w-[13.5rem]'>
|
||||||
{selectors}
|
{selectors}
|
||||||
{viewHidden}
|
{viewHidden}
|
||||||
|
|
|
@ -87,7 +87,7 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
|
||||||
'text-sm',
|
'text-sm',
|
||||||
'cc-scroll-y'
|
'cc-scroll-y'
|
||||||
)}
|
)}
|
||||||
style={{ maxHeight: calculateHeight(windowSize.isSmall ? '12.rem + 2px' : '16.4rem + 2px') }}
|
style={{ maxHeight: calculateHeight(windowSize.isSmall ? '10.4rem + 2px' : '12.5rem + 2px') }}
|
||||||
initial={false}
|
initial={false}
|
||||||
animate={!isFolded ? 'open' : 'closed'}
|
animate={!isFolded ? 'open' : 'closed'}
|
||||||
variants={animateDropdown}
|
variants={animateDropdown}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
import { EdgeProps, getStraightPath } from 'reactflow';
|
|
||||||
|
|
||||||
import { PARAMETER } from '@/utils/constants';
|
|
||||||
|
|
||||||
function TGEdge({ id, markerEnd, style, ...props }: EdgeProps) {
|
|
||||||
const sourceY = props.sourceY - PARAMETER.graphNodeRadius;
|
|
||||||
const targetY = props.targetY + PARAMETER.graphNodeRadius;
|
|
||||||
|
|
||||||
const scale =
|
|
||||||
(PARAMETER.graphNodePadding + PARAMETER.graphNodeRadius) /
|
|
||||||
Math.sqrt(Math.pow(props.sourceX - props.targetX, 2) + Math.pow(Math.abs(sourceY - targetY), 2));
|
|
||||||
|
|
||||||
const [path] = getStraightPath({
|
|
||||||
sourceX: props.sourceX - (props.sourceX - props.targetX) * scale,
|
|
||||||
sourceY: sourceY - (sourceY - targetY) * scale,
|
|
||||||
targetX: props.targetX + (props.sourceX - props.targetX) * scale,
|
|
||||||
targetY: targetY + (sourceY - targetY) * scale
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<path id={id} className='react-flow__edge-path' d={path} markerEnd={markerEnd} style={style} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TGEdge;
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { EdgeTypes } from 'reactflow';
|
import { EdgeTypes } from 'reactflow';
|
||||||
|
|
||||||
import TGEdge from './TGEdge';
|
import DynamicEdge from '../../../../components/ui/Flow/DynamicEdge';
|
||||||
|
|
||||||
export const TGEdgeTypes: EdgeTypes = {
|
export const TGEdgeTypes: EdgeTypes = {
|
||||||
termEdge: TGEdge
|
termEdge: DynamicEdge
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,12 +35,7 @@ function TGNode(node: TGNodeInternal) {
|
||||||
<Handle type='target' position={Position.Top} style={{ opacity: 0 }} />
|
<Handle type='target' position={Position.Top} style={{ opacity: 0 }} />
|
||||||
<div
|
<div
|
||||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||||
style={{
|
style={{ backgroundColor: !node.selected ? node.data.fill : colors.bgActiveSelection }}
|
||||||
backgroundColor: !node.selected ? node.data.fill : colors.bgActiveSelection,
|
|
||||||
outlineOffset: '4px',
|
|
||||||
outlineStyle: 'solid',
|
|
||||||
outlineColor: node.selected ? colors.bgActiveSelection : 'transparent'
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className='absolute top-[9px] left-0 text-center w-full'>{node.data.label}</div>
|
<div className='absolute top-[9px] left-0 text-center w-full'>{node.data.label}</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -97,10 +97,6 @@
|
||||||
box-shadow: 0 0 0 2px var(--cl-prim-bg-80) !important;
|
box-shadow: 0 0 0 2px var(--cl-prim-bg-80) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
|
||||||
border-color: var(--cd-bg-40);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark & {
|
.dark & {
|
||||||
color: var(--cd-fg-100);
|
color: var(--cd-fg-100);
|
||||||
border-color: var(--cd-bg-40);
|
border-color: var(--cd-bg-40);
|
||||||
|
@ -109,10 +105,6 @@
|
||||||
&:hover:not(.selected) {
|
&:hover:not(.selected) {
|
||||||
box-shadow: 0 0 0 3px var(--cd-prim-bg-80) !important;
|
box-shadow: 0 0 0 3px var(--cd-prim-bg-80) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
|
||||||
border-color: var(--cl-bg-40);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +116,16 @@
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
border-color: var(--cd-bg-40);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
&.selected {
|
||||||
|
border-color: var(--cl-bg-40);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-flow__node-step,
|
.react-flow__node-step,
|
||||||
|
@ -134,10 +136,19 @@
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
|
||||||
|
|
||||||
.react-flow__node-concept {
|
outline-offset: 4px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: transparent;
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
|
outline-color: var(--cl-teal-bg-100);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
&.selected {
|
||||||
|
border-color: var(--cd-teal-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ export const PARAMETER = {
|
||||||
ossDistanceX: 180, // pixels - insert x-distance between node centers
|
ossDistanceX: 180, // pixels - insert x-distance between node centers
|
||||||
ossDistanceY: 100, // pixels - insert y-distance between node centers
|
ossDistanceY: 100, // pixels - insert y-distance between node centers
|
||||||
|
|
||||||
|
graphHandleSize: 3, // pixels - size of graph connection handle
|
||||||
graphNodeRadius: 20, // pixels - radius of graph node
|
graphNodeRadius: 20, // pixels - radius of graph node
|
||||||
graphNodePadding: 5, // pixels - padding of graph node
|
graphNodePadding: 5, // pixels - padding of graph node
|
||||||
graphHoverXLimit: 0.4, // ratio to clientWidth used to determine which side of screen popup should be
|
graphHoverXLimit: 0.4, // ratio to clientWidth used to determine which side of screen popup should be
|
||||||
|
|
Loading…
Reference in New Issue
Block a user