Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Splitter): add lazy mode #51557

Merged
merged 32 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
417dc04
feat(spitter): add lazy mode
OysterD3 Nov 9, 2024
1c1b81c
test: cover all codes
OysterD3 Nov 10, 2024
5f74e02
chore(splitter): update zh-CN API description
OysterD3 Nov 11, 2024
e5ddf47
refactor: clamped position calculation logic
OysterD3 Nov 11, 2024
71f443d
chore(splitter): update API release version
OysterD3 Nov 11, 2024
43f66ee
Merge branch 'feature' into feat/lazy-splitter
OysterD3 Nov 11, 2024
ed934ac
refactor: remove inline style
OysterD3 Nov 11, 2024
51e3004
chore(splitter): update doc punctuation
OysterD3 Nov 11, 2024
7812e77
chore(splitter): add version to demo
OysterD3 Nov 11, 2024
a274938
Merge branch 'feature' into feat/lazy-splitter
afc163 Nov 11, 2024
1c9012a
refactor(splitter): replace ref with state
OysterD3 Nov 11, 2024
281db49
refactor: 修改显隐逻辑
OysterD3 Nov 11, 2024
8299c8c
chore(splitter): update version
OysterD3 Nov 12, 2024
246474f
test(splitter): update snapshot
OysterD3 Nov 12, 2024
d5d2db4
Merge branch 'feature' into feat/lazy-splitter
OysterD3 Nov 12, 2024
b297317
fix(splitter): transform style logic error
OysterD3 Nov 12, 2024
81bf7c4
chore(splitter): update demo
OysterD3 Nov 12, 2024
84dea46
refactor: update styling logic
OysterD3 Nov 12, 2024
20d80c1
refactor: replace with css variable
OysterD3 Nov 12, 2024
2514a65
refactor(splitter): ternary operator
OysterD3 Nov 13, 2024
80c2d8e
refactor(splitter): extract into methods
OysterD3 Nov 13, 2024
9a9b242
fix(splitter): cssvar should account prefix as well
OysterD3 Nov 13, 2024
8aa7d45
fix: cover all codes
OysterD3 Nov 13, 2024
062fd73
fix(splitter): fix check touches condition
OysterD3 Nov 13, 2024
f6cc0ba
refactor(splitter): remove useRef
OysterD3 Nov 13, 2024
d11db19
refactor(splitter): simplify ternary operator
OysterD3 Nov 13, 2024
372380c
test(splitter): extract lazy test cases
OysterD3 Nov 13, 2024
170ad42
test(splitter): remove lazy test case
OysterD3 Nov 13, 2024
3f34a96
refactor(splitter): improve readability
OysterD3 Nov 13, 2024
080dfea
refactor(splitter): transform logic
OysterD3 Nov 13, 2024
dc0cbdb
refactor(splitter): css in js
OysterD3 Nov 13, 2024
16567d1
refactor(splitter): rename
OysterD3 Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 68 additions & 3 deletions components/splitter/SplitBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import LeftOutlined from '@ant-design/icons/LeftOutlined';
import RightOutlined from '@ant-design/icons/RightOutlined';
import UpOutlined from '@ant-design/icons/UpOutlined';
import classNames from 'classnames';
import { useEvent } from 'rc-util';
OysterD3 marked this conversation as resolved.
Show resolved Hide resolved

