@tendaui/components 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/alert/Alert.tsx +147 -0
- package/alert/defaultProps.ts +3 -0
- package/alert/index.ts +9 -0
- package/alert/style/css.js +1 -0
- package/alert/style/index.js +1 -0
- package/alert/type.ts +44 -0
- package/badge/Badge.tsx +85 -0
- package/badge/defaultProps.ts +10 -0
- package/badge/index.ts +9 -0
- package/badge/style/css.js +1 -0
- package/badge/style/index.js +1 -0
- package/badge/type.ts +51 -0
- package/button/Button.tsx +95 -0
- package/button/defaultProps.ts +13 -0
- package/button/index.ts +7 -0
- package/button/style/css.js +1 -0
- package/button/style/index.js +1 -0
- package/button/type.ts +82 -0
- package/checkbox/Checkbox.tsx +19 -0
- package/checkbox/CheckboxGroup.tsx +207 -0
- package/checkbox/defaultProps.ts +14 -0
- package/checkbox/index.ts +10 -0
- package/checkbox/style/css.js +1 -0
- package/checkbox/style/index.js +1 -0
- package/checkbox/type.ts +117 -0
- package/common/Check.tsx +131 -0
- package/common/FakeArrow.tsx +36 -0
- package/common/PluginContainer.tsx +21 -0
- package/common/Portal.tsx +67 -0
- package/common.ts +76 -0
- package/config-provider/ConfigContext.tsx +21 -0
- package/config-provider/ConfigProvider.tsx +53 -0
- package/config-provider/index.ts +9 -0
- package/config-provider/type.ts +1062 -0
- package/dialog/Dialog.tsx +254 -0
- package/dialog/DialogCard.tsx +152 -0
- package/dialog/defaultProps.ts +25 -0
- package/dialog/hooks/useDialogDrag.ts +50 -0
- package/dialog/hooks/useDialogEsc.ts +31 -0
- package/dialog/hooks/useDialogPosition.ts +36 -0
- package/dialog/hooks/useLockStyle.ts +54 -0
- package/dialog/index.ts +13 -0
- package/dialog/plugin.tsx +78 -0
- package/dialog/style/css.js +1 -0
- package/dialog/style/index.js +1 -0
- package/dialog/type.ts +241 -0
- package/dialog/utils.ts +4 -0
- package/form/Form.tsx +136 -0
- package/form/FormContext.tsx +64 -0
- package/form/FormItem.tsx +554 -0
- package/form/FormList.tsx +303 -0
- package/form/const.ts +6 -0
- package/form/defaultProps.ts +26 -0
- package/form/formModel.ts +117 -0
- package/form/hooks/interface.ts +20 -0
- package/form/hooks/useForm.ts +122 -0
- package/form/hooks/useFormItemInitialData.ts +95 -0
- package/form/hooks/useFormItemStyle.tsx +122 -0
- package/form/hooks/useInstance.tsx +275 -0
- package/form/hooks/useWatch.ts +42 -0
- package/form/index.ts +11 -0
- package/form/style/css.js +1 -0
- package/form/style/index.js +1 -0
- package/form/type.ts +519 -0
- package/form/utils/index.ts +69 -0
- package/hooks/useAttach.ts +24 -0
- package/hooks/useCommonClassName.ts +45 -0
- package/hooks/useConfig.ts +3 -0
- package/hooks/useControlled.ts +39 -0
- package/hooks/useDefaultProps.ts +16 -0
- package/hooks/useDomCallback.ts +13 -0
- package/hooks/useDomRefCallback.ts +12 -0
- package/hooks/useDragSorter.tsx +151 -0
- package/hooks/useEventCallback.ts +47 -0
- package/hooks/useGlobalConfig.ts +14 -0
- package/hooks/useGlobalIcon.ts +14 -0
- package/hooks/useLastest.ts +13 -0
- package/hooks/useLayoutEffect.ts +7 -0
- package/hooks/useMouseEvent.ts +142 -0
- package/hooks/useMutationObserver.ts +56 -0
- package/hooks/usePopper.ts +189 -0
- package/hooks/useRipple.ts +0 -0
- package/hooks/useSetState.ts +25 -0
- package/hooks/useVirtualScroll.ts +246 -0
- package/hooks/useWindowSize.ts +31 -0
- package/index.ts +70 -0
- package/input/Input.tsx +383 -0
- package/input/InputGroup.tsx +29 -0
- package/input/defaultProps.ts +22 -0
- package/input/index.ts +11 -0
- package/input/style/css.js +1 -0
- package/input/style/index.js +1 -0
- package/input/type.ts +219 -0
- package/loading/Gradient.tsx +36 -0
- package/loading/Loading.tsx +169 -0
- package/loading/circleAdapter.ts +44 -0
- package/loading/defaultProps.ts +12 -0
- package/loading/index.ts +13 -0
- package/loading/style/css.js +1 -0
- package/loading/style/index.js +1 -0
- package/loading/type.ts +71 -0
- package/loading/utils/setStyle.ts +13 -0
- package/myform/index.ts +0 -0
- package/notification/Notify.ts +24 -0
- package/notification/NotifyContainer.tsx +90 -0
- package/notification/NotifyContext.tsx +173 -0
- package/notification/NotifyItem.tsx +121 -0
- package/notification/index.ts +3 -0
- package/notification/style/css.js +1 -0
- package/notification/style/index.js +1 -0
- package/notification/type.ts +23 -0
- package/package.json +52 -0
- package/popup/Popup.tsx +264 -0
- package/popup/defaultProps.ts +13 -0
- package/popup/hooks/useTrigger.ts +276 -0
- package/popup/index.ts +6 -0
- package/popup/style/css.js +1 -0
- package/popup/style/index.js +1 -0
- package/popup/type.ts +130 -0
- package/portal/Portal.tsx +63 -0
- package/portal/index.ts +1 -0
- package/select/Option.tsx +162 -0
- package/select/OptionGroup.tsx +30 -0
- package/select/PopupContent.tsx +271 -0
- package/select/Select.tsx +586 -0
- package/select/defaultProps.ts +27 -0
- package/select/hooks/useOptions.ts +120 -0
- package/select/hooks/usePanelVirtualScroll.ts +111 -0
- package/select/index.ts +9 -0
- package/select/style/css.js +1 -0
- package/select/style/index.js +2 -0
- package/select/type.ts +382 -0
- package/select/utils/helper.ts +256 -0
- package/select-input/SelectInput.tsx +98 -0
- package/select-input/defaultProps.ts +15 -0
- package/select-input/hook/useMultiple.tsx +100 -0
- package/select-input/hook/useOverlayInnerStyle.ts +84 -0
- package/select-input/hook/useSingle.tsx +112 -0
- package/select-input/index.ts +6 -0
- package/select-input/interface.ts +18 -0
- package/select-input/style/css.js +1 -0
- package/select-input/style/index.js +1 -0
- package/select-input/type.ts +280 -0
- package/space/defaultProps.ts +0 -0
- package/space/index.ts +0 -0
- package/space/type.ts +0 -0
- package/style/index.js +2 -0
- package/styles/_global.scss +39 -0
- package/styles/_vars.scss +386 -0
- package/styles/components/alert/_index.scss +175 -0
- package/styles/components/alert/_vars.scss +39 -0
- package/styles/components/badge/_index.scss +70 -0
- package/styles/components/badge/_vars.scss +25 -0
- package/styles/components/button/_index.scss +511 -0
- package/styles/components/button/_mixins.scss +39 -0
- package/styles/components/button/_vars.scss +122 -0
- package/styles/components/checkbox/_index.scss +158 -0
- package/styles/components/checkbox/_mixin.scss +0 -0
- package/styles/components/checkbox/_var.scss +60 -0
- package/styles/components/dialog/_animate.scss +135 -0
- package/styles/components/dialog/_index.scss +311 -0
- package/styles/components/dialog/_mixins.scss +0 -0
- package/styles/components/dialog/_vars.scss +59 -0
- package/styles/components/form/_index.scss +174 -0
- package/styles/components/form/_mixins.scss +76 -0
- package/styles/components/form/_vars.scss +100 -0
- package/styles/components/input/_index.scss +349 -0
- package/styles/components/input/_map.scss +0 -0
- package/styles/components/input/_mixins.scss +116 -0
- package/styles/components/input/_vars.scss +134 -0
- package/styles/components/loading/_index.scss +112 -0
- package/styles/components/loading/_vars.scss +39 -0
- package/styles/components/notification/_index.scss +160 -0
- package/styles/components/notification/_mixins.scss +12 -0
- package/styles/components/notification/_vars.scss +59 -0
- package/styles/components/popup/_index.scss +82 -0
- package/styles/components/popup/_mixin.scss +149 -0
- package/styles/components/popup/_var.scss +31 -0
- package/styles/components/select/_index.scss +290 -0
- package/styles/components/select/_var.scss +65 -0
- package/styles/components/select-input/_index.scss +5 -0
- package/styles/components/select-input/_var.scss +3 -0
- package/styles/components/switch/_index.scss +279 -0
- package/styles/components/switch/_mixins.scss +0 -0
- package/styles/components/switch/_vars.scss +61 -0
- package/styles/components/tag/_index.scss +316 -0
- package/styles/components/tag/_var.scss +85 -0
- package/styles/components/tag-input/_index.scss +163 -0
- package/styles/components/tag-input/_vars.scss +16 -0
- package/styles/globals.css +250 -0
- package/styles/mixins/_focus.scss +7 -0
- package/styles/mixins/_layout.scss +32 -0
- package/styles/mixins/_reset.scss +10 -0
- package/styles/mixins/_scrollbar.scss +31 -0
- package/styles/mixins/_text.scss +48 -0
- package/styles/rillple.css +16 -0
- package/styles/scrollbar.css +42 -0
- package/styles/themes/_dark.scss +191 -0
- package/styles/themes/_font.scss +79 -0
- package/styles/themes/_index.scss +5 -0
- package/styles/themes/_light.scss +190 -0
- package/styles/themes/_radius.scss +9 -0
- package/styles/themes/_size.scss +68 -0
- package/styles/themes.css +66 -0
- package/styles/utilities/_animation.scss +57 -0
- package/styles/utilities/_tips.scss +9 -0
- package/switch/Switch.tsx +120 -0
- package/switch/defaultProps.ts +3 -0
- package/switch/index.ts +7 -0
- package/switch/style/css.js +1 -0
- package/switch/style/index.js +1 -0
- package/switch/type.ts +46 -0
- package/tag/Tag.tsx +149 -0
- package/tag/defaultProps.ts +19 -0
- package/tag/index.ts +8 -0
- package/tag/style/css.js +1 -0
- package/tag/style/index.js +1 -0
- package/tag/type.ts +170 -0
- package/tag-input/TagInput.tsx +215 -0
- package/tag-input/defaultProps.ts +15 -0
- package/tag-input/hooks/useHover.ts +28 -0
- package/tag-input/hooks/useTagList.tsx +131 -0
- package/tag-input/hooks/useTagScroll.ts +105 -0
- package/tag-input/index.ts +9 -0
- package/tag-input/style/css.js +1 -0
- package/tag-input/style/index.js +1 -0
- package/tag-input/type.ts +224 -0
- package/tag-input/useTagList.tsx +131 -0
- package/utils/composeRefs.ts +14 -0
- package/utils/dom.ts +29 -0
- package/utils/forwardRefWithStatics.ts +12 -0
- package/utils/getScrollbarWidth.ts +11 -0
- package/utils/helper.ts +161 -0
- package/utils/isFragment.ts +22 -0
- package/utils/listener.ts +37 -0
- package/utils/noop.ts +3 -0
- package/utils/parentTNode.ts +38 -0
- package/utils/parseTNode.ts +38 -0
- package/utils/react-render.ts +108 -0
- package/utils/ref.ts +6 -0
- package/utils/refs.ts +81 -0
- package/utils/style.ts +60 -0
- package/utils/transition.ts +28 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
|
|
2
|
+
import { CSSTransition } from "react-transition-group";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import { isUndefined } from "lodash-es";
|
|
5
|
+
import type { StyledProps } from "../common";
|
|
6
|
+
import Portal from "../common/Portal";
|
|
7
|
+
import useAttach from "../hooks/useAttach";
|
|
8
|
+
import useConfig from "../hooks/useConfig";
|
|
9
|
+
import useDefaultProps from "../hooks/useDefaultProps";
|
|
10
|
+
import useSetState from "../hooks/useSetState";
|
|
11
|
+
// import { useLocaleReceiver } from '../locale/LocalReceiver';
|
|
12
|
+
import { dialogDefaultProps } from "./defaultProps";
|
|
13
|
+
import DialogCard from "./DialogCard";
|
|
14
|
+
import useDialogDrag from "./hooks/useDialogDrag";
|
|
15
|
+
import useDialogEsc from "./hooks/useDialogEsc";
|
|
16
|
+
import useDialogPosition from "./hooks/useDialogPosition";
|
|
17
|
+
import useLockStyle from "./hooks/useLockStyle";
|
|
18
|
+
import type { DialogInstance, TdDialogProps } from "./type";
|
|
19
|
+
import { parseValueToPx } from "./utils";
|
|
20
|
+
|
|
21
|
+
export interface DialogProps extends TdDialogProps, StyledProps {
|
|
22
|
+
isPlugin?: boolean; // 是否以插件形式调用
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
|
|
26
|
+
const props = useDefaultProps<DialogProps>(originalProps, dialogDefaultProps);
|
|
27
|
+
const { children, ...restProps } = props;
|
|
28
|
+
const { classPrefix } = useConfig();
|
|
29
|
+
|
|
30
|
+
const componentCls = `${classPrefix}-dialog`;
|
|
31
|
+
const wrapRef = useRef<HTMLDivElement>(null);
|
|
32
|
+
const contentClickRef = useRef(false);
|
|
33
|
+
const dialogCardRef = useRef<HTMLDivElement>(null);
|
|
34
|
+
const dialogPosition = useRef(null);
|
|
35
|
+
const portalRef = useRef(null);
|
|
36
|
+
const maskRef = useRef(null);
|
|
37
|
+
const [state, setState] = useSetState<DialogProps>({ isPlugin: false, ...restProps });
|
|
38
|
+
// const [local] = useLocaleReceiver('dialog');
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
className,
|
|
42
|
+
dialogClassName,
|
|
43
|
+
style,
|
|
44
|
+
width,
|
|
45
|
+
mode,
|
|
46
|
+
zIndex,
|
|
47
|
+
visible,
|
|
48
|
+
attach,
|
|
49
|
+
onBeforeOpen,
|
|
50
|
+
onBeforeClose,
|
|
51
|
+
onOpened,
|
|
52
|
+
onCancel,
|
|
53
|
+
onConfirm,
|
|
54
|
+
onClose,
|
|
55
|
+
onClosed,
|
|
56
|
+
isPlugin,
|
|
57
|
+
draggable,
|
|
58
|
+
onOverlayClick,
|
|
59
|
+
onEscKeydown,
|
|
60
|
+
closeOnEscKeydown,
|
|
61
|
+
confirmOnEnter,
|
|
62
|
+
showOverlay,
|
|
63
|
+
showInAttachedElement,
|
|
64
|
+
closeOnOverlayClick,
|
|
65
|
+
destroyOnClose,
|
|
66
|
+
preventScrollThrough,
|
|
67
|
+
onCloseBtnClick,
|
|
68
|
+
forceRender,
|
|
69
|
+
lazy,
|
|
70
|
+
...restState
|
|
71
|
+
} = state;
|
|
72
|
+
|
|
73
|
+
const dialogAttach = useAttach("dialog", attach);
|
|
74
|
+
|
|
75
|
+
useLockStyle({ preventScrollThrough, visible, mode, showInAttachedElement });
|
|
76
|
+
useDialogEsc(visible, wrapRef);
|
|
77
|
+
useDialogPosition(visible, dialogCardRef);
|
|
78
|
+
useDialogDrag({
|
|
79
|
+
dialogCardRef,
|
|
80
|
+
canDraggable: draggable && mode === "modeless"
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (isPlugin) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// 插件式调用不会更新props, 只有组件式调用才会更新props
|
|
88
|
+
setState((prevState) => ({ ...prevState, ...props }));
|
|
89
|
+
}, [props, setState, isPlugin]);
|
|
90
|
+
|
|
91
|
+
useImperativeHandle(ref, () => ({
|
|
92
|
+
show() {
|
|
93
|
+
setState({ visible: true });
|
|
94
|
+
},
|
|
95
|
+
hide() {
|
|
96
|
+
setState({ visible: false });
|
|
97
|
+
},
|
|
98
|
+
setConfirmLoading: (loading: boolean) => {
|
|
99
|
+
setState({ confirmLoading: loading });
|
|
100
|
+
},
|
|
101
|
+
destroy() {
|
|
102
|
+
setState({ visible: false, destroyOnClose: true });
|
|
103
|
+
},
|
|
104
|
+
update(newOptions) {
|
|
105
|
+
setState((prevState) => ({ ...prevState, ...newOptions }));
|
|
106
|
+
}
|
|
107
|
+
}));
|
|
108
|
+
|
|
109
|
+
const onMaskClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
110
|
+
if (showOverlay && closeOnOverlayClick) {
|
|
111
|
+
// 判断点击事件初次点击是否为内容区域
|
|
112
|
+
if (contentClickRef.current) {
|
|
113
|
+
contentClickRef.current = false;
|
|
114
|
+
} else if (e.target === dialogPosition.current) {
|
|
115
|
+
onOverlayClick?.({ e });
|
|
116
|
+
onClose?.({ e, trigger: "overlay" });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleCancel = ({ e }) => {
|
|
122
|
+
onCancel?.({ e });
|
|
123
|
+
onClose?.({ e, trigger: "cancel" });
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const handleClose = ({ e }) => {
|
|
127
|
+
onCloseBtnClick?.({ e });
|
|
128
|
+
onClose?.({ e, trigger: "close-btn" });
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
132
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
|
|
133
|
+
if (e.key === "Escape") {
|
|
134
|
+
e.stopPropagation();
|
|
135
|
+
onEscKeydown?.({ e });
|
|
136
|
+
if (closeOnEscKeydown) {
|
|
137
|
+
onClose?.({ e, trigger: "esc" });
|
|
138
|
+
}
|
|
139
|
+
} else if (e.key === "Enter" || e.key === "NumpadEnter") {
|
|
140
|
+
// 回车键触发点击确认事件
|
|
141
|
+
e.stopPropagation();
|
|
142
|
+
if (confirmOnEnter) {
|
|
143
|
+
onConfirm?.({ e });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const onAnimateLeave = () => {
|
|
149
|
+
onClosed?.();
|
|
150
|
+
|
|
151
|
+
if (!wrapRef.current) return;
|
|
152
|
+
wrapRef.current.style.display = "none";
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const onAnimateStart = () => {
|
|
156
|
+
if (!wrapRef.current) return;
|
|
157
|
+
onBeforeOpen?.();
|
|
158
|
+
wrapRef.current.style.display = "block";
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const onInnerAnimateStart = () => {
|
|
162
|
+
if (!dialogCardRef.current) return;
|
|
163
|
+
dialogCardRef.current.style.display = "block";
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const onInnerAnimateLeave = () => {
|
|
167
|
+
if (!dialogCardRef.current) return;
|
|
168
|
+
dialogCardRef.current.style.display = "none";
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const renderMask = () => {
|
|
172
|
+
if (mode !== "modal") return null;
|
|
173
|
+
|
|
174
|
+
return showOverlay ? (
|
|
175
|
+
<CSSTransition
|
|
176
|
+
in={visible}
|
|
177
|
+
appear
|
|
178
|
+
timeout={300}
|
|
179
|
+
classNames={`${componentCls}-fade`}
|
|
180
|
+
mountOnEnter
|
|
181
|
+
unmountOnExit
|
|
182
|
+
nodeRef={maskRef}
|
|
183
|
+
>
|
|
184
|
+
<div ref={maskRef} className={`${componentCls}__mask`} />
|
|
185
|
+
</CSSTransition>
|
|
186
|
+
) : null;
|
|
187
|
+
};
|
|
188
|
+
return (
|
|
189
|
+
<CSSTransition
|
|
190
|
+
in={visible}
|
|
191
|
+
appear
|
|
192
|
+
timeout={300}
|
|
193
|
+
mountOnEnter={isUndefined(forceRender) ? lazy : !forceRender}
|
|
194
|
+
unmountOnExit={destroyOnClose}
|
|
195
|
+
nodeRef={portalRef}
|
|
196
|
+
onEnter={onAnimateStart}
|
|
197
|
+
onEntered={onOpened}
|
|
198
|
+
onExit={() => onBeforeClose?.()}
|
|
199
|
+
onExited={onAnimateLeave}
|
|
200
|
+
>
|
|
201
|
+
<Portal attach={dialogAttach} ref={portalRef}>
|
|
202
|
+
<div
|
|
203
|
+
ref={wrapRef}
|
|
204
|
+
className={classNames(className, `${componentCls}__ctx`, `${componentCls}__${mode}`, {
|
|
205
|
+
[`${componentCls}__ctx--fixed`]: !showInAttachedElement,
|
|
206
|
+
[`${componentCls}__ctx--absolute`]: showInAttachedElement
|
|
207
|
+
})}
|
|
208
|
+
style={{ zIndex, display: "none" }}
|
|
209
|
+
onKeyDown={handleKeyDown}
|
|
210
|
+
tabIndex={0}
|
|
211
|
+
>
|
|
212
|
+
{renderMask()}
|
|
213
|
+
<div className={`${componentCls}__wrap`}>
|
|
214
|
+
<div
|
|
215
|
+
ref={dialogPosition}
|
|
216
|
+
className={classNames(`${componentCls}__position`, {
|
|
217
|
+
[`${componentCls}--top`]: !!props.top || props.placement === "top",
|
|
218
|
+
[`${componentCls}--center`]: props.placement === "center" && !props.top
|
|
219
|
+
})}
|
|
220
|
+
style={{ paddingTop: parseValueToPx(props.top) }}
|
|
221
|
+
onClick={onMaskClick}
|
|
222
|
+
>
|
|
223
|
+
<CSSTransition
|
|
224
|
+
in={visible}
|
|
225
|
+
appear
|
|
226
|
+
timeout={300}
|
|
227
|
+
classNames={`${componentCls}-zoom`}
|
|
228
|
+
nodeRef={dialogCardRef}
|
|
229
|
+
onEnter={onInnerAnimateStart}
|
|
230
|
+
onExited={onInnerAnimateLeave}
|
|
231
|
+
>
|
|
232
|
+
<DialogCard
|
|
233
|
+
ref={dialogCardRef}
|
|
234
|
+
{...restState}
|
|
235
|
+
className={dialogClassName}
|
|
236
|
+
style={{ ...style, width: parseValueToPx(width || style?.width) }}
|
|
237
|
+
onConfirm={onConfirm}
|
|
238
|
+
onCancel={handleCancel}
|
|
239
|
+
onCloseBtnClick={handleClose}
|
|
240
|
+
>
|
|
241
|
+
{children as React.ReactNode}
|
|
242
|
+
</DialogCard>
|
|
243
|
+
</CSSTransition>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
</Portal>
|
|
248
|
+
</CSSTransition>
|
|
249
|
+
);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
Dialog.displayName = "Dialog";
|
|
253
|
+
|
|
254
|
+
export default Dialog;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React, { forwardRef, isValidElement } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import { isString, isObject, isFunction } from "lodash-es";
|
|
4
|
+
import {
|
|
5
|
+
IconClose as TdCloseIcon,
|
|
6
|
+
IconInfoCircle as TdInfoCircleFilledIcon,
|
|
7
|
+
IconCheckCircleStroked as TdCheckCircleFilledIcon
|
|
8
|
+
} from "@tendaui/icons";
|
|
9
|
+
import Button, { ButtonProps } from "../button";
|
|
10
|
+
import { TdDialogCardProps } from "./type";
|
|
11
|
+
import { StyledProps, TNode } from "../common";
|
|
12
|
+
import parseTNode from "../utils/parseTNode";
|
|
13
|
+
import useConfig from "../hooks/useConfig";
|
|
14
|
+
import useGlobalIcon from "../hooks/useGlobalIcon";
|
|
15
|
+
// import { useLocaleReceiver } from '../locale/LocalReceiver';
|
|
16
|
+
import { dialogCardDefaultProps } from "./defaultProps";
|
|
17
|
+
import useDefaultProps from "../hooks/useDefaultProps";
|
|
18
|
+
|
|
19
|
+
export interface DialogCardProps extends TdDialogCardProps, StyledProps, React.HTMLAttributes<HTMLDivElement> {
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const renderDialogButton = (btn: DialogCardProps["cancelBtn"], defaultProps: ButtonProps) => {
|
|
24
|
+
let result = null;
|
|
25
|
+
|
|
26
|
+
if (isString(btn)) {
|
|
27
|
+
result = <Button {...defaultProps}>{btn as TNode}</Button>;
|
|
28
|
+
} else if (isValidElement(btn)) {
|
|
29
|
+
result = btn;
|
|
30
|
+
} else if (isObject(btn)) {
|
|
31
|
+
result = <Button {...defaultProps} {...(btn as Record<string, unknown>)} />;
|
|
32
|
+
} else if (isFunction(btn)) {
|
|
33
|
+
result = (btn as () => React.ReactNode)();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const DialogCard = forwardRef<HTMLDivElement, DialogCardProps>((props, ref) => {
|
|
40
|
+
const { classPrefix } = useConfig();
|
|
41
|
+
const componentCls = `${classPrefix}-dialog`;
|
|
42
|
+
useGlobalIcon({
|
|
43
|
+
CloseIcon: TdCloseIcon,
|
|
44
|
+
InfoCircleFilledIcon: TdInfoCircleFilledIcon,
|
|
45
|
+
CheckCircleFilledIcon: TdCheckCircleFilledIcon
|
|
46
|
+
});
|
|
47
|
+
// const [local, t] = useLocaleReceiver('dialog');
|
|
48
|
+
// const confirmText = t(local.confirm);
|
|
49
|
+
// const cancelText = t(local.cancel);
|
|
50
|
+
const confirmText = "确认";
|
|
51
|
+
const cancelText = "取消";
|
|
52
|
+
const {
|
|
53
|
+
theme,
|
|
54
|
+
header,
|
|
55
|
+
closeBtn,
|
|
56
|
+
footer,
|
|
57
|
+
body,
|
|
58
|
+
children,
|
|
59
|
+
className,
|
|
60
|
+
onCancel,
|
|
61
|
+
onConfirm,
|
|
62
|
+
onCloseBtnClick,
|
|
63
|
+
cancelBtn = cancelText,
|
|
64
|
+
confirmBtn = confirmText,
|
|
65
|
+
confirmLoading,
|
|
66
|
+
...otherProps
|
|
67
|
+
} = useDefaultProps<DialogCardProps>(props, dialogCardDefaultProps);
|
|
68
|
+
|
|
69
|
+
const renderHeaderContent = () => {
|
|
70
|
+
const iconMap = {
|
|
71
|
+
info: <TdInfoCircleFilledIcon className={`${classPrefix}-is-info`} />,
|
|
72
|
+
warning: <TdInfoCircleFilledIcon className={`${classPrefix}-is-warning`} />,
|
|
73
|
+
// error is going to deprecated
|
|
74
|
+
error: <TdInfoCircleFilledIcon className={`${classPrefix}-is-error`} />,
|
|
75
|
+
danger: <TdInfoCircleFilledIcon className={`${classPrefix}-is-error`} />,
|
|
76
|
+
success: <TdCheckCircleFilledIcon className={`${classPrefix}-is-success`} />
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div className={`${componentCls}__header-content`}>
|
|
81
|
+
{iconMap[theme]}
|
|
82
|
+
{header}
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const renderCloseBtn = () => {
|
|
88
|
+
if (!closeBtn) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const closeIcon = () => (closeBtn === true ? <TdCloseIcon /> : closeBtn);
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<span
|
|
96
|
+
className={`${componentCls}__close`}
|
|
97
|
+
style={{
|
|
98
|
+
marginLeft: "auto"
|
|
99
|
+
}}
|
|
100
|
+
onClick={(e: React.MouseEvent<HTMLDivElement>) => onCloseBtnClick?.({ e })}
|
|
101
|
+
>
|
|
102
|
+
{closeIcon() as React.ReactNode}
|
|
103
|
+
</span>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const renderHeader = () => (
|
|
108
|
+
<div className={classNames(`${componentCls}__header`)}>
|
|
109
|
+
{renderHeaderContent()}
|
|
110
|
+
{renderCloseBtn()}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const renderFooter = () => {
|
|
115
|
+
const defaultFooter = () => {
|
|
116
|
+
const renderCancelBtn = renderDialogButton(cancelBtn, {
|
|
117
|
+
variant: "outline",
|
|
118
|
+
onClick: (e: React.MouseEvent<HTMLButtonElement>) => onCancel?.({ e }),
|
|
119
|
+
className: classNames(
|
|
120
|
+
`${componentCls}__cancel`,
|
|
121
|
+
(cancelBtn as { props?: { className?: string } })?.props?.className
|
|
122
|
+
)
|
|
123
|
+
});
|
|
124
|
+
const renderConfirmBtn = renderDialogButton(confirmBtn, {
|
|
125
|
+
theme: "primary",
|
|
126
|
+
loading: confirmLoading,
|
|
127
|
+
onClick: (e: React.MouseEvent<HTMLButtonElement>) => onConfirm?.({ e }),
|
|
128
|
+
className: classNames(`${componentCls}__confirm`, (confirmBtn as { className?: string })?.className)
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<>
|
|
133
|
+
{renderCancelBtn}
|
|
134
|
+
{renderConfirmBtn}
|
|
135
|
+
</>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
return <div className={`${componentCls}__footer`}>{parseTNode(footer, null, defaultFooter())}</div>;
|
|
140
|
+
};
|
|
141
|
+
return (
|
|
142
|
+
<div ref={ref} {...otherProps} className={classNames(componentCls, `${componentCls}--default`, className)}>
|
|
143
|
+
{!!header && renderHeader()}
|
|
144
|
+
<div className={`${componentCls}__body`}>{(body || children) as React.ReactNode}</div>
|
|
145
|
+
{!!footer && renderFooter()}
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
DialogCard.displayName = "DialogCard";
|
|
151
|
+
|
|
152
|
+
export default DialogCard;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
|
3
|
+
* */
|
|
4
|
+
|
|
5
|
+
import { TdDialogCardProps, TdDialogProps } from "./type";
|
|
6
|
+
|
|
7
|
+
export const dialogCardDefaultProps: TdDialogCardProps = {
|
|
8
|
+
closeBtn: true,
|
|
9
|
+
footer: true,
|
|
10
|
+
header: true,
|
|
11
|
+
theme: "default"
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const dialogDefaultProps: TdDialogProps = {
|
|
15
|
+
closeOnEscKeydown: undefined,
|
|
16
|
+
closeOnOverlayClick: undefined,
|
|
17
|
+
destroyOnClose: false,
|
|
18
|
+
draggable: false,
|
|
19
|
+
mode: "modal",
|
|
20
|
+
placement: "top",
|
|
21
|
+
preventScrollThrough: true,
|
|
22
|
+
showInAttachedElement: false,
|
|
23
|
+
showOverlay: true,
|
|
24
|
+
lazy: true
|
|
25
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { RefObject, useRef } from "react";
|
|
2
|
+
import useMouseEvent from "../../hooks/useMouseEvent";
|
|
3
|
+
|
|
4
|
+
interface DialogDragProps {
|
|
5
|
+
dialogCardRef: RefObject<HTMLDivElement | null>;
|
|
6
|
+
canDraggable?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const useDialogDrag = (props: DialogDragProps) => {
|
|
10
|
+
const { dialogCardRef, canDraggable } = props;
|
|
11
|
+
|
|
12
|
+
const validWindow = typeof window === "object";
|
|
13
|
+
const screenHeight = validWindow ? window.innerHeight || document.documentElement.clientHeight : undefined;
|
|
14
|
+
const screenWidth = validWindow ? window.innerWidth || document.documentElement.clientWidth : undefined;
|
|
15
|
+
|
|
16
|
+
const dragOffset = useRef({ x: 0, y: 0 });
|
|
17
|
+
|
|
18
|
+
useMouseEvent(dialogCardRef, {
|
|
19
|
+
enabled: canDraggable,
|
|
20
|
+
onDown: (e) => {
|
|
21
|
+
if (!validWindow || screenWidth === undefined || screenHeight === undefined || !dialogCardRef.current) return;
|
|
22
|
+
const { offsetLeft, offsetTop, offsetWidth, offsetHeight, style } = dialogCardRef.current;
|
|
23
|
+
if (offsetWidth > screenWidth || offsetHeight > screenHeight) return;
|
|
24
|
+
style.cursor = "move";
|
|
25
|
+
dragOffset.current = {
|
|
26
|
+
x: e.clientX - offsetLeft,
|
|
27
|
+
y: e.clientY - offsetTop
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
onMove: (e) => {
|
|
31
|
+
if (!validWindow || screenWidth === undefined || screenHeight === undefined || !dialogCardRef.current) return;
|
|
32
|
+
const { offsetWidth, offsetHeight, style } = dialogCardRef.current;
|
|
33
|
+
let diffX = e.clientX - dragOffset.current.x;
|
|
34
|
+
let diffY = e.clientY - dragOffset.current.y;
|
|
35
|
+
// 拖拽上左边界限制
|
|
36
|
+
if (diffX < 0) diffX = 0;
|
|
37
|
+
if (diffY < 0) diffY = 0;
|
|
38
|
+
if (screenWidth - offsetWidth - diffX < 0) diffX = screenWidth - offsetWidth;
|
|
39
|
+
if (screenHeight - offsetHeight - diffY < 0) diffY = screenHeight - offsetHeight;
|
|
40
|
+
style.position = "absolute";
|
|
41
|
+
style.left = `${diffX}px`;
|
|
42
|
+
style.top = `${diffY}px`;
|
|
43
|
+
},
|
|
44
|
+
onUp: () => {
|
|
45
|
+
if (dialogCardRef.current) dialogCardRef.current.style.cursor = "default";
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default useDialogDrag;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, type RefObject } from "react";
|
|
2
|
+
|
|
3
|
+
const dialogSet: Set<RefObject<HTMLElement | null>> = new Set();
|
|
4
|
+
|
|
5
|
+
const useDialogEsc = (visible: boolean | undefined, dialog: RefObject<HTMLElement | null>) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (visible) {
|
|
8
|
+
// 将 dialog 添加至 Set 对象
|
|
9
|
+
if (dialog?.current) {
|
|
10
|
+
dialogSet.add(dialog);
|
|
11
|
+
dialog?.current?.focus();
|
|
12
|
+
}
|
|
13
|
+
} else if (dialogSet.has(dialog)) {
|
|
14
|
+
// 将 dialog 从 Set 对象删除
|
|
15
|
+
dialogSet.delete(dialog);
|
|
16
|
+
const dialogList = [...dialogSet];
|
|
17
|
+
// 将 Set 对象中最后一个 dialog 设置为 focus
|
|
18
|
+
dialogList[dialogList.length - 1]?.current?.focus();
|
|
19
|
+
}
|
|
20
|
+
return () => {
|
|
21
|
+
// 从 Set 对象删除无效的 dialog
|
|
22
|
+
dialogSet.forEach((item) => {
|
|
23
|
+
if (item?.current === null) {
|
|
24
|
+
dialogSet.delete(item);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
}, [visible, dialog]);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default useDialogEsc;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { RefObject, useEffect, useRef } from "react";
|
|
2
|
+
import useIsomorphicLayoutEffect from "../../hooks/useLayoutEffect";
|
|
3
|
+
type Position = { x: number; y: number };
|
|
4
|
+
export default function useDialogPosition(visible: boolean | undefined, dialogCardRef: RefObject<HTMLElement | null>) {
|
|
5
|
+
const mousePosRef = useRef<Position>(null);
|
|
6
|
+
|
|
7
|
+
const getClickPosition = (e: MouseEvent) => {
|
|
8
|
+
if (mousePosRef) {
|
|
9
|
+
mousePosRef.current = {
|
|
10
|
+
x: e.clientX,
|
|
11
|
+
y: e.clientY
|
|
12
|
+
};
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
mousePosRef.current = null;
|
|
15
|
+
}, 100);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
useIsomorphicLayoutEffect(() => {
|
|
20
|
+
document.addEventListener("click", getClickPosition, true);
|
|
21
|
+
return () => {
|
|
22
|
+
document.removeEventListener("click", getClickPosition, true);
|
|
23
|
+
};
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!visible) return;
|
|
28
|
+
// 动画渲染初始位置
|
|
29
|
+
if (mousePosRef.current && dialogCardRef.current) {
|
|
30
|
+
// eslint-disable-next-line
|
|
31
|
+
dialogCardRef.current.style.transformOrigin = `${mousePosRef.current.x - dialogCardRef.current.offsetLeft}px ${
|
|
32
|
+
mousePosRef.current.y - dialogCardRef.current.offsetTop
|
|
33
|
+
}px`;
|
|
34
|
+
}
|
|
35
|
+
}, [visible, dialogCardRef]);
|
|
36
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useRef, useCallback } from "react";
|
|
2
|
+
import { getScrollbarWidth } from "../../utils/getScrollbarWidth";
|
|
3
|
+
import useLayoutEffect from "../../hooks/useLayoutEffect";
|
|
4
|
+
import type { TdDialogProps } from "../type";
|
|
5
|
+
let key = 1;
|
|
6
|
+
|
|
7
|
+
export default function useDialogLockStyle({
|
|
8
|
+
preventScrollThrough,
|
|
9
|
+
visible,
|
|
10
|
+
mode,
|
|
11
|
+
showInAttachedElement
|
|
12
|
+
}: Partial<TdDialogProps>) {
|
|
13
|
+
const lockStyleRef = useRef<HTMLStyleElement>(null);
|
|
14
|
+
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
15
|
+
|
|
16
|
+
const clearStyleFunc = useCallback(() => {
|
|
17
|
+
if (timerRef.current) {
|
|
18
|
+
clearTimeout(timerRef.current);
|
|
19
|
+
}
|
|
20
|
+
timerRef.current = setTimeout(() => {
|
|
21
|
+
lockStyleRef.current?.parentNode?.removeChild?.(lockStyleRef.current);
|
|
22
|
+
}, 150);
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
useLayoutEffect(() => {
|
|
26
|
+
if (typeof document === "undefined" || !visible) return;
|
|
27
|
+
if (!lockStyleRef.current) {
|
|
28
|
+
lockStyleRef.current = document.createElement("style");
|
|
29
|
+
}
|
|
30
|
+
const hasScrollBar = document.documentElement.scrollHeight > document.documentElement.clientHeight;
|
|
31
|
+
const scrollbarWidth = hasScrollBar ? getScrollbarWidth() : 0;
|
|
32
|
+
|
|
33
|
+
lockStyleRef.current.dataset.id = `td_dialog_${+new Date()}_${(key += 1)}`;
|
|
34
|
+
lockStyleRef.current.innerHTML = `
|
|
35
|
+
html body {
|
|
36
|
+
overflow-y: hidden;
|
|
37
|
+
width: calc(100% - ${scrollbarWidth}px);
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
return clearStyleFunc;
|
|
42
|
+
}, [visible, clearStyleFunc]);
|
|
43
|
+
|
|
44
|
+
useLayoutEffect(() => {
|
|
45
|
+
if (typeof document === "undefined") return;
|
|
46
|
+
if (mode !== "modal" || !preventScrollThrough || showInAttachedElement) return;
|
|
47
|
+
|
|
48
|
+
if (visible) {
|
|
49
|
+
if (lockStyleRef.current) document.head.appendChild(lockStyleRef.current);
|
|
50
|
+
} else {
|
|
51
|
+
clearStyleFunc();
|
|
52
|
+
}
|
|
53
|
+
}, [preventScrollThrough, visible, mode, showInAttachedElement, clearStyleFunc]);
|
|
54
|
+
}
|
package/dialog/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import _Dialog from "./Dialog";
|
|
2
|
+
import _DialogCard from "./DialogCard";
|
|
3
|
+
import { DialogPlugin as _DialogPlugin } from "./plugin";
|
|
4
|
+
import "./style/index.js";
|
|
5
|
+
|
|
6
|
+
export type { DialogProps } from "./Dialog";
|
|
7
|
+
export * from "./type";
|
|
8
|
+
export const Dialog = _Dialog;
|
|
9
|
+
export const DialogCard = _DialogCard;
|
|
10
|
+
|
|
11
|
+
export const dialog = _DialogPlugin;
|
|
12
|
+
export const DialogPlugin = _DialogPlugin;
|
|
13
|
+
export default Dialog;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "../utils/react-render";
|
|
3
|
+
import DialogComponent, { DialogProps } from "./Dialog";
|
|
4
|
+
import { getAttach } from "../utils/dom";
|
|
5
|
+
import { DialogOptions, DialogMethod, DialogConfirmMethod, DialogAlertMethod, DialogInstance } from "./type";
|
|
6
|
+
import PluginContainer from "../common/PluginContainer";
|
|
7
|
+
import ConfigProvider from "../config-provider";
|
|
8
|
+
|
|
9
|
+
export interface DialogPluginType extends DialogMethod {
|
|
10
|
+
alert: DialogAlertMethod;
|
|
11
|
+
confirm: DialogConfirmMethod;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const createDialog: DialogPluginType = (props: DialogOptions): DialogInstance => {
|
|
15
|
+
const dialogRef = React.createRef<DialogInstance>();
|
|
16
|
+
const options = { ...props };
|
|
17
|
+
const { visible = true } = options;
|
|
18
|
+
|
|
19
|
+
const fragment = document.createDocumentFragment();
|
|
20
|
+
|
|
21
|
+
const dGlobalConfig = ConfigProvider.getGlobalConfig();
|
|
22
|
+
render(
|
|
23
|
+
<PluginContainer globalConfig={dGlobalConfig}>
|
|
24
|
+
<DialogComponent {...(options as DialogProps)} visible={visible} ref={dialogRef} isPlugin />
|
|
25
|
+
</PluginContainer>,
|
|
26
|
+
fragment
|
|
27
|
+
);
|
|
28
|
+
const container = getAttach(options.attach);
|
|
29
|
+
|
|
30
|
+
if (container) {
|
|
31
|
+
container.appendChild(fragment);
|
|
32
|
+
} else {
|
|
33
|
+
console.error("Dialog", "attach is not exist");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const dialogNode: DialogInstance = {
|
|
37
|
+
show: () => {
|
|
38
|
+
requestAnimationFrame(() => {
|
|
39
|
+
container?.appendChild(fragment);
|
|
40
|
+
dialogRef.current?.show();
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
hide: () => {
|
|
44
|
+
requestAnimationFrame(() => {
|
|
45
|
+
dialogRef.current?.destroy();
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
setConfirmLoading: (loading: boolean) => {
|
|
49
|
+
requestAnimationFrame(() => {
|
|
50
|
+
dialogRef.current?.setConfirmLoading(loading);
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
update: (updateOptions: DialogOptions) => {
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
dialogRef.current?.update(updateOptions);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
destroy: () => {
|
|
59
|
+
requestAnimationFrame(() => {
|
|
60
|
+
dialogRef.current?.destroy();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return dialogNode;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const confirm: DialogConfirmMethod = (props: DialogOptions) => createDialog(props);
|
|
68
|
+
|
|
69
|
+
const alert: DialogAlertMethod = (props: Omit<DialogOptions, "confirmBtn">) => {
|
|
70
|
+
const options = { ...props };
|
|
71
|
+
options.cancelBtn = null;
|
|
72
|
+
return createDialog(options);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
createDialog.alert = alert;
|
|
76
|
+
createDialog.confirm = confirm;
|
|
77
|
+
|
|
78
|
+
export const DialogPlugin = createDialog;
|