Skip to content

Commit

Permalink
Feat/swim bg (#113)
Browse files Browse the repository at this point in the history
* ⚰️ feat: tina flow demo

* ✨ feat: add swim lane

* ✨ feat: add dispatch

* 🐛 fix: ci

* 🐛 fix: coverage

* ✨ feat: type

---------

Co-authored-by: jiangchu <[email protected]>
  • Loading branch information
ModestFun and jiangchu authored Jan 3, 2025
1 parent ca49e83 commit ffb4d8c
Show file tree
Hide file tree
Showing 21 changed files with 1,054 additions and 25 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ jobs:
- name: Test and coverage
run: pnpm run test:coverage

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v3
126 changes: 126 additions & 0 deletions docs/caseShow/demos/tinaFlow/comp/box/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
.box {
// width: 600px;
// height: 500px;
// height: 100%;
// border: 1px solid #666;
position: relative;
// background-color: cyan;
transition: width 0.2s, height 0.2s;
&-move {
transition: width 0.05s, height 0.05s;
// 不能选中
user-select: none;
}
.box-holder {
position: absolute;
&-mousedown {
background-color: rgba(27, 110, 197, 0.7);
}
&:hover {
background-color: rgba(27, 110, 197, 0.7);
}
&-left, &-right {
top: 0;
bottom: 0;
width: 8px;
&:hover {
cursor: col-resize;
}
}
&-left {
left: 0;
}
&-right {
right: 0;
}

&-top, &-bottom {
left: 0;
right: 0;
height: 8px;
&:hover {
cursor: row-resize;
}
}
&-top {
top: 0;
}
&-bottom {
bottom: 0;
}
}

.expander {
z-index: 99;
position: absolute;
opacity: 0.7;
border: 12px solid transparent;
// width: 12px;
// height: 64px;
color: rgba(0, 10, 26, .45);
cursor: pointer;
transition: opacity 0.3s;
box-sizing: border-box;
svg {
position: absolute;
top: 50%;
left: 0;
transform: translate(-100%, -50%);
}
&:hover {
opacity: 1;
}
&-left, &-right {
top: 50%;
width: 12px;
height: 64px;
svg {
top: 50%;
}
}
&-left {
left: 0;
transform: translate(-100%, -50%);
border-right: 12px solid #d1d0d0;
svg {
right: 25%;
transform: translate(0, -50%);
}
}
&-right {
right: 0;
transform: translate(100%, -50%);
border-left: 12px solid #d1d0d0;
svg {
left: 0;
transform: translate(-100%, -50%);
}
}
&-top, &-bottom {
left: 50%;
width: 64px;
height: 12px;
svg {
left: 50%;
}
}
&-top {
top: 0;
transform: translate(-50%, -100%);
border-bottom: 12px solid #d1d0d0;
svg {
bottom: 25%;
transform: translate(-50%, -11%) rotate(-90deg);
}
}
&-bottom {
bottom: 0;
transform: translate(-50%, 100%);
border-top: 12px solid #d1d0d0;
svg {
top: 25%;
transform: translate(-50%, -89%) rotate(90deg);
}
}
}
}
143 changes: 143 additions & 0 deletions docs/caseShow/demos/tinaFlow/comp/box/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { FC, useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import './index.less';

export const Box: FC<{
style?: React.CSSProperties;
className?: string;
direction: 'top' | 'bottom' | 'left' | 'right';
// 是否展示收起展开
showExpand?: boolean;
children?: React.ReactNode;
onResizeEnd?: () => void;
}> = ({ className, direction, showExpand, style: _style, children }) => {
const mouseDownState = useState(false);
const isExpandState = useState(false);

const mouseDownRef = useRef({
isMouseDown: false,
x: 0,
y: 0,
width: 0,
height: 0,
});

const boxRef = useRef<HTMLDivElement>(null);

const handleMouseDown = (event: React.MouseEvent) => {
mouseDownState[1](true);
mouseDownRef.current = {
isMouseDown: true,
x: event.clientX,
y: event.clientY,
width: boxRef.current!.offsetWidth,
height: boxRef.current!.offsetHeight,
};
document.documentElement.style.cursor =
direction === 'bottom' || direction === 'top' ? 'row-resize' : 'col-resize';
};

useEffect(() => {
const handleMouseup = () => {
mouseDownState[1](false);
mouseDownRef.current.isMouseDown = false;
document.documentElement.style.cursor = 'auto';
};

const handleMousemove = ({ clientX, clientY }: React.MouseEvent) => {
requestAnimationFrame(() => {
if (!mouseDownRef.current.isMouseDown || !boxRef.current) return;
const moveHorizontalDistance = clientX - mouseDownRef.current.x;
const moveVerticalDistance = clientY - mouseDownRef.current.y;
if (direction === 'right') {
boxRef.current.style.width = mouseDownRef.current.width + moveHorizontalDistance + 'px';
}
if (direction === 'left') {
boxRef.current.style.width = mouseDownRef.current.width - moveHorizontalDistance + 'px';
}
if (direction === 'top') {
boxRef.current.style.height = mouseDownRef.current.height - moveVerticalDistance + 'px';
}
if (direction === 'bottom') {
boxRef.current.style.height = mouseDownRef.current.height + moveVerticalDistance + 'px';
}
});
};

window.addEventListener('mouseup', handleMouseup);
window.addEventListener('mousemove', handleMousemove as any, false);

return () => {
window.removeEventListener('mouseup', handleMouseup);
window.removeEventListener('mousemove', handleMousemove as any, false);
};
}, []);

const handleExpandToggle = () => {
const isHorizontal = direction === 'right' || direction === 'left';
if (!isExpandState[0]) {
mouseDownRef.current.width = boxRef.current!.offsetWidth;
mouseDownRef.current.height = boxRef.current!.offsetHeight;
boxRef.current!.style[isHorizontal ? 'width' : 'height'] = '0px';
} else {
boxRef.current!.style[isHorizontal ? 'width' : 'height'] =
mouseDownRef.current[isHorizontal ? 'width' : 'height'] + 'px';
}
isExpandState[1](!isExpandState[0]);
};

return (
<div
style={_style}
className={`box box-${direction} ${mouseDownState[0] ? 'box-move' : ''} ${className}`}
ref={boxRef}
>
{!isExpandState[0] && (
<div
className={`box-holder box-holder-${direction} ${
mouseDownState[0] ? 'box-holder-mousedown' : ''
}`}
onMouseDown={handleMouseDown}
/>
)}
<div style={isExpandState[0] ? { display: 'none' } : {}}>{children}</div>
{showExpand && (
<div className={`expander expander-${direction}`} onClick={handleExpandToggle}>
<div className="expander-button">
<span className="anticon">
<svg
viewBox="64 64 896 896"
focusable="false"
data-icon="right"
width="1em"
height="1em"
fill="currentColor"
aria-hidden="true"
>
{isExpandState[0] ? (
<path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z" />
) : (
<path d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z" />
)}
</svg>
</span>
</div>
</div>
)}
{mouseDownState[0] &&
ReactDOM.createPortal(
<div
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 10000,
}}
/>,
document.body,
)}
</div>
);
};
45 changes: 45 additions & 0 deletions docs/caseShow/demos/tinaFlow/comp/comp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Handle, Position, useFlowViewer } from '@ant-design/pro-flow';
import { FC, useState } from 'react';
import { IconFont } from '../icon';

interface CompNodeProps {
className?: string;
}

export const CompNode: FC<any> = function CompNode(props) {
const s = useState({ height: '100px', width: '200px' });
// const { updateNodeMeta } = useFlowEditor();
const { selectNode, selectEdges, selectNodes, zoomToNode, fullScreen, instance } =
useFlowViewer();

// @ts-ignore
window.instance = instance;
return (
<div style={{ ...s[0], background: '#fff', borderRadius: 8, border: '1px solid #ccc' }}>
<Handle
id={`${props.id}-target`}
type="target"
position={Position.Left}
style={{
opacity: 0,
}}
/>
compcompcompcomp
<IconFont
type="icon-bianji"
onClick={() => {
if (s[0].width === '200px') {
s[1]({ height: '200px', width: '250px' });
props?.data?.onResize(250, 200);
} else {
s[1]({ height: '100px', width: '200px' });
props?.data?.onResize(200, 100);
}
console.log('props: ', props);
// updateNodeMeta(props.id, "height", 200);
// updateNodeMeta(props.id, "width", 250);
}}
/>
</div>
);
};
Loading

0 comments on commit ffb4d8c

Please sign in to comment.