This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
import React from 'react';
import type { InternalPanelProps, PanelProps } from './interface';
export declare const InternalPanel: React.ForwardRefExoticComponent<InternalPanelProps & {
children?: React.ReactNode | undefined;
} & React.RefAttributes<HTMLDivElement>>;
declare const Panel: React.FC<React.PropsWithChildren<PanelProps>>;
export default Panel;
+38
View File
@@ -0,0 +1,38 @@
"use strict";
"use client";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.InternalPanel = void 0;
var _react = _interopRequireWildcard(require("react"));
var _clsx = require("clsx");
const InternalPanel = exports.InternalPanel = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
const {
prefixCls,
className,
children,
size,
style = {}
} = props;
const panelClassName = (0, _clsx.clsx)(`${prefixCls}-panel`, {
[`${prefixCls}-panel-hidden`]: size === 0
}, className);
const hasSize = size !== undefined;
return /*#__PURE__*/_react.default.createElement("div", {
ref: ref,
className: panelClassName,
style: {
...style,
// Use auto when start from ssr
flexBasis: hasSize ? size : 'auto',
flexGrow: hasSize ? 0 : 1
}
}, children);
});
if (process.env.NODE_ENV !== 'production') {
InternalPanel.displayName = 'Panel';
}
const Panel = () => null;
var _default = exports.default = Panel;
+31
View File
@@ -0,0 +1,31 @@
import React from 'react';
import type { SplitterProps, SplitterSemanticDraggerClassNames } from './interface';
export type ShowCollapsibleIconMode = boolean | 'auto';
export interface SplitBarProps {
index: number;
active: boolean;
draggerStyle?: React.CSSProperties;
draggerClassName?: SplitterSemanticDraggerClassNames;
prefixCls: string;
rootPrefixCls: string;
resizable: boolean;
startCollapsible: boolean;
endCollapsible: boolean;
draggerIcon?: SplitterProps['draggerIcon'];
collapsibleIcon?: SplitterProps['collapsibleIcon'];
showStartCollapsibleIcon: ShowCollapsibleIconMode;
showEndCollapsibleIcon: ShowCollapsibleIconMode;
onDraggerDoubleClick?: (index: number) => void;
onOffsetStart: (index: number) => void;
onOffsetUpdate: (index: number, offsetX: number, offsetY: number, lazyEnd?: boolean) => void;
onOffsetEnd: (lazyEnd?: boolean) => void;
onCollapse: (index: number, type: 'start' | 'end') => void;
vertical: boolean;
ariaNow: number;
ariaMin: number;
ariaMax: number;
lazy?: boolean;
containerSize: number;
}
declare const SplitBar: React.FC<SplitBarProps>;
export default SplitBar;
+228
View File
@@ -0,0 +1,228 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _DownOutlined = _interopRequireDefault(require("@ant-design/icons/DownOutlined"));
var _LeftOutlined = _interopRequireDefault(require("@ant-design/icons/LeftOutlined"));
var _RightOutlined = _interopRequireDefault(require("@ant-design/icons/RightOutlined"));
var _UpOutlined = _interopRequireDefault(require("@ant-design/icons/UpOutlined"));
var _util = require("@rc-component/util");
var _useLayoutEffect = _interopRequireDefault(require("@rc-component/util/lib/hooks/useLayoutEffect"));
var _clsx = require("clsx");
var _is = require("../_util/is");
var _genStyleUtils = require("../theme/util/genStyleUtils");
const getValidNumber = num => {
return (0, _is.isNumber)(num) && Number.isFinite(num) ? Math.round(num) : 0;
};
const DOUBLE_CLICK_TIME_GAP = 300;
const SplitBar = props => {
const {
prefixCls,
rootPrefixCls,
vertical,
index,
active,
ariaNow,
ariaMin,
ariaMax,
resizable,
draggerIcon,
draggerStyle,
draggerClassName,
collapsibleIcon,
startCollapsible,
endCollapsible,
onDraggerDoubleClick,
onOffsetStart,
onOffsetUpdate,
onOffsetEnd,
onCollapse,
lazy,
containerSize,
showStartCollapsibleIcon,
showEndCollapsibleIcon
} = props;
const splitBarPrefixCls = `${prefixCls}-bar`;
const lastClickTimeRef = (0, _react.useRef)(0);
const [varName] = (0, _genStyleUtils.genCssVar)(rootPrefixCls, 'splitter');
// ======================== Resize ========================
const [startPos, setStartPos] = (0, _react.useState)(null);
const [constrainedOffset, setConstrainedOffset] = (0, _react.useState)(0);
const constrainedOffsetX = vertical ? 0 : constrainedOffset;
const constrainedOffsetY = vertical ? constrainedOffset : 0;
const onMouseDown = e => {
e.stopPropagation();
const currentTime = Date.now();
const timeGap = currentTime - lastClickTimeRef.current;
if (timeGap > 0 && timeGap < DOUBLE_CLICK_TIME_GAP) {
// Prevent drag start if it's a double-click action
return;
}
lastClickTimeRef.current = currentTime;
if (resizable && e.currentTarget) {
setStartPos([e.pageX, e.pageY]);
onOffsetStart(index);
}
};
const onTouchStart = e => {
if (resizable && e.touches.length === 1) {
const touch = e.touches[0];
setStartPos([touch.pageX, touch.pageY]);
onOffsetStart(index);
}
};
// Updated constraint calculation
const getConstrainedOffset = rawOffset => {
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 = (0, _util.useEvent)((offsetX, offsetY) => {
const constrainedOffsetValue = getConstrainedOffset(vertical ? offsetY : offsetX);
setConstrainedOffset(constrainedOffsetValue);
});
const handleLazyEnd = (0, _util.useEvent)(() => {
onOffsetUpdate(index, constrainedOffsetX, constrainedOffsetY, true);
setConstrainedOffset(0);
onOffsetEnd(true);
});
const getVisibilityClass = mode => {
switch (mode) {
case true:
return `${splitBarPrefixCls}-collapse-bar-always-visible`;
case false:
return `${splitBarPrefixCls}-collapse-bar-always-hidden`;
case 'auto':
return `${splitBarPrefixCls}-collapse-bar-hover-only`;
}
};
(0, _useLayoutEffect.default)(() => {
if (!startPos) {
return;
}
const onMouseMove = e => {
const {
pageX,
pageY
} = e;
const offsetX = pageX - startPos[0];
const offsetY = pageY - startPos[1];
if (lazy) {
handleLazyMove(offsetX, offsetY);
} else {
onOffsetUpdate(index, offsetX, offsetY);
}
};
const onMouseUp = () => {
if (lazy) {
handleLazyEnd();
} else {
onOffsetEnd();
}
setStartPos(null);
};
const handleTouchMove = e => {
if (e.touches.length === 1) {
const touch = e.touches[0];
const offsetX = touch.pageX - startPos[0];
const offsetY = touch.pageY - startPos[1];
if (lazy) {
handleLazyMove(offsetX, offsetY);
} else {
onOffsetUpdate(index, offsetX, offsetY);
}
}
};
const handleTouchEnd = () => {
if (lazy) {
handleLazyEnd();
} else {
onOffsetEnd();
}
setStartPos(null);
};
const eventHandlerMap = {
mousemove: onMouseMove,
mouseup: onMouseUp,
touchmove: handleTouchMove,
touchend: handleTouchEnd
};
for (const [event, handler] of Object.entries(eventHandlerMap)) {
// eslint-disable-next-line react-web-api/no-leaked-event-listener
window.addEventListener(event, handler);
}
return () => {
for (const [event, handler] of Object.entries(eventHandlerMap)) {
window.removeEventListener(event, handler);
}
};
}, [startPos, index, lazy]);
const transformStyle = {
[varName('bar-preview-offset')]: `${constrainedOffset}px`
};
// ======================== Render ========================
const [startIcon, endIcon, startCustomize, endCustomize] = _react.default.useMemo(() => {
let startIcon = null;
let endIcon = null;
const startCustomize = collapsibleIcon?.start !== undefined;
const endCustomize = collapsibleIcon?.end !== undefined;
if (vertical) {
startIcon = startCustomize ? collapsibleIcon.start : /*#__PURE__*/_react.default.createElement(_UpOutlined.default, null);
endIcon = endCustomize ? collapsibleIcon.end : /*#__PURE__*/_react.default.createElement(_DownOutlined.default, null);
} else {
startIcon = startCustomize ? collapsibleIcon.start : /*#__PURE__*/_react.default.createElement(_LeftOutlined.default, null);
endIcon = endCustomize ? collapsibleIcon.end : /*#__PURE__*/_react.default.createElement(_RightOutlined.default, null);
}
return [startIcon, endIcon, startCustomize, endCustomize];
}, [collapsibleIcon, vertical]);
return /*#__PURE__*/_react.default.createElement("div", {
className: splitBarPrefixCls,
role: "separator",
"aria-valuenow": getValidNumber(ariaNow),
"aria-valuemin": getValidNumber(ariaMin),
"aria-valuemax": getValidNumber(ariaMax)
}, lazy && (/*#__PURE__*/_react.default.createElement("div", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-preview`, {
[`${splitBarPrefixCls}-preview-active`]: !!constrainedOffset
}),
style: transformStyle
})), /*#__PURE__*/_react.default.createElement("div", {
style: draggerStyle,
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-dragger`, {
[`${splitBarPrefixCls}-dragger-disabled`]: !resizable,
[`${splitBarPrefixCls}-dragger-active`]: active,
[`${splitBarPrefixCls}-dragger-customize`]: draggerIcon !== undefined
}, draggerClassName?.default, active && draggerClassName?.active),
onMouseDown: onMouseDown,
onTouchStart: onTouchStart,
onDoubleClick: () => onDraggerDoubleClick?.(index)
}, draggerIcon !== undefined ? (/*#__PURE__*/_react.default.createElement("div", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-dragger-icon`)
}, draggerIcon)) : null), startCollapsible && (/*#__PURE__*/_react.default.createElement("div", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-collapse-bar`, `${splitBarPrefixCls}-collapse-bar-start`, {
[`${splitBarPrefixCls}-collapse-bar-customize`]: startCustomize
}, getVisibilityClass(showStartCollapsibleIcon)),
onClick: () => onCollapse(index, 'start')
}, /*#__PURE__*/_react.default.createElement("span", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-collapse-icon`, `${splitBarPrefixCls}-collapse-start`)
}, startIcon))), endCollapsible && (/*#__PURE__*/_react.default.createElement("div", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-collapse-bar`, `${splitBarPrefixCls}-collapse-bar-end`, {
[`${splitBarPrefixCls}-collapse-bar-customize`]: endCustomize
}, getVisibilityClass(showEndCollapsibleIcon)),
onClick: () => onCollapse(index, 'end')
}, /*#__PURE__*/_react.default.createElement("span", {
className: (0, _clsx.clsx)(`${splitBarPrefixCls}-collapse-icon`, `${splitBarPrefixCls}-collapse-end`)
}, endIcon))));
};
var _default = exports.default = SplitBar;
+4
View File
@@ -0,0 +1,4 @@
import React from 'react';
import type { SplitterProps } from './interface';
declare const Splitter: React.FC<React.PropsWithChildren<SplitterProps>>;
export default Splitter;
+229
View File
@@ -0,0 +1,229 @@
"use strict";
"use client";
/* eslint-disable react/no-array-index-key */
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _resizeObserver = _interopRequireDefault(require("@rc-component/resize-observer"));
var _util = require("@rc-component/util");
var _clsx = require("clsx");
var _hooks = require("../_util/hooks");
var _is = require("../_util/is");
var _warning = require("../_util/warning");
var _context = require("../config-provider/context");
var _useCSSVarCls = _interopRequireDefault(require("../config-provider/hooks/useCSSVarCls"));
var _useItems = _interopRequireDefault(require("./hooks/useItems"));
var _useResizable = _interopRequireDefault(require("./hooks/useResizable"));
var _useResize = _interopRequireDefault(require("./hooks/useResize"));
var _useSizes = _interopRequireDefault(require("./hooks/useSizes"));
var _Panel = require("./Panel");
var _SplitBar = _interopRequireDefault(require("./SplitBar"));
var _style = _interopRequireDefault(require("./style"));
const Splitter = props => {
const {
prefixCls: customizePrefixCls,
className,
classNames,
style,
styles,
layout,
orientation,
vertical,
children,
draggerIcon,
collapsibleIcon,
rootClassName,
onDraggerDoubleClick,
onResizeStart,
onResize,
onResizeEnd,
lazy
} = props;
const {
getPrefixCls,
direction,
className: contextClassName,
style: contextStyle,
classNames: contextClassNames,
styles: contextStyles
} = (0, _context.useComponentConfig)('splitter');
const prefixCls = getPrefixCls('splitter', customizePrefixCls);
const rootPrefixCls = getPrefixCls();
const rootCls = (0, _useCSSVarCls.default)(prefixCls);
const [hashId, cssVarCls] = (0, _style.default)(prefixCls, rootCls);
// ======================== Direct ========================
const [mergedOrientation, isVertical] = (0, _hooks.useOrientation)(orientation, vertical, layout);
const isRTL = direction === 'rtl';
const reverse = !isVertical && isRTL;
// ====================== Items Data ======================
const items = (0, _useItems.default)(children);
// >>> Warning for uncontrolled
if (process.env.NODE_ENV !== 'production') {
const warning = (0, _warning.devUseWarning)('Splitter');
const existSize = items.some(item => item.size !== undefined);
const existUndefinedSize = items.some(item => item.size === undefined);
if (existSize && existUndefinedSize && !onResize) {
process.env.NODE_ENV !== "production" ? warning(false, 'usage', 'When part of `Splitter.Panel` has `size`, `onResize` is required or change `size` to `defaultSize`.') : void 0;
}
warning.deprecated(!layout, 'layout', 'orientation');
}
// ====================== Container =======================
const [containerSize, setContainerSize] = (0, _react.useState)();
const onContainerResize = size => {
const {
offsetWidth,
offsetHeight
} = size;
const containerSize = isVertical ? offsetHeight : offsetWidth;
// Skip when container has no size, Such as nested in a hidden tab panel
// to fix: https://github.com/ant-design/ant-design/issues/51106
if (containerSize === 0) {
return;
}
setContainerSize(containerSize);
};
// ========================= Size =========================
const [panelSizes, itemPxSizes, itemPtgSizes, itemPtgMinSizes, itemPtgMaxSizes, updateSizes] = (0, _useSizes.default)(items, containerSize);
// ====================== Resizable =======================
const resizableInfos = (0, _useResizable.default)(items, itemPxSizes, reverse);
const [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex] = (0, _useResize.default)(items, resizableInfos, itemPtgSizes, containerSize, updateSizes, reverse);
// ======================== Events ========================
const onInternalResizeStart = (0, _util.useEvent)(index => {
onOffsetStart(index);
onResizeStart?.(itemPxSizes);
});
const onInternalResizeUpdate = (0, _util.useEvent)((index, offset, lazyEnd) => {
const nextSizes = onOffsetUpdate(index, offset);
if (lazyEnd) {
onResizeEnd?.(nextSizes);
} else {
onResize?.(nextSizes);
}
});
const onInternalResizeEnd = (0, _util.useEvent)(lazyEnd => {
onOffsetEnd();
if (!lazyEnd) {
onResizeEnd?.(itemPxSizes);
}
});
const onInternalCollapse = (0, _util.useEvent)((index, type) => {
const nextSizes = onCollapse(index, type);
onResize?.(nextSizes);
onResizeEnd?.(nextSizes);
const collapsed = nextSizes.map(size => Math.abs(size) < Number.EPSILON);
props.onCollapse?.(collapsed, nextSizes);
});
// =========== Merged Props for Semantic ==========
const mergedProps = {
...props,
vertical: isVertical,
orientation: mergedOrientation
};
// ======================== Styles ========================
const [mergedClassNames, mergedStyles] = (0, _hooks.useMergeSemantic)([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
}, {
// Convert `classNames.dragger: 'a'` to
// `classNames.dragger: { default: 'a' }`
dragger: {
_default: 'default'
}
});
const containerClassName = (0, _clsx.clsx)(prefixCls, className, `${prefixCls}-${mergedOrientation}`, {
[`${prefixCls}-rtl`]: isRTL
}, rootClassName, mergedClassNames.root, contextClassName, cssVarCls, rootCls, hashId);
// ======================== Render ========================
const maskCls = `${prefixCls}-mask`;
const stackSizes = _react.default.useMemo(() => {
const mergedSizes = [];
let stack = 0;
const len = items.length;
for (let i = 0; i < len; i += 1) {
stack += itemPtgSizes[i];
mergedSizes.push(stack);
}
return mergedSizes;
}, [itemPtgSizes, items.length]);
const mergedStyle = {
...mergedStyles.root,
...contextStyle,
...style
};
return /*#__PURE__*/_react.default.createElement(_resizeObserver.default, {
onResize: onContainerResize
}, /*#__PURE__*/_react.default.createElement("div", {
style: mergedStyle,
className: containerClassName
}, items.map((item, idx) => {
const panelProps = {
...item,
className: (0, _clsx.clsx)(mergedClassNames.panel, item.className),
style: {
...mergedStyles.panel,
...item.style
}
};
// Panel
const panel = /*#__PURE__*/_react.default.createElement(_Panel.InternalPanel, {
...panelProps,
prefixCls: prefixCls,
size: panelSizes[idx]
});
// Split Bar
let splitBar = null;
const resizableInfo = resizableInfos[idx];
if (resizableInfo) {
const ariaMinStart = (stackSizes[idx - 1] || 0) + itemPtgMinSizes[idx];
const ariaMinEnd = (stackSizes[idx + 1] || 100) - itemPtgMaxSizes[idx + 1];
const ariaMaxStart = (stackSizes[idx - 1] || 0) + itemPtgMaxSizes[idx];
const ariaMaxEnd = (stackSizes[idx + 1] || 100) - itemPtgMinSizes[idx + 1];
splitBar = /*#__PURE__*/_react.default.createElement(_SplitBar.default, {
lazy: lazy,
index: idx,
active: movingIndex === idx,
prefixCls: prefixCls,
rootPrefixCls: rootPrefixCls,
vertical: isVertical,
resizable: resizableInfo.resizable,
draggerStyle: mergedStyles.dragger,
draggerClassName: mergedClassNames.dragger,
draggerIcon: draggerIcon,
collapsibleIcon: collapsibleIcon,
ariaNow: stackSizes[idx] * 100,
ariaMin: Math.max(ariaMinStart, ariaMinEnd) * 100,
ariaMax: Math.min(ariaMaxStart, ariaMaxEnd) * 100,
startCollapsible: resizableInfo.startCollapsible,
endCollapsible: resizableInfo.endCollapsible,
showStartCollapsibleIcon: resizableInfo.showStartCollapsibleIcon,
showEndCollapsibleIcon: resizableInfo.showEndCollapsibleIcon,
onDraggerDoubleClick: onDraggerDoubleClick,
onOffsetStart: onInternalResizeStart,
onOffsetUpdate: (index, offsetX, offsetY, lazyEnd) => {
let offset = isVertical ? offsetY : offsetX;
if (reverse) {
offset = -offset;
}
onInternalResizeUpdate(index, offset, lazyEnd);
},
onOffsetEnd: onInternalResizeEnd,
onCollapse: onInternalCollapse,
containerSize: containerSize || 0
});
}
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
key: `split-panel-${idx}`
}, panel, splitBar);
}), (0, _is.isNumber)(movingIndex) && (/*#__PURE__*/_react.default.createElement("div", {
"aria-hidden": true,
className: (0, _clsx.clsx)(maskCls, `${maskCls}-${mergedOrientation}`)
}))));
};
if (process.env.NODE_ENV !== 'production') {
Splitter.displayName = 'Splitter';
}
var _default = exports.default = Splitter;
+3
View File
@@ -0,0 +1,3 @@
type SizeUnit = number | undefined;
export declare function autoPtgSizes(ptgSizes: SizeUnit[], minPtgSizes: SizeUnit[], maxPtgSizes: SizeUnit[]): number[];
export {};
+75
View File
@@ -0,0 +1,75 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.autoPtgSizes = autoPtgSizes;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
function autoPtgSizes(ptgSizes, minPtgSizes, maxPtgSizes) {
// Static current data
let currentTotalPtg = 0;
const undefinedIndexes = [];
ptgSizes.forEach((size, index) => {
if (size === undefined) {
undefinedIndexes.push(index);
} else {
currentTotalPtg += size;
}
});
const restPtg = 1 - currentTotalPtg;
const undefinedCount = undefinedIndexes.length;
// If all sizes are defined but don't sum to 1, scale them.
if (ptgSizes.length && !undefinedIndexes.length && currentTotalPtg !== 1) {
// Handle the case when all sizes are 0
if (currentTotalPtg === 0) {
const avg = 1 / ptgSizes.length;
return ptgSizes.map(() => avg);
}
const scale = 1 / currentTotalPtg;
// We know `size` is a number here because undefinedIndexes is empty.
return ptgSizes.map(size => size * scale);
}
// Fill if exceed
if (restPtg < 0) {
const scale = 1 / currentTotalPtg;
return ptgSizes.map(size => size === undefined ? 0 : size * scale);
}
// Check if limit exists
let sumMin = 0;
let sumMax = 0;
let limitMin = 0;
let limitMax = 1;
for (const index of undefinedIndexes) {
const min = minPtgSizes[index] || 0;
const max = maxPtgSizes[index] || 1;
sumMin += min;
sumMax += max;
limitMin = Math.max(limitMin, min);
limitMax = Math.min(limitMax, max);
}
// Impossible case, just average fill
if (sumMin > 1 && sumMax < 1) {
const avg = 1 / undefinedCount;
return ptgSizes.map(size => size === undefined ? avg : size);
}
// Quickly fill if can
const restAvg = restPtg / undefinedCount;
if (limitMin <= restAvg && restAvg <= limitMax) {
return ptgSizes.map(size => size === undefined ? restAvg : size);
}
// Greedy algorithm
const result = (0, _toConsumableArray2.default)(ptgSizes);
let remain = restPtg - sumMin;
for (let i = 0; i < undefinedCount; i += 1) {
const index = undefinedIndexes[i];
const min = minPtgSizes[index] || 0;
const max = maxPtgSizes[index] || 1;
result[index] = min;
const canAdd = max - min;
const add = Math.min(canAdd, remain);
result[index] += add;
remain -= add;
}
return result;
}
+14
View File
@@ -0,0 +1,14 @@
import * as React from 'react';
import type { PanelProps } from '../interface';
export type ItemType = Omit<PanelProps, 'collapsible'> & {
collapsible: {
start?: boolean;
end?: boolean;
showCollapsibleIcon: 'auto' | boolean;
};
};
/**
* Convert `children` into `items`.
*/
declare function useItems(children: React.ReactNode): ItemType[];
export default useItems;
+44
View File
@@ -0,0 +1,44 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _util = require("@rc-component/util");
var _is = require("../../_util/is");
function getCollapsible(collapsible) {
if ((0, _is.isPlainObject)(collapsible)) {
return {
...collapsible,
showCollapsibleIcon: collapsible.showCollapsibleIcon === undefined ? 'auto' : collapsible.showCollapsibleIcon
};
}
const mergedCollapsible = !!collapsible;
return {
start: mergedCollapsible,
end: mergedCollapsible,
showCollapsibleIcon: 'auto'
};
}
/**
* Convert `children` into `items`.
*/
function useItems(children) {
const items = React.useMemo(() => (0, _util.toArray)(children).filter(item => /*#__PURE__*/React.isValidElement(item)).map(node => {
const {
props
} = node;
const {
collapsible,
...restProps
} = props;
return {
...restProps,
collapsible: getCollapsible(collapsible)
};
}), [children]);
return items;
}
var _default = exports.default = useItems;
+10
View File
@@ -0,0 +1,10 @@
import type { ShowCollapsibleIconMode } from '../SplitBar';
import type { ItemType } from './useItems';
export type ResizableInfo = {
resizable: boolean;
startCollapsible: boolean;
endCollapsible: boolean;
showStartCollapsibleIcon: ShowCollapsibleIconMode;
showEndCollapsibleIcon: ShowCollapsibleIconMode;
};
export default function useResizable(items: ItemType[], pxSizes: number[], reverse: boolean): ResizableInfo[];
+82
View File
@@ -0,0 +1,82 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useResizable;
var React = _interopRequireWildcard(require("react"));
function getShowCollapsibleIcon(prev, next) {
if (prev.collapsible && next.collapsible) {
if (prev.showCollapsibleIcon === true || next.showCollapsibleIcon === true) {
return true;
}
if (prev.showCollapsibleIcon === 'auto' || next.showCollapsibleIcon === 'auto') {
return 'auto';
}
return false;
}
if (prev.collapsible) {
return prev.showCollapsibleIcon;
}
if (next.collapsible) {
return next.showCollapsibleIcon;
}
return false;
}
function useResizable(items, pxSizes, reverse) {
return React.useMemo(() => {
const resizeInfos = [];
for (let i = 0; i < items.length - 1; i += 1) {
const prevItem = items[i];
const nextItem = items[i + 1];
const prevSize = pxSizes[i];
const nextSize = pxSizes[i + 1];
const {
resizable: prevResizable = true,
min: prevMin,
collapsible: prevCollapsible
} = prevItem;
const {
resizable: nextResizable = true,
min: nextMin,
collapsible: nextCollapsible
} = nextItem;
const mergedResizable =
// Both need to be resizable
prevResizable && nextResizable && (
// Prev is not collapsed and limit min size
prevSize !== 0 || !prevMin) && (
// Next is not collapsed and limit min size
nextSize !== 0 || !nextMin);
const prevEndCollapsible = !!prevCollapsible.end && prevSize > 0;
const nextStartExpandable = !!nextCollapsible.start && nextSize === 0 && prevSize > 0;
const startCollapsible = prevEndCollapsible || nextStartExpandable;
const nextStartCollapsible = !!nextCollapsible.start && nextSize > 0;
const prevEndExpandable = !!prevCollapsible.end && prevSize === 0 && nextSize > 0;
const endCollapsible = nextStartCollapsible || prevEndExpandable;
const showStartCollapsibleIcon = getShowCollapsibleIcon({
collapsible: prevEndCollapsible,
showCollapsibleIcon: prevCollapsible.showCollapsibleIcon
}, {
collapsible: nextStartExpandable,
showCollapsibleIcon: nextCollapsible.showCollapsibleIcon
});
const showEndCollapsibleIcon = getShowCollapsibleIcon({
collapsible: nextStartCollapsible,
showCollapsibleIcon: nextCollapsible.showCollapsibleIcon
}, {
collapsible: prevEndExpandable,
showCollapsibleIcon: prevCollapsible.showCollapsibleIcon
});
resizeInfos[i] = {
resizable: mergedResizable,
startCollapsible: !!(reverse ? endCollapsible : startCollapsible),
endCollapsible: !!(reverse ? startCollapsible : endCollapsible),
showStartCollapsibleIcon: reverse ? showEndCollapsibleIcon : showStartCollapsibleIcon,
showEndCollapsibleIcon: reverse ? showStartCollapsibleIcon : showEndCollapsibleIcon
};
}
return resizeInfos;
}, [pxSizes, items, reverse]);
}
+6
View File
@@ -0,0 +1,6 @@
import type { ItemType } from './useItems';
import type { ResizableInfo } from './useResizable';
/**
* Handle user drag resize logic.
*/
export default function useResize(items: ItemType[], resizableInfos: ResizableInfo[], percentSizes: number[], containerSize: number | undefined, updateSizes: (sizes: number[]) => void, reverse: boolean): readonly [(index: number) => void, (index: number, offset: number) => number[], () => void, (index: number, type: "start" | "end") => number[], number | undefined];
+135
View File
@@ -0,0 +1,135 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useResize;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var React = _interopRequireWildcard(require("react"));
var _useSizes = require("./useSizes");
/**
* Handle user drag resize logic.
*/
function useResize(items, resizableInfos, percentSizes, containerSize, updateSizes, reverse) {
const limitSizes = items.map(item => [item.min, item.max]);
const mergedContainerSize = containerSize || 0;
const ptg2px = ptg => ptg * mergedContainerSize;
// ======================== Resize ========================
function getLimitSize(str, defaultLimit) {
if (typeof str === 'string') {
return ptg2px((0, _useSizes.getPtg)(str));
}
return str ?? defaultLimit;
}
// Real px sizes
const [cacheSizes, setCacheSizes] = React.useState([]);
const cacheCollapsedSizeRef = React.useRef([]);
/**
* When start drag, check the direct is `start` or `end`.
* This will handle when 2 splitter bar are in the same position.
*/
const [movingIndex, setMovingIndex] = React.useState(null);
const getPxSizes = () => percentSizes.map(ptg2px);
const onOffsetStart = index => {
setCacheSizes(getPxSizes());
setMovingIndex({
index,
confirmed: false
});
};
const onOffsetUpdate = (index, offset) => {
// First time trigger move index update is not sync in the state
let confirmedIndex = null;
// We need to know what the real index is.
if ((!movingIndex || !movingIndex.confirmed) && offset !== 0) {
// Search for the real index
if (offset > 0) {
confirmedIndex = index;
setMovingIndex({
index,
confirmed: true
});
} else {
for (let i = index; i >= 0; i -= 1) {
if (cacheSizes[i] > 0 && resizableInfos[i].resizable) {
confirmedIndex = i;
setMovingIndex({
index: i,
confirmed: true
});
break;
}
}
}
}
const mergedIndex = confirmedIndex ?? movingIndex?.index ?? index;
const numSizes = (0, _toConsumableArray2.default)(cacheSizes);
const nextIndex = mergedIndex + 1;
// Get boundary
const startMinSize = getLimitSize(limitSizes[mergedIndex][0], 0);
const endMinSize = getLimitSize(limitSizes[nextIndex][0], 0);
const startMaxSize = getLimitSize(limitSizes[mergedIndex][1], mergedContainerSize);
const endMaxSize = getLimitSize(limitSizes[nextIndex][1], mergedContainerSize);
let mergedOffset = offset;
// Align with the boundary
if (numSizes[mergedIndex] + mergedOffset < startMinSize) {
mergedOffset = startMinSize - numSizes[mergedIndex];
}
if (numSizes[nextIndex] - mergedOffset < endMinSize) {
mergedOffset = numSizes[nextIndex] - endMinSize;
}
if (numSizes[mergedIndex] + mergedOffset > startMaxSize) {
mergedOffset = startMaxSize - numSizes[mergedIndex];
}
if (numSizes[nextIndex] - mergedOffset > endMaxSize) {
mergedOffset = numSizes[nextIndex] - endMaxSize;
}
// Do offset
numSizes[mergedIndex] += mergedOffset;
numSizes[nextIndex] -= mergedOffset;
updateSizes(numSizes);
return numSizes;
};
const onOffsetEnd = () => {
setMovingIndex(null);
};
// ======================= Collapse =======================
const onCollapse = (index, type) => {
const currentSizes = getPxSizes();
const adjustedType = reverse ? type === 'start' ? 'end' : 'start' : type;
const currentIndex = adjustedType === 'start' ? index : index + 1;
const targetIndex = adjustedType === 'start' ? index + 1 : index;
const currentSize = currentSizes[currentIndex];
const targetSize = currentSizes[targetIndex];
if (currentSize !== 0 && targetSize !== 0) {
// Collapse directly
currentSizes[currentIndex] = 0;
currentSizes[targetIndex] += currentSize;
cacheCollapsedSizeRef.current[index] = currentSize;
} else {
const totalSize = currentSize + targetSize;
const currentSizeMin = getLimitSize(limitSizes[currentIndex][0], 0);
const currentSizeMax = getLimitSize(limitSizes[currentIndex][1], mergedContainerSize);
const targetSizeMin = getLimitSize(limitSizes[targetIndex][0], 0);
const targetSizeMax = getLimitSize(limitSizes[targetIndex][1], mergedContainerSize);
const limitStart = Math.max(currentSizeMin, totalSize - targetSizeMax);
const limitEnd = Math.min(currentSizeMax, totalSize - targetSizeMin);
const halfOffset = targetSizeMin || (limitEnd - limitStart) / 2;
const targetCacheCollapsedSize = cacheCollapsedSizeRef.current[index];
const currentCacheCollapsedSize = totalSize - targetCacheCollapsedSize;
const shouldUseCache = targetCacheCollapsedSize && targetCacheCollapsedSize <= targetSizeMax && targetCacheCollapsedSize >= targetSizeMin && currentCacheCollapsedSize <= currentSizeMax && currentCacheCollapsedSize >= currentSizeMin;
if (shouldUseCache) {
currentSizes[targetIndex] = targetCacheCollapsedSize;
currentSizes[currentIndex] = currentCacheCollapsedSize;
} else {
currentSizes[currentIndex] -= halfOffset;
currentSizes[targetIndex] += halfOffset;
}
}
updateSizes(currentSizes);
return currentSizes;
};
return [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex?.index];
}
+8
View File
@@ -0,0 +1,8 @@
import React from 'react';
import type { PanelProps } from '../interface';
export declare function getPtg(str: string): number;
/**
* Save the size state.
* Align the size into flex percentage base.
*/
export default function useSizes(items: PanelProps[], containerSize?: number): readonly [(string | number | undefined)[], number[], number[], number[], number[], React.Dispatch<React.SetStateAction<(string | number | undefined)[]>>];
+74
View File
@@ -0,0 +1,74 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useSizes;
exports.getPtg = getPtg;
var _react = _interopRequireDefault(require("react"));
var _is = require("../../_util/is");
var _sizeUtil = require("./sizeUtil");
function getPtg(str) {
return Number(str.slice(0, -1)) / 100;
}
function isPtg(itemSize) {
return typeof itemSize === 'string' && itemSize.endsWith('%');
}
/**
* Save the size state.
* Align the size into flex percentage base.
*/
function useSizes(items, containerSize) {
const propSizes = items.map(item => item.size);
const itemsCount = items.length;
const mergedContainerSize = containerSize || 0;
const ptg2px = ptg => ptg * mergedContainerSize;
// We do not need care the size state match the `items` length in `useState`.
// It will calculate later.
const [innerSizes, setInnerSizes] = _react.default.useState(() => items.map(item => item.defaultSize));
const sizes = _react.default.useMemo(() => {
// If any panel has a `size` passed as a prop, use `propSizes` and calculate all other panel sizes that don't have a `size` defined by the prop.
// If no panel has received a value for the `size` prop, use `innerSizes`.
return propSizes.some(_is.isNonNullable) ? propSizes : innerSizes;
}, [itemsCount, innerSizes, propSizes]);
const postPercentMinSizes = _react.default.useMemo(() => items.map(item => {
if (isPtg(item.min)) {
return getPtg(item.min);
}
return (item.min || 0) / mergedContainerSize;
}), [items, mergedContainerSize]);
const postPercentMaxSizes = _react.default.useMemo(() => items.map(item => {
if (isPtg(item.max)) {
return getPtg(item.max);
}
return (item.max || mergedContainerSize) / mergedContainerSize;
}), [items, mergedContainerSize]);
// Post handle the size. Will do:
// 1. Convert all the px into percentage if not empty.
// 2. Get rest percentage for exist percentage.
// 3. Fill the rest percentage into empty item.
const postPercentSizes = _react.default.useMemo(() => {
const ptgList = [];
// Fill default percentage
for (let i = 0; i < itemsCount; i += 1) {
const itemSize = sizes[i];
if (isPtg(itemSize)) {
ptgList[i] = getPtg(itemSize);
} else if (itemSize || itemSize === 0) {
const num = Number(itemSize);
if (!Number.isNaN(num)) {
ptgList[i] = num / mergedContainerSize;
}
} else {
ptgList[i] = undefined;
}
}
// Use autoPtgSizes to handle the undefined sizes
return (0, _sizeUtil.autoPtgSizes)(ptgList, postPercentMinSizes, postPercentMaxSizes);
}, [itemsCount, sizes, mergedContainerSize, postPercentMinSizes, postPercentMaxSizes]);
const postPxSizes = _react.default.useMemo(() => postPercentSizes.map(ptg2px), [postPercentSizes, mergedContainerSize]);
// If ssr, we will use the size from developer config first.
const panelSizes = _react.default.useMemo(() => containerSize ? postPxSizes : sizes, [postPxSizes, sizes, containerSize]);
return [panelSizes, postPxSizes, postPercentSizes, postPercentMinSizes, postPercentMaxSizes, setInnerSizes];
}
+8
View File
@@ -0,0 +1,8 @@
import Panel from './Panel';
import SplitterComp from './Splitter';
export type { DraggerSemantic, DraggerSemanticClassNames, DraggerSemanticStyles, SplitterProps, SplitterSemanticClassNames, SplitterSemanticName, SplitterSemanticStyles, } from './interface';
type CompoundedComponent = typeof SplitterComp & {
Panel: typeof Panel;
};
declare const Splitter: CompoundedComponent;
export default Splitter;
+13
View File
@@ -0,0 +1,13 @@
"use strict";
"use client";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _Panel = _interopRequireDefault(require("./Panel"));
var _Splitter = _interopRequireDefault(require("./Splitter"));
const Splitter = _Splitter.default;
Splitter.Panel = _Panel.default;
var _default = exports.default = Splitter;
+111
View File
@@ -0,0 +1,111 @@
import type { Orientation, SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { ShowCollapsibleIconMode } from './SplitBar';
export type SplitterSemanticName = keyof SplitterSemanticClassNames & keyof SplitterSemanticStyles;
export type SplitterSemanticClassNames = {
root?: string;
panel?: string;
};
export type SplitterSemanticStyles = {
root?: React.CSSProperties;
panel?: React.CSSProperties;
};
export type DraggerSemantic = keyof DraggerSemanticClassNames & keyof DraggerSemanticStyles;
export type DraggerSemanticClassNames = {
default?: string;
active?: string;
};
export type DraggerSemanticStyles = {
default?: React.CSSProperties;
active?: React.CSSProperties;
};
export interface SplitterSemanticDraggerClassNames {
default?: string;
active?: string;
}
export type SplitterClassNamesType = SemanticClassNamesType<SplitterProps, SplitterSemanticClassNames, {
dragger?: string | DraggerSemanticClassNames;
}>;
export type SplitterStylesType = SemanticStylesType<SplitterProps, SplitterSemanticStyles, {
dragger?: React.CSSProperties | DraggerSemanticStyles;
}>;
export interface SplitterProps {
prefixCls?: string;
className?: string;
classNames?: SplitterClassNamesType;
style?: React.CSSProperties;
styles?: SplitterStylesType;
rootClassName?: string;
/**
* @deprecated please use `orientation`
* @default horizontal
*/
layout?: Orientation;
orientation?: Orientation;
vertical?: boolean;
draggerIcon?: React.ReactNode;
collapsibleIcon?: {
start?: React.ReactNode;
end?: React.ReactNode;
};
onDraggerDoubleClick?: (index: number) => void;
onResizeStart?: (sizes: number[]) => void;
onResize?: (sizes: number[]) => void;
onResizeEnd?: (sizes: number[]) => void;
onCollapse?: (collapsed: boolean[], sizes: number[]) => void;
lazy?: boolean;
}
export interface PanelProps {
className?: string;
style?: React.CSSProperties;
min?: number | string;
max?: number | string;
size?: number | string;
collapsible?: boolean | {
start?: boolean;
end?: boolean;
showCollapsibleIcon?: ShowCollapsibleIconMode;
};
resizable?: boolean;
defaultSize?: number | string;
}
export interface InternalPanelProps extends PanelProps {
className?: string;
prefixCls?: string;
}
export interface UseResizeProps extends Pick<SplitterProps, 'onResize'> {
basicsState: number[];
items: PanelProps[];
panelsRef: React.RefObject<(HTMLDivElement | null)[]>;
reverse: boolean;
setBasicsState: React.Dispatch<React.SetStateAction<number[]>>;
}
export interface UseResize {
setSize: (data: {
size: number;
index: number;
}[]) => void;
setOffset: (offset: number, containerSize: number, index: number) => void;
}
export interface UseHandleProps extends Pick<SplitterProps, 'layout' | 'onResizeStart' | 'onResizeEnd'> {
basicsState: number[];
containerRef?: React.RefObject<HTMLDivElement | null>;
setOffset: UseResize['setOffset'];
setResizing: React.Dispatch<React.SetStateAction<boolean>>;
}
export interface UseHandle {
onStart: (x: number, y: number, index: number) => void;
}
export interface UseCollapsibleProps {
basicsState: number[];
collapsible?: PanelProps['collapsible'];
index: number;
reverse: boolean;
setSize?: UseResize['setSize'];
}
export interface UseCollapsible {
nextIcon: boolean;
overlap: boolean;
previousIcon: boolean;
onFold: (type: 'previous' | 'next') => void;
setOldBasics: () => void;
}
+5
View File
@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
+27
View File
@@ -0,0 +1,27 @@
import type { GetDefaultToken } from '../../theme/internal';
export interface ComponentToken {
/**
* @desc 拖拽标识元素大小
* @descEN Drag and drop the identity element size
* @deprecated Please use `splitBarDraggableSize` instead.
*/
resizeSpinnerSize: number;
/**
* @desc 拖拽标识元素大小
* @descEN Drag and drop the identity element size
*/
splitBarDraggableSize: number;
/**
* @desc 拖拽元素显示大小
* @descEN Drag the element display size
*/
splitBarSize: number;
/**
* @desc 拖拽触发区域大小
* @descEN Drag and drop trigger area size
*/
splitTriggerSize: number;
}
export declare const prepareComponentToken: GetDefaultToken<'Splitter'>;
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+319
View File
@@ -0,0 +1,319 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.prepareComponentToken = exports.default = void 0;
var _style = require("../../style");
var _internal = require("../../theme/internal");
var _genStyleUtils = require("../../theme/util/genStyleUtils");
const centerStyle = {
position: 'absolute',
top: '50%',
left: {
_skip_check_: true,
value: '50%'
},
transform: 'translate(-50%, -50%)'
};
const genSplitterStyle = token => {
const {
componentCls,
colorFill,
splitBarDraggableSize,
splitBarSize,
splitTriggerSize,
controlItemBgHover,
controlItemBgActive,
controlItemBgActiveHover,
colorPrimary,
antCls,
calc
} = token;
const [, varRef] = (0, _genStyleUtils.genCssVar)(antCls, 'splitter');
const splitBarCls = `${componentCls}-bar`;
const splitMaskCls = `${componentCls}-mask`;
const splitPanelCls = `${componentCls}-panel`;
const halfTriggerSize = calc(splitTriggerSize).div(2).equal();
const splitterBarPreviewStyle = {
position: 'absolute',
background: token.colorPrimary,
opacity: 0.2,
pointerEvents: 'none',
transition: 'none',
zIndex: 1,
display: 'none'
};
return {
[componentCls]: {
...(0, _style.resetComponent)(token),
display: 'flex',
width: '100%',
height: '100%',
alignItems: 'stretch',
// ======================== SplitBar ========================
// Use `>` to avoid conflict with mix layout
[`> ${splitBarCls}`]: {
flex: 'none',
position: 'relative',
userSelect: 'none',
// ======================= Dragger =======================
[`${splitBarCls}-dragger`]: {
...centerStyle,
zIndex: 1,
// Hover background
'&::before': {
content: '""',
background: controlItemBgHover,
...centerStyle
},
// Spinner
'&::after': {
content: '""',
background: colorFill,
...centerStyle
},
// Hover
[`&:hover:not(${splitBarCls}-dragger-active)`]: {
'&::before': {
background: controlItemBgActive
}
},
// Active
'&-active': {
zIndex: 2,
'&::before': {
background: controlItemBgActiveHover
}
},
[`&-active${splitBarCls}-dragger-customize`]: {
[`${splitBarCls}-dragger-icon`]: {
color: colorPrimary
}
},
// Disabled, not use `pointer-events: none` since still need trigger collapse
[`&-disabled${splitBarCls}-dragger`]: {
zIndex: 0,
'&, &:hover, &-active': {
cursor: 'default',
'&::before': {
background: controlItemBgHover
}
},
'&::after': {
display: 'none'
},
[`${splitBarCls}-dragger-icon`]: {
display: 'none'
}
},
// customize dragger icon
'&-customize': {
[`${splitBarCls}-dragger-icon`]: {
...centerStyle,
display: 'flex',
alignItems: 'center',
color: colorFill
},
'&::after': {
display: 'none'
}
}
},
// ======================= Collapse =======================
[`${splitBarCls}-collapse-bar`]: {
...centerStyle,
zIndex: token.zIndexPopupBase,
background: controlItemBgHover,
fontSize: token.fontSizeSM,
borderRadius: token.borderRadiusXS,
color: token.colorText,
cursor: 'pointer',
opacity: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
// Hover
[`&:hover:not(${splitBarCls}-collapse-bar-customize)`]: {
background: controlItemBgActive
},
// Active
[`&:active:not(${splitBarCls}-collapse-bar-customize)`]: {
background: controlItemBgActiveHover
},
[`${splitBarCls}-collapse-icon`]: {
display: 'flex',
alignItems: 'center'
}
},
[`${splitBarCls}-collapse-bar-customize`]: {
background: 'transparent'
},
'&:hover, &:active': {
[`${splitBarCls}-collapse-bar-hover-only`]: {
opacity: 1
}
},
[`${splitBarCls}-collapse-bar-hover-only`]: {
'@media(hover:none)': {
opacity: 1
}
},
[`${splitBarCls}-collapse-bar-always-hidden`]: {
display: 'none'
},
[`${splitBarCls}-collapse-bar-always-visible`]: {
opacity: 1
}
},
// =========================== Mask =========================
// Util dom for handle cursor
[splitMaskCls]: {
position: 'fixed',
zIndex: token.zIndexPopupBase,
inset: 0,
'&-horizontal': {
cursor: 'col-resize'
},
'&-vertical': {
cursor: 'row-resize'
}
},
// ==========================================================
// == Layout ==
// ==========================================================
'&-horizontal': {
flexDirection: 'row',
[`> ${splitBarCls}`]: {
width: 0,
// ======================= Preview =======================
[`${splitBarCls}-preview`]: {
height: '100%',
width: splitBarSize,
...splitterBarPreviewStyle,
[`&${splitBarCls}-preview-active`]: {
display: 'block',
transform: `translate3d(${varRef('bar-preview-offset')}, 0, 0)`
}
},
// ======================= Dragger =======================
[`${splitBarCls}-dragger`]: {
cursor: 'col-resize',
height: '100%',
width: splitTriggerSize,
'&::before': {
height: '100%',
width: splitBarSize
},
'&::after': {
height: splitBarDraggableSize,
width: splitBarSize
}
},
// ======================= Collapse =======================
[`${splitBarCls}-collapse-bar`]: {
width: token.fontSizeSM,
height: token.controlHeightSM,
'&-start': {
left: {
_skip_check_: true,
value: 'auto'
},
right: {
_skip_check_: true,
value: halfTriggerSize
},
transform: 'translateY(-50%)'
},
'&-end': {
left: {
_skip_check_: true,
value: halfTriggerSize
},
right: {
_skip_check_: true,
value: 'auto'
},
transform: 'translateY(-50%)'
}
}
}
},
'&-vertical': {
flexDirection: 'column',
[`> ${splitBarCls}`]: {
height: 0,
// ======================= Preview =======================
[`${splitBarCls}-preview`]: {
height: splitBarSize,
width: '100%',
...splitterBarPreviewStyle,
[`&${splitBarCls}-preview-active`]: {
display: 'block',
transform: `translate3d(0, ${varRef('bar-preview-offset')}, 0)`
}
},
// ======================= Dragger =======================
[`${splitBarCls}-dragger`]: {
cursor: 'row-resize',
width: '100%',
height: splitTriggerSize,
'&::before': {
width: '100%',
height: splitBarSize
},
'&::after': {
width: splitBarDraggableSize,
height: splitBarSize
}
},
// ======================= Collapse =======================
[`${splitBarCls}-collapse-bar`]: {
height: token.fontSizeSM,
width: token.controlHeightSM,
'&-start': {
top: 'auto',
bottom: halfTriggerSize,
transform: 'translateX(-50%)'
},
'&-end': {
top: halfTriggerSize,
bottom: 'auto',
transform: 'translateX(-50%)'
}
}
}
},
// ========================= Panels =========================
[splitPanelCls]: {
overflow: 'auto',
padding: '0 1px',
scrollbarWidth: 'thin',
boxSizing: 'border-box',
'&-hidden': {
padding: 0,
overflow: 'hidden'
},
[`&:has(${componentCls}:only-child)`]: {
overflow: 'hidden'
}
}
}
};
};
const prepareComponentToken = token => {
const splitBarSize = token.splitBarSize || 2;
const splitTriggerSize = token.splitTriggerSize || 6;
// https://github.com/ant-design/ant-design/pull/51223
const resizeSpinnerSize = token.resizeSpinnerSize || 20;
const splitBarDraggableSize = token.splitBarDraggableSize ?? resizeSpinnerSize;
return {
splitBarSize,
splitTriggerSize,
splitBarDraggableSize,
resizeSpinnerSize
};
};
// ============================== Export ==============================
exports.prepareComponentToken = prepareComponentToken;
var _default = exports.default = (0, _internal.genStyleHooks)('Splitter', genSplitterStyle, prepareComponentToken);