export interface SplitBarProps {
index: number;
Expand All @@ -20,6 +21,8 @@ export interface SplitBarProps {
ariaNow: number;
ariaMin: number;
ariaMax: number;
lazy?: boolean;
containerSize: number;
}

function getValidNumber(num: number | undefined): number {
Expand All @@ -42,12 +45,15 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
onOffsetUpdate,
onOffsetEnd,
onCollapse,
lazy,
containerSize,
} = props;

const splitBarPrefixCls = `${prefixCls}-bar`;

// ======================== Resize ========================
const [startPos, setStartPos] = useState<[x: number, y: number] | null>(null);
const [constrainedOffset, setConstrainedOffset] = useState<[x: number, y: number] | null>(null);
OysterD3 marked this conversation as resolved.
Show resolved Hide resolved

const onMouseDown: React.MouseEventHandler<HTMLDivElement> = (e) => {
if (resizable && e.currentTarget) {
Expand All @@ -64,17 +70,55 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
}
};

// Updated constraint calculation
const getConstrainedOffset = (rawOffset: number) => {
const currentPos = (containerSize * ariaNow) / 100;
const newPos = currentPos + rawOffset;

// Calculate available space
const minAllowed = Math.max(0, (containerSize * ariaMin) / 100);
const maxAllowed = Math.min(containerSize, (containerSize * ariaMax) / 100);

// Constrain new position within bounds
const clampedPos = Math.max(minAllowed, Math.min(maxAllowed, newPos));
return clampedPos - currentPos;
};

const handleLazyMove = useEvent((offsetX: number, offsetY: number) => {
const constrainedOffsetValue = getConstrainedOffset(vertical ? offsetY : offsetX);
setConstrainedOffset(vertical ? [0, constrainedOffsetValue] : [constrainedOffsetValue, 0]);
});

const handleLazyEnd = useEvent(() => {
const constrainedOffsetValue = getConstrainedOffset(
vertical ? (constrainedOffset?.[1] ?? 0) : (constrainedOffset?.[0] ?? 0),
OysterD3 marked this conversation as resolved.
Show resolved Hide resolved
);
onOffsetUpdate(
index,
vertical ? 0 : constrainedOffsetValue,
vertical ? constrainedOffsetValue : 0,
);
setConstrainedOffset(null);
});

React.useEffect(() => {
if (startPos) {
const onMouseMove = (e: MouseEvent) => {
const { pageX, pageY } = e;
const offsetX = pageX - startPos[0];
const offsetY = pageY - startPos[1];

onOffsetUpdate(index, offsetX, offsetY);
if (lazy) {
handleLazyMove(offsetX, offsetY);
} else {
onOffsetUpdate(index, offsetX, offsetY);
}
};

const onMouseUp = () => {
if (lazy) {
handleLazyEnd();
}
setStartPos(null);
onOffsetEnd();
};
Expand All @@ -85,11 +129,18 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
const offsetX = touch.pageX - startPos[0];
const offsetY = touch.pageY - startPos[1];

onOffsetUpdate(index, offsetX, offsetY);
if (lazy) {
handleLazyMove(offsetX, offsetY);
} else {
onOffsetUpdate(index, offsetX, offsetY);
}
}
OysterD3 marked this conversation as resolved.
Show resolved Hide resolved
};

const handleTouchEnd = () => {
if (lazy) {
handleLazyEnd();
}
setStartPos(null);
onOffsetEnd();
};
Expand All @@ -106,7 +157,12 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
window.removeEventListener('touchend', handleTouchEnd);
};
}
}, [startPos]);
}, [startPos, lazy, vertical, index, containerSize, ariaNow, ariaMin, ariaMax]);

const transformStyle = {
[`--${splitBarPrefixCls}-preview-translate-x`]: `${constrainedOffset?.[0] ?? 0}px`,
[`--${splitBarPrefixCls}-preview-translate-y`]: `${constrainedOffset?.[1] ?? 0}px`,
};

// ======================== Render ========================
const StartIcon = vertical ? UpOutlined : LeftOutlined;
Expand All @@ -120,6 +176,15 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
aria-valuemin={getValidNumber(ariaMin)}
aria-valuemax={getValidNumber(ariaMax)}
>
{lazy && (
<div
className={classNames(`${splitBarPrefixCls}-preview`, {
[`${splitBarPrefixCls}-preview-active`]: !!constrainedOffset,
})}
style={transformStyle}
/>
)}

