tdesign-react
Version:
TDesign Component for React
434 lines (430 loc) • 19.9 kB
JavaScript
/**
* tdesign v1.15.1
* (c) 2025 tdesign
* @license MIT
*/
import { _ as _defineProperty } from '../_chunks/dep-cb0a3966.js';
import { _ as _slicedToArray } from '../_chunks/dep-48805ab8.js';
import React, { useRef, useState, useMemo, useEffect } from 'react';
import { debounce, isFunction } from 'lodash-es';
import classNames from 'classnames';
import { createPortal } from 'react-dom';
import { s as setStyle } from '../_chunks/dep-c48e2ca1.js';
import { Button } from '../button/index.js';
import useConfig from '../hooks/useConfig.js';
import { Popup } from '../popup/index.js';
import { r as removeClass, a as addClass, c as canUseDocument, i as isFixed } from '../_chunks/dep-3a09424a.js';
import './utils/index.js';
import useControlled from '../hooks/useControlled.js';
import { guideDefaultProps } from './defaultProps.js';
import useDefaultProps from '../hooks/useDefaultProps.js';
import useIsomorphicLayoutEffect from '../hooks/useLayoutEffect.js';
import { getWindowScroll } from '../_util/scroll.js';
import useEventCallback from '../hooks/useEventCallback.js';
import getRelativePosition from './utils/getRelativePosition.js';
import getTargetElm from './utils/getTargetElm.js';
import { scrollToParentVisibleArea } from './utils/getScrollParent.js';
import scrollToElm from './utils/scrollToElm.js';
import '../_chunks/dep-eca3a3de.js';
import '../_chunks/dep-026a4c6b.js';
import '../button/Button.js';
import '../_chunks/dep-6b660ef0.js';
import '../hooks/useDomRefCallback.js';
import '../hooks/useRipple.js';
import '../hooks/useAnimation.js';
import '../config-provider/ConfigContext.js';
import '../locale/zh_CN.js';
import '../_chunks/dep-e29214cb.js';
import 'dayjs';
import '../_chunks/dep-3c9ab31a.js';
import '../loading/index.js';
import '../loading/Loading.js';
import '../common/Portal.js';
import '../loading/gradient.js';
import '../_chunks/dep-1630b9b4.js';
import '../_chunks/dep-87d110df.js';
import '../loading/defaultProps.js';
import '../loading/plugin.js';
import '../_util/react-render.js';
import '../_chunks/dep-a74cc5e4.js';
import '../common/PluginContainer.js';
import '../config-provider/index.js';
import '../config-provider/ConfigProvider.js';
import '../config-provider/type.js';
import '../loading/style/css.js';
import '../loading/type.js';
import '../button/defaultProps.js';
import '../_util/parseTNode.js';
import '../_chunks/dep-f53c91cd.js';
import '../_chunks/dep-b908e1fe.js';
import '../button/style/css.js';
import '../button/type.js';
import '../popup/Popup.js';
import 'react-transition-group';
import '../_util/ref.js';
import 'react-is';
import '../_util/isFragment.js';
import '../hooks/useAttach.js';
import '../hooks/useMutationObserver.js';
import '../hooks/useLatest.js';
import '../hooks/usePopper.js';
import '@popperjs/core';
import 'react-fast-compare';
import '../hooks/useWindowSize.js';
import '../popup/defaultProps.js';
import '../popup/hooks/useTrigger.js';
import '../_util/composeRefs.js';
import '../_util/listener.js';
import '../popup/utils/transition.js';
import '../_util/noop.js';
import '../popup/PopupPlugin.js';
import '../popup/style/css.js';
import '../popup/type.js';
import 'raf';
import '../_util/easing.js';
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var Guide = function Guide(originalProps) {
var props = useDefaultProps(originalProps, guideDefaultProps);
var counter = props.counter,
hideCounter = props.hideCounter,
hidePrev = props.hidePrev,
hideSkip = props.hideSkip,
steps = props.steps,
zIndex = props.zIndex;
var _useConfig = useConfig(),
classPrefix = _useConfig.classPrefix,
guideGlobalConfig = _useConfig.guide;
var prefixCls = "".concat(classPrefix, "-guide");
var lockCls = "".concat(prefixCls, "--lock");
var _useControlled = useControlled(props, "current", props.onChange),
_useControlled2 = _slicedToArray(_useControlled, 2),
innerCurrent = _useControlled2[0],
setInnerCurrent = _useControlled2[1];
var overlayLayerRef = useRef(null);
var highlightLayerRef = useRef(null);
var referenceLayerRef = useRef(null);
var currentHighlightLayerElm = useRef(null);
var dialogWrapperRef = useRef(null);
var dialogTooltipRef = useRef(null);
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
active = _useState2[0],
setActive = _useState2[1];
var stepsTotal = steps.length;
var currentStepInfo = useMemo(function () {
return steps[innerCurrent];
}, [steps, innerCurrent]);
var getCurrentCrossProps = function getCurrentCrossProps(propsName) {
var _currentStepInfo$prop;
return (_currentStepInfo$prop = currentStepInfo === null || currentStepInfo === void 0 ? void 0 : currentStepInfo[propsName]) !== null && _currentStepInfo$prop !== void 0 ? _currentStepInfo$prop : props[propsName];
};
var isPopup = getCurrentCrossProps("mode") === "popup";
var setHighlightLayerPosition = function setHighlightLayerPosition(highlightLayer) {
var _getRelativePosition = getRelativePosition(currentHighlightLayerElm.current),
top = _getRelativePosition.top,
left = _getRelativePosition.left;
var _currentHighlightLaye = currentHighlightLayerElm.current.getBoundingClientRect(),
width = _currentHighlightLaye.width,
height = _currentHighlightLaye.height;
var highlightPadding = getCurrentCrossProps("highlightPadding");
if (isPopup) {
width += highlightPadding * 2;
height += highlightPadding * 2;
top -= highlightPadding;
left -= highlightPadding;
} else {
var _getWindowScroll = getWindowScroll(),
scrollTop = _getWindowScroll.scrollTop,
scrollLeft = _getWindowScroll.scrollLeft;
top += scrollTop;
left += scrollLeft;
}
setStyle(highlightLayer, {
width: "".concat(width, "px"),
height: "".concat(height, "px"),
top: "".concat(top, "px"),
left: "".concat(left, "px")
});
};
var showPopupGuide = function showPopupGuide() {
currentHighlightLayerElm.current = getTargetElm(currentStepInfo.element);
setTimeout(function () {
scrollToParentVisibleArea(currentHighlightLayerElm.current);
setHighlightLayerPosition(highlightLayerRef.current);
setHighlightLayerPosition(referenceLayerRef.current);
scrollToElm(currentHighlightLayerElm.current);
});
};
var destroyTooltipElm = function destroyTooltipElm() {
var _referenceLayerRef$cu;
(_referenceLayerRef$cu = referenceLayerRef.current) === null || _referenceLayerRef$cu === void 0 || _referenceLayerRef$cu.parentNode.removeChild(referenceLayerRef.current);
};
var showDialogGuide = function showDialogGuide() {
setTimeout(function () {
currentHighlightLayerElm.current = dialogTooltipRef.current;
scrollToParentVisibleArea(currentHighlightLayerElm.current);
setHighlightLayerPosition(highlightLayerRef.current);
scrollToElm(currentHighlightLayerElm.current);
});
};
var destroyDialogTooltipElm = function destroyDialogTooltipElm() {
var _dialogTooltipRef$cur, _dialogWrapperRef$cur;
(_dialogTooltipRef$cur = dialogTooltipRef.current) === null || _dialogTooltipRef$cur === void 0 || _dialogTooltipRef$cur.parentNode.removeChild(dialogTooltipRef.current);
(_dialogWrapperRef$cur = dialogWrapperRef.current) === null || _dialogWrapperRef$cur === void 0 || _dialogWrapperRef$cur.parentNode.removeChild(dialogWrapperRef.current);
};
var showGuide = useEventCallback(function () {
if (isPopup) {
destroyDialogTooltipElm();
showPopupGuide();
} else {
destroyTooltipElm();
showDialogGuide();
}
});
var showGuideDebounce = useMemo(function () {
return debounce(showGuide, 250);
}, [showGuide]);
var destroyGuide = function destroyGuide() {
var _highlightLayerRef$cu, _overlayLayerRef$curr;
destroyTooltipElm();
destroyDialogTooltipElm();
(_highlightLayerRef$cu = highlightLayerRef.current) === null || _highlightLayerRef$cu === void 0 || _highlightLayerRef$cu.parentNode.removeChild(highlightLayerRef.current);
(_overlayLayerRef$curr = overlayLayerRef.current) === null || _overlayLayerRef$curr === void 0 || _overlayLayerRef$curr.parentNode.removeChild(overlayLayerRef.current);
removeClass(document.body, lockCls);
};
var handleSkip = function handleSkip(e) {
var _props$onSkip;
var total = stepsTotal;
setActive(false);
setInnerCurrent(-1, {
e: e,
total: total
});
(_props$onSkip = props.onSkip) === null || _props$onSkip === void 0 || _props$onSkip.call(props, {
e: e,
current: innerCurrent,
total: total
});
};
var handlePrev = function handlePrev(e) {
var _props$onPrevStepClic;
var total = stepsTotal;
setInnerCurrent(innerCurrent - 1, {
e: e,
total: total
});
(_props$onPrevStepClic = props.onPrevStepClick) === null || _props$onPrevStepClic === void 0 || _props$onPrevStepClic.call(props, {
e: e,
prev: innerCurrent - 1,
current: innerCurrent,
total: total
});
};
var handleNext = function handleNext(e) {
var _props$onNextStepClic;
var total = stepsTotal;
setInnerCurrent(innerCurrent + 1, {
e: e,
total: total
});
(_props$onNextStepClic = props.onNextStepClick) === null || _props$onNextStepClic === void 0 || _props$onNextStepClic.call(props, {
e: e,
next: innerCurrent + 1,
current: innerCurrent,
total: total
});
};
var handleFinish = function handleFinish(e) {
var _props$onFinish;
var total = stepsTotal;
setActive(false);
setInnerCurrent(-1, {
e: e,
total: total
});
(_props$onFinish = props.onFinish) === null || _props$onFinish === void 0 || _props$onFinish.call(props, {
e: e,
current: innerCurrent,
total: total
});
};
var initGuide = function initGuide() {
if (innerCurrent >= 0 && innerCurrent < steps.length) {
if (!active) {
setActive(true);
addClass(document.body, lockCls);
}
showGuide();
}
};
useIsomorphicLayoutEffect(function () {
if (innerCurrent >= 0 && innerCurrent < steps.length) {
initGuide();
} else {
setActive(false);
destroyGuide();
}
}, [innerCurrent]);
useIsomorphicLayoutEffect(function () {
initGuide();
}, []);
useEffect(function () {
window.addEventListener("resize", showGuideDebounce);
return function () {
window.removeEventListener("resize", showGuideDebounce);
destroyGuide();
};
}, []);
if (!canUseDocument) {
return null;
}
var currentElmIsFixed = isFixed(currentHighlightLayerElm.current || document.body);
var renderOverlayLayer = function renderOverlayLayer() {
return /*#__PURE__*/createPortal(/* @__PURE__ */React.createElement("div", {
ref: overlayLayerRef,
className: "".concat(prefixCls, "__overlay"),
style: {
zIndex: zIndex - 2
}
}), document.body);
};
var renderHighlightLayer = function renderHighlightLayer() {
var style = {
zIndex: zIndex - 1
};
var highlightClass = ["".concat(prefixCls, "__highlight"), "".concat(prefixCls, "__highlight--").concat(isPopup ? "popup" : "dialog"), "".concat(prefixCls, "--").concat(currentElmIsFixed && isPopup ? "fixed" : "absolute")];
var showOverlay = getCurrentCrossProps("showOverlay");
var maskClass = ["".concat(prefixCls, "__highlight--").concat(showOverlay ? "mask" : "nomask")];
var highlightContent = currentStepInfo.highlightContent;
var showHighlightContent = highlightContent && isPopup;
return /*#__PURE__*/createPortal(/* @__PURE__ */React.createElement("div", {
ref: highlightLayerRef,
className: classNames(highlightClass.concat(showHighlightContent ? highlightClass : maskClass)),
style: style
}, showHighlightContent && /*#__PURE__*/React.cloneElement(highlightContent, {
className: classNames(highlightClass.concat(maskClass, highlightContent.props.className)),
style: _objectSpread(_objectSpread({}, style), highlightContent.props.style)
})), document.body);
};
var renderCounter = function renderCounter() {
var popupSlotCounter = isFunction(counter) ? counter({
total: stepsTotal,
current: innerCurrent
}) : counter;
var popupDefaultCounter = /* @__PURE__ */React.createElement("div", {
className: "".concat(prefixCls, "__counter")
}, popupSlotCounter || /* @__PURE__ */React.createElement(React.Fragment, null, innerCurrent + 1, "/", stepsTotal));
return /* @__PURE__ */React.createElement(React.Fragment, null, !hideCounter && popupDefaultCounter);
};
var renderAction = function renderAction(mode) {
var _getCurrentCrossProps, _getCurrentCrossProps2, _getCurrentCrossProps3, _props$finishButtonPr;
var isLast = innerCurrent === stepsTotal - 1;
var isFirst = innerCurrent === 0;
var buttonSize = mode === "popup" ? "small" : "medium";
return /* @__PURE__ */React.createElement("div", {
className: "".concat(prefixCls, "__action")
}, !hideSkip && !isLast && /* @__PURE__ */React.createElement(Button, _objectSpread({
className: "".concat(prefixCls, "__skip"),
theme: "default",
size: buttonSize,
variant: "base",
onClick: handleSkip
}, (_getCurrentCrossProps = getCurrentCrossProps("skipButtonProps")) !== null && _getCurrentCrossProps !== void 0 ? _getCurrentCrossProps : guideGlobalConfig.skipButtonProps)), !hidePrev && !isFirst && /* @__PURE__ */React.createElement(Button, _objectSpread({
className: "".concat(prefixCls, "__prev"),
theme: "primary",
size: buttonSize,
variant: "base",
onClick: handlePrev
}, (_getCurrentCrossProps2 = getCurrentCrossProps("prevButtonProps")) !== null && _getCurrentCrossProps2 !== void 0 ? _getCurrentCrossProps2 : guideGlobalConfig.prevButtonProps)), !isLast && /* @__PURE__ */React.createElement(Button, _objectSpread({
className: "".concat(prefixCls, "__next"),
theme: "primary",
size: buttonSize,
variant: "base",
onClick: handleNext
}, (_getCurrentCrossProps3 = getCurrentCrossProps("nextButtonProps")) !== null && _getCurrentCrossProps3 !== void 0 ? _getCurrentCrossProps3 : guideGlobalConfig.nextButtonProps)), isLast && /* @__PURE__ */React.createElement(Button, _objectSpread({
className: "".concat(prefixCls, "__finish"),
theme: "primary",
size: buttonSize,
variant: "base",
onClick: handleFinish
}, (_props$finishButtonPr = props.finishButtonProps) !== null && _props$finishButtonPr !== void 0 ? _props$finishButtonPr : guideGlobalConfig.finishButtonProps)));
};
var renderTooltipBody = function renderTooltipBody() {
var title = /* @__PURE__ */React.createElement("div", {
className: "".concat(prefixCls, "__title")
}, currentStepInfo.title);
var descBody = currentStepInfo.body;
var desc = /* @__PURE__ */React.createElement("div", {
className: "".concat(prefixCls, "__desc")
}, descBody);
return /* @__PURE__ */React.createElement(React.Fragment, null, title, desc);
};
var renderPopupContent = function renderPopupContent() {
var footerClasses = ["".concat(prefixCls, "__footer"), "".concat(prefixCls, "__footer--popup")];
var action = /* @__PURE__ */React.createElement("div", {
className: classNames(footerClasses)
}, renderCounter(), renderAction("popup"));
return /* @__PURE__ */React.createElement("div", {
className: "".concat(prefixCls, "__tooltip")
}, renderTooltipBody(), action);
};
var renderPopupGuide = function renderPopupGuide() {
var _currentStepInfo$chil, _currentStepInfo$popu, _currentStepInfo$popu2;
var content = (_currentStepInfo$chil = currentStepInfo.children) !== null && _currentStepInfo$chil !== void 0 ? _currentStepInfo$chil : currentStepInfo.content;
var renderBody;
if (/*#__PURE__*/React.isValidElement(content)) {
var contentProps = {
handlePrev: handlePrev,
handleNext: handleNext,
handleSkip: handleSkip,
handleFinish: handleFinish,
current: innerCurrent,
total: stepsTotal
};
renderBody = isFunction(content) ? content(contentProps) : /*#__PURE__*/React.cloneElement(content, contentProps);
} else {
renderBody = renderPopupContent();
}
var classes = ["".concat(prefixCls, "__reference"), "".concat(prefixCls, "--").concat(currentElmIsFixed ? "fixed" : "absolute")];
var innerClassName = [_defineProperty({}, "".concat(prefixCls, "__popup--content"), !!content)];
return /*#__PURE__*/createPortal(/* @__PURE__ */React.createElement(Popup, _objectSpread(_objectSpread({
visible: true,
content: renderBody,
showArrow: !content,
zIndex: zIndex,
placement: currentStepInfo.placement
}, currentStepInfo.popupProps), {}, {
overlayClassName: ["".concat(prefixCls, "__popup"), currentStepInfo.stepOverlayClass, (_currentStepInfo$popu = currentStepInfo.popupProps) === null || _currentStepInfo$popu === void 0 ? void 0 : _currentStepInfo$popu.overlayClassName],
overlayInnerClassName: innerClassName.concat((_currentStepInfo$popu2 = currentStepInfo.popupProps) === null || _currentStepInfo$popu2 === void 0 ? void 0 : _currentStepInfo$popu2.overlayInnerClassName)
}), /* @__PURE__ */React.createElement("div", {
ref: referenceLayerRef,
className: classNames(classes)
})), document.body);
};
var renderDialogGuide = function renderDialogGuide() {
var style = {
zIndex: zIndex
};
var wrapperClasses = ["".concat(prefixCls, "__wrapper"), _defineProperty({}, "".concat(prefixCls, "__wrapper--center"), currentStepInfo.placement === "center")];
var dialogClasses = ["".concat(prefixCls, "__reference"), "".concat(prefixCls, "--absolute"), "".concat(prefixCls, "__dialog"), _defineProperty(_defineProperty({}, "".concat(prefixCls, "__dialog--nomask"), !getCurrentCrossProps("showOverlay")), currentStepInfo.stepOverlayClass, !!currentStepInfo.stepOverlayClass)];
var footerClasses = ["".concat(prefixCls, "__footer"), "".concat(prefixCls, "__footer--popup")];
return /* @__PURE__ */React.createElement(React.Fragment, null, /*#__PURE__*/createPortal(/* @__PURE__ */React.createElement("div", {
ref: dialogWrapperRef,
className: classNames(wrapperClasses),
style: style
}, /* @__PURE__ */React.createElement("div", {
ref: dialogTooltipRef,
className: classNames(dialogClasses)
}, renderTooltipBody(), /* @__PURE__ */React.createElement("div", {
className: classNames(footerClasses)
}, renderCounter(), renderAction("dialog")))), document.body));
};
var renderGuide = function renderGuide() {
return /* @__PURE__ */React.createElement(React.Fragment, null, renderOverlayLayer(), renderHighlightLayer(), isPopup ? renderPopupGuide() : renderDialogGuide());
};
return /* @__PURE__ */React.createElement(React.Fragment, null, innerCurrent > -1 && active && renderGuide());
};
Guide.displayName = "Guide";
export { Guide as default };
//# sourceMappingURL=Guide.js.map