1
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
/// <reference types="react" />
|
||||
import type { Tab } from './interface';
|
||||
export interface TabContextProps {
|
||||
tabs: Tab[];
|
||||
prefixCls: string;
|
||||
}
|
||||
declare const _default: import("react").Context<TabContextProps>;
|
||||
export default _default;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _react = require("react");
|
||||
var _default = exports.default = /*#__PURE__*/(0, _react.createContext)(null);
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import type { EditableConfig, TabsLocale } from '../interface';
|
||||
export interface AddButtonProps {
|
||||
prefixCls: string;
|
||||
editable?: EditableConfig;
|
||||
locale?: TabsLocale;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
declare const AddButton: React.ForwardRefExoticComponent<AddButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
||||
export default AddButton;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const AddButton = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
prefixCls,
|
||||
editable,
|
||||
locale,
|
||||
style
|
||||
} = props;
|
||||
if (!editable || editable.showAdd === false) {
|
||||
return null;
|
||||
}
|
||||
return /*#__PURE__*/React.createElement("button", {
|
||||
ref: ref,
|
||||
type: "button",
|
||||
className: `${prefixCls}-nav-add`,
|
||||
style: style,
|
||||
"aria-label": locale?.addAriaLabel || 'Add tab',
|
||||
onClick: event => {
|
||||
editable.onEdit('add', {
|
||||
event
|
||||
});
|
||||
}
|
||||
}, editable.addIcon || '+');
|
||||
});
|
||||
var _default = exports.default = AddButton;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import type { TabBarExtraContent, TabBarExtraPosition } from '../interface';
|
||||
interface ExtraContentProps {
|
||||
position: TabBarExtraPosition;
|
||||
prefixCls: string;
|
||||
extra?: TabBarExtraContent;
|
||||
}
|
||||
declare const ExtraContent: React.ForwardRefExoticComponent<ExtraContentProps & React.RefAttributes<HTMLDivElement>>;
|
||||
export default ExtraContent;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const ExtraContent = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
position,
|
||||
prefixCls,
|
||||
extra
|
||||
} = props;
|
||||
if (!extra) {
|
||||
return null;
|
||||
}
|
||||
let content;
|
||||
|
||||
// Parse extra
|
||||
let assertExtra = {};
|
||||
if (typeof extra === 'object' && ! /*#__PURE__*/React.isValidElement(extra)) {
|
||||
assertExtra = extra;
|
||||
} else {
|
||||
assertExtra.right = extra;
|
||||
}
|
||||
if (position === 'right') {
|
||||
content = assertExtra.right;
|
||||
}
|
||||
if (position === 'left') {
|
||||
content = assertExtra.left;
|
||||
}
|
||||
return content ? /*#__PURE__*/React.createElement("div", {
|
||||
className: `${prefixCls}-extra-content`,
|
||||
ref: ref
|
||||
}, content) : null;
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
ExtraContent.displayName = 'ExtraContent';
|
||||
}
|
||||
var _default = exports.default = ExtraContent;
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import type { EditableConfig, Tab, TabsLocale, MoreProps } from '../interface';
|
||||
export interface OperationNodeProps {
|
||||
prefixCls: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
id: string;
|
||||
tabs: Tab[];
|
||||
rtl: boolean;
|
||||
tabBarGutter?: number;
|
||||
activeKey: string;
|
||||
mobile: boolean;
|
||||
more?: MoreProps;
|
||||
editable?: EditableConfig;
|
||||
locale?: TabsLocale;
|
||||
removeAriaLabel?: string;
|
||||
onTabClick: (key: string, e: React.MouseEvent | React.KeyboardEvent) => void;
|
||||
tabMoving?: boolean;
|
||||
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
||||
popupClassName?: string;
|
||||
popupStyle?: React.CSSProperties;
|
||||
}
|
||||
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<OperationNodeProps & React.RefAttributes<HTMLDivElement>>>;
|
||||
export default _default;
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var _dropdown = _interopRequireDefault(require("@rc-component/dropdown"));
|
||||
var _menu = _interopRequireWildcard(require("@rc-component/menu"));
|
||||
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
var React = _react;
|
||||
var _util = require("../util");
|
||||
var _AddButton = _interopRequireDefault(require("./AddButton"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
const OperationNode = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
prefixCls,
|
||||
id,
|
||||
tabs,
|
||||
locale,
|
||||
mobile,
|
||||
more: moreProps = {},
|
||||
style,
|
||||
className,
|
||||
editable,
|
||||
tabBarGutter,
|
||||
rtl,
|
||||
removeAriaLabel,
|
||||
onTabClick,
|
||||
getPopupContainer,
|
||||
popupClassName,
|
||||
popupStyle
|
||||
} = props;
|
||||
// ======================== Dropdown ========================
|
||||
const [open, setOpen] = (0, _react.useState)(false);
|
||||
const [selectedKey, setSelectedKey] = (0, _react.useState)(null);
|
||||
const {
|
||||
icon: moreIcon = 'More'
|
||||
} = moreProps;
|
||||
const popupId = `${id}-more-popup`;
|
||||
const dropdownPrefix = `${prefixCls}-dropdown`;
|
||||
const selectedItemId = selectedKey !== null ? `${popupId}-${selectedKey}` : null;
|
||||
const dropdownAriaLabel = locale?.dropdownAriaLabel;
|
||||
function onRemoveTab(event, key) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
editable.onEdit('remove', {
|
||||
key,
|
||||
event
|
||||
});
|
||||
}
|
||||
const menu = /*#__PURE__*/React.createElement(_menu.default, {
|
||||
onClick: ({
|
||||
key,
|
||||
domEvent
|
||||
}) => {
|
||||
onTabClick(key, domEvent);
|
||||
setOpen(false);
|
||||
},
|
||||
prefixCls: `${dropdownPrefix}-menu`,
|
||||
id: popupId,
|
||||
tabIndex: -1,
|
||||
role: "listbox",
|
||||
"aria-activedescendant": selectedItemId,
|
||||
selectedKeys: [selectedKey],
|
||||
"aria-label": dropdownAriaLabel !== undefined ? dropdownAriaLabel : 'expanded dropdown'
|
||||
}, tabs.map(tab => {
|
||||
const {
|
||||
closable,
|
||||
disabled,
|
||||
closeIcon,
|
||||
key,
|
||||
label
|
||||
} = tab;
|
||||
const removable = (0, _util.getRemovable)(closable, closeIcon, editable, disabled);
|
||||
return /*#__PURE__*/React.createElement(_menu.MenuItem, {
|
||||
key: key,
|
||||
id: `${popupId}-${key}`,
|
||||
role: "option",
|
||||
"aria-controls": id && `${id}-panel-${key}`,
|
||||
disabled: disabled
|
||||
}, /*#__PURE__*/React.createElement("span", null, label), removable && /*#__PURE__*/React.createElement("button", {
|
||||
type: "button",
|
||||
"aria-label": removeAriaLabel || 'remove',
|
||||
tabIndex: 0,
|
||||
className: `${dropdownPrefix}-menu-item-remove`,
|
||||
onClick: e => {
|
||||
e.stopPropagation();
|
||||
onRemoveTab(e, key);
|
||||
}
|
||||
}, closeIcon || editable.removeIcon || '×'));
|
||||
}));
|
||||
function selectOffset(offset) {
|
||||
const enabledTabs = tabs.filter(tab => !tab.disabled);
|
||||
let selectedIndex = enabledTabs.findIndex(tab => tab.key === selectedKey) || 0;
|
||||
const len = enabledTabs.length;
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
selectedIndex = (selectedIndex + offset + len) % len;
|
||||
const tab = enabledTabs[selectedIndex];
|
||||
if (!tab.disabled) {
|
||||
setSelectedKey(tab.key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
function onKeyDown(e) {
|
||||
const {
|
||||
which
|
||||
} = e;
|
||||
if (!open) {
|
||||
if ([_KeyCode.default.DOWN, _KeyCode.default.SPACE, _KeyCode.default.ENTER].includes(which)) {
|
||||
setOpen(true);
|
||||
e.preventDefault();
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (which) {
|
||||
case _KeyCode.default.UP:
|
||||
selectOffset(-1);
|
||||
e.preventDefault();
|
||||
break;
|
||||
case _KeyCode.default.DOWN:
|
||||
selectOffset(1);
|
||||
e.preventDefault();
|
||||
break;
|
||||
case _KeyCode.default.ESC:
|
||||
setOpen(false);
|
||||
break;
|
||||
case _KeyCode.default.SPACE:
|
||||
case _KeyCode.default.ENTER:
|
||||
if (selectedKey !== null) {
|
||||
onTabClick(selectedKey, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================= Effect =========================
|
||||
(0, _react.useEffect)(() => {
|
||||
// We use query element here to avoid React strict warning
|
||||
const ele = document.getElementById(selectedItemId);
|
||||
if (ele?.scrollIntoView) {
|
||||
ele.scrollIntoView(false);
|
||||
}
|
||||
}, [selectedItemId, selectedKey]);
|
||||
(0, _react.useEffect)(() => {
|
||||
if (!open) {
|
||||
setSelectedKey(null);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
// ========================= Render =========================
|
||||
const moreStyle = {
|
||||
marginInlineStart: tabBarGutter
|
||||
};
|
||||
if (!tabs.length) {
|
||||
moreStyle.visibility = 'hidden';
|
||||
moreStyle.order = 1;
|
||||
}
|
||||
const overlayClassName = (0, _clsx.clsx)(popupClassName, {
|
||||
[`${dropdownPrefix}-rtl`]: rtl
|
||||
});
|
||||
const moreNode = mobile ? null : /*#__PURE__*/React.createElement(_dropdown.default, _extends({
|
||||
prefixCls: dropdownPrefix,
|
||||
overlay: menu,
|
||||
visible: tabs.length ? open : false,
|
||||
onVisibleChange: setOpen,
|
||||
overlayClassName: overlayClassName,
|
||||
overlayStyle: popupStyle,
|
||||
mouseEnterDelay: 0.1,
|
||||
mouseLeaveDelay: 0.1,
|
||||
getPopupContainer: getPopupContainer
|
||||
}, moreProps), /*#__PURE__*/React.createElement("button", {
|
||||
type: "button",
|
||||
className: `${prefixCls}-nav-more`,
|
||||
style: moreStyle,
|
||||
"aria-haspopup": "listbox",
|
||||
"aria-controls": popupId,
|
||||
id: `${id}-more`,
|
||||
"aria-expanded": open,
|
||||
onKeyDown: onKeyDown
|
||||
}, moreIcon));
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: (0, _clsx.clsx)(`${prefixCls}-nav-operations`, className),
|
||||
style: style,
|
||||
ref: ref
|
||||
}, moreNode, /*#__PURE__*/React.createElement(_AddButton.default, {
|
||||
prefixCls: prefixCls,
|
||||
locale: locale,
|
||||
editable: editable
|
||||
}));
|
||||
});
|
||||
var _default = exports.default = /*#__PURE__*/React.memo(OperationNode, (_, next) =>
|
||||
// https://github.com/ant-design/ant-design/issues/32544
|
||||
// We'd better remove syntactic sugar in `rc-menu` since this has perf issue
|
||||
next.tabMoving);
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import * as React from 'react';
|
||||
import type { EditableConfig, Tab } from '../interface';
|
||||
export interface TabNodeProps {
|
||||
id: string;
|
||||
prefixCls: string;
|
||||
tab: Tab;
|
||||
active: boolean;
|
||||
focus: boolean;
|
||||
closable?: boolean;
|
||||
editable?: EditableConfig;
|
||||
onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;
|
||||
onResize?: (width: number, height: number, left: number, top: number) => void;
|
||||
renderWrapper?: (node: React.ReactElement) => React.ReactElement;
|
||||
removeAriaLabel?: string;
|
||||
tabCount: number;
|
||||
currentPosition: number;
|
||||
removeIcon?: React.ReactNode;
|
||||
onKeyDown: React.KeyboardEventHandler;
|
||||
onMouseDown: React.MouseEventHandler;
|
||||
onMouseUp: React.MouseEventHandler;
|
||||
onFocus: React.FocusEventHandler;
|
||||
onBlur: React.FocusEventHandler;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
declare const TabNode: React.FC<TabNodeProps>;
|
||||
export default TabNode;
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
var _util = require("../util");
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const TabNode = props => {
|
||||
const {
|
||||
prefixCls,
|
||||
id,
|
||||
active,
|
||||
focus,
|
||||
tab: {
|
||||
key,
|
||||
label,
|
||||
disabled,
|
||||
closeIcon,
|
||||
icon
|
||||
},
|
||||
closable,
|
||||
renderWrapper,
|
||||
removeAriaLabel,
|
||||
editable,
|
||||
onClick,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onKeyDown,
|
||||
onMouseDown,
|
||||
onMouseUp,
|
||||
style,
|
||||
className,
|
||||
tabCount,
|
||||
currentPosition
|
||||
} = props;
|
||||
const tabPrefix = `${prefixCls}-tab`;
|
||||
const removable = (0, _util.getRemovable)(closable, closeIcon, editable, disabled);
|
||||
function onInternalClick(e) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
onClick(e);
|
||||
}
|
||||
function onRemoveTab(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
editable.onEdit('remove', {
|
||||
key,
|
||||
event
|
||||
});
|
||||
}
|
||||
const labelNode = React.useMemo(() => icon && typeof label === 'string' ? /*#__PURE__*/React.createElement("span", null, label) : label, [label, icon]);
|
||||
const btnRef = React.useRef(null);
|
||||
React.useEffect(() => {
|
||||
if (focus && btnRef.current) {
|
||||
btnRef.current.focus();
|
||||
}
|
||||
}, [focus]);
|
||||
const node = /*#__PURE__*/React.createElement("div", {
|
||||
key: key,
|
||||
"data-node-key": (0, _util.genDataNodeKey)(key),
|
||||
className: (0, _clsx.clsx)(tabPrefix, className, {
|
||||
[`${tabPrefix}-with-remove`]: removable,
|
||||
[`${tabPrefix}-active`]: active,
|
||||
[`${tabPrefix}-disabled`]: disabled,
|
||||
[`${tabPrefix}-focus`]: focus
|
||||
}),
|
||||
style: style,
|
||||
onClick: onInternalClick
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
ref: btnRef,
|
||||
role: "tab",
|
||||
"aria-selected": active,
|
||||
id: id && `${id}-tab-${key}`,
|
||||
className: `${tabPrefix}-btn`,
|
||||
"aria-controls": id && `${id}-panel-${key}`,
|
||||
"aria-disabled": disabled,
|
||||
tabIndex: disabled ? null : active ? 0 : -1,
|
||||
onClick: e => {
|
||||
e.stopPropagation();
|
||||
onInternalClick(e);
|
||||
},
|
||||
onKeyDown: onKeyDown,
|
||||
onMouseDown: onMouseDown,
|
||||
onMouseUp: onMouseUp,
|
||||
onFocus: onFocus,
|
||||
onBlur: onBlur
|
||||
}, focus && /*#__PURE__*/React.createElement("div", {
|
||||
"aria-live": "polite",
|
||||
style: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
position: 'absolute',
|
||||
overflow: 'hidden',
|
||||
opacity: 0
|
||||
}
|
||||
}, `Tab ${currentPosition} of ${tabCount}`), icon && /*#__PURE__*/React.createElement("span", {
|
||||
className: `${tabPrefix}-icon`
|
||||
}, icon), label && labelNode), removable && /*#__PURE__*/React.createElement("button", {
|
||||
type: "button",
|
||||
"aria-label": removeAriaLabel || 'remove',
|
||||
tabIndex: active ? 0 : -1,
|
||||
className: `${tabPrefix}-remove`,
|
||||
onClick: e => {
|
||||
e.stopPropagation();
|
||||
onRemoveTab(e);
|
||||
}
|
||||
}, closeIcon || editable.removeIcon || '×'));
|
||||
return renderWrapper ? renderWrapper(node) : node;
|
||||
};
|
||||
var _default = exports.default = TabNode;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import type { TabNavListProps } from '.';
|
||||
export type TabNavListWrapperProps = Required<Omit<TabNavListProps, 'children' | 'className'>> & TabNavListProps;
|
||||
declare const TabNavListWrapper: React.FC<TabNavListWrapperProps>;
|
||||
export default TabNavListWrapper;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
var _ = _interopRequireDefault(require("."));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
// zombieJ: To compatible with `renderTabBar` usage.
|
||||
|
||||
// We have to create a TabNavList components.
|
||||
const TabNavListWrapper = ({
|
||||
renderTabBar,
|
||||
...restProps
|
||||
}) => {
|
||||
if (renderTabBar) {
|
||||
return renderTabBar(restProps, _.default);
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(_.default, restProps);
|
||||
};
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
TabNavListWrapper.displayName = 'TabNavListWrapper';
|
||||
}
|
||||
var _default = exports.default = TabNavListWrapper;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import * as React from 'react';
|
||||
import type { GetIndicatorSize } from '../hooks/useIndicator';
|
||||
import type { AnimatedConfig, EditableConfig, MoreProps, OnTabScroll, RenderTabBar, TabBarExtraContent, TabPosition, TabsLocale } from '../interface';
|
||||
import type { SemanticName } from '../Tabs';
|
||||
export interface TabNavListProps {
|
||||
id: string;
|
||||
tabPosition: TabPosition;
|
||||
activeKey: string;
|
||||
rtl: boolean;
|
||||
animated?: AnimatedConfig;
|
||||
extra?: TabBarExtraContent;
|
||||
editable?: EditableConfig;
|
||||
more?: MoreProps;
|
||||
mobile: boolean;
|
||||
tabBarGutter?: number;
|
||||
renderTabBar?: RenderTabBar;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
locale?: TabsLocale;
|
||||
onTabClick: (activeKey: string, e: React.MouseEvent | React.KeyboardEvent) => void;
|
||||
onTabScroll?: OnTabScroll;
|
||||
children?: (node: React.ReactElement) => React.ReactElement;
|
||||
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
||||
popupClassName?: string;
|
||||
indicator?: {
|
||||
size?: GetIndicatorSize;
|
||||
align?: 'start' | 'center' | 'end';
|
||||
};
|
||||
classNames?: Partial<Record<SemanticName, string>>;
|
||||
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
|
||||
}
|
||||
declare const TabNavList: React.ForwardRefExoticComponent<TabNavListProps & React.RefAttributes<HTMLDivElement>>;
|
||||
export default TabNavList;
|
||||
+598
@@ -0,0 +1,598 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var _resizeObserver = _interopRequireDefault(require("@rc-component/resize-observer"));
|
||||
var _useEvent = _interopRequireDefault(require("@rc-component/util/lib/hooks/useEvent"));
|
||||
var _ref = require("@rc-component/util/lib/ref");
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
var React = _react;
|
||||
var _TabContext = _interopRequireDefault(require("../TabContext"));
|
||||
var _useIndicator = _interopRequireDefault(require("../hooks/useIndicator"));
|
||||
var _useOffsets = _interopRequireDefault(require("../hooks/useOffsets"));
|
||||
var _useSyncState = _interopRequireDefault(require("../hooks/useSyncState"));
|
||||
var _useTouchMove = _interopRequireDefault(require("../hooks/useTouchMove"));
|
||||
var _useUpdate = _interopRequireWildcard(require("../hooks/useUpdate"));
|
||||
var _useVisibleRange = _interopRequireDefault(require("../hooks/useVisibleRange"));
|
||||
var _util = require("../util");
|
||||
var _AddButton = _interopRequireDefault(require("./AddButton"));
|
||||
var _ExtraContent = _interopRequireDefault(require("./ExtraContent"));
|
||||
var _OperationNode = _interopRequireDefault(require("./OperationNode"));
|
||||
var _TabNode = _interopRequireDefault(require("./TabNode"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
const getTabSize = (tab, containerRect) => {
|
||||
// tabListRef
|
||||
const {
|
||||
offsetWidth,
|
||||
offsetHeight,
|
||||
offsetTop,
|
||||
offsetLeft
|
||||
} = tab;
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
left,
|
||||
top
|
||||
} = tab.getBoundingClientRect();
|
||||
|
||||
// Use getBoundingClientRect to avoid decimal inaccuracy
|
||||
if (Math.abs(width - offsetWidth) < 1) {
|
||||
return [width, height, left - containerRect.left, top - containerRect.top];
|
||||
}
|
||||
return [offsetWidth, offsetHeight, offsetLeft, offsetTop];
|
||||
};
|
||||
const getSize = refObj => {
|
||||
const {
|
||||
offsetWidth = 0,
|
||||
offsetHeight = 0
|
||||
} = refObj.current || {};
|
||||
|
||||
// Use getBoundingClientRect to avoid decimal inaccuracy
|
||||
if (refObj.current) {
|
||||
const {
|
||||
width,
|
||||
height
|
||||
} = refObj.current.getBoundingClientRect();
|
||||
if (Math.abs(width - offsetWidth) < 1) {
|
||||
return [width, height];
|
||||
}
|
||||
}
|
||||
return [offsetWidth, offsetHeight];
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert `SizeInfo` to unit value. Such as [123, 456] with `top` position get `123`
|
||||
*/
|
||||
const getUnitValue = (size, tabPositionTopOrBottom) => {
|
||||
return size[tabPositionTopOrBottom ? 0 : 1];
|
||||
};
|
||||
const TabNavList = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
className,
|
||||
style,
|
||||
id,
|
||||
animated,
|
||||
activeKey,
|
||||
rtl,
|
||||
extra,
|
||||
editable,
|
||||
locale,
|
||||
tabPosition,
|
||||
tabBarGutter,
|
||||
children,
|
||||
onTabClick,
|
||||
onTabScroll,
|
||||
indicator,
|
||||
classNames: tabsClassNames,
|
||||
styles
|
||||
} = props;
|
||||
const {
|
||||
prefixCls,
|
||||
tabs
|
||||
} = React.useContext(_TabContext.default);
|
||||
const containerRef = (0, _react.useRef)(null);
|
||||
const extraLeftRef = (0, _react.useRef)(null);
|
||||
const extraRightRef = (0, _react.useRef)(null);
|
||||
const tabsWrapperRef = (0, _react.useRef)(null);
|
||||
const tabListRef = (0, _react.useRef)(null);
|
||||
const operationsRef = (0, _react.useRef)(null);
|
||||
const innerAddButtonRef = (0, _react.useRef)(null);
|
||||
const tabPositionTopOrBottom = tabPosition === 'top' || tabPosition === 'bottom';
|
||||
const [transformLeft, setTransformLeft] = (0, _useSyncState.default)(0, (next, prev) => {
|
||||
if (tabPositionTopOrBottom && onTabScroll) {
|
||||
onTabScroll({
|
||||
direction: next > prev ? 'left' : 'right'
|
||||
});
|
||||
}
|
||||
});
|
||||
const [transformTop, setTransformTop] = (0, _useSyncState.default)(0, (next, prev) => {
|
||||
if (!tabPositionTopOrBottom && onTabScroll) {
|
||||
onTabScroll({
|
||||
direction: next > prev ? 'top' : 'bottom'
|
||||
});
|
||||
}
|
||||
});
|
||||
const [containerExcludeExtraSize, setContainerExcludeExtraSize] = (0, _react.useState)([0, 0]);
|
||||
const [tabContentSize, setTabContentSize] = (0, _react.useState)([0, 0]);
|
||||
const [addSize, setAddSize] = (0, _react.useState)([0, 0]);
|
||||
const [operationSize, setOperationSize] = (0, _react.useState)([0, 0]);
|
||||
const [tabSizes, setTabSizes] = (0, _useUpdate.useUpdateState)(new Map());
|
||||
const tabOffsets = (0, _useOffsets.default)(tabs, tabSizes, tabContentSize[0]);
|
||||
|
||||
// ========================== Unit =========================
|
||||
const containerExcludeExtraSizeValue = getUnitValue(containerExcludeExtraSize, tabPositionTopOrBottom);
|
||||
const tabContentSizeValue = getUnitValue(tabContentSize, tabPositionTopOrBottom);
|
||||
const addSizeValue = getUnitValue(addSize, tabPositionTopOrBottom);
|
||||
const operationSizeValue = getUnitValue(operationSize, tabPositionTopOrBottom);
|
||||
const needScroll = Math.floor(containerExcludeExtraSizeValue) < Math.floor(tabContentSizeValue + addSizeValue);
|
||||
const visibleTabContentValue = needScroll ? containerExcludeExtraSizeValue - operationSizeValue : containerExcludeExtraSizeValue - addSizeValue;
|
||||
|
||||
// ========================== Util =========================
|
||||
const operationsHiddenClassName = `${prefixCls}-nav-operations-hidden`;
|
||||
let transformMin = 0;
|
||||
let transformMax = 0;
|
||||
if (!tabPositionTopOrBottom) {
|
||||
transformMin = Math.min(0, visibleTabContentValue - tabContentSizeValue);
|
||||
transformMax = 0;
|
||||
} else if (rtl) {
|
||||
transformMin = 0;
|
||||
transformMax = Math.max(0, tabContentSizeValue - visibleTabContentValue);
|
||||
} else {
|
||||
transformMin = Math.min(0, visibleTabContentValue - tabContentSizeValue);
|
||||
transformMax = 0;
|
||||
}
|
||||
function alignInRange(value) {
|
||||
if (value < transformMin) {
|
||||
return transformMin;
|
||||
}
|
||||
if (value > transformMax) {
|
||||
return transformMax;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// ========================= Mobile ========================
|
||||
const touchMovingRef = (0, _react.useRef)(null);
|
||||
const [lockAnimation, setLockAnimation] = (0, _react.useState)();
|
||||
function doLockAnimation() {
|
||||
setLockAnimation(Date.now());
|
||||
}
|
||||
function clearTouchMoving() {
|
||||
if (touchMovingRef.current) {
|
||||
clearTimeout(touchMovingRef.current);
|
||||
}
|
||||
}
|
||||
(0, _useTouchMove.default)(tabsWrapperRef, (offsetX, offsetY) => {
|
||||
function doMove(setState, offset) {
|
||||
setState(value => {
|
||||
const newValue = alignInRange(value + offset);
|
||||
return newValue;
|
||||
});
|
||||
}
|
||||
|
||||
// Skip scroll if place is enough
|
||||
if (!needScroll) {
|
||||
return false;
|
||||
}
|
||||
if (tabPositionTopOrBottom) {
|
||||
doMove(setTransformLeft, offsetX);
|
||||
} else {
|
||||
doMove(setTransformTop, offsetY);
|
||||
}
|
||||
clearTouchMoving();
|
||||
doLockAnimation();
|
||||
return true;
|
||||
});
|
||||
(0, _react.useEffect)(() => {
|
||||
clearTouchMoving();
|
||||
if (lockAnimation) {
|
||||
touchMovingRef.current = setTimeout(() => {
|
||||
setLockAnimation(0);
|
||||
}, 100);
|
||||
}
|
||||
return clearTouchMoving;
|
||||
}, [lockAnimation]);
|
||||
|
||||
// ===================== Visible Range =====================
|
||||
// Render tab node & collect tab offset
|
||||
const [visibleStart, visibleEnd] = (0, _useVisibleRange.default)(tabOffsets,
|
||||
// Container
|
||||
visibleTabContentValue,
|
||||
// Transform
|
||||
tabPositionTopOrBottom ? transformLeft : transformTop,
|
||||
// Tabs
|
||||
tabContentSizeValue,
|
||||
// Add
|
||||
addSizeValue,
|
||||
// Operation
|
||||
operationSizeValue, {
|
||||
...props,
|
||||
tabs
|
||||
});
|
||||
|
||||
// ========================= Scroll ========================
|
||||
const scrollToTab = (0, _useEvent.default)((key = activeKey) => {
|
||||
const tabOffset = tabOffsets.get(key) || {
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0
|
||||
};
|
||||
if (tabPositionTopOrBottom) {
|
||||
// ============ Align with top & bottom ============
|
||||
let newTransform = transformLeft;
|
||||
|
||||
// RTL
|
||||
if (rtl) {
|
||||
if (tabOffset.right < transformLeft) {
|
||||
newTransform = tabOffset.right;
|
||||
} else if (tabOffset.right + tabOffset.width > transformLeft + visibleTabContentValue) {
|
||||
newTransform = tabOffset.right + tabOffset.width - visibleTabContentValue;
|
||||
}
|
||||
}
|
||||
// LTR
|
||||
else if (tabOffset.left < -transformLeft) {
|
||||
newTransform = -tabOffset.left;
|
||||
} else if (tabOffset.left + tabOffset.width > -transformLeft + visibleTabContentValue) {
|
||||
newTransform = -(tabOffset.left + tabOffset.width - visibleTabContentValue);
|
||||
}
|
||||
setTransformTop(0);
|
||||
setTransformLeft(alignInRange(newTransform));
|
||||
} else {
|
||||
// ============ Align with left & right ============
|
||||
let newTransform = transformTop;
|
||||
if (tabOffset.top < -transformTop) {
|
||||
newTransform = -tabOffset.top;
|
||||
} else if (tabOffset.top + tabOffset.height > -transformTop + visibleTabContentValue) {
|
||||
newTransform = -(tabOffset.top + tabOffset.height - visibleTabContentValue);
|
||||
}
|
||||
setTransformLeft(0);
|
||||
setTransformTop(alignInRange(newTransform));
|
||||
}
|
||||
});
|
||||
|
||||
// ========================= Focus =========================
|
||||
const [focusKey, setFocusKey] = (0, _react.useState)();
|
||||
const [isMouse, setIsMouse] = (0, _react.useState)(false);
|
||||
const enabledTabs = tabs.filter(tab => !tab.disabled).map(tab => tab.key);
|
||||
const onOffset = offset => {
|
||||
const currentIndex = enabledTabs.indexOf(focusKey || activeKey);
|
||||
const len = enabledTabs.length;
|
||||
const nextIndex = (currentIndex + offset + len) % len;
|
||||
const newKey = enabledTabs[nextIndex];
|
||||
setFocusKey(newKey);
|
||||
};
|
||||
const handleRemoveTab = (removalTabKey, e) => {
|
||||
const removeIndex = enabledTabs.indexOf(removalTabKey);
|
||||
const removeTab = tabs.find(tab => tab.key === removalTabKey);
|
||||
const removable = (0, _util.getRemovable)(removeTab?.closable, removeTab?.closeIcon, editable, removeTab?.disabled);
|
||||
if (removable) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
editable.onEdit('remove', {
|
||||
key: removalTabKey,
|
||||
event: e
|
||||
});
|
||||
|
||||
// when remove last tab, focus previous tab
|
||||
if (removeIndex === enabledTabs.length - 1) {
|
||||
onOffset(-1);
|
||||
} else {
|
||||
onOffset(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleMouseDown = (key, e) => {
|
||||
setIsMouse(true);
|
||||
// Middle mouse button
|
||||
if (e.button === 1) {
|
||||
handleRemoveTab(key, e);
|
||||
}
|
||||
};
|
||||
const handleKeyDown = e => {
|
||||
const {
|
||||
code
|
||||
} = e;
|
||||
const isRTL = rtl && tabPositionTopOrBottom;
|
||||
const firstEnabledTab = enabledTabs[0];
|
||||
const lastEnabledTab = enabledTabs[enabledTabs.length - 1];
|
||||
switch (code) {
|
||||
// LEFT
|
||||
case 'ArrowLeft':
|
||||
{
|
||||
if (tabPositionTopOrBottom) {
|
||||
onOffset(isRTL ? 1 : -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// RIGHT
|
||||
case 'ArrowRight':
|
||||
{
|
||||
if (tabPositionTopOrBottom) {
|
||||
onOffset(isRTL ? -1 : 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// UP
|
||||
case 'ArrowUp':
|
||||
{
|
||||
e.preventDefault();
|
||||
if (!tabPositionTopOrBottom) {
|
||||
onOffset(-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// DOWN
|
||||
case 'ArrowDown':
|
||||
{
|
||||
e.preventDefault();
|
||||
if (!tabPositionTopOrBottom) {
|
||||
onOffset(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// HOME
|
||||
case 'Home':
|
||||
{
|
||||
e.preventDefault();
|
||||
setFocusKey(firstEnabledTab);
|
||||
break;
|
||||
}
|
||||
|
||||
// END
|
||||
case 'End':
|
||||
{
|
||||
e.preventDefault();
|
||||
setFocusKey(lastEnabledTab);
|
||||
break;
|
||||
}
|
||||
|
||||
// Enter & Space
|
||||
case 'Enter':
|
||||
case 'Space':
|
||||
{
|
||||
e.preventDefault();
|
||||
onTabClick(focusKey ?? activeKey, e);
|
||||
break;
|
||||
}
|
||||
// Backspace
|
||||
case 'Backspace':
|
||||
case 'Delete':
|
||||
{
|
||||
handleRemoveTab(focusKey, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ========================== Tab ==========================
|
||||
const tabNodeStyle = {};
|
||||
if (tabPositionTopOrBottom) {
|
||||
tabNodeStyle.marginInlineStart = tabBarGutter;
|
||||
} else {
|
||||
tabNodeStyle.marginTop = tabBarGutter;
|
||||
}
|
||||
const tabNodes = tabs.map((tab, i) => {
|
||||
const {
|
||||
key
|
||||
} = tab;
|
||||
return /*#__PURE__*/React.createElement(_TabNode.default, {
|
||||
id: id,
|
||||
prefixCls: prefixCls,
|
||||
key: key,
|
||||
tab: tab,
|
||||
className: tabsClassNames?.item
|
||||
/* first node should not have margin left */,
|
||||
style: i === 0 ? styles?.item : {
|
||||
...tabNodeStyle,
|
||||
...styles?.item
|
||||
},
|
||||
closable: tab.closable,
|
||||
editable: editable,
|
||||
active: key === activeKey,
|
||||
focus: key === focusKey,
|
||||
renderWrapper: children,
|
||||
removeAriaLabel: locale?.removeAriaLabel,
|
||||
tabCount: enabledTabs.length,
|
||||
currentPosition: i + 1,
|
||||
onClick: e => {
|
||||
onTabClick(key, e);
|
||||
},
|
||||
onKeyDown: handleKeyDown,
|
||||
onFocus: () => {
|
||||
if (!isMouse) {
|
||||
setFocusKey(key);
|
||||
}
|
||||
scrollToTab(key);
|
||||
doLockAnimation();
|
||||
if (!tabsWrapperRef.current) {
|
||||
return;
|
||||
}
|
||||
// Focus element will make scrollLeft change which we should reset back
|
||||
if (!rtl) {
|
||||
tabsWrapperRef.current.scrollLeft = 0;
|
||||
}
|
||||
tabsWrapperRef.current.scrollTop = 0;
|
||||
},
|
||||
onBlur: () => {
|
||||
setFocusKey(undefined);
|
||||
},
|
||||
onMouseDown: e => handleMouseDown(key, e),
|
||||
onMouseUp: () => {
|
||||
setIsMouse(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Update buttons records
|
||||
const updateTabSizes = () => setTabSizes(() => {
|
||||
const newSizes = new Map();
|
||||
const listRect = tabListRef.current?.getBoundingClientRect();
|
||||
tabs.forEach(({
|
||||
key
|
||||
}) => {
|
||||
const btnNode = tabListRef.current?.querySelector(`[data-node-key="${(0, _util.genDataNodeKey)(key)}"]`);
|
||||
if (btnNode) {
|
||||
const [width, height, left, top] = getTabSize(btnNode, listRect);
|
||||
newSizes.set(key, {
|
||||
width,
|
||||
height,
|
||||
left,
|
||||
top
|
||||
});
|
||||
}
|
||||
});
|
||||
return newSizes;
|
||||
});
|
||||
(0, _react.useEffect)(() => {
|
||||
updateTabSizes();
|
||||
}, [tabs.map(tab => tab.key).join('_')]);
|
||||
const onListHolderResize = (0, _useUpdate.default)(() => {
|
||||
// Update wrapper records
|
||||
const containerSize = getSize(containerRef);
|
||||
const extraLeftSize = getSize(extraLeftRef);
|
||||
const extraRightSize = getSize(extraRightRef);
|
||||
setContainerExcludeExtraSize([containerSize[0] - extraLeftSize[0] - extraRightSize[0], containerSize[1] - extraLeftSize[1] - extraRightSize[1]]);
|
||||
const newAddSize = getSize(innerAddButtonRef);
|
||||
setAddSize(newAddSize);
|
||||
const newOperationSize = getSize(operationsRef);
|
||||
setOperationSize(newOperationSize);
|
||||
|
||||
// Which includes add button size
|
||||
const tabContentFullSize = getSize(tabListRef);
|
||||
setTabContentSize([tabContentFullSize[0] - newAddSize[0], tabContentFullSize[1] - newAddSize[1]]);
|
||||
|
||||
// Update buttons records
|
||||
updateTabSizes();
|
||||
});
|
||||
|
||||
// ======================== Dropdown =======================
|
||||
const startHiddenTabs = tabs.slice(0, visibleStart);
|
||||
const endHiddenTabs = tabs.slice(visibleEnd + 1);
|
||||
const hiddenTabs = [...startHiddenTabs, ...endHiddenTabs];
|
||||
|
||||
// =================== Link & Operations ===================
|
||||
const activeTabOffset = tabOffsets.get(activeKey);
|
||||
const {
|
||||
style: indicatorStyle
|
||||
} = (0, _useIndicator.default)({
|
||||
activeTabOffset,
|
||||
horizontal: tabPositionTopOrBottom,
|
||||
indicator,
|
||||
rtl
|
||||
});
|
||||
|
||||
// ========================= Effect ========================
|
||||
(0, _react.useEffect)(() => {
|
||||
scrollToTab();
|
||||
}, [activeKey, transformMin, transformMax, (0, _util.stringify)(activeTabOffset), (0, _util.stringify)(tabOffsets), tabPositionTopOrBottom]);
|
||||
|
||||
// Should recalculate when rtl changed
|
||||
(0, _react.useEffect)(() => {
|
||||
onListHolderResize();
|
||||
// eslint-disable-next-line
|
||||
}, [rtl]);
|
||||
|
||||
// ========================= Render ========================
|
||||
const hasDropdown = !!hiddenTabs.length;
|
||||
const wrapPrefix = `${prefixCls}-nav-wrap`;
|
||||
let pingLeft;
|
||||
let pingRight;
|
||||
let pingTop;
|
||||
let pingBottom;
|
||||
if (tabPositionTopOrBottom) {
|
||||
if (rtl) {
|
||||
pingRight = transformLeft > 0;
|
||||
pingLeft = transformLeft !== transformMax;
|
||||
} else {
|
||||
pingLeft = transformLeft < 0;
|
||||
pingRight = transformLeft !== transformMin;
|
||||
}
|
||||
} else {
|
||||
pingTop = transformTop < 0;
|
||||
pingBottom = transformTop !== transformMin;
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(_resizeObserver.default, {
|
||||
onResize: onListHolderResize
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
ref: (0, _ref.useComposeRef)(ref, containerRef),
|
||||
role: "tablist",
|
||||
"aria-orientation": tabPositionTopOrBottom ? 'horizontal' : 'vertical',
|
||||
className: (0, _clsx.clsx)(`${prefixCls}-nav`, className, tabsClassNames?.header),
|
||||
style: {
|
||||
...styles?.header,
|
||||
...style
|
||||
},
|
||||
onKeyDown: () => {
|
||||
// No need animation when use keyboard
|
||||
doLockAnimation();
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(_ExtraContent.default, {
|
||||
ref: extraLeftRef,
|
||||
position: "left",
|
||||
extra: extra,
|
||||
prefixCls: prefixCls
|
||||
}), /*#__PURE__*/React.createElement(_resizeObserver.default, {
|
||||
onResize: onListHolderResize
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: (0, _clsx.clsx)(wrapPrefix, {
|
||||
[`${wrapPrefix}-ping-left`]: pingLeft,
|
||||
[`${wrapPrefix}-ping-right`]: pingRight,
|
||||
[`${wrapPrefix}-ping-top`]: pingTop,
|
||||
[`${wrapPrefix}-ping-bottom`]: pingBottom
|
||||
}),
|
||||
ref: tabsWrapperRef
|
||||
}, /*#__PURE__*/React.createElement(_resizeObserver.default, {
|
||||
onResize: onListHolderResize
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
ref: tabListRef,
|
||||
className: `${prefixCls}-nav-list`,
|
||||
style: {
|
||||
transform: `translate(${transformLeft}px, ${transformTop}px)`,
|
||||
transition: lockAnimation ? 'none' : undefined
|
||||
}
|
||||
}, tabNodes, /*#__PURE__*/React.createElement(_AddButton.default, {
|
||||
ref: innerAddButtonRef,
|
||||
prefixCls: prefixCls,
|
||||
locale: locale,
|
||||
editable: editable,
|
||||
style: {
|
||||
...(tabNodes.length === 0 ? undefined : tabNodeStyle),
|
||||
visibility: hasDropdown ? 'hidden' : null
|
||||
}
|
||||
}), /*#__PURE__*/React.createElement("div", {
|
||||
className: (0, _clsx.clsx)(`${prefixCls}-ink-bar`, tabsClassNames?.indicator, {
|
||||
[`${prefixCls}-ink-bar-animated`]: animated.inkBar
|
||||
}),
|
||||
style: {
|
||||
...indicatorStyle,
|
||||
...styles?.indicator
|
||||
}
|
||||
}))))), /*#__PURE__*/React.createElement(_OperationNode.default, _extends({}, props, {
|
||||
removeAriaLabel: locale?.removeAriaLabel,
|
||||
ref: operationsRef,
|
||||
prefixCls: prefixCls,
|
||||
tabs: hiddenTabs,
|
||||
className: !hasDropdown && operationsHiddenClassName,
|
||||
popupStyle: styles?.popup,
|
||||
tabMoving: !!lockAnimation
|
||||
})), /*#__PURE__*/React.createElement(_ExtraContent.default, {
|
||||
ref: extraRightRef,
|
||||
position: "right",
|
||||
extra: extra,
|
||||
prefixCls: prefixCls
|
||||
})));
|
||||
/* eslint-enable */
|
||||
});
|
||||
var _default = exports.default = TabNavList;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react';
|
||||
export interface TabPaneProps {
|
||||
tab?: React.ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
disabled?: boolean;
|
||||
children?: React.ReactNode;
|
||||
forceRender?: boolean;
|
||||
closable?: boolean;
|
||||
closeIcon?: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
prefixCls?: string;
|
||||
tabKey?: string;
|
||||
id?: string;
|
||||
animated?: boolean;
|
||||
active?: boolean;
|
||||
destroyOnHidden?: boolean;
|
||||
}
|
||||
declare const TabPane: React.ForwardRefExoticComponent<TabPaneProps & React.RefAttributes<HTMLDivElement>>;
|
||||
export default TabPane;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const TabPane = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
prefixCls,
|
||||
className,
|
||||
style,
|
||||
id,
|
||||
active,
|
||||
tabKey,
|
||||
children
|
||||
} = props;
|
||||
const hasContent = React.Children.count(children) > 0;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
id: id && `${id}-panel-${tabKey}`,
|
||||
role: "tabpanel",
|
||||
tabIndex: active && hasContent ? 0 : -1,
|
||||
"aria-labelledby": id && `${id}-tab-${tabKey}`,
|
||||
"aria-hidden": !active,
|
||||
style: style,
|
||||
className: (0, _clsx.clsx)(prefixCls, active && `${prefixCls}-active`, className),
|
||||
ref: ref
|
||||
}, children);
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
TabPane.displayName = 'TabPane';
|
||||
}
|
||||
var _default = exports.default = TabPane;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import type { AnimatedConfig, TabPosition } from '../interface';
|
||||
export interface TabPanelListProps {
|
||||
activeKey: string;
|
||||
id: string;
|
||||
animated?: AnimatedConfig;
|
||||
tabPosition?: TabPosition;
|
||||
destroyOnHidden?: boolean;
|
||||
contentStyle?: React.CSSProperties;
|
||||
contentClassName?: string;
|
||||
}
|
||||
declare const TabPanelList: React.FC<TabPanelListProps>;
|
||||
export default TabPanelList;
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var _motion = _interopRequireDefault(require("@rc-component/motion"));
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
var _TabContext = _interopRequireDefault(require("../TabContext"));
|
||||
var _TabPane = _interopRequireDefault(require("./TabPane"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||
const TabPanelList = props => {
|
||||
const {
|
||||
id,
|
||||
activeKey,
|
||||
animated,
|
||||
tabPosition,
|
||||
destroyOnHidden,
|
||||
contentStyle,
|
||||
contentClassName
|
||||
} = props;
|
||||
const {
|
||||
prefixCls,
|
||||
tabs
|
||||
} = React.useContext(_TabContext.default);
|
||||
const tabPaneAnimated = animated.tabPane;
|
||||
const tabPanePrefixCls = `${prefixCls}-tabpane`;
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
className: (0, _clsx.clsx)(`${prefixCls}-content-holder`)
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: (0, _clsx.clsx)(`${prefixCls}-content`, `${prefixCls}-content-${tabPosition}`, {
|
||||
[`${prefixCls}-content-animated`]: tabPaneAnimated
|
||||
})
|
||||
}, tabs.map(item => {
|
||||
const {
|
||||
key,
|
||||
forceRender,
|
||||
style: paneStyle,
|
||||
className: paneClassName,
|
||||
destroyOnHidden: itemDestroyOnHidden,
|
||||
...restTabProps
|
||||
} = item;
|
||||
const active = key === activeKey;
|
||||
return /*#__PURE__*/React.createElement(_motion.default, _extends({
|
||||
key: key,
|
||||
visible: active,
|
||||
forceRender: forceRender,
|
||||
removeOnLeave: !!(destroyOnHidden ?? itemDestroyOnHidden),
|
||||
leavedClassName: `${tabPanePrefixCls}-hidden`
|
||||
}, animated.tabPaneMotion), ({
|
||||
style: motionStyle,
|
||||
className: motionClassName
|
||||
}, ref) => /*#__PURE__*/React.createElement(_TabPane.default, _extends({}, restTabProps, {
|
||||
prefixCls: tabPanePrefixCls,
|
||||
id: id,
|
||||
tabKey: key,
|
||||
animated: tabPaneAnimated,
|
||||
active: active,
|
||||
style: {
|
||||
...contentStyle,
|
||||
...paneStyle,
|
||||
...motionStyle
|
||||
},
|
||||
className: (0, _clsx.clsx)(contentClassName, paneClassName, motionClassName),
|
||||
ref: ref
|
||||
})));
|
||||
})));
|
||||
};
|
||||
var _default = exports.default = TabPanelList;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import * as React from 'react';
|
||||
import type { GetIndicatorSize } from './hooks/useIndicator';
|
||||
import type { AnimatedConfig, EditableConfig, MoreProps, OnTabScroll, RenderTabBar, Tab, TabBarExtraContent, TabPosition, TabsLocale } from './interface';
|
||||
export type SemanticName = 'popup' | 'item' | 'indicator' | 'content' | 'header';
|
||||
export interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'children'> {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
classNames?: Partial<Record<SemanticName, string>>;
|
||||
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
|
||||
id?: string;
|
||||
items?: Tab[];
|
||||
activeKey?: string;
|
||||
defaultActiveKey?: string;
|
||||
direction?: 'ltr' | 'rtl';
|
||||
animated?: boolean | AnimatedConfig;
|
||||
renderTabBar?: RenderTabBar;
|
||||
tabBarExtraContent?: TabBarExtraContent;
|
||||
tabBarGutter?: number;
|
||||
tabBarStyle?: React.CSSProperties;
|
||||
tabPosition?: TabPosition;
|
||||
destroyOnHidden?: boolean;
|
||||
onChange?: (activeKey: string) => void;
|
||||
onTabClick?: (activeKey: string, e: React.KeyboardEvent | React.MouseEvent) => void;
|
||||
onTabScroll?: OnTabScroll;
|
||||
editable?: EditableConfig;
|
||||
getPopupContainer?: (node: HTMLElement) => HTMLElement;
|
||||
locale?: TabsLocale;
|
||||
more?: MoreProps;
|
||||
/** @private Internal usage. Not promise will rename in future */
|
||||
popupClassName?: string;
|
||||
indicator?: {
|
||||
size?: GetIndicatorSize;
|
||||
align?: 'start' | 'center' | 'end';
|
||||
};
|
||||
}
|
||||
declare const Tabs: React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<HTMLDivElement>>;
|
||||
export default Tabs;
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _clsx = require("clsx");
|
||||
var _useControlledState = _interopRequireDefault(require("@rc-component/util/lib/hooks/useControlledState"));
|
||||
var _isMobile = _interopRequireDefault(require("@rc-component/util/lib/isMobile"));
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
var React = _react;
|
||||
var _TabContext = _interopRequireDefault(require("./TabContext"));
|
||||
var _Wrapper = _interopRequireDefault(require("./TabNavList/Wrapper"));
|
||||
var _TabPanelList = _interopRequireDefault(require("./TabPanelList"));
|
||||
var _useAnimateConfig = _interopRequireDefault(require("./hooks/useAnimateConfig"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } // Accessibility https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role
|
||||
/**
|
||||
* Should added antd:
|
||||
* - type
|
||||
*
|
||||
* Removed:
|
||||
* - onNextClick
|
||||
* - onPrevClick
|
||||
* - keyboard
|
||||
*/
|
||||
|
||||
// Used for accessibility
|
||||
let uuid = 0;
|
||||
const Tabs = /*#__PURE__*/React.forwardRef((props, ref) => {
|
||||
const {
|
||||
id,
|
||||
prefixCls = 'rc-tabs',
|
||||
className,
|
||||
items,
|
||||
direction,
|
||||
activeKey,
|
||||
defaultActiveKey,
|
||||
editable,
|
||||
animated,
|
||||
tabPosition = 'top',
|
||||
tabBarGutter,
|
||||
tabBarStyle,
|
||||
tabBarExtraContent,
|
||||
locale,
|
||||
more,
|
||||
destroyOnHidden,
|
||||
renderTabBar,
|
||||
onChange,
|
||||
onTabClick,
|
||||
onTabScroll,
|
||||
getPopupContainer,
|
||||
popupClassName,
|
||||
indicator,
|
||||
classNames: tabsClassNames,
|
||||
styles,
|
||||
...restProps
|
||||
} = props;
|
||||
const tabs = React.useMemo(() => (items || []).filter(item => item && typeof item === 'object' && 'key' in item), [items]);
|
||||
const rtl = direction === 'rtl';
|
||||
const mergedAnimated = (0, _useAnimateConfig.default)(animated);
|
||||
|
||||
// ======================== Mobile ========================
|
||||
const [mobile, setMobile] = (0, _react.useState)(false);
|
||||
(0, _react.useEffect)(() => {
|
||||
// Only update on the client side
|
||||
setMobile((0, _isMobile.default)());
|
||||
}, []);
|
||||
|
||||
// ====================== Active Key ======================
|
||||
const [mergedActiveKey, setMergedActiveKey] = (0, _useControlledState.default)(defaultActiveKey ?? tabs[0]?.key, activeKey);
|
||||
const [activeIndex, setActiveIndex] = (0, _react.useState)(() => tabs.findIndex(tab => tab.key === mergedActiveKey));
|
||||
|
||||
// Reset active key if not exist anymore
|
||||
(0, _react.useEffect)(() => {
|
||||
let newActiveIndex = tabs.findIndex(tab => tab.key === mergedActiveKey);
|
||||
if (newActiveIndex === -1) {
|
||||
newActiveIndex = Math.max(0, Math.min(activeIndex, tabs.length - 1));
|
||||
setMergedActiveKey(tabs[newActiveIndex]?.key);
|
||||
}
|
||||
setActiveIndex(newActiveIndex);
|
||||
}, [tabs.map(tab => tab.key).join('_'), mergedActiveKey, activeIndex]);
|
||||
|
||||
// ===================== Accessibility ====================
|
||||
const [mergedId, setMergedId] = (0, _useControlledState.default)(null, id);
|
||||
|
||||
// Async generate id to avoid ssr mapping failed
|
||||
(0, _react.useEffect)(() => {
|
||||
if (!id) {
|
||||
setMergedId(`rc-tabs-${process.env.NODE_ENV === 'test' ? 'test' : uuid}`);
|
||||
uuid += 1;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// ======================== Events ========================
|
||||
function onInternalTabClick(key, e) {
|
||||
onTabClick?.(key, e);
|
||||
const isActiveChanged = key !== mergedActiveKey;
|
||||
setMergedActiveKey(key);
|
||||
if (isActiveChanged) {
|
||||
onChange?.(key);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== Render ========================
|
||||
const sharedProps = {
|
||||
id: mergedId,
|
||||
activeKey: mergedActiveKey,
|
||||
animated: mergedAnimated,
|
||||
tabPosition,
|
||||
rtl,
|
||||
mobile
|
||||
};
|
||||
const tabNavBarProps = {
|
||||
...sharedProps,
|
||||
editable,
|
||||
locale,
|
||||
more,
|
||||
tabBarGutter,
|
||||
onTabClick: onInternalTabClick,
|
||||
onTabScroll,
|
||||
extra: tabBarExtraContent,
|
||||
style: tabBarStyle,
|
||||
getPopupContainer,
|
||||
popupClassName: (0, _clsx.clsx)(popupClassName, tabsClassNames?.popup),
|
||||
indicator,
|
||||
styles,
|
||||
classNames: tabsClassNames
|
||||
};
|
||||
const memoizedValue = React.useMemo(() => {
|
||||
return {
|
||||
tabs,
|
||||
prefixCls
|
||||
};
|
||||
}, [tabs, prefixCls]);
|
||||
return /*#__PURE__*/React.createElement(_TabContext.default.Provider, {
|
||||
value: memoizedValue
|
||||
}, /*#__PURE__*/React.createElement("div", _extends({
|
||||
ref: ref,
|
||||
id: id,
|
||||
className: (0, _clsx.clsx)(prefixCls, `${prefixCls}-${tabPosition}`, {
|
||||
[`${prefixCls}-mobile`]: mobile,
|
||||
[`${prefixCls}-editable`]: editable,
|
||||
[`${prefixCls}-rtl`]: rtl
|
||||
}, className)
|
||||
}, restProps), /*#__PURE__*/React.createElement(_Wrapper.default, _extends({}, tabNavBarProps, {
|
||||
renderTabBar: renderTabBar
|
||||
})), /*#__PURE__*/React.createElement(_TabPanelList.default, _extends({
|
||||
destroyOnHidden: destroyOnHidden
|
||||
}, sharedProps, {
|
||||
contentStyle: styles?.content,
|
||||
contentClassName: tabsClassNames?.content,
|
||||
animated: mergedAnimated
|
||||
}))));
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Tabs.displayName = 'Tabs';
|
||||
}
|
||||
var _default = exports.default = Tabs;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type { TabsProps } from '..';
|
||||
import type { AnimatedConfig } from '../interface';
|
||||
export default function useAnimateConfig(animated?: TabsProps['animated']): AnimatedConfig;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useAnimateConfig;
|
||||
var _warning = _interopRequireDefault(require("@rc-component/util/lib/warning"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function useAnimateConfig(animated = {
|
||||
inkBar: true,
|
||||
tabPane: false
|
||||
}) {
|
||||
let mergedAnimated;
|
||||
if (animated === false) {
|
||||
mergedAnimated = {
|
||||
inkBar: false,
|
||||
tabPane: false
|
||||
};
|
||||
} else if (animated === true) {
|
||||
mergedAnimated = {
|
||||
inkBar: true,
|
||||
tabPane: false
|
||||
};
|
||||
} else {
|
||||
mergedAnimated = {
|
||||
inkBar: true,
|
||||
...(typeof animated === 'object' ? animated : {})
|
||||
};
|
||||
}
|
||||
|
||||
// Enable tabPane animation if provide motion
|
||||
if (mergedAnimated.tabPaneMotion && mergedAnimated.tabPane === undefined) {
|
||||
mergedAnimated.tabPane = true;
|
||||
}
|
||||
if (!mergedAnimated.tabPaneMotion && mergedAnimated.tabPane) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
(0, _warning.default)(false, '`animated.tabPane` is true but `animated.tabPaneMotion` is not provided. Motion will not work.');
|
||||
}
|
||||
mergedAnimated.tabPane = false;
|
||||
}
|
||||
return mergedAnimated;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import type { TabOffset } from '../interface';
|
||||
export type GetIndicatorSize = number | ((origin: number) => number);
|
||||
interface UseIndicatorOptions {
|
||||
activeTabOffset: TabOffset;
|
||||
horizontal: boolean;
|
||||
rtl: boolean;
|
||||
indicator?: {
|
||||
size?: GetIndicatorSize;
|
||||
align?: 'start' | 'center' | 'end';
|
||||
};
|
||||
}
|
||||
declare const useIndicator: (options: UseIndicatorOptions) => {
|
||||
style: React.CSSProperties;
|
||||
};
|
||||
export default useIndicator;
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _raf = _interopRequireDefault(require("@rc-component/util/lib/raf"));
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const useIndicator = options => {
|
||||
const {
|
||||
activeTabOffset,
|
||||
horizontal,
|
||||
rtl,
|
||||
indicator = {}
|
||||
} = options;
|
||||
const {
|
||||
size,
|
||||
align = 'center'
|
||||
} = indicator;
|
||||
const [inkStyle, setInkStyle] = (0, _react.useState)();
|
||||
const inkBarRafRef = (0, _react.useRef)();
|
||||
const getLength = _react.default.useCallback(origin => {
|
||||
if (typeof size === 'function') {
|
||||
return size(origin);
|
||||
}
|
||||
if (typeof size === 'number') {
|
||||
return size;
|
||||
}
|
||||
return origin;
|
||||
}, [size]);
|
||||
|
||||
// Delay set ink style to avoid remove tab blink
|
||||
function cleanInkBarRaf() {
|
||||
_raf.default.cancel(inkBarRafRef.current);
|
||||
}
|
||||
(0, _react.useEffect)(() => {
|
||||
const newInkStyle = {};
|
||||
if (activeTabOffset) {
|
||||
if (horizontal) {
|
||||
newInkStyle.width = getLength(activeTabOffset.width);
|
||||
const key = rtl ? 'right' : 'left';
|
||||
if (align === 'start') {
|
||||
newInkStyle[key] = activeTabOffset[key];
|
||||
}
|
||||
if (align === 'center') {
|
||||
newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width / 2;
|
||||
newInkStyle.transform = rtl ? 'translateX(50%)' : 'translateX(-50%)';
|
||||
}
|
||||
if (align === 'end') {
|
||||
newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width;
|
||||
newInkStyle.transform = 'translateX(-100%)';
|
||||
}
|
||||
} else {
|
||||
newInkStyle.height = getLength(activeTabOffset.height);
|
||||
if (align === 'start') {
|
||||
newInkStyle.top = activeTabOffset.top;
|
||||
}
|
||||
if (align === 'center') {
|
||||
newInkStyle.top = activeTabOffset.top + activeTabOffset.height / 2;
|
||||
newInkStyle.transform = 'translateY(-50%)';
|
||||
}
|
||||
if (align === 'end') {
|
||||
newInkStyle.top = activeTabOffset.top + activeTabOffset.height;
|
||||
newInkStyle.transform = 'translateY(-100%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanInkBarRaf();
|
||||
inkBarRafRef.current = (0, _raf.default)(() => {
|
||||
// Avoid jitter caused by tiny numerical differences
|
||||
// fix https://github.com/ant-design/ant-design/issues/53378
|
||||
const isEqual = inkStyle && newInkStyle && Object.keys(newInkStyle).every(key => {
|
||||
const newValue = newInkStyle[key];
|
||||
const oldValue = inkStyle[key];
|
||||
return typeof newValue === 'number' && typeof oldValue === 'number' ? Math.round(newValue) === Math.round(oldValue) : newValue === oldValue;
|
||||
});
|
||||
if (!isEqual) {
|
||||
setInkStyle(newInkStyle);
|
||||
}
|
||||
});
|
||||
return cleanInkBarRaf;
|
||||
}, [JSON.stringify(activeTabOffset), horizontal, rtl, align, getLength]);
|
||||
return {
|
||||
style: inkStyle
|
||||
};
|
||||
};
|
||||
var _default = exports.default = useIndicator;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import type { Tab, TabOffsetMap, TabSizeMap } from '../interface';
|
||||
export default function useOffsets(tabs: Tab[], tabSizes: TabSizeMap, holderScrollWidth: number): TabOffsetMap;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useOffsets;
|
||||
var _react = require("react");
|
||||
const DEFAULT_SIZE = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: 0,
|
||||
top: 0
|
||||
};
|
||||
function useOffsets(tabs, tabSizes, holderScrollWidth) {
|
||||
return (0, _react.useMemo)(() => {
|
||||
const map = new Map();
|
||||
const lastOffset = tabSizes.get(tabs[0]?.key) || DEFAULT_SIZE;
|
||||
const rightOffset = lastOffset.left + lastOffset.width;
|
||||
for (let i = 0; i < tabs.length; i += 1) {
|
||||
const {
|
||||
key
|
||||
} = tabs[i];
|
||||
let data = tabSizes.get(key);
|
||||
|
||||
// Reuse last one when not exist yet
|
||||
if (!data) {
|
||||
data = tabSizes.get(tabs[i - 1]?.key) || DEFAULT_SIZE;
|
||||
}
|
||||
const entity = map.get(key) || {
|
||||
...data
|
||||
};
|
||||
|
||||
// Right
|
||||
entity.right = rightOffset - entity.left - entity.width;
|
||||
|
||||
// Update entity
|
||||
map.set(key, entity);
|
||||
}
|
||||
return map;
|
||||
}, [tabs.map(tab => tab.key).join('_'), tabSizes, holderScrollWidth]);
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
type Updater<T> = (prev: T) => T;
|
||||
export default function useSyncState<T>(defaultState: T, onChange: (newValue: T, prevValue: T) => void): [T, (updater: T | Updater<T>) => void];
|
||||
export {};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useSyncState;
|
||||
var React = _interopRequireWildcard(require("react"));
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function useSyncState(defaultState, onChange) {
|
||||
const stateRef = React.useRef(defaultState);
|
||||
const [, forceUpdate] = React.useState({});
|
||||
function setState(updater) {
|
||||
const newValue = typeof updater === 'function' ? updater(stateRef.current) : updater;
|
||||
if (newValue !== stateRef.current) {
|
||||
onChange(newValue, stateRef.current);
|
||||
}
|
||||
stateRef.current = newValue;
|
||||
forceUpdate({});
|
||||
}
|
||||
return [stateRef.current, setState];
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import * as React from 'react';
|
||||
export default function useTouchMove(ref: React.RefObject<HTMLDivElement>, onOffset: (offsetX: number, offsetY: number) => boolean): void;
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useTouchMove;
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
var React = _react;
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
const MIN_SWIPE_DISTANCE = 0.1;
|
||||
const STOP_SWIPE_DISTANCE = 0.01;
|
||||
const REFRESH_INTERVAL = 20;
|
||||
const SPEED_OFF_MULTIPLE = 0.995 ** REFRESH_INTERVAL;
|
||||
|
||||
// ================================= Hook =================================
|
||||
function useTouchMove(ref, onOffset) {
|
||||
const [touchPosition, setTouchPosition] = (0, _react.useState)();
|
||||
const [lastTimestamp, setLastTimestamp] = (0, _react.useState)(0);
|
||||
const [lastTimeDiff, setLastTimeDiff] = (0, _react.useState)(0);
|
||||
const [lastOffset, setLastOffset] = (0, _react.useState)();
|
||||
const motionRef = (0, _react.useRef)();
|
||||
|
||||
// ========================= Events =========================
|
||||
// >>> Touch events
|
||||
function onTouchStart(e) {
|
||||
const {
|
||||
screenX,
|
||||
screenY
|
||||
} = e.touches[0];
|
||||
setTouchPosition({
|
||||
x: screenX,
|
||||
y: screenY
|
||||
});
|
||||
window.clearInterval(motionRef.current);
|
||||
}
|
||||
function onTouchMove(e) {
|
||||
if (!touchPosition) return;
|
||||
|
||||
// e.preventDefault();
|
||||
const {
|
||||
screenX,
|
||||
screenY
|
||||
} = e.touches[0];
|
||||
setTouchPosition({
|
||||
x: screenX,
|
||||
y: screenY
|
||||
});
|
||||
const offsetX = screenX - touchPosition.x;
|
||||
const offsetY = screenY - touchPosition.y;
|
||||
onOffset(offsetX, offsetY);
|
||||
const now = Date.now();
|
||||
setLastTimestamp(now);
|
||||
setLastTimeDiff(now - lastTimestamp);
|
||||
setLastOffset({
|
||||
x: offsetX,
|
||||
y: offsetY
|
||||
});
|
||||
}
|
||||
function onTouchEnd() {
|
||||
if (!touchPosition) return;
|
||||
setTouchPosition(null);
|
||||
setLastOffset(null);
|
||||
|
||||
// Swipe if needed
|
||||
if (lastOffset) {
|
||||
const distanceX = lastOffset.x / lastTimeDiff;
|
||||
const distanceY = lastOffset.y / lastTimeDiff;
|
||||
const absX = Math.abs(distanceX);
|
||||
const absY = Math.abs(distanceY);
|
||||
|
||||
// Skip swipe if low distance
|
||||
if (Math.max(absX, absY) < MIN_SWIPE_DISTANCE) return;
|
||||
let currentX = distanceX;
|
||||
let currentY = distanceY;
|
||||
motionRef.current = window.setInterval(() => {
|
||||
if (Math.abs(currentX) < STOP_SWIPE_DISTANCE && Math.abs(currentY) < STOP_SWIPE_DISTANCE) {
|
||||
window.clearInterval(motionRef.current);
|
||||
return;
|
||||
}
|
||||
currentX *= SPEED_OFF_MULTIPLE;
|
||||
currentY *= SPEED_OFF_MULTIPLE;
|
||||
onOffset(currentX * REFRESH_INTERVAL, currentY * REFRESH_INTERVAL);
|
||||
}, REFRESH_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
// >>> Wheel event
|
||||
const lastWheelDirectionRef = (0, _react.useRef)();
|
||||
function onWheel(e) {
|
||||
const {
|
||||
deltaX,
|
||||
deltaY
|
||||
} = e;
|
||||
|
||||
// Convert both to x & y since wheel only happened on PC
|
||||
let mixed = 0;
|
||||
const absX = Math.abs(deltaX);
|
||||
const absY = Math.abs(deltaY);
|
||||
if (absX === absY) {
|
||||
mixed = lastWheelDirectionRef.current === 'x' ? deltaX : deltaY;
|
||||
} else if (absX > absY) {
|
||||
mixed = deltaX;
|
||||
lastWheelDirectionRef.current = 'x';
|
||||
} else {
|
||||
mixed = deltaY;
|
||||
lastWheelDirectionRef.current = 'y';
|
||||
}
|
||||
if (onOffset(-mixed, -mixed)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// ========================= Effect =========================
|
||||
const touchEventsRef = (0, _react.useRef)(null);
|
||||
touchEventsRef.current = {
|
||||
onTouchStart,
|
||||
onTouchMove,
|
||||
onTouchEnd,
|
||||
onWheel
|
||||
};
|
||||
React.useEffect(() => {
|
||||
function onProxyTouchStart(e) {
|
||||
touchEventsRef.current.onTouchStart(e);
|
||||
}
|
||||
function onProxyTouchMove(e) {
|
||||
touchEventsRef.current.onTouchMove(e);
|
||||
}
|
||||
function onProxyTouchEnd(e) {
|
||||
touchEventsRef.current.onTouchEnd(e);
|
||||
}
|
||||
function onProxyWheel(e) {
|
||||
touchEventsRef.current.onWheel(e);
|
||||
}
|
||||
document.addEventListener('touchmove', onProxyTouchMove, {
|
||||
passive: false
|
||||
});
|
||||
document.addEventListener('touchend', onProxyTouchEnd, {
|
||||
passive: true
|
||||
});
|
||||
|
||||
// No need to clean up since element removed
|
||||
ref.current.addEventListener('touchstart', onProxyTouchStart, {
|
||||
passive: true
|
||||
});
|
||||
ref.current.addEventListener('wheel', onProxyWheel, {
|
||||
passive: false
|
||||
});
|
||||
return () => {
|
||||
document.removeEventListener('touchmove', onProxyTouchMove);
|
||||
document.removeEventListener('touchend', onProxyTouchEnd);
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Help to merge callback with `useLayoutEffect`.
|
||||
* One time will only trigger once.
|
||||
*/
|
||||
export default function useUpdate(callback: VoidFunction): () => void;
|
||||
type Callback<T> = (ori: T) => T;
|
||||
export declare function useUpdateState<T>(defaultState: T | (() => T)): [T, (updater: Callback<T>) => void];
|
||||
export {};
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useUpdate;
|
||||
exports.useUpdateState = useUpdateState;
|
||||
var _useLayoutEffect = require("@rc-component/util/lib/hooks/useLayoutEffect");
|
||||
var _react = require("react");
|
||||
/**
|
||||
* Help to merge callback with `useLayoutEffect`.
|
||||
* One time will only trigger once.
|
||||
*/
|
||||
function useUpdate(callback) {
|
||||
const [count, setCount] = (0, _react.useState)(0);
|
||||
const effectRef = (0, _react.useRef)(0);
|
||||
const callbackRef = (0, _react.useRef)();
|
||||
callbackRef.current = callback;
|
||||
|
||||
// Trigger on `useLayoutEffect`
|
||||
(0, _useLayoutEffect.useLayoutUpdateEffect)(() => {
|
||||
callbackRef.current?.();
|
||||
}, [count]);
|
||||
|
||||
// Trigger to update count
|
||||
return () => {
|
||||
if (effectRef.current !== count) {
|
||||
return;
|
||||
}
|
||||
effectRef.current += 1;
|
||||
setCount(effectRef.current);
|
||||
};
|
||||
}
|
||||
function useUpdateState(defaultState) {
|
||||
const batchRef = (0, _react.useRef)([]);
|
||||
const [, forceUpdate] = (0, _react.useState)({});
|
||||
const state = (0, _react.useRef)(typeof defaultState === 'function' ? defaultState() : defaultState);
|
||||
const flushUpdate = useUpdate(() => {
|
||||
let current = state.current;
|
||||
batchRef.current.forEach(callback => {
|
||||
current = callback(current);
|
||||
});
|
||||
batchRef.current = [];
|
||||
state.current = current;
|
||||
forceUpdate({});
|
||||
});
|
||||
function updater(callback) {
|
||||
batchRef.current.push(callback);
|
||||
flushUpdate();
|
||||
}
|
||||
return [state.current, updater];
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import type { Tab, TabOffsetMap } from '../interface';
|
||||
import type { TabNavListProps } from '../TabNavList';
|
||||
export type ContainerSizeInfo = [width: number, height: number, left: number, top: number];
|
||||
export default function useVisibleRange(tabOffsets: TabOffsetMap, visibleTabContentValue: number, transform: number, tabContentSizeValue: number, addNodeSizeValue: number, operationNodeSizeValue: number, { tabs, tabPosition, rtl }: {
|
||||
tabs: Tab[];
|
||||
} & TabNavListProps): [visibleStart: number, visibleEnd: number];
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = useVisibleRange;
|
||||
var _react = require("react");
|
||||
const DEFAULT_SIZE = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0
|
||||
};
|
||||
function useVisibleRange(tabOffsets, visibleTabContentValue, transform, tabContentSizeValue, addNodeSizeValue, operationNodeSizeValue, {
|
||||
tabs,
|
||||
tabPosition,
|
||||
rtl
|
||||
}) {
|
||||
let charUnit;
|
||||
let position;
|
||||
let transformSize;
|
||||
if (['top', 'bottom'].includes(tabPosition)) {
|
||||
charUnit = 'width';
|
||||
position = rtl ? 'right' : 'left';
|
||||
transformSize = Math.abs(transform);
|
||||
} else {
|
||||
charUnit = 'height';
|
||||
position = 'top';
|
||||
transformSize = -transform;
|
||||
}
|
||||
return (0, _react.useMemo)(() => {
|
||||
if (!tabs.length) {
|
||||
return [0, 0];
|
||||
}
|
||||
const len = tabs.length;
|
||||
let endIndex = len;
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
const offset = tabOffsets.get(tabs[i].key) || DEFAULT_SIZE;
|
||||
if (Math.floor(offset[position] + offset[charUnit]) > Math.floor(transformSize + visibleTabContentValue)) {
|
||||
endIndex = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let startIndex = 0;
|
||||
for (let i = len - 1; i >= 0; i -= 1) {
|
||||
const offset = tabOffsets.get(tabs[i].key) || DEFAULT_SIZE;
|
||||
if (offset[position] < transformSize) {
|
||||
startIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return startIndex > endIndex ? [0, -1] : [startIndex, endIndex];
|
||||
}, [tabOffsets, visibleTabContentValue, tabContentSizeValue, addNodeSizeValue, operationNodeSizeValue, transformSize, tabPosition, tabs.map(tab => tab.key).join('_'), rtl]);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { TabsProps } from './Tabs';
|
||||
import Tabs from './Tabs';
|
||||
export type { TabsProps };
|
||||
export default Tabs;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _Tabs = _interopRequireDefault(require("./Tabs"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
var _default = exports.default = _Tabs.default;
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import type { CSSMotionProps } from '@rc-component/motion';
|
||||
import type { DropdownProps } from '@rc-component/dropdown';
|
||||
import type React from 'react';
|
||||
import type { TabNavListProps } from './TabNavList';
|
||||
import type { TabPaneProps } from './TabPanelList/TabPane';
|
||||
export type TriggerProps = {
|
||||
trigger?: 'hover' | 'click';
|
||||
};
|
||||
export type moreIcon = React.ReactNode;
|
||||
export type MoreProps = {
|
||||
icon?: moreIcon;
|
||||
} & Omit<DropdownProps, 'children'>;
|
||||
export type SizeInfo = [width: number, height: number];
|
||||
export type TabSizeMap = Map<React.Key, {
|
||||
width: number;
|
||||
height: number;
|
||||
left: number;
|
||||
top: number;
|
||||
}>;
|
||||
export interface TabOffset {
|
||||
width: number;
|
||||
height: number;
|
||||
left: number;
|
||||
right: number;
|
||||
top: number;
|
||||
}
|
||||
export type TabOffsetMap = Map<React.Key, TabOffset>;
|
||||
export type TabPosition = 'left' | 'right' | 'top' | 'bottom';
|
||||
export interface Tab extends Omit<TabPaneProps, 'tab'> {
|
||||
key: string;
|
||||
label: React.ReactNode;
|
||||
}
|
||||
type RenderTabBarProps = {
|
||||
id: string;
|
||||
activeKey: string;
|
||||
animated: AnimatedConfig;
|
||||
tabPosition: TabPosition;
|
||||
rtl: boolean;
|
||||
mobile: boolean;
|
||||
editable: EditableConfig;
|
||||
locale: TabsLocale;
|
||||
more: MoreProps;
|
||||
tabBarGutter: number;
|
||||
onTabClick: (key: string, e: React.MouseEvent | React.KeyboardEvent) => void;
|
||||
onTabScroll: OnTabScroll;
|
||||
extra: TabBarExtraContent;
|
||||
style: React.CSSProperties;
|
||||
};
|
||||
export type RenderTabBar = (props: RenderTabBarProps, DefaultTabBar: React.ComponentType<TabNavListProps>) => React.ReactElement;
|
||||
export interface TabsLocale {
|
||||
dropdownAriaLabel?: string;
|
||||
removeAriaLabel?: string;
|
||||
addAriaLabel?: string;
|
||||
}
|
||||
export interface EditableConfig {
|
||||
onEdit: (type: 'add' | 'remove', info: {
|
||||
key?: string;
|
||||
event: React.MouseEvent | React.KeyboardEvent;
|
||||
}) => void;
|
||||
showAdd?: boolean;
|
||||
removeIcon?: React.ReactNode;
|
||||
addIcon?: React.ReactNode;
|
||||
}
|
||||
export interface AnimatedConfig {
|
||||
inkBar?: boolean;
|
||||
tabPane?: boolean;
|
||||
tabPaneMotion?: CSSMotionProps;
|
||||
}
|
||||
export type OnTabScroll = (info: {
|
||||
direction: 'left' | 'right' | 'top' | 'bottom';
|
||||
}) => void;
|
||||
export type TabBarExtraPosition = 'left' | 'right';
|
||||
export type TabBarExtraMap = Partial<Record<TabBarExtraPosition, React.ReactNode>>;
|
||||
export type TabBarExtraContent = React.ReactNode | TabBarExtraMap;
|
||||
export {};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import type React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { EditableConfig } from './interface';
|
||||
/**
|
||||
* We trade Map as deps which may change with same value but different ref object.
|
||||
* We should make it as hash for deps
|
||||
* */
|
||||
export declare function stringify<K extends PropertyKey, V>(obj: Record<K, V> | Map<K, V>): string;
|
||||
export declare function genDataNodeKey(key: React.Key): string;
|
||||
export declare function getRemovable(closable?: boolean, closeIcon?: ReactNode, editable?: EditableConfig, disabled?: boolean): boolean;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.genDataNodeKey = genDataNodeKey;
|
||||
exports.getRemovable = getRemovable;
|
||||
exports.stringify = stringify;
|
||||
/**
|
||||
* We trade Map as deps which may change with same value but different ref object.
|
||||
* We should make it as hash for deps
|
||||
* */
|
||||
function stringify(obj) {
|
||||
let tgt;
|
||||
if (obj instanceof Map) {
|
||||
tgt = {};
|
||||
obj.forEach((v, k) => {
|
||||
tgt[k] = v;
|
||||
});
|
||||
} else {
|
||||
tgt = obj;
|
||||
}
|
||||
return JSON.stringify(tgt);
|
||||
}
|
||||
const RC_TABS_DOUBLE_QUOTE = 'TABS_DQ';
|
||||
function genDataNodeKey(key) {
|
||||
return String(key).replace(/"/g, RC_TABS_DOUBLE_QUOTE);
|
||||
}
|
||||
function getRemovable(closable, closeIcon, editable, disabled) {
|
||||
if (
|
||||
// Only editable tabs can be removed
|
||||
!editable ||
|
||||
// Tabs cannot be removed when disabled
|
||||
disabled ||
|
||||
// closable is false
|
||||
closable === false ||
|
||||
// If closable is undefined, the remove button should be hidden when closeIcon is null or false
|
||||
closable === undefined && (closeIcon === false || closeIcon === null)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user