<div
className={classNames(`${splitBarPrefixCls}-dragger`, {
[`${splitBarPrefixCls}-dragger-disabled`]: !resizable,
Expand Down
3 changes: 3 additions & 0 deletions components/splitter/Splitter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
onResizeStart,
onResize,
onResizeEnd,
lazy,
} = props;

const { getPrefixCls, direction, splitter } = React.useContext(ConfigContext);
Expand Down Expand Up @@ -170,6 +171,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {

splitBar = (
<SplitBar
lazy={lazy}
index={idx}
active={movingIndex === idx}
prefixCls={prefixCls}
Expand All @@ -190,6 +192,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
}}
onOffsetEnd={onInternalResizeEnd}
onCollapse={onInternalCollapse}
containerSize={containerSize || 0}
/>
);
}
Expand Down
122 changes: 122 additions & 0 deletions components/splitter/__tests__/__snapshots__/demo-extend.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,128 @@ exports[`renders components/splitter/demo/group.tsx extend context correctly 1`]

exports[`renders components/splitter/demo/group.tsx extend context correctly 2`] = `[]`;

exports[`renders components/splitter/demo/lazy.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-vertical ant-space-gap-row-small ant-space-gap-col-small"
style="width: 100%;"
>
<div
class="ant-space-item"
>
<div
class="ant-splitter ant-splitter-horizontal"
style="height: 200px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);"
>
<div
class="ant-splitter-panel"
style="flex-basis: 40%; flex-grow: 0;"
>
<div
class="ant-flex ant-flex-align-center ant-flex-justify-center"
style="height: 100%;"
>
<h5
class="ant-typography ant-typography-secondary"
style="white-space: nowrap;"
>
First
</h5>
</div>
</div>
<div
aria-valuemax="0"
aria-valuemin="0"
aria-valuenow="40"
class="ant-splitter-bar"
role="separator"
>
<div
class="ant-splitter-bar-preview"
style="--ant-splitter-bar-preview-translate-x: 0px; --ant-splitter-bar-preview-translate-y: 0px;"
/>
<div
class="ant-splitter-bar-dragger ant-splitter-bar-dragger-disabled"
/>
</div>
<div
class="ant-splitter-panel"
style="flex-basis: auto; flex-grow: 1;"
>
<div
class="ant-flex ant-flex-align-center ant-flex-justify-center"
style="height: 100%;"
>
<h5
class="ant-typography ant-typography-secondary"
style="white-space: nowrap;"
>
Second
</h5>
</div>
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-splitter ant-splitter-vertical"
style="height: 200px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);"
>
<div
class="ant-splitter-panel"
style="flex-basis: 40%; flex-grow: 0;"
>
<div
class="ant-flex ant-flex-align-center ant-flex-justify-center"
style="height: 100%;"
>
<h5
class="ant-typography ant-typography-secondary"
style="white-space: nowrap;"
>
First
</h5>
</div>
</div>
<div
aria-valuemax="0"
aria-valuemin="0"
aria-valuenow="40"
class="ant-splitter-bar"
role="separator"
>
<div
class="ant-splitter-bar-preview"
style="--ant-splitter-bar-preview-translate-x: 0px; --ant-splitter-bar-preview-translate-y: 0px;"
/>
<div
class="ant-splitter-bar-dragger ant-splitter-bar-dragger-disabled"
/>
</div>
<div
class="ant-splitter-panel"
style="flex-basis: auto; flex-grow: 1;"
>
<div
class="ant-flex ant-flex-align-center ant-flex-justify-center"
style="height: 100%;"
>
<h5
class="ant-typography ant-typography-secondary"
style="white-space: nowrap;"
>
Second
</h5>
</div>
</div>
</div>
</div>
</div>
`;

exports[`renders components/splitter/demo/lazy.tsx extend context correctly 2`] = `[]`;

exports[`renders components/splitter/demo/multiple.tsx extend context correctly 1`] = `
<div
class="ant-splitter ant-splitter-horizontal"
Expand Down
Loading
Loading