antd-overlay 0.0.1 → 0.0.3
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 +20 -10
- package/dist/index.cjs +39 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +39 -21
- package/dist/index.js.map +1 -1
- package/package.json +8 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 RaineySpace
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -62,19 +62,19 @@ interface MyModalProps extends CustomModalProps<{ result: string }> {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const MyModal: React.FC<MyModalProps> = ({
|
|
65
|
-
open,
|
|
66
65
|
customClose,
|
|
67
66
|
customOk,
|
|
68
67
|
initialValue,
|
|
68
|
+
...props
|
|
69
69
|
}) => {
|
|
70
70
|
const [value, setValue] = useState(initialValue || '');
|
|
71
71
|
|
|
72
72
|
return (
|
|
73
73
|
<Modal
|
|
74
74
|
title="输入内容"
|
|
75
|
-
open={open}
|
|
76
75
|
onCancel={customClose}
|
|
77
76
|
onOk={() => customOk?.({ result: value })}
|
|
77
|
+
{...props}
|
|
78
78
|
>
|
|
79
79
|
<Input value={value} onChange={(e) => setValue(e.target.value)} />
|
|
80
80
|
</Modal>
|
|
@@ -125,10 +125,23 @@ function GlobalUsage() {
|
|
|
125
125
|
|
|
126
126
|
全局覆盖层容器,使用 `useGlobalModal`、`useGlobalDrawer`、`useGlobalOverlay` 时需要在应用外层包裹。
|
|
127
127
|
|
|
128
|
+
**属性:**
|
|
129
|
+
- `children: React.ReactNode` - 子节点
|
|
130
|
+
- `defaultModalProps?: Partial<ModalProps>` - 默认 Modal 属性,会应用到所有 Modal
|
|
131
|
+
- `defaultDrawerProps?: Partial<DrawerProps>` - 默认 Drawer 属性,会应用到所有 Drawer
|
|
132
|
+
|
|
128
133
|
```tsx
|
|
129
134
|
<AntdOverlayProvider>
|
|
130
135
|
<App />
|
|
131
136
|
</AntdOverlayProvider>
|
|
137
|
+
|
|
138
|
+
// 或设置默认属性
|
|
139
|
+
<AntdOverlayProvider
|
|
140
|
+
defaultModalProps={{ centered: true, maskClosable: false }}
|
|
141
|
+
defaultDrawerProps={{ width: 600 }}
|
|
142
|
+
>
|
|
143
|
+
<App />
|
|
144
|
+
</AntdOverlayProvider>
|
|
132
145
|
```
|
|
133
146
|
|
|
134
147
|
### Modal Hooks
|
|
@@ -299,22 +312,19 @@ import { CustomModalProps, useGlobalModal } from 'antd-overlay';
|
|
|
299
312
|
|
|
300
313
|
interface ConfirmDeleteModalProps extends CustomModalProps<void> {
|
|
301
314
|
itemName: string;
|
|
302
|
-
onConfirm: () => Promise<void>;
|
|
303
315
|
}
|
|
304
316
|
|
|
305
317
|
const ConfirmDeleteModal: React.FC<ConfirmDeleteModalProps> = ({
|
|
306
|
-
open,
|
|
307
318
|
customClose,
|
|
308
319
|
customOk,
|
|
309
320
|
itemName,
|
|
310
|
-
|
|
321
|
+
...props
|
|
311
322
|
}) => {
|
|
312
323
|
const [loading, setLoading] = useState(false);
|
|
313
324
|
|
|
314
325
|
const handleOk = async () => {
|
|
315
326
|
setLoading(true);
|
|
316
327
|
try {
|
|
317
|
-
await onConfirm();
|
|
318
328
|
message.success('删除成功');
|
|
319
329
|
customOk?.();
|
|
320
330
|
} catch (error) {
|
|
@@ -327,12 +337,12 @@ const ConfirmDeleteModal: React.FC<ConfirmDeleteModalProps> = ({
|
|
|
327
337
|
return (
|
|
328
338
|
<Modal
|
|
329
339
|
title="确认删除"
|
|
330
|
-
open={open}
|
|
331
340
|
onCancel={customClose}
|
|
332
341
|
onOk={handleOk}
|
|
333
342
|
confirmLoading={loading}
|
|
334
343
|
okText="删除"
|
|
335
344
|
okType="danger"
|
|
345
|
+
{...props}
|
|
336
346
|
>
|
|
337
347
|
确定要删除 "{itemName}" 吗?此操作不可恢复。
|
|
338
348
|
</Modal>
|
|
@@ -346,7 +356,7 @@ function ItemList() {
|
|
|
346
356
|
const handleDelete = (item: Item) => {
|
|
347
357
|
openConfirm({
|
|
348
358
|
itemName: item.name,
|
|
349
|
-
|
|
359
|
+
customOk: () => deleteItem(item.id),
|
|
350
360
|
});
|
|
351
361
|
};
|
|
352
362
|
|
|
@@ -380,9 +390,9 @@ interface UserDetailDrawerProps extends CustomDrawerProps {
|
|
|
380
390
|
}
|
|
381
391
|
|
|
382
392
|
const UserDetailDrawer: React.FC<UserDetailDrawerProps> = ({
|
|
383
|
-
open,
|
|
384
393
|
customClose,
|
|
385
394
|
userId,
|
|
395
|
+
...props
|
|
386
396
|
}) => {
|
|
387
397
|
const [user, setUser] = useState<User | null>(null);
|
|
388
398
|
const [loading, setLoading] = useState(false);
|
|
@@ -399,9 +409,9 @@ const UserDetailDrawer: React.FC<UserDetailDrawerProps> = ({
|
|
|
399
409
|
return (
|
|
400
410
|
<Drawer
|
|
401
411
|
title="用户详情"
|
|
402
|
-
open={open}
|
|
403
412
|
onClose={customClose}
|
|
404
413
|
width={500}
|
|
414
|
+
{...props}
|
|
405
415
|
>
|
|
406
416
|
{loading ? (
|
|
407
417
|
<Spin />
|
package/dist/index.cjs
CHANGED
|
@@ -9,7 +9,11 @@ var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
|
9
9
|
|
|
10
10
|
// src/AntdOverlayContext.tsx
|
|
11
11
|
var AntdOverlayContext = React2.createContext(null);
|
|
12
|
-
function AntdOverlayProvider({
|
|
12
|
+
function AntdOverlayProvider({
|
|
13
|
+
children,
|
|
14
|
+
defaultModalProps,
|
|
15
|
+
defaultDrawerProps
|
|
16
|
+
}) {
|
|
13
17
|
const [holders, setHolders] = React2.useState([]);
|
|
14
18
|
const addHolder = React2.useCallback((holder) => {
|
|
15
19
|
setHolders((prev) => [...prev, holder]);
|
|
@@ -18,8 +22,8 @@ function AntdOverlayProvider({ children }) {
|
|
|
18
22
|
setHolders((prev) => prev.filter((h) => h !== holder));
|
|
19
23
|
}, []);
|
|
20
24
|
const value = React2.useMemo(
|
|
21
|
-
() => ({ holders, addHolder, removeHolder }),
|
|
22
|
-
[holders, addHolder, removeHolder]
|
|
25
|
+
() => ({ holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps }),
|
|
26
|
+
[holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps]
|
|
23
27
|
);
|
|
24
28
|
return /* @__PURE__ */ jsxRuntime.jsxs(AntdOverlayContext.Provider, { value, children: [
|
|
25
29
|
children,
|
|
@@ -27,13 +31,7 @@ function AntdOverlayProvider({ children }) {
|
|
|
27
31
|
] });
|
|
28
32
|
}
|
|
29
33
|
function useAntdOverlayContext() {
|
|
30
|
-
|
|
31
|
-
if (!context) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
"useAntdOverlayContext must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>."
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
return context;
|
|
34
|
+
return React2.useContext(AntdOverlayContext);
|
|
37
35
|
}
|
|
38
36
|
var defaultPropsAdapter = (props, state) => {
|
|
39
37
|
const result = {
|
|
@@ -115,7 +113,13 @@ function useOverlay(OverlayComponent, options = {}) {
|
|
|
115
113
|
return [openOverlay, contextHolder];
|
|
116
114
|
}
|
|
117
115
|
function useGlobalOverlay(OverlayComponent, options) {
|
|
118
|
-
const
|
|
116
|
+
const context = useAntdOverlayContext();
|
|
117
|
+
if (!context) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
"useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>."
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
const { addHolder, removeHolder } = context;
|
|
119
123
|
const [openOverlay, contextHolder] = useOverlay(OverlayComponent, options);
|
|
120
124
|
React2.useEffect(() => {
|
|
121
125
|
addHolder(contextHolder);
|
|
@@ -137,11 +141,10 @@ function generateUseOverlayHook(OverlayComponent, defaultOptions) {
|
|
|
137
141
|
useGlobalOverlay: (options) => useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options })
|
|
138
142
|
};
|
|
139
143
|
}
|
|
140
|
-
var createModalPropsAdapter = () => {
|
|
144
|
+
var createModalPropsAdapter = (defaultProps) => {
|
|
141
145
|
return (props, state) => {
|
|
142
146
|
const result = {
|
|
143
|
-
|
|
144
|
-
// 默认禁止点击遮罩关闭
|
|
147
|
+
...defaultProps,
|
|
145
148
|
...props,
|
|
146
149
|
open: state.open,
|
|
147
150
|
customClose: state.onClose,
|
|
@@ -162,7 +165,11 @@ var createModalPropsAdapter = () => {
|
|
|
162
165
|
};
|
|
163
166
|
};
|
|
164
167
|
function useModal(ModalComponent, options) {
|
|
165
|
-
const
|
|
168
|
+
const context = useAntdOverlayContext();
|
|
169
|
+
const propsAdapter = React2.useMemo(
|
|
170
|
+
() => createModalPropsAdapter(context?.defaultModalProps),
|
|
171
|
+
[context?.defaultModalProps]
|
|
172
|
+
);
|
|
166
173
|
return useOverlay(ModalComponent, {
|
|
167
174
|
...options,
|
|
168
175
|
keyPrefix: "use-modal",
|
|
@@ -170,7 +177,11 @@ function useModal(ModalComponent, options) {
|
|
|
170
177
|
});
|
|
171
178
|
}
|
|
172
179
|
function useGlobalModal(ModalComponent, options) {
|
|
173
|
-
const
|
|
180
|
+
const context = useAntdOverlayContext();
|
|
181
|
+
const propsAdapter = React2.useMemo(
|
|
182
|
+
() => createModalPropsAdapter(context?.defaultModalProps),
|
|
183
|
+
[context?.defaultModalProps]
|
|
184
|
+
);
|
|
174
185
|
return useGlobalOverlay(ModalComponent, {
|
|
175
186
|
...options,
|
|
176
187
|
keyPrefix: "use-modal",
|
|
@@ -183,11 +194,10 @@ function generateUseModalHook(ModalComponent) {
|
|
|
183
194
|
useGlobalModal: (options) => useGlobalModal(ModalComponent, options)
|
|
184
195
|
};
|
|
185
196
|
}
|
|
186
|
-
var createDrawerPropsAdapter = () => {
|
|
197
|
+
var createDrawerPropsAdapter = (defaultProps) => {
|
|
187
198
|
return (props, state) => {
|
|
188
199
|
const result = {
|
|
189
|
-
|
|
190
|
-
// 默认禁止点击遮罩关闭
|
|
200
|
+
...defaultProps,
|
|
191
201
|
...props,
|
|
192
202
|
open: state.open,
|
|
193
203
|
customClose: state.onClose,
|
|
@@ -210,7 +220,11 @@ var createDrawerPropsAdapter = () => {
|
|
|
210
220
|
};
|
|
211
221
|
};
|
|
212
222
|
function useDrawer(DrawerComponent, options) {
|
|
213
|
-
const
|
|
223
|
+
const context = useAntdOverlayContext();
|
|
224
|
+
const propsAdapter = React2.useMemo(
|
|
225
|
+
() => createDrawerPropsAdapter(context?.defaultDrawerProps),
|
|
226
|
+
[context?.defaultDrawerProps]
|
|
227
|
+
);
|
|
214
228
|
return useOverlay(DrawerComponent, {
|
|
215
229
|
...options,
|
|
216
230
|
keyPrefix: "use-drawer",
|
|
@@ -218,7 +232,11 @@ function useDrawer(DrawerComponent, options) {
|
|
|
218
232
|
});
|
|
219
233
|
}
|
|
220
234
|
function useGlobalDrawer(DrawerComponent, options) {
|
|
221
|
-
const
|
|
235
|
+
const context = useAntdOverlayContext();
|
|
236
|
+
const propsAdapter = React2.useMemo(
|
|
237
|
+
() => createDrawerPropsAdapter(context?.defaultDrawerProps),
|
|
238
|
+
[context?.defaultDrawerProps]
|
|
239
|
+
);
|
|
222
240
|
return useGlobalOverlay(DrawerComponent, {
|
|
223
241
|
...options,
|
|
224
242
|
keyPrefix: "use-drawer",
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AntdOverlayContext.tsx","../src/useOverlay.tsx","../src/useModal.tsx","../src/useDrawer.tsx"],"names":["createContext","useState","useCallback","useMemo","jsxs","useContext","useId","useRef","React","jsx","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @file AntdOverlayContext - 全局覆盖层容器 Context\n * @description\n * 提供全局覆盖层的挂载点管理。所有通过 useGlobalOverlay 系列 Hook\n * 创建的覆盖层都会被挂载到 AntdOverlayProvider 下。\n *\n * 工作原理:\n * 1. AntdOverlayProvider 维护一个 holders 数组\n * 2. useGlobalOverlay 通过 useAntdOverlayContext 获取注册方法\n * 3. 覆盖层的 contextHolder 被添加到 holders 数组\n * 4. Provider 在子节点之后统一渲染所有 holders\n *\n * 这种设计的优势:\n * - 覆盖层与业务组件解耦,可在任意位置调用\n * - 统一的挂载点,避免 z-index 混乱\n * - 组件卸载时自动清理对应的覆盖层\n *\n * @example\n * // 在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n */\n\nimport React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * AntdOverlay Context 的值类型\n *\n * @property holders - 当前所有已注册的覆盖层 holder 节点\n * @property addHolder - 注册一个新的 holder 到全局容器\n * @property removeHolder - 从全局容器移除一个已注册的 holder\n */\ninterface AntdOverlayContextValue {\n /** 所有已注册的 holder 节点列表 */\n holders: React.ReactNode[];\n /** 添加 holder 到全局容器 */\n addHolder: (holder: React.ReactNode) => void;\n /** 从全局容器移除 holder */\n removeHolder: (holder: React.ReactNode) => void;\n}\n\n// ============================================================================\n// Context 定义\n// ============================================================================\n\n/**\n * AntdOverlay Context\n *\n * 默认值为 null,使用时必须在 AntdOverlayProvider 内部。\n * 如果在 Provider 外部调用 useAntdOverlayContext,会抛出明确的错误提示。\n */\nconst AntdOverlayContext = createContext<AntdOverlayContextValue | null>(null);\n\n// ============================================================================\n// Provider 组件\n// ============================================================================\n\n/**\n * AntdOverlay 容器提供者组件\n *\n * 用于管理全局覆盖层的挂载点。所有通过 useGlobalOverlay、useGlobalModal、\n * useGlobalDrawer 等 Hook 创建的覆盖层都会被挂载到这个 Provider 下。\n *\n * 渲染结构:\n * ```\n * <AntdOverlayContext.Provider>\n * {children} <- 应用的主要内容\n * {holders[0]} <- 全局覆盖层 1\n * {holders[1]} <- 全局覆盖层 2\n * ...\n * </AntdOverlayContext.Provider>\n * ```\n *\n * @param children - 子节点,通常是整个应用\n *\n * @example\n * // 基础用法 - 在应用入口包裹\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n *\n * @example\n * // 与其他 Provider 配合使用\n * function App() {\n * return (\n * <ConfigProvider>\n * <AntdOverlayProvider>\n * <App />\n * </AntdOverlayProvider>\n * </ConfigProvider>\n * );\n * }\n */\nexport function AntdOverlayProvider({ children }: { children: React.ReactNode }) {\n // 存储所有已注册的 holder 节点\n const [holders, setHolders] = useState<React.ReactNode[]>([]);\n\n /**\n * 添加 holder 到全局容器\n *\n * 使用函数式更新确保并发安全,避免闭包陷阱。\n * 新的 holder 会被追加到数组末尾,因此后添加的覆盖层会显示在上层。\n */\n const addHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => [...prev, holder]);\n }, []);\n\n /**\n * 从全局容器移除 holder\n *\n * 通过引用比较(===)找到并移除对应的 holder。\n * 这要求每次传入的 holder 必须是同一个引用。\n */\n const removeHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => prev.filter((h) => h !== holder));\n }, []);\n\n // 使用 useMemo 优化 Context 值,避免不必要的重渲染\n // 只有当 holders、addHolder 或 removeHolder 变化时才会创建新的值对象\n const value = useMemo(\n () => ({ holders, addHolder, removeHolder }),\n [holders, addHolder, removeHolder],\n );\n\n return (\n <AntdOverlayContext.Provider value={value}>\n {children}\n {/* 在 children 之后渲染所有全局覆盖层 */}\n {holders}\n </AntdOverlayContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * 获取 AntdOverlay Context 的 Hook\n *\n * 返回全局容器的注册和注销方法,供 useGlobalOverlay 系列 Hook 内部使用。\n *\n * 注意事项:\n * - 必须在 AntdOverlayProvider 内部使用\n * - 如果在 Provider 外部调用,会抛出明确的错误\n * - 主要供库内部使用,一般不需要在业务代码中直接调用\n *\n * @returns AntdOverlayContextValue 包含 holders、addHolder、removeHolder\n * @throws Error 如果不在 AntdOverlayProvider 内部使用\n *\n * @example\n * // 库内部使用示例(useGlobalOverlay 的实现)\n * function useGlobalOverlay(Component, options) {\n * const { addHolder, removeHolder } = useAntdOverlayContext();\n * const [open, holder] = useOverlay(Component, options);\n *\n * useEffect(() => {\n * addHolder(holder);\n * return () => removeHolder(holder);\n * }, [holder]);\n *\n * return open;\n * }\n */\nexport function useAntdOverlayContext() {\n const context = useContext(AntdOverlayContext);\n\n if (!context) {\n throw new Error(\n 'useAntdOverlayContext must be used within an AntdOverlayProvider. ' +\n 'Please wrap your application with <AntdOverlayProvider>.',\n );\n }\n\n return context;\n}\n","/**\n * @file useOverlay - 通用覆盖层管理 Hook\n * @description\n * 提供一个与具体 UI 组件无关的覆盖层(Overlay)管理方案。\n * 支持任意满足 CustomOverlayProps 接口的组件,如 Modal、Drawer、Popover 等。\n *\n * 核心设计理念:\n * 1. 命令式调用 - 通过函数调用打开覆盖层,而非声明式管理 open 状态\n * 2. 动画支持 - 正确处理打开/关闭动画,避免动画未完成就卸载组件\n * 3. 全局挂载 - 支持将覆盖层挂载到全局容器,实现跨组件调用\n * 4. 类型安全 - 完整的 TypeScript 类型支持\n *\n * 架构层次:\n * ┌─────────────────────────────────────────────────────────┐\n * │ useModal / useDrawer │ <- 业务层封装\n * ├─────────────────────────────────────────────────────────┤\n * │ useOverlay / useGlobalOverlay │ <- 核心逻辑层\n * ├─────────────────────────────────────────────────────────┤\n * │ GlobalHolderProvider │ <- 全局容器层\n * └─────────────────────────────────────────────────────────┘\n *\n * @example\n * // 直接使用 useOverlay(不推荐,建议使用 useModal/useDrawer)\n * const [openOverlay, holder] = useOverlay(MyOverlayComponent, {\n * propsAdapter: (props, state) => ({ ...props, visible: state.open }),\n * });\n */\n\nimport React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useAntdOverlayContext } from './AntdOverlayContext';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * 自定义覆盖层组件必须实现的属性接口\n *\n * 这是所有覆盖层组件的基础接口,定义了控制覆盖层所需的最小属性集。\n * 具体的 UI 组件(如 Modal、Drawer)应该扩展此接口。\n *\n * @template T - customOk 回调接收的参数类型,用于传递确认操作的数据\n * @template R - customOk 回调的返回类型,通常为 void\n *\n * @property open - 控制覆盖层的显示/隐藏状态\n * @property customClose - 关闭覆盖层的回调函数,由 useOverlay 注入\n * @property customOk - 确认操作的回调函数,调用后会自动关闭覆盖层\n *\n * @example\n * interface MyOverlayProps extends CustomOverlayProps<{ id: number }> {\n * title: string;\n * data: SomeData;\n * }\n *\n * const MyOverlay: React.FC<MyOverlayProps> = ({\n * open,\n * customClose,\n * customOk,\n * title,\n * data,\n * }) => {\n * const handleConfirm = () => {\n * // 调用 customOk 会自动关闭覆盖层\n * customOk?.({ id: data.id });\n * };\n * return (\n * <Modal open={open} onCancel={customClose} onOk={handleConfirm}>\n * {title}\n * </Modal>\n * );\n * };\n */\nexport interface CustomOverlayProps<T = any, R = void> {\n /** 覆盖层的显示状态 */\n open?: boolean;\n /** 关闭覆盖层的回调,由 useOverlay 自动注入 */\n customClose: () => void;\n /** 确认操作回调,调用后自动关闭覆盖层 */\n customOk?: (value: T) => R;\n}\n\n/**\n * 内部使用的属性类型\n * 排除 customClose,因为它由 useOverlay 自动注入,用户无需传递\n */\ntype InternalProps<T extends CustomOverlayProps> = Omit<T, 'customClose'>;\n\n/**\n * 覆盖层控制器接口\n *\n * 打开覆盖层后返回的控制器对象,用于后续操作(更新属性或关闭)。\n * 使用 readonly 确保方法引用稳定,不会被意外修改。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @example\n * const controller = openModal({ title: '初始标题' });\n *\n * // 动态更新属性\n * controller.update({ title: '新标题', loading: true });\n *\n * // 编程式关闭\n * controller.close();\n */\nexport interface OverlayController<T extends CustomOverlayProps> {\n /**\n * 更新覆盖层的属性\n * @param props - 新的属性对象,会完全替换之前的属性\n */\n readonly update: (props: InternalProps<T>) => void;\n /**\n * 关闭覆盖层\n * 如果启用了动画,会等待动画结束后再卸载组件\n */\n readonly close: () => void;\n}\n\n/**\n * 覆盖层打开函数的类型定义\n *\n * @template T - 覆盖层组件的属性类型\n * @param initialize - 初始化属性,可选\n * @returns 覆盖层控制器,用于后续的更新和关闭操作\n *\n * @example\n * const openModal: OverlayOpener<MyModalProps> = (props) => {\n * // 返回控制器\n * };\n *\n * // 无参数调用\n * const ctrl1 = openModal();\n *\n * // 带初始属性调用\n * const ctrl2 = openModal({ title: '标题', data: someData });\n */\nexport type OverlayOpener<T extends CustomOverlayProps> = (\n initialize?: InternalProps<T>,\n) => OverlayController<T>;\n\n/**\n * useOverlay Hook 的配置选项\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @property animation - 是否启用动画支持,默认 true\n * - true: 关闭时先设置 open=false,等待动画结束后再卸载组件\n * - false: 关闭时直接卸载组件,适用于无动画的覆盖层\n *\n * @property keyPrefix - React key 的前缀,用于区分不同类型的覆盖层\n * - 默认值: 'use-overlay'\n * - useModal 使用 'use-modal'\n * - useDrawer 使用 'use-drawer'\n *\n * @property propsAdapter - 属性适配器函数\n * 用于将内部状态转换为组件实际需要的属性。\n * 不同的 UI 组件(Modal、Drawer)有不同的动画回调机制,\n * 通过适配器实现统一的接口。\n */\nexport interface UseOverlayOptions<T extends CustomOverlayProps> {\n /** 是否启用关闭动画,默认 true */\n animation?: boolean;\n /** React key 前缀,用于标识覆盖层类型 */\n keyPrefix?: string;\n /**\n * 属性适配器函数\n * @param props - 用户传入的属性\n * @param state - 内部状态,包含 open、onClose、onAnimationEnd\n * @returns 传递给组件的最终属性\n */\n propsAdapter?: (\n props: InternalProps<T> | undefined,\n state: {\n /** 当前的打开状态 */\n open: boolean;\n /** 触发关闭的回调 */\n onClose: () => void;\n /** 动画结束后的回调,用于卸载组件 */\n onAnimationEnd: () => void;\n },\n ) => T;\n}\n\n// ============================================================================\n// 默认属性适配器\n// ============================================================================\n\n/**\n * 默认的属性适配器\n *\n * 提供基本的属性转换逻辑:\n * 1. 将用户传入的 props 与内部状态合并\n * 2. 注入 open 和 customClose\n * 3. 包装 customOk 使其调用后自动关闭覆盖层\n *\n * 注意:这是一个简化的适配器,不处理动画。\n * 对于 Modal 和 Drawer,应该使用各自的专用适配器来处理动画回调。\n *\n * @template T - 覆盖层组件的属性类型\n * @param props - 用户传入的属性\n * @param state - 内部状态\n * @returns 最终传递给组件的属性\n */\nconst defaultPropsAdapter = <T extends CustomOverlayProps>(\n props: InternalProps<T> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n): T => {\n const result = {\n ...props,\n open: state.open,\n customClose: state.onClose,\n } as unknown as T;\n\n // 包装 customOk,使其调用后自动触发关闭\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n};\n\n// ============================================================================\n// 核心 Hook 实现\n// ============================================================================\n\n/**\n * 覆盖层管理核心 Hook\n *\n * 这是整个库的核心,提供覆盖层的生命周期管理:\n * - 挂载/卸载控制\n * - 打开/关闭状态管理\n * - 动画支持\n * - 属性更新\n *\n * 状态机说明:\n * ```\n * [未挂载] --open()--> [已挂载, open=true] --close()--> [已挂载, open=false] --动画结束--> [未挂载]\n * │\n * └── (animation=false) --> [未挂载]\n * ```\n *\n * @template T - 覆盖层组件的属性类型,必须继承 CustomOverlayProps\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 元组 [openOverlay, contextHolder]\n * - openOverlay: 打开覆盖层的函数,返回控制器\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyComponent() {\n * const [openOverlay, holder] = useOverlay(MyOverlay, {\n * animation: true,\n * propsAdapter: (props, state) => ({\n * ...props,\n * visible: state.open,\n * onClose: state.onClose,\n * afterVisibleChange: (visible) => {\n * if (!visible) state.onAnimationEnd();\n * },\n * }),\n * });\n *\n * return (\n * <>\n * <button onClick={() => openOverlay({ title: '标题' })}>打开</button>\n * {holder}\n * </>\n * );\n * }\n */\nexport function useOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options: UseOverlayOptions<T> = {},\n): [OverlayOpener<T>, React.ReactNode] {\n // 解构配置选项,设置默认值\n const {\n animation = true,\n keyPrefix = 'use-overlay',\n propsAdapter = defaultPropsAdapter,\n } = options;\n\n // 生成唯一 ID,用于 React key\n const id = useId();\n const key = `${keyPrefix}-${id}`;\n\n // ========== 状态管理 ==========\n\n /**\n * open: 控制覆盖层的显示状态(用于动画)\n * - true: 覆盖层显示\n * - false: 覆盖层隐藏(但可能还在播放关闭动画)\n */\n const [open, setOpen] = useState(false);\n\n /**\n * renderEnable: 控制组件是否挂载到 DOM\n * - true: 组件已挂载\n * - false: 组件已卸载\n *\n * 与 open 分离是为了支持关闭动画:\n * 关闭时先设置 open=false 触发动画,动画结束后再设置 renderEnable=false 卸载组件\n */\n const [renderEnable, setRenderEnable] = useState(false);\n\n /**\n * props: 用户传入的属性\n * 存储最近一次 open 或 update 调用时传入的属性\n */\n const [props, setProps] = useState<InternalProps<T> | undefined>();\n\n /**\n * 使用 ref 存储 animation 配置\n * 避免 animation 变化时重新创建回调函数\n */\n const animationRef = useRef(animation);\n animationRef.current = animation;\n\n // ========== 回调函数 ==========\n\n /**\n * 处理关闭操作\n *\n * 根据是否启用动画采取不同策略:\n * - 启用动画: 仅设置 open=false,等待动画结束后再卸载\n * - 禁用动画: 直接卸载组件\n */\n const handleClose = useCallback(() => {\n if (animationRef.current) {\n // 启用动画时,先触发关闭动画\n setOpen(false);\n } else {\n // 禁用动画时,直接卸载\n setRenderEnable(false);\n }\n }, []);\n\n /**\n * 处理动画结束\n *\n * 由属性适配器在关闭动画结束时调用。\n * 仅在启用动画时执行实际的卸载操作。\n */\n const handleAnimationEnd = useCallback(() => {\n if (animationRef.current) {\n setRenderEnable(false);\n }\n }, []);\n\n // ========== 渲染逻辑 ==========\n\n /**\n * contextHolder: 需要渲染到组件树中的节点\n *\n * 使用 useMemo 优化性能:\n * - 未挂载时返回空 Fragment(保持 key 稳定)\n * - 已挂载时渲染实际组件,通过 propsAdapter 转换属性\n */\n const contextHolder = useMemo(() => {\n // 未挂载时返回带 key 的空 Fragment\n // 保持 key 稳定可以避免不必要的 DOM 操作\n if (!renderEnable) return <React.Fragment key={key} />;\n\n // 通过适配器转换属性\n const realProps = propsAdapter(props, {\n open,\n onClose: handleClose,\n onAnimationEnd: handleAnimationEnd,\n });\n\n return <OverlayComponent key={key} {...realProps} />;\n }, [\n renderEnable,\n open,\n props,\n key,\n propsAdapter,\n handleClose,\n handleAnimationEnd,\n OverlayComponent,\n ]);\n\n // ========== 打开函数 ==========\n\n /**\n * 打开覆盖层的函数\n *\n * @param initializeProps - 初始化属性\n * @returns 控制器对象,包含 update 和 close 方法\n */\n const openOverlay = useCallback(\n (initializeProps?: InternalProps<T>) => {\n // 1. 挂载组件\n setRenderEnable(true);\n // 2. 设置为打开状态(触发打开动画)\n setOpen(true);\n // 3. 存储初始属性\n setProps(initializeProps);\n\n // 返回控制器\n return {\n /**\n * 更新覆盖层属性\n * 注意:这是完全替换,不是合并\n */\n update: (newProps: InternalProps<T>) => setProps(newProps),\n /**\n * 关闭覆盖层\n */\n close: handleClose,\n } as const;\n },\n [handleClose],\n );\n\n return [openOverlay, contextHolder];\n}\n\n/**\n * 全局覆盖层管理 Hook\n *\n * 与 useOverlay 的区别:\n * - useOverlay: 需要手动渲染 contextHolder\n * - useGlobalOverlay: 自动挂载到 AntdOverlayProvider\n *\n * 实现原理:\n * 1. 内部调用 useOverlay 获取 openOverlay 和 contextHolder\n * 2. 使用 useEffect 将 contextHolder 注册到全局容器\n * 3. 组件卸载时自动从全局容器移除\n *\n * 使用前提:\n * - 必须在组件树的上层包裹 AntdOverlayProvider\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 打开覆盖层的函数(无需再渲染 holder)\n *\n * @example\n * // 1. 先在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <YourApp />\n * </AntdOverlayProvider>\n * );\n * }\n *\n * // 2. 在任意组件中使用\n * function AnyComponent() {\n * const openOverlay = useGlobalOverlay(MyOverlay);\n *\n * return (\n * <button onClick={() => openOverlay({ data: someData })}>\n * 打开全局覆盖层\n * </button>\n * );\n * }\n */\nexport function useGlobalOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options?: UseOverlayOptions<T>,\n): OverlayOpener<T> {\n // 获取全局容器的注册/注销方法\n const { addHolder, removeHolder } = useAntdOverlayContext();\n\n // 使用基础 useOverlay 获取功能\n const [openOverlay, contextHolder] = useOverlay<T>(OverlayComponent, options);\n\n // 将 contextHolder 注册到全局容器\n useEffect(() => {\n addHolder(contextHolder);\n // 清理函数:组件卸载时从全局容器移除\n return () => removeHolder(contextHolder);\n }, [contextHolder, addHolder, removeHolder]);\n\n // 仅返回 openOverlay,holder 已自动挂载\n return openOverlay;\n}\n\n// ============================================================================\n// 工厂函数\n// ============================================================================\n\n/**\n * 生成绑定了特定组件的 Hook 工厂函数\n *\n * 当某个覆盖层组件在多处使用时,可以使用此函数生成专用 Hook,\n * 避免每次使用都需要传入组件引用。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param defaultOptions - 默认配置选项,会与调用时的选项合并\n *\n * @returns 包含 useOverlay 和 useGlobalOverlay 的对象\n *\n * @example\n * // 创建专用 Hook\n * const {\n * useOverlay: useMyOverlay,\n * useGlobalOverlay: useGlobalMyOverlay,\n * } = generateUseOverlayHook(MyOverlayComponent, {\n * animation: true,\n * propsAdapter: myAdapter,\n * });\n *\n * // 使用专用 Hook(无需再传组件)\n * function SomeComponent() {\n * const openOverlay = useGlobalMyOverlay();\n * return <button onClick={() => openOverlay()}>打开</button>;\n * }\n */\nexport function generateUseOverlayHook<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n defaultOptions?: UseOverlayOptions<T>,\n) {\n return {\n /**\n * 绑定了特定组件的 useOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useOverlay: (options?: UseOverlayOptions<T>) =>\n useOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n\n /**\n * 绑定了特定组件的 useGlobalOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useGlobalOverlay: (options?: UseOverlayOptions<T>) =>\n useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n };\n}\n","/**\n * @file useModal - Ant Design Modal 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Modal 专用管理方案。\n * 提供命令式 API 来控制 Modal 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 visible 状态\n * - 支持动态更新 Modal 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterClose 回调)\n *\n * @example\n * // 基础用法\n * const [openModal, holder] = useModal(MyModal);\n *\n * // 全局用法\n * const openModal = useGlobalModal(MyModal);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalModal: useGlobalMyModal } = generateUseModalHook(MyModal);\n */\n\nimport { ModalProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Modal 组件的属性接口\n * 继承 Ant Design ModalProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyModal: React.FC<CustomModalProps<{ name: string }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Modal open={open} onCancel={customClose} onOk={() => customOk?.({ name: 'test' })}>\n * 内容\n * </Modal>\n * );\n * };\n */\nexport interface CustomModalProps<T = any, R = void> extends ModalProps, CustomOverlayProps<T, R> {}\n\n/**\n * useModal Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseModalOptions = Omit<\n UseOverlayOptions<CustomModalProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Modal 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterClose 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Modal 组件的属性类型\n * @returns 属性适配器函数\n */\nconst createModalPropsAdapter = <T extends CustomModalProps>() => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n maskClosable: false, // 默认禁止点击遮罩关闭\n ...props,\n open: state.open,\n customClose: state.onClose,\n // 在 Modal 关闭动画结束后触发,用于卸载组件\n afterClose: () => {\n props?.afterClose?.();\n state.onAnimationEnd();\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Modal\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Modal 管理 Hook\n *\n * @template T - Modal 组件的属性类型,必须继承 CustomModalProps\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openModal, contextHolder]\n * - openModal: 打开 Modal 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openModal, modalHolder] = useModal(ConfirmModal);\n *\n * const handleDelete = () => {\n * openModal({\n * title: '确认删除',\n * content: '删除后无法恢复',\n * });\n * };\n *\n * return (\n * <>\n * <button onClick={handleDelete}>删除</button>\n * {modalHolder}\n * </>\n * );\n * }\n */\nexport function useModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const propsAdapter = useMemo(() => createModalPropsAdapter<T>(), []);\n return useOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Modal 管理 Hook\n *\n * 与 useModal 的区别:\n * - 无需手动渲染 contextHolder\n * - Modal 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 打开 Modal 的函数\n *\n * @example\n * function DeleteButton() {\n * const openConfirm = useGlobalModal(ConfirmModal);\n *\n * return (\n * <button onClick={() => openConfirm({ title: '确认删除?' })}>\n * 删除\n * </button>\n * );\n * }\n */\nexport function useGlobalModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): OverlayOpener<T> {\n const propsAdapter = useMemo(() => createModalPropsAdapter<T>(), []);\n return useGlobalOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Modal 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Modal 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Modal 的默认配置\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n *\n * @returns 包含 useModal 和 useGlobalModal 的对象\n *\n * @example\n * // 在 Modal 组件文件中导出专用 Hook\n * const ConfirmModal: React.FC<CustomModalProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useModal: useConfirmModal,\n * useGlobalModal: useGlobalConfirmModal,\n * } = generateUseModalHook(ConfirmModal);\n *\n * // 在其他组件中使用\n * function MyPage() {\n * const openConfirm = useGlobalConfirmModal();\n * return <button onClick={() => openConfirm()}>确认</button>;\n * }\n */\nexport function generateUseModalHook<T extends CustomModalProps>(ModalComponent: React.FC<T>) {\n return {\n useModal: (options?: UseModalOptions) => useModal(ModalComponent, options),\n useGlobalModal: (options?: UseModalOptions) => useGlobalModal(ModalComponent, options),\n };\n}\n\nexport default useModal;\n","/**\n * @file useDrawer - Ant Design Drawer 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Drawer 专用管理方案。\n * 提供命令式 API 来控制 Drawer 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 open 状态\n * - 支持动态更新 Drawer 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterOpenChange 回调)\n *\n * @example\n * // 基础用法\n * const [openDrawer, holder] = useDrawer(MyDrawer);\n *\n * // 全局用法\n * const openDrawer = useGlobalDrawer(MyDrawer);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalDrawer: useGlobalMyDrawer } = generateUseDrawerHook(MyDrawer);\n */\n\nimport { DrawerProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Drawer 组件的属性接口\n * 继承 Ant Design DrawerProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyDrawer: React.FC<CustomDrawerProps<{ id: number }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Drawer open={open} onClose={customClose}>\n * <Button onClick={() => customOk?.({ id: 1 })}>确认</Button>\n * </Drawer>\n * );\n * };\n */\nexport interface CustomDrawerProps<T = any, R = void>\n extends DrawerProps, CustomOverlayProps<T, R> {}\n\n/**\n * useDrawer Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseDrawerOptions = Omit<\n UseOverlayOptions<CustomDrawerProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Drawer 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterOpenChange 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * 与 Modal 的区别:\n * - Modal 使用 afterClose 回调(仅在关闭后触发)\n * - Drawer 使用 afterOpenChange 回调(打开和关闭都会触发,需要判断状态)\n *\n * @template T - Drawer 组件的属性类型\n * @returns 属性适配器函数\n */\nconst createDrawerPropsAdapter = <T extends CustomDrawerProps>() => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n maskClosable: false, // 默认禁止点击遮罩关闭\n ...props,\n open: state.open,\n customClose: state.onClose,\n // Drawer 的动画回调,打开和关闭时都会触发\n afterOpenChange: (open: boolean) => {\n props?.afterOpenChange?.(open);\n // 仅在关闭动画结束时触发卸载\n if (!open) {\n state.onAnimationEnd();\n }\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Drawer\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Drawer 管理 Hook\n *\n * @template T - Drawer 组件的属性类型,必须继承 CustomDrawerProps\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openDrawer, contextHolder]\n * - openDrawer: 打开 Drawer 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openDrawer, drawerHolder] = useDrawer(UserDetailDrawer);\n *\n * const handleViewUser = (userId: number) => {\n * openDrawer({ userId, title: '用户详情' });\n * };\n *\n * return (\n * <>\n * <button onClick={() => handleViewUser(1)}>查看用户</button>\n * {drawerHolder}\n * </>\n * );\n * }\n */\nexport function useDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const propsAdapter = useMemo(() => createDrawerPropsAdapter<T>(), []);\n return useOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Drawer 管理 Hook\n *\n * 与 useDrawer 的区别:\n * - 无需手动渲染 contextHolder\n * - Drawer 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 打开 Drawer 的函数\n *\n * @example\n * function UserCard({ userId }: { userId: number }) {\n * const openDetail = useGlobalDrawer(UserDetailDrawer);\n *\n * return (\n * <Card onClick={() => openDetail({ userId })}>\n * 查看详情\n * </Card>\n * );\n * }\n */\nexport function useGlobalDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): OverlayOpener<T> {\n const propsAdapter = useMemo(() => createDrawerPropsAdapter<T>(), []);\n return useGlobalOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Drawer 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Drawer 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Drawer 的默认配置\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n *\n * @returns 包含 useDrawer 和 useGlobalDrawer 的对象\n *\n * @example\n * // 在 Drawer 组件文件中导出专用 Hook\n * const ProjectMemberDrawer: React.FC<CustomDrawerProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useDrawer: useProjectMemberDrawer,\n * useGlobalDrawer: useGlobalProjectMemberDrawer,\n * } = generateUseDrawerHook(ProjectMemberDrawer);\n *\n * // 在其他组件中使用\n * function ProjectPage() {\n * const openMemberDrawer = useGlobalProjectMemberDrawer();\n * return <button onClick={() => openMemberDrawer()}>管理成员</button>;\n * }\n */\nexport function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerComponent: React.FC<T>) {\n return {\n useDrawer: (options?: UseDrawerOptions) => useDrawer(DrawerComponent, options),\n useGlobalDrawer: (options?: UseDrawerOptions) => useGlobalDrawer(DrawerComponent, options),\n };\n}\n\nexport default useDrawer;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/AntdOverlayContext.tsx","../src/useOverlay.tsx","../src/useModal.tsx","../src/useDrawer.tsx"],"names":["createContext","useState","useCallback","useMemo","jsxs","useContext","useId","useRef","React","jsx","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @file AntdOverlayContext - 全局覆盖层容器 Context\n * @description\n * 提供全局覆盖层的挂载点管理。所有通过 useGlobalOverlay 系列 Hook\n * 创建的覆盖层都会被挂载到 AntdOverlayProvider 下。\n *\n * 工作原理:\n * 1. AntdOverlayProvider 维护一个 holders 数组\n * 2. useGlobalOverlay 通过 useAntdOverlayContext 获取注册方法\n * 3. 覆盖层的 contextHolder 被添加到 holders 数组\n * 4. Provider 在子节点之后统一渲染所有 holders\n *\n * 这种设计的优势:\n * - 覆盖层与业务组件解耦,可在任意位置调用\n * - 统一的挂载点,避免 z-index 混乱\n * - 组件卸载时自动清理对应的覆盖层\n *\n * @example\n * // 在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n */\n\nimport { DrawerProps, ModalProps } from 'antd';\nimport React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\nexport type DefaultModalProps = Partial<ModalProps>;\nexport type DefaultDrawerProps = Partial<DrawerProps>;\n\n/**\n * AntdOverlay Context 的值类型\n *\n * @property holders - 当前所有已注册的覆盖层 holder 节点\n * @property addHolder - 注册一个新的 holder 到全局容器\n * @property removeHolder - 从全局容器移除一个已注册的 holder\n */\ninterface AntdOverlayContextValue {\n /** 所有已注册的 holder 节点列表 */\n holders: React.ReactNode[];\n /** 添加 holder 到全局容器 */\n addHolder: (holder: React.ReactNode) => void;\n /** 从全局容器移除 holder */\n removeHolder: (holder: React.ReactNode) => void;\n /** 默认 Modal 属性 */\n defaultModalProps?: DefaultModalProps;\n /** 默认 Drawer 属性 */\n defaultDrawerProps?: DefaultDrawerProps;\n}\n\n// ============================================================================\n// Context 定义\n// ============================================================================\n\n/**\n * AntdOverlay Context\n *\n * 默认值为 null,使用时必须在 AntdOverlayProvider 内部。\n * 如果在 Provider 外部调用 useAntdOverlayContext,会抛出明确的错误提示。\n */\nconst AntdOverlayContext = createContext<AntdOverlayContextValue | null>(null);\n\n// ============================================================================\n// Provider 组件\n// ============================================================================\n\n/**\n * AntdOverlay 容器提供者组件\n *\n * 用于管理全局覆盖层的挂载点。所有通过 useGlobalOverlay、useGlobalModal、\n * useGlobalDrawer 等 Hook 创建的覆盖层都会被挂载到这个 Provider 下。\n *\n * 渲染结构:\n * ```\n * <AntdOverlayContext.Provider>\n * {children} <- 应用的主要内容\n * {holders[0]} <- 全局覆盖层 1\n * {holders[1]} <- 全局覆盖层 2\n * ...\n * </AntdOverlayContext.Provider>\n * ```\n *\n * @param children - 子节点,通常是整个应用\n *\n * @example\n * // 基础用法 - 在应用入口包裹\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n *\n * @example\n * // 与其他 Provider 配合使用\n * function App() {\n * return (\n * <ConfigProvider>\n * <AntdOverlayProvider>\n * <App />\n * </AntdOverlayProvider>\n * </ConfigProvider>\n * );\n * }\n */\nexport interface AntdOverlayProviderProps {\n /** 子节点 */\n children: React.ReactNode;\n /** 默认 Modal 属性 */\n defaultModalProps?: DefaultModalProps;\n /** 默认 Drawer 属性 */\n defaultDrawerProps?: DefaultDrawerProps;\n}\n\n\n/**\n * AntdOverlayProvider 组件\n * @param children - 子节点\n * @param defaultModalProps - 默认 Modal 属性\n * @param defaultDrawerProps - 默认 Drawer 属性\n * @returns React.ReactNode\n */\nexport function AntdOverlayProvider({\n children,\n defaultModalProps,\n defaultDrawerProps,\n}: AntdOverlayProviderProps) {\n // 存储所有已注册的 holder 节点\n const [holders, setHolders] = useState<React.ReactNode[]>([]);\n\n /**\n * 添加 holder 到全局容器\n *\n * 使用函数式更新确保并发安全,避免闭包陷阱。\n * 新的 holder 会被追加到数组末尾,因此后添加的覆盖层会显示在上层。\n */\n const addHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => [...prev, holder]);\n }, []);\n\n /**\n * 从全局容器移除 holder\n *\n * 通过引用比较(===)找到并移除对应的 holder。\n * 这要求每次传入的 holder 必须是同一个引用。\n */\n const removeHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => prev.filter((h) => h !== holder));\n }, []);\n\n // 使用 useMemo 优化 Context 值,避免不必要的重渲染\n // 只有当 holders、addHolder 或 removeHolder 变化时才会创建新的值对象\n const value = useMemo(\n () => ({ holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps }),\n [holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps],\n );\n\n return (\n <AntdOverlayContext.Provider value={value}>\n {children}\n {/* 在 children 之后渲染所有全局覆盖层 */}\n {holders}\n </AntdOverlayContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * 获取 AntdOverlay Context 的 Hook\n *\n * 返回全局容器的注册和注销方法,供 useGlobalOverlay 系列 Hook 内部使用。\n *\n * 注意事项:\n * - 必须在 AntdOverlayProvider 内部使用\n * - 如果在 Provider 外部调用,会抛出明确的错误\n * - 主要供库内部使用,一般不需要在业务代码中直接调用\n *\n * @returns AntdOverlayContextValue 包含 holders、addHolder、removeHolder\n * @throws Error 如果不在 AntdOverlayProvider 内部使用\n *\n * @example\n * // 库内部使用示例(useGlobalOverlay 的实现)\n * function useGlobalOverlay(Component, options) {\n * const context = useAntdOverlayContext();\n * if (!context) {\n * throw new Error('useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>.');\n * }\n * const { addHolder, removeHolder } = context;\n * const [open, holder] = useOverlay(Component, options);\n *\n * useEffect(() => {\n * addHolder(holder);\n * return () => removeHolder(holder);\n * }, [holder]);\n *\n * return open;\n * }\n */\nexport function useAntdOverlayContext() {\n return useContext(AntdOverlayContext);\n}\n","/**\n * @file useOverlay - 通用覆盖层管理 Hook\n * @description\n * 提供一个与具体 UI 组件无关的覆盖层(Overlay)管理方案。\n * 支持任意满足 CustomOverlayProps 接口的组件,如 Modal、Drawer、Popover 等。\n *\n * 核心设计理念:\n * 1. 命令式调用 - 通过函数调用打开覆盖层,而非声明式管理 open 状态\n * 2. 动画支持 - 正确处理打开/关闭动画,避免动画未完成就卸载组件\n * 3. 全局挂载 - 支持将覆盖层挂载到全局容器,实现跨组件调用\n * 4. 类型安全 - 完整的 TypeScript 类型支持\n *\n * 架构层次:\n * ┌─────────────────────────────────────────────────────────┐\n * │ useModal / useDrawer │ <- 业务层封装\n * ├─────────────────────────────────────────────────────────┤\n * │ useOverlay / useGlobalOverlay │ <- 核心逻辑层\n * ├─────────────────────────────────────────────────────────┤\n * │ GlobalHolderProvider │ <- 全局容器层\n * └─────────────────────────────────────────────────────────┘\n *\n * @example\n * // 直接使用 useOverlay(不推荐,建议使用 useModal/useDrawer)\n * const [openOverlay, holder] = useOverlay(MyOverlayComponent, {\n * propsAdapter: (props, state) => ({ ...props, visible: state.open }),\n * });\n */\n\nimport React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useAntdOverlayContext } from './AntdOverlayContext';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * 自定义覆盖层组件必须实现的属性接口\n *\n * 这是所有覆盖层组件的基础接口,定义了控制覆盖层所需的最小属性集。\n * 具体的 UI 组件(如 Modal、Drawer)应该扩展此接口。\n *\n * @template T - customOk 回调接收的参数类型,用于传递确认操作的数据\n * @template R - customOk 回调的返回类型,通常为 void\n *\n * @property open - 控制覆盖层的显示/隐藏状态\n * @property customClose - 关闭覆盖层的回调函数,由 useOverlay 注入\n * @property customOk - 确认操作的回调函数,调用后会自动关闭覆盖层\n *\n * @example\n * interface MyOverlayProps extends CustomOverlayProps<{ id: number }> {\n * title: string;\n * data: SomeData;\n * }\n *\n * const MyOverlay: React.FC<MyOverlayProps> = ({\n * open,\n * customClose,\n * customOk,\n * title,\n * data,\n * }) => {\n * const handleConfirm = () => {\n * // 调用 customOk 会自动关闭覆盖层\n * customOk?.({ id: data.id });\n * };\n * return (\n * <Modal open={open} onCancel={customClose} onOk={handleConfirm}>\n * {title}\n * </Modal>\n * );\n * };\n */\nexport interface CustomOverlayProps<T = any, R = void> {\n /** 覆盖层的显示状态 */\n open?: boolean;\n /** 关闭覆盖层的回调,由 useOverlay 自动注入 */\n customClose: () => void;\n /** 确认操作回调,调用后自动关闭覆盖层 */\n customOk?: (value: T) => R;\n}\n\n/**\n * 内部使用的属性类型\n * 排除 customClose,因为它由 useOverlay 自动注入,用户无需传递\n */\ntype InternalProps<T extends CustomOverlayProps> = Omit<T, 'customClose'>;\n\n/**\n * 覆盖层控制器接口\n *\n * 打开覆盖层后返回的控制器对象,用于后续操作(更新属性或关闭)。\n * 使用 readonly 确保方法引用稳定,不会被意外修改。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @example\n * const controller = openModal({ title: '初始标题' });\n *\n * // 动态更新属性\n * controller.update({ title: '新标题', loading: true });\n *\n * // 编程式关闭\n * controller.close();\n */\nexport interface OverlayController<T extends CustomOverlayProps> {\n /**\n * 更新覆盖层的属性\n * @param props - 新的属性对象,会完全替换之前的属性\n */\n readonly update: (props: InternalProps<T>) => void;\n /**\n * 关闭覆盖层\n * 如果启用了动画,会等待动画结束后再卸载组件\n */\n readonly close: () => void;\n}\n\n/**\n * 覆盖层打开函数的类型定义\n *\n * @template T - 覆盖层组件的属性类型\n * @param initialize - 初始化属性,可选\n * @returns 覆盖层控制器,用于后续的更新和关闭操作\n *\n * @example\n * const openModal: OverlayOpener<MyModalProps> = (props) => {\n * // 返回控制器\n * };\n *\n * // 无参数调用\n * const ctrl1 = openModal();\n *\n * // 带初始属性调用\n * const ctrl2 = openModal({ title: '标题', data: someData });\n */\nexport type OverlayOpener<T extends CustomOverlayProps> = (\n initialize?: InternalProps<T>,\n) => OverlayController<T>;\n\n/**\n * useOverlay Hook 的配置选项\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @property animation - 是否启用动画支持,默认 true\n * - true: 关闭时先设置 open=false,等待动画结束后再卸载组件\n * - false: 关闭时直接卸载组件,适用于无动画的覆盖层\n *\n * @property keyPrefix - React key 的前缀,用于区分不同类型的覆盖层\n * - 默认值: 'use-overlay'\n * - useModal 使用 'use-modal'\n * - useDrawer 使用 'use-drawer'\n *\n * @property propsAdapter - 属性适配器函数\n * 用于将内部状态转换为组件实际需要的属性。\n * 不同的 UI 组件(Modal、Drawer)有不同的动画回调机制,\n * 通过适配器实现统一的接口。\n */\nexport interface UseOverlayOptions<T extends CustomOverlayProps> {\n /** 是否启用关闭动画,默认 true */\n animation?: boolean;\n /** React key 前缀,用于标识覆盖层类型 */\n keyPrefix?: string;\n /**\n * 属性适配器函数\n * @param props - 用户传入的属性\n * @param state - 内部状态,包含 open、onClose、onAnimationEnd\n * @returns 传递给组件的最终属性\n */\n propsAdapter?: (\n props: InternalProps<T> | undefined,\n state: {\n /** 当前的打开状态 */\n open: boolean;\n /** 触发关闭的回调 */\n onClose: () => void;\n /** 动画结束后的回调,用于卸载组件 */\n onAnimationEnd: () => void;\n },\n ) => T;\n}\n\n// ============================================================================\n// 默认属性适配器\n// ============================================================================\n\n/**\n * 默认的属性适配器\n *\n * 提供基本的属性转换逻辑:\n * 1. 将用户传入的 props 与内部状态合并\n * 2. 注入 open 和 customClose\n * 3. 包装 customOk 使其调用后自动关闭覆盖层\n *\n * 注意:这是一个简化的适配器,不处理动画。\n * 对于 Modal 和 Drawer,应该使用各自的专用适配器来处理动画回调。\n *\n * @template T - 覆盖层组件的属性类型\n * @param props - 用户传入的属性\n * @param state - 内部状态\n * @returns 最终传递给组件的属性\n */\nconst defaultPropsAdapter = <T extends CustomOverlayProps>(\n props: InternalProps<T> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n): T => {\n const result = {\n ...props,\n open: state.open,\n customClose: state.onClose,\n } as unknown as T;\n\n // 包装 customOk,使其调用后自动触发关闭\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n};\n\n// ============================================================================\n// 核心 Hook 实现\n// ============================================================================\n\n/**\n * 覆盖层管理核心 Hook\n *\n * 这是整个库的核心,提供覆盖层的生命周期管理:\n * - 挂载/卸载控制\n * - 打开/关闭状态管理\n * - 动画支持\n * - 属性更新\n *\n * 状态机说明:\n * ```\n * [未挂载] --open()--> [已挂载, open=true] --close()--> [已挂载, open=false] --动画结束--> [未挂载]\n * │\n * └── (animation=false) --> [未挂载]\n * ```\n *\n * @template T - 覆盖层组件的属性类型,必须继承 CustomOverlayProps\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 元组 [openOverlay, contextHolder]\n * - openOverlay: 打开覆盖层的函数,返回控制器\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyComponent() {\n * const [openOverlay, holder] = useOverlay(MyOverlay, {\n * animation: true,\n * propsAdapter: (props, state) => ({\n * ...props,\n * visible: state.open,\n * onClose: state.onClose,\n * afterVisibleChange: (visible) => {\n * if (!visible) state.onAnimationEnd();\n * },\n * }),\n * });\n *\n * return (\n * <>\n * <button onClick={() => openOverlay({ title: '标题' })}>打开</button>\n * {holder}\n * </>\n * );\n * }\n */\nexport function useOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options: UseOverlayOptions<T> = {},\n): [OverlayOpener<T>, React.ReactNode] {\n // 解构配置选项,设置默认值\n const {\n animation = true,\n keyPrefix = 'use-overlay',\n propsAdapter = defaultPropsAdapter,\n } = options;\n\n // 生成唯一 ID,用于 React key\n const id = useId();\n const key = `${keyPrefix}-${id}`;\n\n // ========== 状态管理 ==========\n\n /**\n * open: 控制覆盖层的显示状态(用于动画)\n * - true: 覆盖层显示\n * - false: 覆盖层隐藏(但可能还在播放关闭动画)\n */\n const [open, setOpen] = useState(false);\n\n /**\n * renderEnable: 控制组件是否挂载到 DOM\n * - true: 组件已挂载\n * - false: 组件已卸载\n *\n * 与 open 分离是为了支持关闭动画:\n * 关闭时先设置 open=false 触发动画,动画结束后再设置 renderEnable=false 卸载组件\n */\n const [renderEnable, setRenderEnable] = useState(false);\n\n /**\n * props: 用户传入的属性\n * 存储最近一次 open 或 update 调用时传入的属性\n */\n const [props, setProps] = useState<InternalProps<T> | undefined>();\n\n /**\n * 使用 ref 存储 animation 配置\n * 避免 animation 变化时重新创建回调函数\n */\n const animationRef = useRef(animation);\n animationRef.current = animation;\n\n // ========== 回调函数 ==========\n\n /**\n * 处理关闭操作\n *\n * 根据是否启用动画采取不同策略:\n * - 启用动画: 仅设置 open=false,等待动画结束后再卸载\n * - 禁用动画: 直接卸载组件\n */\n const handleClose = useCallback(() => {\n if (animationRef.current) {\n // 启用动画时,先触发关闭动画\n setOpen(false);\n } else {\n // 禁用动画时,直接卸载\n setRenderEnable(false);\n }\n }, []);\n\n /**\n * 处理动画结束\n *\n * 由属性适配器在关闭动画结束时调用。\n * 仅在启用动画时执行实际的卸载操作。\n */\n const handleAnimationEnd = useCallback(() => {\n if (animationRef.current) {\n setRenderEnable(false);\n }\n }, []);\n\n // ========== 渲染逻辑 ==========\n\n /**\n * contextHolder: 需要渲染到组件树中的节点\n *\n * 使用 useMemo 优化性能:\n * - 未挂载时返回空 Fragment(保持 key 稳定)\n * - 已挂载时渲染实际组件,通过 propsAdapter 转换属性\n */\n const contextHolder = useMemo(() => {\n // 未挂载时返回带 key 的空 Fragment\n // 保持 key 稳定可以避免不必要的 DOM 操作\n if (!renderEnable) return <React.Fragment key={key} />;\n\n // 通过适配器转换属性\n const realProps = propsAdapter(props, {\n open,\n onClose: handleClose,\n onAnimationEnd: handleAnimationEnd,\n });\n\n return <OverlayComponent key={key} {...realProps} />;\n }, [\n renderEnable,\n open,\n props,\n key,\n propsAdapter,\n handleClose,\n handleAnimationEnd,\n OverlayComponent,\n ]);\n\n // ========== 打开函数 ==========\n\n /**\n * 打开覆盖层的函数\n *\n * @param initializeProps - 初始化属性\n * @returns 控制器对象,包含 update 和 close 方法\n */\n const openOverlay = useCallback(\n (initializeProps?: InternalProps<T>) => {\n // 1. 挂载组件\n setRenderEnable(true);\n // 2. 设置为打开状态(触发打开动画)\n setOpen(true);\n // 3. 存储初始属性\n setProps(initializeProps);\n\n // 返回控制器\n return {\n /**\n * 更新覆盖层属性\n * 注意:这是完全替换,不是合并\n */\n update: (newProps: InternalProps<T>) => setProps(newProps),\n /**\n * 关闭覆盖层\n */\n close: handleClose,\n } as const;\n },\n [handleClose],\n );\n\n return [openOverlay, contextHolder];\n}\n\n/**\n * 全局覆盖层管理 Hook\n *\n * 与 useOverlay 的区别:\n * - useOverlay: 需要手动渲染 contextHolder\n * - useGlobalOverlay: 自动挂载到 AntdOverlayProvider\n *\n * 实现原理:\n * 1. 内部调用 useOverlay 获取 openOverlay 和 contextHolder\n * 2. 使用 useEffect 将 contextHolder 注册到全局容器\n * 3. 组件卸载时自动从全局容器移除\n *\n * 使用前提:\n * - 必须在组件树的上层包裹 AntdOverlayProvider\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 打开覆盖层的函数(无需再渲染 holder)\n *\n * @example\n * // 1. 先在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <YourApp />\n * </AntdOverlayProvider>\n * );\n * }\n *\n * // 2. 在任意组件中使用\n * function AnyComponent() {\n * const openOverlay = useGlobalOverlay(MyOverlay);\n *\n * return (\n * <button onClick={() => openOverlay({ data: someData })}>\n * 打开全局覆盖层\n * </button>\n * );\n * }\n */\nexport function useGlobalOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options?: UseOverlayOptions<T>,\n): OverlayOpener<T> {\n // 获取全局容器的注册/注销方法\n const context = useAntdOverlayContext();\n\n if (!context) {\n throw new Error(\n 'useGlobalOverlay must be used within an AntdOverlayProvider. ' +\n 'Please wrap your application with <AntdOverlayProvider>.'\n );\n }\n\n const { addHolder, removeHolder } = context;\n\n // 使用基础 useOverlay 获取功能\n const [openOverlay, contextHolder] = useOverlay<T>(OverlayComponent, options);\n\n // 将 contextHolder 注册到全局容器\n useEffect(() => {\n addHolder(contextHolder);\n // 清理函数:组件卸载时从全局容器移除\n return () => removeHolder(contextHolder);\n }, [contextHolder, addHolder, removeHolder]);\n\n // 仅返回 openOverlay,holder 已自动挂载\n return openOverlay;\n}\n\n// ============================================================================\n// 工厂函数\n// ============================================================================\n\n/**\n * 生成绑定了特定组件的 Hook 工厂函数\n *\n * 当某个覆盖层组件在多处使用时,可以使用此函数生成专用 Hook,\n * 避免每次使用都需要传入组件引用。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param defaultOptions - 默认配置选项,会与调用时的选项合并\n *\n * @returns 包含 useOverlay 和 useGlobalOverlay 的对象\n *\n * @example\n * // 创建专用 Hook\n * const {\n * useOverlay: useMyOverlay,\n * useGlobalOverlay: useGlobalMyOverlay,\n * } = generateUseOverlayHook(MyOverlayComponent, {\n * animation: true,\n * propsAdapter: myAdapter,\n * });\n *\n * // 使用专用 Hook(无需再传组件)\n * function SomeComponent() {\n * const openOverlay = useGlobalMyOverlay();\n * return <button onClick={() => openOverlay()}>打开</button>;\n * }\n */\nexport function generateUseOverlayHook<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n defaultOptions?: UseOverlayOptions<T>,\n) {\n return {\n /**\n * 绑定了特定组件的 useOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useOverlay: (options?: UseOverlayOptions<T>) =>\n useOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n\n /**\n * 绑定了特定组件的 useGlobalOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useGlobalOverlay: (options?: UseOverlayOptions<T>) =>\n useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n };\n}\n","/**\n * @file useModal - Ant Design Modal 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Modal 专用管理方案。\n * 提供命令式 API 来控制 Modal 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 visible 状态\n * - 支持动态更新 Modal 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterClose 回调)\n *\n * @example\n * // 基础用法\n * const [openModal, holder] = useModal(MyModal);\n *\n * // 全局用法\n * const openModal = useGlobalModal(MyModal);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalModal: useGlobalMyModal } = generateUseModalHook(MyModal);\n */\n\nimport { ModalProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport { useAntdOverlayContext, DefaultModalProps } from './AntdOverlayContext';\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Modal 组件的属性接口\n * 继承 Ant Design ModalProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyModal: React.FC<CustomModalProps<{ name: string }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Modal open={open} onCancel={customClose} onOk={() => customOk?.({ name: 'test' })}>\n * 内容\n * </Modal>\n * );\n * };\n */\nexport interface CustomModalProps<T = any, R = void> extends ModalProps, CustomOverlayProps<T, R> {}\n\n/**\n * useModal Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseModalOptions = Omit<\n UseOverlayOptions<CustomModalProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Modal 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterClose 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Modal 组件的属性类型\n * @param defaultProps - 默认 Modal 属性\n * @returns 属性适配器函数\n */\nconst createModalPropsAdapter = <T extends CustomModalProps>(\n defaultProps?: DefaultModalProps,\n) => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n ...defaultProps,\n ...props,\n open: state.open,\n customClose: state.onClose,\n // 在 Modal 关闭动画结束后触发,用于卸载组件\n afterClose: () => {\n props?.afterClose?.();\n state.onAnimationEnd();\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Modal\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Modal 管理 Hook\n *\n * @template T - Modal 组件的属性类型,必须继承 CustomModalProps\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openModal, contextHolder]\n * - openModal: 打开 Modal 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openModal, modalHolder] = useModal(ConfirmModal);\n *\n * const handleDelete = () => {\n * openModal({\n * title: '确认删除',\n * content: '删除后无法恢复',\n * });\n * };\n *\n * return (\n * <>\n * <button onClick={handleDelete}>删除</button>\n * {modalHolder}\n * </>\n * );\n * }\n */\nexport function useModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createModalPropsAdapter<T>(context?.defaultModalProps),\n [context?.defaultModalProps],\n );\n return useOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Modal 管理 Hook\n *\n * 与 useModal 的区别:\n * - 无需手动渲染 contextHolder\n * - Modal 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 打开 Modal 的函数\n *\n * @example\n * function DeleteButton() {\n * const openConfirm = useGlobalModal(ConfirmModal);\n *\n * return (\n * <button onClick={() => openConfirm({ title: '确认删除?' })}>\n * 删除\n * </button>\n * );\n * }\n */\nexport function useGlobalModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): OverlayOpener<T> {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createModalPropsAdapter<T>(context?.defaultModalProps),\n [context?.defaultModalProps],\n );\n return useGlobalOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Modal 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Modal 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Modal 的默认配置\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n *\n * @returns 包含 useModal 和 useGlobalModal 的对象\n *\n * @example\n * // 在 Modal 组件文件中导出专用 Hook\n * const ConfirmModal: React.FC<CustomModalProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useModal: useConfirmModal,\n * useGlobalModal: useGlobalConfirmModal,\n * } = generateUseModalHook(ConfirmModal);\n *\n * // 在其他组件中使用\n * function MyPage() {\n * const openConfirm = useGlobalConfirmModal();\n * return <button onClick={() => openConfirm()}>确认</button>;\n * }\n */\nexport function generateUseModalHook<T extends CustomModalProps>(ModalComponent: React.FC<T>) {\n return {\n useModal: (options?: UseModalOptions) => useModal(ModalComponent, options),\n useGlobalModal: (options?: UseModalOptions) => useGlobalModal(ModalComponent, options),\n };\n}\n\nexport default useModal;\n","/**\n * @file useDrawer - Ant Design Drawer 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Drawer 专用管理方案。\n * 提供命令式 API 来控制 Drawer 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 open 状态\n * - 支持动态更新 Drawer 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterOpenChange 回调)\n *\n * @example\n * // 基础用法\n * const [openDrawer, holder] = useDrawer(MyDrawer);\n *\n * // 全局用法\n * const openDrawer = useGlobalDrawer(MyDrawer);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalDrawer: useGlobalMyDrawer } = generateUseDrawerHook(MyDrawer);\n */\n\nimport { DrawerProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport { useAntdOverlayContext, DefaultDrawerProps } from './AntdOverlayContext';\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Drawer 组件的属性接口\n * 继承 Ant Design DrawerProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyDrawer: React.FC<CustomDrawerProps<{ id: number }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Drawer open={open} onClose={customClose}>\n * <Button onClick={() => customOk?.({ id: 1 })}>确认</Button>\n * </Drawer>\n * );\n * };\n */\nexport interface CustomDrawerProps<T = any, R = void>\n extends DrawerProps, CustomOverlayProps<T, R> {}\n\n/**\n * useDrawer Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseDrawerOptions = Omit<\n UseOverlayOptions<CustomDrawerProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Drawer 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterOpenChange 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Drawer 组件的属性类型\n * @param defaultProps - 默认 Drawer 属性\n * @returns 属性适配器函数\n */\nconst createDrawerPropsAdapter = <T extends CustomDrawerProps>(\n defaultProps?: DefaultDrawerProps,\n) => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n ...defaultProps,\n ...props,\n open: state.open,\n customClose: state.onClose,\n // Drawer 的动画回调,打开和关闭时都会触发\n afterOpenChange: (open: boolean) => {\n props?.afterOpenChange?.(open);\n // 仅在关闭动画结束时触发卸载\n if (!open) {\n state.onAnimationEnd();\n }\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Drawer\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Drawer 管理 Hook\n *\n * @template T - Drawer 组件的属性类型,必须继承 CustomDrawerProps\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openDrawer, contextHolder]\n * - openDrawer: 打开 Drawer 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openDrawer, drawerHolder] = useDrawer(UserDetailDrawer);\n *\n * const handleViewUser = (userId: number) => {\n * openDrawer({ userId, title: '用户详情' });\n * };\n *\n * return (\n * <>\n * <button onClick={() => handleViewUser(1)}>查看用户</button>\n * {drawerHolder}\n * </>\n * );\n * }\n */\nexport function useDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createDrawerPropsAdapter<T>(context?.defaultDrawerProps),\n [context?.defaultDrawerProps],\n );\n return useOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Drawer 管理 Hook\n *\n * 与 useDrawer 的区别:\n * - 无需手动渲染 contextHolder\n * - Drawer 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 打开 Drawer 的函数\n *\n * @example\n * function UserCard({ userId }: { userId: number }) {\n * const openDetail = useGlobalDrawer(UserDetailDrawer);\n *\n * return (\n * <Card onClick={() => openDetail({ userId })}>\n * 查看详情\n * </Card>\n * );\n * }\n */\nexport function useGlobalDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): OverlayOpener<T> {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createDrawerPropsAdapter<T>(context?.defaultDrawerProps),\n [context?.defaultDrawerProps],\n );\n return useGlobalOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Drawer 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Drawer 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Drawer 的默认配置\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n *\n * @returns 包含 useDrawer 和 useGlobalDrawer 的对象\n *\n * @example\n * // 在 Drawer 组件文件中导出专用 Hook\n * const ProjectMemberDrawer: React.FC<CustomDrawerProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useDrawer: useProjectMemberDrawer,\n * useGlobalDrawer: useGlobalProjectMemberDrawer,\n * } = generateUseDrawerHook(ProjectMemberDrawer);\n *\n * // 在其他组件中使用\n * function ProjectPage() {\n * const openMemberDrawer = useGlobalProjectMemberDrawer();\n * return <button onClick={() => openMemberDrawer()}>管理成员</button>;\n * }\n */\nexport function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerComponent: React.FC<T>) {\n return {\n useDrawer: (options?: UseDrawerOptions) => useDrawer(DrawerComponent, options),\n useGlobalDrawer: (options?: UseDrawerOptions) => useGlobalDrawer(DrawerComponent, options),\n };\n}\n\nexport default useDrawer;\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ModalProps, DrawerProps } from 'antd';
|
|
2
3
|
import * as React$1 from 'react';
|
|
3
4
|
import React__default from 'react';
|
|
4
|
-
import { ModalProps, DrawerProps } from 'antd';
|
|
5
5
|
|
|
6
|
+
type DefaultModalProps = Partial<ModalProps>;
|
|
7
|
+
type DefaultDrawerProps = Partial<DrawerProps>;
|
|
6
8
|
/**
|
|
7
9
|
* AntdOverlay Context 的值类型
|
|
8
10
|
*
|
|
@@ -17,6 +19,10 @@ interface AntdOverlayContextValue {
|
|
|
17
19
|
addHolder: (holder: React__default.ReactNode) => void;
|
|
18
20
|
/** 从全局容器移除 holder */
|
|
19
21
|
removeHolder: (holder: React__default.ReactNode) => void;
|
|
22
|
+
/** 默认 Modal 属性 */
|
|
23
|
+
defaultModalProps?: DefaultModalProps;
|
|
24
|
+
/** 默认 Drawer 属性 */
|
|
25
|
+
defaultDrawerProps?: DefaultDrawerProps;
|
|
20
26
|
}
|
|
21
27
|
/**
|
|
22
28
|
* AntdOverlay 容器提供者组件
|
|
@@ -60,9 +66,22 @@ interface AntdOverlayContextValue {
|
|
|
60
66
|
* );
|
|
61
67
|
* }
|
|
62
68
|
*/
|
|
63
|
-
|
|
69
|
+
interface AntdOverlayProviderProps {
|
|
70
|
+
/** 子节点 */
|
|
64
71
|
children: React__default.ReactNode;
|
|
65
|
-
|
|
72
|
+
/** 默认 Modal 属性 */
|
|
73
|
+
defaultModalProps?: DefaultModalProps;
|
|
74
|
+
/** 默认 Drawer 属性 */
|
|
75
|
+
defaultDrawerProps?: DefaultDrawerProps;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* AntdOverlayProvider 组件
|
|
79
|
+
* @param children - 子节点
|
|
80
|
+
* @param defaultModalProps - 默认 Modal 属性
|
|
81
|
+
* @param defaultDrawerProps - 默认 Drawer 属性
|
|
82
|
+
* @returns React.ReactNode
|
|
83
|
+
*/
|
|
84
|
+
declare function AntdOverlayProvider({ children, defaultModalProps, defaultDrawerProps, }: AntdOverlayProviderProps): react_jsx_runtime.JSX.Element;
|
|
66
85
|
/**
|
|
67
86
|
* 获取 AntdOverlay Context 的 Hook
|
|
68
87
|
*
|
|
@@ -79,7 +98,11 @@ declare function AntdOverlayProvider({ children }: {
|
|
|
79
98
|
* @example
|
|
80
99
|
* // 库内部使用示例(useGlobalOverlay 的实现)
|
|
81
100
|
* function useGlobalOverlay(Component, options) {
|
|
82
|
-
* const
|
|
101
|
+
* const context = useAntdOverlayContext();
|
|
102
|
+
* if (!context) {
|
|
103
|
+
* throw new Error('useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>.');
|
|
104
|
+
* }
|
|
105
|
+
* const { addHolder, removeHolder } = context;
|
|
83
106
|
* const [open, holder] = useOverlay(Component, options);
|
|
84
107
|
*
|
|
85
108
|
* useEffect(() => {
|
|
@@ -90,7 +113,7 @@ declare function AntdOverlayProvider({ children }: {
|
|
|
90
113
|
* return open;
|
|
91
114
|
* }
|
|
92
115
|
*/
|
|
93
|
-
declare function useAntdOverlayContext(): AntdOverlayContextValue;
|
|
116
|
+
declare function useAntdOverlayContext(): AntdOverlayContextValue | null;
|
|
94
117
|
|
|
95
118
|
/**
|
|
96
119
|
* @file useOverlay - 通用覆盖层管理 Hook
|
|
@@ -632,4 +655,4 @@ declare function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerCompon
|
|
|
632
655
|
useGlobalDrawer: (options?: UseDrawerOptions) => OverlayOpener<T>;
|
|
633
656
|
};
|
|
634
657
|
|
|
635
|
-
export { AntdOverlayProvider, type CustomDrawerProps, type CustomModalProps, type CustomOverlayProps, type OverlayController, type OverlayOpener, type UseDrawerOptions, type UseModalOptions, type UseOverlayOptions, generateUseDrawerHook, generateUseModalHook, generateUseOverlayHook, useAntdOverlayContext, useDrawer, useGlobalDrawer, useGlobalModal, useGlobalOverlay, useModal, useOverlay };
|
|
658
|
+
export { AntdOverlayProvider, type AntdOverlayProviderProps, type CustomDrawerProps, type CustomModalProps, type CustomOverlayProps, type DefaultDrawerProps, type DefaultModalProps, type OverlayController, type OverlayOpener, type UseDrawerOptions, type UseModalOptions, type UseOverlayOptions, generateUseDrawerHook, generateUseModalHook, generateUseOverlayHook, useAntdOverlayContext, useDrawer, useGlobalDrawer, useGlobalModal, useGlobalOverlay, useModal, useOverlay };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ModalProps, DrawerProps } from 'antd';
|
|
2
3
|
import * as React$1 from 'react';
|
|
3
4
|
import React__default from 'react';
|
|
4
|
-
import { ModalProps, DrawerProps } from 'antd';
|
|
5
5
|
|
|
6
|
+
type DefaultModalProps = Partial<ModalProps>;
|
|
7
|
+
type DefaultDrawerProps = Partial<DrawerProps>;
|
|
6
8
|
/**
|
|
7
9
|
* AntdOverlay Context 的值类型
|
|
8
10
|
*
|
|
@@ -17,6 +19,10 @@ interface AntdOverlayContextValue {
|
|
|
17
19
|
addHolder: (holder: React__default.ReactNode) => void;
|
|
18
20
|
/** 从全局容器移除 holder */
|
|
19
21
|
removeHolder: (holder: React__default.ReactNode) => void;
|
|
22
|
+
/** 默认 Modal 属性 */
|
|
23
|
+
defaultModalProps?: DefaultModalProps;
|
|
24
|
+
/** 默认 Drawer 属性 */
|
|
25
|
+
defaultDrawerProps?: DefaultDrawerProps;
|
|
20
26
|
}
|
|
21
27
|
/**
|
|
22
28
|
* AntdOverlay 容器提供者组件
|
|
@@ -60,9 +66,22 @@ interface AntdOverlayContextValue {
|
|
|
60
66
|
* );
|
|
61
67
|
* }
|
|
62
68
|
*/
|
|
63
|
-
|
|
69
|
+
interface AntdOverlayProviderProps {
|
|
70
|
+
/** 子节点 */
|
|
64
71
|
children: React__default.ReactNode;
|
|
65
|
-
|
|
72
|
+
/** 默认 Modal 属性 */
|
|
73
|
+
defaultModalProps?: DefaultModalProps;
|
|
74
|
+
/** 默认 Drawer 属性 */
|
|
75
|
+
defaultDrawerProps?: DefaultDrawerProps;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* AntdOverlayProvider 组件
|
|
79
|
+
* @param children - 子节点
|
|
80
|
+
* @param defaultModalProps - 默认 Modal 属性
|
|
81
|
+
* @param defaultDrawerProps - 默认 Drawer 属性
|
|
82
|
+
* @returns React.ReactNode
|
|
83
|
+
*/
|
|
84
|
+
declare function AntdOverlayProvider({ children, defaultModalProps, defaultDrawerProps, }: AntdOverlayProviderProps): react_jsx_runtime.JSX.Element;
|
|
66
85
|
/**
|
|
67
86
|
* 获取 AntdOverlay Context 的 Hook
|
|
68
87
|
*
|
|
@@ -79,7 +98,11 @@ declare function AntdOverlayProvider({ children }: {
|
|
|
79
98
|
* @example
|
|
80
99
|
* // 库内部使用示例(useGlobalOverlay 的实现)
|
|
81
100
|
* function useGlobalOverlay(Component, options) {
|
|
82
|
-
* const
|
|
101
|
+
* const context = useAntdOverlayContext();
|
|
102
|
+
* if (!context) {
|
|
103
|
+
* throw new Error('useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>.');
|
|
104
|
+
* }
|
|
105
|
+
* const { addHolder, removeHolder } = context;
|
|
83
106
|
* const [open, holder] = useOverlay(Component, options);
|
|
84
107
|
*
|
|
85
108
|
* useEffect(() => {
|
|
@@ -90,7 +113,7 @@ declare function AntdOverlayProvider({ children }: {
|
|
|
90
113
|
* return open;
|
|
91
114
|
* }
|
|
92
115
|
*/
|
|
93
|
-
declare function useAntdOverlayContext(): AntdOverlayContextValue;
|
|
116
|
+
declare function useAntdOverlayContext(): AntdOverlayContextValue | null;
|
|
94
117
|
|
|
95
118
|
/**
|
|
96
119
|
* @file useOverlay - 通用覆盖层管理 Hook
|
|
@@ -632,4 +655,4 @@ declare function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerCompon
|
|
|
632
655
|
useGlobalDrawer: (options?: UseDrawerOptions) => OverlayOpener<T>;
|
|
633
656
|
};
|
|
634
657
|
|
|
635
|
-
export { AntdOverlayProvider, type CustomDrawerProps, type CustomModalProps, type CustomOverlayProps, type OverlayController, type OverlayOpener, type UseDrawerOptions, type UseModalOptions, type UseOverlayOptions, generateUseDrawerHook, generateUseModalHook, generateUseOverlayHook, useAntdOverlayContext, useDrawer, useGlobalDrawer, useGlobalModal, useGlobalOverlay, useModal, useOverlay };
|
|
658
|
+
export { AntdOverlayProvider, type AntdOverlayProviderProps, type CustomDrawerProps, type CustomModalProps, type CustomOverlayProps, type DefaultDrawerProps, type DefaultModalProps, type OverlayController, type OverlayOpener, type UseDrawerOptions, type UseModalOptions, type UseOverlayOptions, generateUseDrawerHook, generateUseModalHook, generateUseOverlayHook, useAntdOverlayContext, useDrawer, useGlobalDrawer, useGlobalModal, useGlobalOverlay, useModal, useOverlay };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,11 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
|
|
4
4
|
// src/AntdOverlayContext.tsx
|
|
5
5
|
var AntdOverlayContext = createContext(null);
|
|
6
|
-
function AntdOverlayProvider({
|
|
6
|
+
function AntdOverlayProvider({
|
|
7
|
+
children,
|
|
8
|
+
defaultModalProps,
|
|
9
|
+
defaultDrawerProps
|
|
10
|
+
}) {
|
|
7
11
|
const [holders, setHolders] = useState([]);
|
|
8
12
|
const addHolder = useCallback((holder) => {
|
|
9
13
|
setHolders((prev) => [...prev, holder]);
|
|
@@ -12,8 +16,8 @@ function AntdOverlayProvider({ children }) {
|
|
|
12
16
|
setHolders((prev) => prev.filter((h) => h !== holder));
|
|
13
17
|
}, []);
|
|
14
18
|
const value = useMemo(
|
|
15
|
-
() => ({ holders, addHolder, removeHolder }),
|
|
16
|
-
[holders, addHolder, removeHolder]
|
|
19
|
+
() => ({ holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps }),
|
|
20
|
+
[holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps]
|
|
17
21
|
);
|
|
18
22
|
return /* @__PURE__ */ jsxs(AntdOverlayContext.Provider, { value, children: [
|
|
19
23
|
children,
|
|
@@ -21,13 +25,7 @@ function AntdOverlayProvider({ children }) {
|
|
|
21
25
|
] });
|
|
22
26
|
}
|
|
23
27
|
function useAntdOverlayContext() {
|
|
24
|
-
|
|
25
|
-
if (!context) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
"useAntdOverlayContext must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>."
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
return context;
|
|
28
|
+
return useContext(AntdOverlayContext);
|
|
31
29
|
}
|
|
32
30
|
var defaultPropsAdapter = (props, state) => {
|
|
33
31
|
const result = {
|
|
@@ -109,7 +107,13 @@ function useOverlay(OverlayComponent, options = {}) {
|
|
|
109
107
|
return [openOverlay, contextHolder];
|
|
110
108
|
}
|
|
111
109
|
function useGlobalOverlay(OverlayComponent, options) {
|
|
112
|
-
const
|
|
110
|
+
const context = useAntdOverlayContext();
|
|
111
|
+
if (!context) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
"useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>."
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
const { addHolder, removeHolder } = context;
|
|
113
117
|
const [openOverlay, contextHolder] = useOverlay(OverlayComponent, options);
|
|
114
118
|
useEffect(() => {
|
|
115
119
|
addHolder(contextHolder);
|
|
@@ -131,11 +135,10 @@ function generateUseOverlayHook(OverlayComponent, defaultOptions) {
|
|
|
131
135
|
useGlobalOverlay: (options) => useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options })
|
|
132
136
|
};
|
|
133
137
|
}
|
|
134
|
-
var createModalPropsAdapter = () => {
|
|
138
|
+
var createModalPropsAdapter = (defaultProps) => {
|
|
135
139
|
return (props, state) => {
|
|
136
140
|
const result = {
|
|
137
|
-
|
|
138
|
-
// 默认禁止点击遮罩关闭
|
|
141
|
+
...defaultProps,
|
|
139
142
|
...props,
|
|
140
143
|
open: state.open,
|
|
141
144
|
customClose: state.onClose,
|
|
@@ -156,7 +159,11 @@ var createModalPropsAdapter = () => {
|
|
|
156
159
|
};
|
|
157
160
|
};
|
|
158
161
|
function useModal(ModalComponent, options) {
|
|
159
|
-
const
|
|
162
|
+
const context = useAntdOverlayContext();
|
|
163
|
+
const propsAdapter = useMemo(
|
|
164
|
+
() => createModalPropsAdapter(context?.defaultModalProps),
|
|
165
|
+
[context?.defaultModalProps]
|
|
166
|
+
);
|
|
160
167
|
return useOverlay(ModalComponent, {
|
|
161
168
|
...options,
|
|
162
169
|
keyPrefix: "use-modal",
|
|
@@ -164,7 +171,11 @@ function useModal(ModalComponent, options) {
|
|
|
164
171
|
});
|
|
165
172
|
}
|
|
166
173
|
function useGlobalModal(ModalComponent, options) {
|
|
167
|
-
const
|
|
174
|
+
const context = useAntdOverlayContext();
|
|
175
|
+
const propsAdapter = useMemo(
|
|
176
|
+
() => createModalPropsAdapter(context?.defaultModalProps),
|
|
177
|
+
[context?.defaultModalProps]
|
|
178
|
+
);
|
|
168
179
|
return useGlobalOverlay(ModalComponent, {
|
|
169
180
|
...options,
|
|
170
181
|
keyPrefix: "use-modal",
|
|
@@ -177,11 +188,10 @@ function generateUseModalHook(ModalComponent) {
|
|
|
177
188
|
useGlobalModal: (options) => useGlobalModal(ModalComponent, options)
|
|
178
189
|
};
|
|
179
190
|
}
|
|
180
|
-
var createDrawerPropsAdapter = () => {
|
|
191
|
+
var createDrawerPropsAdapter = (defaultProps) => {
|
|
181
192
|
return (props, state) => {
|
|
182
193
|
const result = {
|
|
183
|
-
|
|
184
|
-
// 默认禁止点击遮罩关闭
|
|
194
|
+
...defaultProps,
|
|
185
195
|
...props,
|
|
186
196
|
open: state.open,
|
|
187
197
|
customClose: state.onClose,
|
|
@@ -204,7 +214,11 @@ var createDrawerPropsAdapter = () => {
|
|
|
204
214
|
};
|
|
205
215
|
};
|
|
206
216
|
function useDrawer(DrawerComponent, options) {
|
|
207
|
-
const
|
|
217
|
+
const context = useAntdOverlayContext();
|
|
218
|
+
const propsAdapter = useMemo(
|
|
219
|
+
() => createDrawerPropsAdapter(context?.defaultDrawerProps),
|
|
220
|
+
[context?.defaultDrawerProps]
|
|
221
|
+
);
|
|
208
222
|
return useOverlay(DrawerComponent, {
|
|
209
223
|
...options,
|
|
210
224
|
keyPrefix: "use-drawer",
|
|
@@ -212,7 +226,11 @@ function useDrawer(DrawerComponent, options) {
|
|
|
212
226
|
});
|
|
213
227
|
}
|
|
214
228
|
function useGlobalDrawer(DrawerComponent, options) {
|
|
215
|
-
const
|
|
229
|
+
const context = useAntdOverlayContext();
|
|
230
|
+
const propsAdapter = useMemo(
|
|
231
|
+
() => createDrawerPropsAdapter(context?.defaultDrawerProps),
|
|
232
|
+
[context?.defaultDrawerProps]
|
|
233
|
+
);
|
|
216
234
|
return useGlobalOverlay(DrawerComponent, {
|
|
217
235
|
...options,
|
|
218
236
|
keyPrefix: "use-drawer",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AntdOverlayContext.tsx","../src/useOverlay.tsx","../src/useModal.tsx","../src/useDrawer.tsx"],"names":["useState","useCallback","useMemo","React"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file AntdOverlayContext - 全局覆盖层容器 Context\n * @description\n * 提供全局覆盖层的挂载点管理。所有通过 useGlobalOverlay 系列 Hook\n * 创建的覆盖层都会被挂载到 AntdOverlayProvider 下。\n *\n * 工作原理:\n * 1. AntdOverlayProvider 维护一个 holders 数组\n * 2. useGlobalOverlay 通过 useAntdOverlayContext 获取注册方法\n * 3. 覆盖层的 contextHolder 被添加到 holders 数组\n * 4. Provider 在子节点之后统一渲染所有 holders\n *\n * 这种设计的优势:\n * - 覆盖层与业务组件解耦,可在任意位置调用\n * - 统一的挂载点,避免 z-index 混乱\n * - 组件卸载时自动清理对应的覆盖层\n *\n * @example\n * // 在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n */\n\nimport React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * AntdOverlay Context 的值类型\n *\n * @property holders - 当前所有已注册的覆盖层 holder 节点\n * @property addHolder - 注册一个新的 holder 到全局容器\n * @property removeHolder - 从全局容器移除一个已注册的 holder\n */\ninterface AntdOverlayContextValue {\n /** 所有已注册的 holder 节点列表 */\n holders: React.ReactNode[];\n /** 添加 holder 到全局容器 */\n addHolder: (holder: React.ReactNode) => void;\n /** 从全局容器移除 holder */\n removeHolder: (holder: React.ReactNode) => void;\n}\n\n// ============================================================================\n// Context 定义\n// ============================================================================\n\n/**\n * AntdOverlay Context\n *\n * 默认值为 null,使用时必须在 AntdOverlayProvider 内部。\n * 如果在 Provider 外部调用 useAntdOverlayContext,会抛出明确的错误提示。\n */\nconst AntdOverlayContext = createContext<AntdOverlayContextValue | null>(null);\n\n// ============================================================================\n// Provider 组件\n// ============================================================================\n\n/**\n * AntdOverlay 容器提供者组件\n *\n * 用于管理全局覆盖层的挂载点。所有通过 useGlobalOverlay、useGlobalModal、\n * useGlobalDrawer 等 Hook 创建的覆盖层都会被挂载到这个 Provider 下。\n *\n * 渲染结构:\n * ```\n * <AntdOverlayContext.Provider>\n * {children} <- 应用的主要内容\n * {holders[0]} <- 全局覆盖层 1\n * {holders[1]} <- 全局覆盖层 2\n * ...\n * </AntdOverlayContext.Provider>\n * ```\n *\n * @param children - 子节点,通常是整个应用\n *\n * @example\n * // 基础用法 - 在应用入口包裹\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n *\n * @example\n * // 与其他 Provider 配合使用\n * function App() {\n * return (\n * <ConfigProvider>\n * <AntdOverlayProvider>\n * <App />\n * </AntdOverlayProvider>\n * </ConfigProvider>\n * );\n * }\n */\nexport function AntdOverlayProvider({ children }: { children: React.ReactNode }) {\n // 存储所有已注册的 holder 节点\n const [holders, setHolders] = useState<React.ReactNode[]>([]);\n\n /**\n * 添加 holder 到全局容器\n *\n * 使用函数式更新确保并发安全,避免闭包陷阱。\n * 新的 holder 会被追加到数组末尾,因此后添加的覆盖层会显示在上层。\n */\n const addHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => [...prev, holder]);\n }, []);\n\n /**\n * 从全局容器移除 holder\n *\n * 通过引用比较(===)找到并移除对应的 holder。\n * 这要求每次传入的 holder 必须是同一个引用。\n */\n const removeHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => prev.filter((h) => h !== holder));\n }, []);\n\n // 使用 useMemo 优化 Context 值,避免不必要的重渲染\n // 只有当 holders、addHolder 或 removeHolder 变化时才会创建新的值对象\n const value = useMemo(\n () => ({ holders, addHolder, removeHolder }),\n [holders, addHolder, removeHolder],\n );\n\n return (\n <AntdOverlayContext.Provider value={value}>\n {children}\n {/* 在 children 之后渲染所有全局覆盖层 */}\n {holders}\n </AntdOverlayContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * 获取 AntdOverlay Context 的 Hook\n *\n * 返回全局容器的注册和注销方法,供 useGlobalOverlay 系列 Hook 内部使用。\n *\n * 注意事项:\n * - 必须在 AntdOverlayProvider 内部使用\n * - 如果在 Provider 外部调用,会抛出明确的错误\n * - 主要供库内部使用,一般不需要在业务代码中直接调用\n *\n * @returns AntdOverlayContextValue 包含 holders、addHolder、removeHolder\n * @throws Error 如果不在 AntdOverlayProvider 内部使用\n *\n * @example\n * // 库内部使用示例(useGlobalOverlay 的实现)\n * function useGlobalOverlay(Component, options) {\n * const { addHolder, removeHolder } = useAntdOverlayContext();\n * const [open, holder] = useOverlay(Component, options);\n *\n * useEffect(() => {\n * addHolder(holder);\n * return () => removeHolder(holder);\n * }, [holder]);\n *\n * return open;\n * }\n */\nexport function useAntdOverlayContext() {\n const context = useContext(AntdOverlayContext);\n\n if (!context) {\n throw new Error(\n 'useAntdOverlayContext must be used within an AntdOverlayProvider. ' +\n 'Please wrap your application with <AntdOverlayProvider>.',\n );\n }\n\n return context;\n}\n","/**\n * @file useOverlay - 通用覆盖层管理 Hook\n * @description\n * 提供一个与具体 UI 组件无关的覆盖层(Overlay)管理方案。\n * 支持任意满足 CustomOverlayProps 接口的组件,如 Modal、Drawer、Popover 等。\n *\n * 核心设计理念:\n * 1. 命令式调用 - 通过函数调用打开覆盖层,而非声明式管理 open 状态\n * 2. 动画支持 - 正确处理打开/关闭动画,避免动画未完成就卸载组件\n * 3. 全局挂载 - 支持将覆盖层挂载到全局容器,实现跨组件调用\n * 4. 类型安全 - 完整的 TypeScript 类型支持\n *\n * 架构层次:\n * ┌─────────────────────────────────────────────────────────┐\n * │ useModal / useDrawer │ <- 业务层封装\n * ├─────────────────────────────────────────────────────────┤\n * │ useOverlay / useGlobalOverlay │ <- 核心逻辑层\n * ├─────────────────────────────────────────────────────────┤\n * │ GlobalHolderProvider │ <- 全局容器层\n * └─────────────────────────────────────────────────────────┘\n *\n * @example\n * // 直接使用 useOverlay(不推荐,建议使用 useModal/useDrawer)\n * const [openOverlay, holder] = useOverlay(MyOverlayComponent, {\n * propsAdapter: (props, state) => ({ ...props, visible: state.open }),\n * });\n */\n\nimport React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useAntdOverlayContext } from './AntdOverlayContext';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * 自定义覆盖层组件必须实现的属性接口\n *\n * 这是所有覆盖层组件的基础接口,定义了控制覆盖层所需的最小属性集。\n * 具体的 UI 组件(如 Modal、Drawer)应该扩展此接口。\n *\n * @template T - customOk 回调接收的参数类型,用于传递确认操作的数据\n * @template R - customOk 回调的返回类型,通常为 void\n *\n * @property open - 控制覆盖层的显示/隐藏状态\n * @property customClose - 关闭覆盖层的回调函数,由 useOverlay 注入\n * @property customOk - 确认操作的回调函数,调用后会自动关闭覆盖层\n *\n * @example\n * interface MyOverlayProps extends CustomOverlayProps<{ id: number }> {\n * title: string;\n * data: SomeData;\n * }\n *\n * const MyOverlay: React.FC<MyOverlayProps> = ({\n * open,\n * customClose,\n * customOk,\n * title,\n * data,\n * }) => {\n * const handleConfirm = () => {\n * // 调用 customOk 会自动关闭覆盖层\n * customOk?.({ id: data.id });\n * };\n * return (\n * <Modal open={open} onCancel={customClose} onOk={handleConfirm}>\n * {title}\n * </Modal>\n * );\n * };\n */\nexport interface CustomOverlayProps<T = any, R = void> {\n /** 覆盖层的显示状态 */\n open?: boolean;\n /** 关闭覆盖层的回调,由 useOverlay 自动注入 */\n customClose: () => void;\n /** 确认操作回调,调用后自动关闭覆盖层 */\n customOk?: (value: T) => R;\n}\n\n/**\n * 内部使用的属性类型\n * 排除 customClose,因为它由 useOverlay 自动注入,用户无需传递\n */\ntype InternalProps<T extends CustomOverlayProps> = Omit<T, 'customClose'>;\n\n/**\n * 覆盖层控制器接口\n *\n * 打开覆盖层后返回的控制器对象,用于后续操作(更新属性或关闭)。\n * 使用 readonly 确保方法引用稳定,不会被意外修改。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @example\n * const controller = openModal({ title: '初始标题' });\n *\n * // 动态更新属性\n * controller.update({ title: '新标题', loading: true });\n *\n * // 编程式关闭\n * controller.close();\n */\nexport interface OverlayController<T extends CustomOverlayProps> {\n /**\n * 更新覆盖层的属性\n * @param props - 新的属性对象,会完全替换之前的属性\n */\n readonly update: (props: InternalProps<T>) => void;\n /**\n * 关闭覆盖层\n * 如果启用了动画,会等待动画结束后再卸载组件\n */\n readonly close: () => void;\n}\n\n/**\n * 覆盖层打开函数的类型定义\n *\n * @template T - 覆盖层组件的属性类型\n * @param initialize - 初始化属性,可选\n * @returns 覆盖层控制器,用于后续的更新和关闭操作\n *\n * @example\n * const openModal: OverlayOpener<MyModalProps> = (props) => {\n * // 返回控制器\n * };\n *\n * // 无参数调用\n * const ctrl1 = openModal();\n *\n * // 带初始属性调用\n * const ctrl2 = openModal({ title: '标题', data: someData });\n */\nexport type OverlayOpener<T extends CustomOverlayProps> = (\n initialize?: InternalProps<T>,\n) => OverlayController<T>;\n\n/**\n * useOverlay Hook 的配置选项\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @property animation - 是否启用动画支持,默认 true\n * - true: 关闭时先设置 open=false,等待动画结束后再卸载组件\n * - false: 关闭时直接卸载组件,适用于无动画的覆盖层\n *\n * @property keyPrefix - React key 的前缀,用于区分不同类型的覆盖层\n * - 默认值: 'use-overlay'\n * - useModal 使用 'use-modal'\n * - useDrawer 使用 'use-drawer'\n *\n * @property propsAdapter - 属性适配器函数\n * 用于将内部状态转换为组件实际需要的属性。\n * 不同的 UI 组件(Modal、Drawer)有不同的动画回调机制,\n * 通过适配器实现统一的接口。\n */\nexport interface UseOverlayOptions<T extends CustomOverlayProps> {\n /** 是否启用关闭动画,默认 true */\n animation?: boolean;\n /** React key 前缀,用于标识覆盖层类型 */\n keyPrefix?: string;\n /**\n * 属性适配器函数\n * @param props - 用户传入的属性\n * @param state - 内部状态,包含 open、onClose、onAnimationEnd\n * @returns 传递给组件的最终属性\n */\n propsAdapter?: (\n props: InternalProps<T> | undefined,\n state: {\n /** 当前的打开状态 */\n open: boolean;\n /** 触发关闭的回调 */\n onClose: () => void;\n /** 动画结束后的回调,用于卸载组件 */\n onAnimationEnd: () => void;\n },\n ) => T;\n}\n\n// ============================================================================\n// 默认属性适配器\n// ============================================================================\n\n/**\n * 默认的属性适配器\n *\n * 提供基本的属性转换逻辑:\n * 1. 将用户传入的 props 与内部状态合并\n * 2. 注入 open 和 customClose\n * 3. 包装 customOk 使其调用后自动关闭覆盖层\n *\n * 注意:这是一个简化的适配器,不处理动画。\n * 对于 Modal 和 Drawer,应该使用各自的专用适配器来处理动画回调。\n *\n * @template T - 覆盖层组件的属性类型\n * @param props - 用户传入的属性\n * @param state - 内部状态\n * @returns 最终传递给组件的属性\n */\nconst defaultPropsAdapter = <T extends CustomOverlayProps>(\n props: InternalProps<T> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n): T => {\n const result = {\n ...props,\n open: state.open,\n customClose: state.onClose,\n } as unknown as T;\n\n // 包装 customOk,使其调用后自动触发关闭\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n};\n\n// ============================================================================\n// 核心 Hook 实现\n// ============================================================================\n\n/**\n * 覆盖层管理核心 Hook\n *\n * 这是整个库的核心,提供覆盖层的生命周期管理:\n * - 挂载/卸载控制\n * - 打开/关闭状态管理\n * - 动画支持\n * - 属性更新\n *\n * 状态机说明:\n * ```\n * [未挂载] --open()--> [已挂载, open=true] --close()--> [已挂载, open=false] --动画结束--> [未挂载]\n * │\n * └── (animation=false) --> [未挂载]\n * ```\n *\n * @template T - 覆盖层组件的属性类型,必须继承 CustomOverlayProps\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 元组 [openOverlay, contextHolder]\n * - openOverlay: 打开覆盖层的函数,返回控制器\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyComponent() {\n * const [openOverlay, holder] = useOverlay(MyOverlay, {\n * animation: true,\n * propsAdapter: (props, state) => ({\n * ...props,\n * visible: state.open,\n * onClose: state.onClose,\n * afterVisibleChange: (visible) => {\n * if (!visible) state.onAnimationEnd();\n * },\n * }),\n * });\n *\n * return (\n * <>\n * <button onClick={() => openOverlay({ title: '标题' })}>打开</button>\n * {holder}\n * </>\n * );\n * }\n */\nexport function useOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options: UseOverlayOptions<T> = {},\n): [OverlayOpener<T>, React.ReactNode] {\n // 解构配置选项,设置默认值\n const {\n animation = true,\n keyPrefix = 'use-overlay',\n propsAdapter = defaultPropsAdapter,\n } = options;\n\n // 生成唯一 ID,用于 React key\n const id = useId();\n const key = `${keyPrefix}-${id}`;\n\n // ========== 状态管理 ==========\n\n /**\n * open: 控制覆盖层的显示状态(用于动画)\n * - true: 覆盖层显示\n * - false: 覆盖层隐藏(但可能还在播放关闭动画)\n */\n const [open, setOpen] = useState(false);\n\n /**\n * renderEnable: 控制组件是否挂载到 DOM\n * - true: 组件已挂载\n * - false: 组件已卸载\n *\n * 与 open 分离是为了支持关闭动画:\n * 关闭时先设置 open=false 触发动画,动画结束后再设置 renderEnable=false 卸载组件\n */\n const [renderEnable, setRenderEnable] = useState(false);\n\n /**\n * props: 用户传入的属性\n * 存储最近一次 open 或 update 调用时传入的属性\n */\n const [props, setProps] = useState<InternalProps<T> | undefined>();\n\n /**\n * 使用 ref 存储 animation 配置\n * 避免 animation 变化时重新创建回调函数\n */\n const animationRef = useRef(animation);\n animationRef.current = animation;\n\n // ========== 回调函数 ==========\n\n /**\n * 处理关闭操作\n *\n * 根据是否启用动画采取不同策略:\n * - 启用动画: 仅设置 open=false,等待动画结束后再卸载\n * - 禁用动画: 直接卸载组件\n */\n const handleClose = useCallback(() => {\n if (animationRef.current) {\n // 启用动画时,先触发关闭动画\n setOpen(false);\n } else {\n // 禁用动画时,直接卸载\n setRenderEnable(false);\n }\n }, []);\n\n /**\n * 处理动画结束\n *\n * 由属性适配器在关闭动画结束时调用。\n * 仅在启用动画时执行实际的卸载操作。\n */\n const handleAnimationEnd = useCallback(() => {\n if (animationRef.current) {\n setRenderEnable(false);\n }\n }, []);\n\n // ========== 渲染逻辑 ==========\n\n /**\n * contextHolder: 需要渲染到组件树中的节点\n *\n * 使用 useMemo 优化性能:\n * - 未挂载时返回空 Fragment(保持 key 稳定)\n * - 已挂载时渲染实际组件,通过 propsAdapter 转换属性\n */\n const contextHolder = useMemo(() => {\n // 未挂载时返回带 key 的空 Fragment\n // 保持 key 稳定可以避免不必要的 DOM 操作\n if (!renderEnable) return <React.Fragment key={key} />;\n\n // 通过适配器转换属性\n const realProps = propsAdapter(props, {\n open,\n onClose: handleClose,\n onAnimationEnd: handleAnimationEnd,\n });\n\n return <OverlayComponent key={key} {...realProps} />;\n }, [\n renderEnable,\n open,\n props,\n key,\n propsAdapter,\n handleClose,\n handleAnimationEnd,\n OverlayComponent,\n ]);\n\n // ========== 打开函数 ==========\n\n /**\n * 打开覆盖层的函数\n *\n * @param initializeProps - 初始化属性\n * @returns 控制器对象,包含 update 和 close 方法\n */\n const openOverlay = useCallback(\n (initializeProps?: InternalProps<T>) => {\n // 1. 挂载组件\n setRenderEnable(true);\n // 2. 设置为打开状态(触发打开动画)\n setOpen(true);\n // 3. 存储初始属性\n setProps(initializeProps);\n\n // 返回控制器\n return {\n /**\n * 更新覆盖层属性\n * 注意:这是完全替换,不是合并\n */\n update: (newProps: InternalProps<T>) => setProps(newProps),\n /**\n * 关闭覆盖层\n */\n close: handleClose,\n } as const;\n },\n [handleClose],\n );\n\n return [openOverlay, contextHolder];\n}\n\n/**\n * 全局覆盖层管理 Hook\n *\n * 与 useOverlay 的区别:\n * - useOverlay: 需要手动渲染 contextHolder\n * - useGlobalOverlay: 自动挂载到 AntdOverlayProvider\n *\n * 实现原理:\n * 1. 内部调用 useOverlay 获取 openOverlay 和 contextHolder\n * 2. 使用 useEffect 将 contextHolder 注册到全局容器\n * 3. 组件卸载时自动从全局容器移除\n *\n * 使用前提:\n * - 必须在组件树的上层包裹 AntdOverlayProvider\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 打开覆盖层的函数(无需再渲染 holder)\n *\n * @example\n * // 1. 先在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <YourApp />\n * </AntdOverlayProvider>\n * );\n * }\n *\n * // 2. 在任意组件中使用\n * function AnyComponent() {\n * const openOverlay = useGlobalOverlay(MyOverlay);\n *\n * return (\n * <button onClick={() => openOverlay({ data: someData })}>\n * 打开全局覆盖层\n * </button>\n * );\n * }\n */\nexport function useGlobalOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options?: UseOverlayOptions<T>,\n): OverlayOpener<T> {\n // 获取全局容器的注册/注销方法\n const { addHolder, removeHolder } = useAntdOverlayContext();\n\n // 使用基础 useOverlay 获取功能\n const [openOverlay, contextHolder] = useOverlay<T>(OverlayComponent, options);\n\n // 将 contextHolder 注册到全局容器\n useEffect(() => {\n addHolder(contextHolder);\n // 清理函数:组件卸载时从全局容器移除\n return () => removeHolder(contextHolder);\n }, [contextHolder, addHolder, removeHolder]);\n\n // 仅返回 openOverlay,holder 已自动挂载\n return openOverlay;\n}\n\n// ============================================================================\n// 工厂函数\n// ============================================================================\n\n/**\n * 生成绑定了特定组件的 Hook 工厂函数\n *\n * 当某个覆盖层组件在多处使用时,可以使用此函数生成专用 Hook,\n * 避免每次使用都需要传入组件引用。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param defaultOptions - 默认配置选项,会与调用时的选项合并\n *\n * @returns 包含 useOverlay 和 useGlobalOverlay 的对象\n *\n * @example\n * // 创建专用 Hook\n * const {\n * useOverlay: useMyOverlay,\n * useGlobalOverlay: useGlobalMyOverlay,\n * } = generateUseOverlayHook(MyOverlayComponent, {\n * animation: true,\n * propsAdapter: myAdapter,\n * });\n *\n * // 使用专用 Hook(无需再传组件)\n * function SomeComponent() {\n * const openOverlay = useGlobalMyOverlay();\n * return <button onClick={() => openOverlay()}>打开</button>;\n * }\n */\nexport function generateUseOverlayHook<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n defaultOptions?: UseOverlayOptions<T>,\n) {\n return {\n /**\n * 绑定了特定组件的 useOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useOverlay: (options?: UseOverlayOptions<T>) =>\n useOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n\n /**\n * 绑定了特定组件的 useGlobalOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useGlobalOverlay: (options?: UseOverlayOptions<T>) =>\n useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n };\n}\n","/**\n * @file useModal - Ant Design Modal 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Modal 专用管理方案。\n * 提供命令式 API 来控制 Modal 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 visible 状态\n * - 支持动态更新 Modal 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterClose 回调)\n *\n * @example\n * // 基础用法\n * const [openModal, holder] = useModal(MyModal);\n *\n * // 全局用法\n * const openModal = useGlobalModal(MyModal);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalModal: useGlobalMyModal } = generateUseModalHook(MyModal);\n */\n\nimport { ModalProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Modal 组件的属性接口\n * 继承 Ant Design ModalProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyModal: React.FC<CustomModalProps<{ name: string }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Modal open={open} onCancel={customClose} onOk={() => customOk?.({ name: 'test' })}>\n * 内容\n * </Modal>\n * );\n * };\n */\nexport interface CustomModalProps<T = any, R = void> extends ModalProps, CustomOverlayProps<T, R> {}\n\n/**\n * useModal Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseModalOptions = Omit<\n UseOverlayOptions<CustomModalProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Modal 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterClose 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Modal 组件的属性类型\n * @returns 属性适配器函数\n */\nconst createModalPropsAdapter = <T extends CustomModalProps>() => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n maskClosable: false, // 默认禁止点击遮罩关闭\n ...props,\n open: state.open,\n customClose: state.onClose,\n // 在 Modal 关闭动画结束后触发,用于卸载组件\n afterClose: () => {\n props?.afterClose?.();\n state.onAnimationEnd();\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Modal\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Modal 管理 Hook\n *\n * @template T - Modal 组件的属性类型,必须继承 CustomModalProps\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openModal, contextHolder]\n * - openModal: 打开 Modal 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openModal, modalHolder] = useModal(ConfirmModal);\n *\n * const handleDelete = () => {\n * openModal({\n * title: '确认删除',\n * content: '删除后无法恢复',\n * });\n * };\n *\n * return (\n * <>\n * <button onClick={handleDelete}>删除</button>\n * {modalHolder}\n * </>\n * );\n * }\n */\nexport function useModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const propsAdapter = useMemo(() => createModalPropsAdapter<T>(), []);\n return useOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Modal 管理 Hook\n *\n * 与 useModal 的区别:\n * - 无需手动渲染 contextHolder\n * - Modal 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 打开 Modal 的函数\n *\n * @example\n * function DeleteButton() {\n * const openConfirm = useGlobalModal(ConfirmModal);\n *\n * return (\n * <button onClick={() => openConfirm({ title: '确认删除?' })}>\n * 删除\n * </button>\n * );\n * }\n */\nexport function useGlobalModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): OverlayOpener<T> {\n const propsAdapter = useMemo(() => createModalPropsAdapter<T>(), []);\n return useGlobalOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Modal 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Modal 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Modal 的默认配置\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n *\n * @returns 包含 useModal 和 useGlobalModal 的对象\n *\n * @example\n * // 在 Modal 组件文件中导出专用 Hook\n * const ConfirmModal: React.FC<CustomModalProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useModal: useConfirmModal,\n * useGlobalModal: useGlobalConfirmModal,\n * } = generateUseModalHook(ConfirmModal);\n *\n * // 在其他组件中使用\n * function MyPage() {\n * const openConfirm = useGlobalConfirmModal();\n * return <button onClick={() => openConfirm()}>确认</button>;\n * }\n */\nexport function generateUseModalHook<T extends CustomModalProps>(ModalComponent: React.FC<T>) {\n return {\n useModal: (options?: UseModalOptions) => useModal(ModalComponent, options),\n useGlobalModal: (options?: UseModalOptions) => useGlobalModal(ModalComponent, options),\n };\n}\n\nexport default useModal;\n","/**\n * @file useDrawer - Ant Design Drawer 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Drawer 专用管理方案。\n * 提供命令式 API 来控制 Drawer 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 open 状态\n * - 支持动态更新 Drawer 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterOpenChange 回调)\n *\n * @example\n * // 基础用法\n * const [openDrawer, holder] = useDrawer(MyDrawer);\n *\n * // 全局用法\n * const openDrawer = useGlobalDrawer(MyDrawer);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalDrawer: useGlobalMyDrawer } = generateUseDrawerHook(MyDrawer);\n */\n\nimport { DrawerProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Drawer 组件的属性接口\n * 继承 Ant Design DrawerProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyDrawer: React.FC<CustomDrawerProps<{ id: number }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Drawer open={open} onClose={customClose}>\n * <Button onClick={() => customOk?.({ id: 1 })}>确认</Button>\n * </Drawer>\n * );\n * };\n */\nexport interface CustomDrawerProps<T = any, R = void>\n extends DrawerProps, CustomOverlayProps<T, R> {}\n\n/**\n * useDrawer Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseDrawerOptions = Omit<\n UseOverlayOptions<CustomDrawerProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Drawer 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterOpenChange 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * 与 Modal 的区别:\n * - Modal 使用 afterClose 回调(仅在关闭后触发)\n * - Drawer 使用 afterOpenChange 回调(打开和关闭都会触发,需要判断状态)\n *\n * @template T - Drawer 组件的属性类型\n * @returns 属性适配器函数\n */\nconst createDrawerPropsAdapter = <T extends CustomDrawerProps>() => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n maskClosable: false, // 默认禁止点击遮罩关闭\n ...props,\n open: state.open,\n customClose: state.onClose,\n // Drawer 的动画回调,打开和关闭时都会触发\n afterOpenChange: (open: boolean) => {\n props?.afterOpenChange?.(open);\n // 仅在关闭动画结束时触发卸载\n if (!open) {\n state.onAnimationEnd();\n }\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Drawer\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Drawer 管理 Hook\n *\n * @template T - Drawer 组件的属性类型,必须继承 CustomDrawerProps\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openDrawer, contextHolder]\n * - openDrawer: 打开 Drawer 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openDrawer, drawerHolder] = useDrawer(UserDetailDrawer);\n *\n * const handleViewUser = (userId: number) => {\n * openDrawer({ userId, title: '用户详情' });\n * };\n *\n * return (\n * <>\n * <button onClick={() => handleViewUser(1)}>查看用户</button>\n * {drawerHolder}\n * </>\n * );\n * }\n */\nexport function useDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const propsAdapter = useMemo(() => createDrawerPropsAdapter<T>(), []);\n return useOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Drawer 管理 Hook\n *\n * 与 useDrawer 的区别:\n * - 无需手动渲染 contextHolder\n * - Drawer 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 打开 Drawer 的函数\n *\n * @example\n * function UserCard({ userId }: { userId: number }) {\n * const openDetail = useGlobalDrawer(UserDetailDrawer);\n *\n * return (\n * <Card onClick={() => openDetail({ userId })}>\n * 查看详情\n * </Card>\n * );\n * }\n */\nexport function useGlobalDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): OverlayOpener<T> {\n const propsAdapter = useMemo(() => createDrawerPropsAdapter<T>(), []);\n return useGlobalOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Drawer 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Drawer 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Drawer 的默认配置\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n *\n * @returns 包含 useDrawer 和 useGlobalDrawer 的对象\n *\n * @example\n * // 在 Drawer 组件文件中导出专用 Hook\n * const ProjectMemberDrawer: React.FC<CustomDrawerProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useDrawer: useProjectMemberDrawer,\n * useGlobalDrawer: useGlobalProjectMemberDrawer,\n * } = generateUseDrawerHook(ProjectMemberDrawer);\n *\n * // 在其他组件中使用\n * function ProjectPage() {\n * const openMemberDrawer = useGlobalProjectMemberDrawer();\n * return <button onClick={() => openMemberDrawer()}>管理成员</button>;\n * }\n */\nexport function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerComponent: React.FC<T>) {\n return {\n useDrawer: (options?: UseDrawerOptions) => useDrawer(DrawerComponent, options),\n useGlobalDrawer: (options?: UseDrawerOptions) => useGlobalDrawer(DrawerComponent, options),\n };\n}\n\nexport default useDrawer;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/AntdOverlayContext.tsx","../src/useOverlay.tsx","../src/useModal.tsx","../src/useDrawer.tsx"],"names":["useState","useCallback","useMemo","React"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file AntdOverlayContext - 全局覆盖层容器 Context\n * @description\n * 提供全局覆盖层的挂载点管理。所有通过 useGlobalOverlay 系列 Hook\n * 创建的覆盖层都会被挂载到 AntdOverlayProvider 下。\n *\n * 工作原理:\n * 1. AntdOverlayProvider 维护一个 holders 数组\n * 2. useGlobalOverlay 通过 useAntdOverlayContext 获取注册方法\n * 3. 覆盖层的 contextHolder 被添加到 holders 数组\n * 4. Provider 在子节点之后统一渲染所有 holders\n *\n * 这种设计的优势:\n * - 覆盖层与业务组件解耦,可在任意位置调用\n * - 统一的挂载点,避免 z-index 混乱\n * - 组件卸载时自动清理对应的覆盖层\n *\n * @example\n * // 在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n */\n\nimport { DrawerProps, ModalProps } from 'antd';\nimport React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\nexport type DefaultModalProps = Partial<ModalProps>;\nexport type DefaultDrawerProps = Partial<DrawerProps>;\n\n/**\n * AntdOverlay Context 的值类型\n *\n * @property holders - 当前所有已注册的覆盖层 holder 节点\n * @property addHolder - 注册一个新的 holder 到全局容器\n * @property removeHolder - 从全局容器移除一个已注册的 holder\n */\ninterface AntdOverlayContextValue {\n /** 所有已注册的 holder 节点列表 */\n holders: React.ReactNode[];\n /** 添加 holder 到全局容器 */\n addHolder: (holder: React.ReactNode) => void;\n /** 从全局容器移除 holder */\n removeHolder: (holder: React.ReactNode) => void;\n /** 默认 Modal 属性 */\n defaultModalProps?: DefaultModalProps;\n /** 默认 Drawer 属性 */\n defaultDrawerProps?: DefaultDrawerProps;\n}\n\n// ============================================================================\n// Context 定义\n// ============================================================================\n\n/**\n * AntdOverlay Context\n *\n * 默认值为 null,使用时必须在 AntdOverlayProvider 内部。\n * 如果在 Provider 外部调用 useAntdOverlayContext,会抛出明确的错误提示。\n */\nconst AntdOverlayContext = createContext<AntdOverlayContextValue | null>(null);\n\n// ============================================================================\n// Provider 组件\n// ============================================================================\n\n/**\n * AntdOverlay 容器提供者组件\n *\n * 用于管理全局覆盖层的挂载点。所有通过 useGlobalOverlay、useGlobalModal、\n * useGlobalDrawer 等 Hook 创建的覆盖层都会被挂载到这个 Provider 下。\n *\n * 渲染结构:\n * ```\n * <AntdOverlayContext.Provider>\n * {children} <- 应用的主要内容\n * {holders[0]} <- 全局覆盖层 1\n * {holders[1]} <- 全局覆盖层 2\n * ...\n * </AntdOverlayContext.Provider>\n * ```\n *\n * @param children - 子节点,通常是整个应用\n *\n * @example\n * // 基础用法 - 在应用入口包裹\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <Router>\n * <Routes />\n * </Router>\n * </AntdOverlayProvider>\n * );\n * }\n *\n * @example\n * // 与其他 Provider 配合使用\n * function App() {\n * return (\n * <ConfigProvider>\n * <AntdOverlayProvider>\n * <App />\n * </AntdOverlayProvider>\n * </ConfigProvider>\n * );\n * }\n */\nexport interface AntdOverlayProviderProps {\n /** 子节点 */\n children: React.ReactNode;\n /** 默认 Modal 属性 */\n defaultModalProps?: DefaultModalProps;\n /** 默认 Drawer 属性 */\n defaultDrawerProps?: DefaultDrawerProps;\n}\n\n\n/**\n * AntdOverlayProvider 组件\n * @param children - 子节点\n * @param defaultModalProps - 默认 Modal 属性\n * @param defaultDrawerProps - 默认 Drawer 属性\n * @returns React.ReactNode\n */\nexport function AntdOverlayProvider({\n children,\n defaultModalProps,\n defaultDrawerProps,\n}: AntdOverlayProviderProps) {\n // 存储所有已注册的 holder 节点\n const [holders, setHolders] = useState<React.ReactNode[]>([]);\n\n /**\n * 添加 holder 到全局容器\n *\n * 使用函数式更新确保并发安全,避免闭包陷阱。\n * 新的 holder 会被追加到数组末尾,因此后添加的覆盖层会显示在上层。\n */\n const addHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => [...prev, holder]);\n }, []);\n\n /**\n * 从全局容器移除 holder\n *\n * 通过引用比较(===)找到并移除对应的 holder。\n * 这要求每次传入的 holder 必须是同一个引用。\n */\n const removeHolder = useCallback((holder: React.ReactNode) => {\n setHolders((prev) => prev.filter((h) => h !== holder));\n }, []);\n\n // 使用 useMemo 优化 Context 值,避免不必要的重渲染\n // 只有当 holders、addHolder 或 removeHolder 变化时才会创建新的值对象\n const value = useMemo(\n () => ({ holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps }),\n [holders, addHolder, removeHolder, defaultModalProps, defaultDrawerProps],\n );\n\n return (\n <AntdOverlayContext.Provider value={value}>\n {children}\n {/* 在 children 之后渲染所有全局覆盖层 */}\n {holders}\n </AntdOverlayContext.Provider>\n );\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * 获取 AntdOverlay Context 的 Hook\n *\n * 返回全局容器的注册和注销方法,供 useGlobalOverlay 系列 Hook 内部使用。\n *\n * 注意事项:\n * - 必须在 AntdOverlayProvider 内部使用\n * - 如果在 Provider 外部调用,会抛出明确的错误\n * - 主要供库内部使用,一般不需要在业务代码中直接调用\n *\n * @returns AntdOverlayContextValue 包含 holders、addHolder、removeHolder\n * @throws Error 如果不在 AntdOverlayProvider 内部使用\n *\n * @example\n * // 库内部使用示例(useGlobalOverlay 的实现)\n * function useGlobalOverlay(Component, options) {\n * const context = useAntdOverlayContext();\n * if (!context) {\n * throw new Error('useGlobalOverlay must be used within an AntdOverlayProvider. Please wrap your application with <AntdOverlayProvider>.');\n * }\n * const { addHolder, removeHolder } = context;\n * const [open, holder] = useOverlay(Component, options);\n *\n * useEffect(() => {\n * addHolder(holder);\n * return () => removeHolder(holder);\n * }, [holder]);\n *\n * return open;\n * }\n */\nexport function useAntdOverlayContext() {\n return useContext(AntdOverlayContext);\n}\n","/**\n * @file useOverlay - 通用覆盖层管理 Hook\n * @description\n * 提供一个与具体 UI 组件无关的覆盖层(Overlay)管理方案。\n * 支持任意满足 CustomOverlayProps 接口的组件,如 Modal、Drawer、Popover 等。\n *\n * 核心设计理念:\n * 1. 命令式调用 - 通过函数调用打开覆盖层,而非声明式管理 open 状态\n * 2. 动画支持 - 正确处理打开/关闭动画,避免动画未完成就卸载组件\n * 3. 全局挂载 - 支持将覆盖层挂载到全局容器,实现跨组件调用\n * 4. 类型安全 - 完整的 TypeScript 类型支持\n *\n * 架构层次:\n * ┌─────────────────────────────────────────────────────────┐\n * │ useModal / useDrawer │ <- 业务层封装\n * ├─────────────────────────────────────────────────────────┤\n * │ useOverlay / useGlobalOverlay │ <- 核心逻辑层\n * ├─────────────────────────────────────────────────────────┤\n * │ GlobalHolderProvider │ <- 全局容器层\n * └─────────────────────────────────────────────────────────┘\n *\n * @example\n * // 直接使用 useOverlay(不推荐,建议使用 useModal/useDrawer)\n * const [openOverlay, holder] = useOverlay(MyOverlayComponent, {\n * propsAdapter: (props, state) => ({ ...props, visible: state.open }),\n * });\n */\n\nimport React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { useAntdOverlayContext } from './AntdOverlayContext';\n\n// ============================================================================\n// 类型定义\n// ============================================================================\n\n/**\n * 自定义覆盖层组件必须实现的属性接口\n *\n * 这是所有覆盖层组件的基础接口,定义了控制覆盖层所需的最小属性集。\n * 具体的 UI 组件(如 Modal、Drawer)应该扩展此接口。\n *\n * @template T - customOk 回调接收的参数类型,用于传递确认操作的数据\n * @template R - customOk 回调的返回类型,通常为 void\n *\n * @property open - 控制覆盖层的显示/隐藏状态\n * @property customClose - 关闭覆盖层的回调函数,由 useOverlay 注入\n * @property customOk - 确认操作的回调函数,调用后会自动关闭覆盖层\n *\n * @example\n * interface MyOverlayProps extends CustomOverlayProps<{ id: number }> {\n * title: string;\n * data: SomeData;\n * }\n *\n * const MyOverlay: React.FC<MyOverlayProps> = ({\n * open,\n * customClose,\n * customOk,\n * title,\n * data,\n * }) => {\n * const handleConfirm = () => {\n * // 调用 customOk 会自动关闭覆盖层\n * customOk?.({ id: data.id });\n * };\n * return (\n * <Modal open={open} onCancel={customClose} onOk={handleConfirm}>\n * {title}\n * </Modal>\n * );\n * };\n */\nexport interface CustomOverlayProps<T = any, R = void> {\n /** 覆盖层的显示状态 */\n open?: boolean;\n /** 关闭覆盖层的回调,由 useOverlay 自动注入 */\n customClose: () => void;\n /** 确认操作回调,调用后自动关闭覆盖层 */\n customOk?: (value: T) => R;\n}\n\n/**\n * 内部使用的属性类型\n * 排除 customClose,因为它由 useOverlay 自动注入,用户无需传递\n */\ntype InternalProps<T extends CustomOverlayProps> = Omit<T, 'customClose'>;\n\n/**\n * 覆盖层控制器接口\n *\n * 打开覆盖层后返回的控制器对象,用于后续操作(更新属性或关闭)。\n * 使用 readonly 确保方法引用稳定,不会被意外修改。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @example\n * const controller = openModal({ title: '初始标题' });\n *\n * // 动态更新属性\n * controller.update({ title: '新标题', loading: true });\n *\n * // 编程式关闭\n * controller.close();\n */\nexport interface OverlayController<T extends CustomOverlayProps> {\n /**\n * 更新覆盖层的属性\n * @param props - 新的属性对象,会完全替换之前的属性\n */\n readonly update: (props: InternalProps<T>) => void;\n /**\n * 关闭覆盖层\n * 如果启用了动画,会等待动画结束后再卸载组件\n */\n readonly close: () => void;\n}\n\n/**\n * 覆盖层打开函数的类型定义\n *\n * @template T - 覆盖层组件的属性类型\n * @param initialize - 初始化属性,可选\n * @returns 覆盖层控制器,用于后续的更新和关闭操作\n *\n * @example\n * const openModal: OverlayOpener<MyModalProps> = (props) => {\n * // 返回控制器\n * };\n *\n * // 无参数调用\n * const ctrl1 = openModal();\n *\n * // 带初始属性调用\n * const ctrl2 = openModal({ title: '标题', data: someData });\n */\nexport type OverlayOpener<T extends CustomOverlayProps> = (\n initialize?: InternalProps<T>,\n) => OverlayController<T>;\n\n/**\n * useOverlay Hook 的配置选项\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @property animation - 是否启用动画支持,默认 true\n * - true: 关闭时先设置 open=false,等待动画结束后再卸载组件\n * - false: 关闭时直接卸载组件,适用于无动画的覆盖层\n *\n * @property keyPrefix - React key 的前缀,用于区分不同类型的覆盖层\n * - 默认值: 'use-overlay'\n * - useModal 使用 'use-modal'\n * - useDrawer 使用 'use-drawer'\n *\n * @property propsAdapter - 属性适配器函数\n * 用于将内部状态转换为组件实际需要的属性。\n * 不同的 UI 组件(Modal、Drawer)有不同的动画回调机制,\n * 通过适配器实现统一的接口。\n */\nexport interface UseOverlayOptions<T extends CustomOverlayProps> {\n /** 是否启用关闭动画,默认 true */\n animation?: boolean;\n /** React key 前缀,用于标识覆盖层类型 */\n keyPrefix?: string;\n /**\n * 属性适配器函数\n * @param props - 用户传入的属性\n * @param state - 内部状态,包含 open、onClose、onAnimationEnd\n * @returns 传递给组件的最终属性\n */\n propsAdapter?: (\n props: InternalProps<T> | undefined,\n state: {\n /** 当前的打开状态 */\n open: boolean;\n /** 触发关闭的回调 */\n onClose: () => void;\n /** 动画结束后的回调,用于卸载组件 */\n onAnimationEnd: () => void;\n },\n ) => T;\n}\n\n// ============================================================================\n// 默认属性适配器\n// ============================================================================\n\n/**\n * 默认的属性适配器\n *\n * 提供基本的属性转换逻辑:\n * 1. 将用户传入的 props 与内部状态合并\n * 2. 注入 open 和 customClose\n * 3. 包装 customOk 使其调用后自动关闭覆盖层\n *\n * 注意:这是一个简化的适配器,不处理动画。\n * 对于 Modal 和 Drawer,应该使用各自的专用适配器来处理动画回调。\n *\n * @template T - 覆盖层组件的属性类型\n * @param props - 用户传入的属性\n * @param state - 内部状态\n * @returns 最终传递给组件的属性\n */\nconst defaultPropsAdapter = <T extends CustomOverlayProps>(\n props: InternalProps<T> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n): T => {\n const result = {\n ...props,\n open: state.open,\n customClose: state.onClose,\n } as unknown as T;\n\n // 包装 customOk,使其调用后自动触发关闭\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n};\n\n// ============================================================================\n// 核心 Hook 实现\n// ============================================================================\n\n/**\n * 覆盖层管理核心 Hook\n *\n * 这是整个库的核心,提供覆盖层的生命周期管理:\n * - 挂载/卸载控制\n * - 打开/关闭状态管理\n * - 动画支持\n * - 属性更新\n *\n * 状态机说明:\n * ```\n * [未挂载] --open()--> [已挂载, open=true] --close()--> [已挂载, open=false] --动画结束--> [未挂载]\n * │\n * └── (animation=false) --> [未挂载]\n * ```\n *\n * @template T - 覆盖层组件的属性类型,必须继承 CustomOverlayProps\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 元组 [openOverlay, contextHolder]\n * - openOverlay: 打开覆盖层的函数,返回控制器\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyComponent() {\n * const [openOverlay, holder] = useOverlay(MyOverlay, {\n * animation: true,\n * propsAdapter: (props, state) => ({\n * ...props,\n * visible: state.open,\n * onClose: state.onClose,\n * afterVisibleChange: (visible) => {\n * if (!visible) state.onAnimationEnd();\n * },\n * }),\n * });\n *\n * return (\n * <>\n * <button onClick={() => openOverlay({ title: '标题' })}>打开</button>\n * {holder}\n * </>\n * );\n * }\n */\nexport function useOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options: UseOverlayOptions<T> = {},\n): [OverlayOpener<T>, React.ReactNode] {\n // 解构配置选项,设置默认值\n const {\n animation = true,\n keyPrefix = 'use-overlay',\n propsAdapter = defaultPropsAdapter,\n } = options;\n\n // 生成唯一 ID,用于 React key\n const id = useId();\n const key = `${keyPrefix}-${id}`;\n\n // ========== 状态管理 ==========\n\n /**\n * open: 控制覆盖层的显示状态(用于动画)\n * - true: 覆盖层显示\n * - false: 覆盖层隐藏(但可能还在播放关闭动画)\n */\n const [open, setOpen] = useState(false);\n\n /**\n * renderEnable: 控制组件是否挂载到 DOM\n * - true: 组件已挂载\n * - false: 组件已卸载\n *\n * 与 open 分离是为了支持关闭动画:\n * 关闭时先设置 open=false 触发动画,动画结束后再设置 renderEnable=false 卸载组件\n */\n const [renderEnable, setRenderEnable] = useState(false);\n\n /**\n * props: 用户传入的属性\n * 存储最近一次 open 或 update 调用时传入的属性\n */\n const [props, setProps] = useState<InternalProps<T> | undefined>();\n\n /**\n * 使用 ref 存储 animation 配置\n * 避免 animation 变化时重新创建回调函数\n */\n const animationRef = useRef(animation);\n animationRef.current = animation;\n\n // ========== 回调函数 ==========\n\n /**\n * 处理关闭操作\n *\n * 根据是否启用动画采取不同策略:\n * - 启用动画: 仅设置 open=false,等待动画结束后再卸载\n * - 禁用动画: 直接卸载组件\n */\n const handleClose = useCallback(() => {\n if (animationRef.current) {\n // 启用动画时,先触发关闭动画\n setOpen(false);\n } else {\n // 禁用动画时,直接卸载\n setRenderEnable(false);\n }\n }, []);\n\n /**\n * 处理动画结束\n *\n * 由属性适配器在关闭动画结束时调用。\n * 仅在启用动画时执行实际的卸载操作。\n */\n const handleAnimationEnd = useCallback(() => {\n if (animationRef.current) {\n setRenderEnable(false);\n }\n }, []);\n\n // ========== 渲染逻辑 ==========\n\n /**\n * contextHolder: 需要渲染到组件树中的节点\n *\n * 使用 useMemo 优化性能:\n * - 未挂载时返回空 Fragment(保持 key 稳定)\n * - 已挂载时渲染实际组件,通过 propsAdapter 转换属性\n */\n const contextHolder = useMemo(() => {\n // 未挂载时返回带 key 的空 Fragment\n // 保持 key 稳定可以避免不必要的 DOM 操作\n if (!renderEnable) return <React.Fragment key={key} />;\n\n // 通过适配器转换属性\n const realProps = propsAdapter(props, {\n open,\n onClose: handleClose,\n onAnimationEnd: handleAnimationEnd,\n });\n\n return <OverlayComponent key={key} {...realProps} />;\n }, [\n renderEnable,\n open,\n props,\n key,\n propsAdapter,\n handleClose,\n handleAnimationEnd,\n OverlayComponent,\n ]);\n\n // ========== 打开函数 ==========\n\n /**\n * 打开覆盖层的函数\n *\n * @param initializeProps - 初始化属性\n * @returns 控制器对象,包含 update 和 close 方法\n */\n const openOverlay = useCallback(\n (initializeProps?: InternalProps<T>) => {\n // 1. 挂载组件\n setRenderEnable(true);\n // 2. 设置为打开状态(触发打开动画)\n setOpen(true);\n // 3. 存储初始属性\n setProps(initializeProps);\n\n // 返回控制器\n return {\n /**\n * 更新覆盖层属性\n * 注意:这是完全替换,不是合并\n */\n update: (newProps: InternalProps<T>) => setProps(newProps),\n /**\n * 关闭覆盖层\n */\n close: handleClose,\n } as const;\n },\n [handleClose],\n );\n\n return [openOverlay, contextHolder];\n}\n\n/**\n * 全局覆盖层管理 Hook\n *\n * 与 useOverlay 的区别:\n * - useOverlay: 需要手动渲染 contextHolder\n * - useGlobalOverlay: 自动挂载到 AntdOverlayProvider\n *\n * 实现原理:\n * 1. 内部调用 useOverlay 获取 openOverlay 和 contextHolder\n * 2. 使用 useEffect 将 contextHolder 注册到全局容器\n * 3. 组件卸载时自动从全局容器移除\n *\n * 使用前提:\n * - 必须在组件树的上层包裹 AntdOverlayProvider\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param options - 配置选项\n *\n * @returns 打开覆盖层的函数(无需再渲染 holder)\n *\n * @example\n * // 1. 先在应用入口包裹 Provider\n * function App() {\n * return (\n * <AntdOverlayProvider>\n * <YourApp />\n * </AntdOverlayProvider>\n * );\n * }\n *\n * // 2. 在任意组件中使用\n * function AnyComponent() {\n * const openOverlay = useGlobalOverlay(MyOverlay);\n *\n * return (\n * <button onClick={() => openOverlay({ data: someData })}>\n * 打开全局覆盖层\n * </button>\n * );\n * }\n */\nexport function useGlobalOverlay<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n options?: UseOverlayOptions<T>,\n): OverlayOpener<T> {\n // 获取全局容器的注册/注销方法\n const context = useAntdOverlayContext();\n\n if (!context) {\n throw new Error(\n 'useGlobalOverlay must be used within an AntdOverlayProvider. ' +\n 'Please wrap your application with <AntdOverlayProvider>.'\n );\n }\n\n const { addHolder, removeHolder } = context;\n\n // 使用基础 useOverlay 获取功能\n const [openOverlay, contextHolder] = useOverlay<T>(OverlayComponent, options);\n\n // 将 contextHolder 注册到全局容器\n useEffect(() => {\n addHolder(contextHolder);\n // 清理函数:组件卸载时从全局容器移除\n return () => removeHolder(contextHolder);\n }, [contextHolder, addHolder, removeHolder]);\n\n // 仅返回 openOverlay,holder 已自动挂载\n return openOverlay;\n}\n\n// ============================================================================\n// 工厂函数\n// ============================================================================\n\n/**\n * 生成绑定了特定组件的 Hook 工厂函数\n *\n * 当某个覆盖层组件在多处使用时,可以使用此函数生成专用 Hook,\n * 避免每次使用都需要传入组件引用。\n *\n * @template T - 覆盖层组件的属性类型\n *\n * @param OverlayComponent - 覆盖层组件\n * @param defaultOptions - 默认配置选项,会与调用时的选项合并\n *\n * @returns 包含 useOverlay 和 useGlobalOverlay 的对象\n *\n * @example\n * // 创建专用 Hook\n * const {\n * useOverlay: useMyOverlay,\n * useGlobalOverlay: useGlobalMyOverlay,\n * } = generateUseOverlayHook(MyOverlayComponent, {\n * animation: true,\n * propsAdapter: myAdapter,\n * });\n *\n * // 使用专用 Hook(无需再传组件)\n * function SomeComponent() {\n * const openOverlay = useGlobalMyOverlay();\n * return <button onClick={() => openOverlay()}>打开</button>;\n * }\n */\nexport function generateUseOverlayHook<T extends CustomOverlayProps>(\n OverlayComponent: React.FC<T>,\n defaultOptions?: UseOverlayOptions<T>,\n) {\n return {\n /**\n * 绑定了特定组件的 useOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useOverlay: (options?: UseOverlayOptions<T>) =>\n useOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n\n /**\n * 绑定了特定组件的 useGlobalOverlay\n * @param options - 配置选项,会与 defaultOptions 合并\n */\n useGlobalOverlay: (options?: UseOverlayOptions<T>) =>\n useGlobalOverlay(OverlayComponent, { ...defaultOptions, ...options }),\n };\n}\n","/**\n * @file useModal - Ant Design Modal 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Modal 专用管理方案。\n * 提供命令式 API 来控制 Modal 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 visible 状态\n * - 支持动态更新 Modal 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterClose 回调)\n *\n * @example\n * // 基础用法\n * const [openModal, holder] = useModal(MyModal);\n *\n * // 全局用法\n * const openModal = useGlobalModal(MyModal);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalModal: useGlobalMyModal } = generateUseModalHook(MyModal);\n */\n\nimport { ModalProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport { useAntdOverlayContext, DefaultModalProps } from './AntdOverlayContext';\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Modal 组件的属性接口\n * 继承 Ant Design ModalProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyModal: React.FC<CustomModalProps<{ name: string }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Modal open={open} onCancel={customClose} onOk={() => customOk?.({ name: 'test' })}>\n * 内容\n * </Modal>\n * );\n * };\n */\nexport interface CustomModalProps<T = any, R = void> extends ModalProps, CustomOverlayProps<T, R> {}\n\n/**\n * useModal Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseModalOptions = Omit<\n UseOverlayOptions<CustomModalProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Modal 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterClose 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Modal 组件的属性类型\n * @param defaultProps - 默认 Modal 属性\n * @returns 属性适配器函数\n */\nconst createModalPropsAdapter = <T extends CustomModalProps>(\n defaultProps?: DefaultModalProps,\n) => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n ...defaultProps,\n ...props,\n open: state.open,\n customClose: state.onClose,\n // 在 Modal 关闭动画结束后触发,用于卸载组件\n afterClose: () => {\n props?.afterClose?.();\n state.onAnimationEnd();\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Modal\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Modal 管理 Hook\n *\n * @template T - Modal 组件的属性类型,必须继承 CustomModalProps\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openModal, contextHolder]\n * - openModal: 打开 Modal 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openModal, modalHolder] = useModal(ConfirmModal);\n *\n * const handleDelete = () => {\n * openModal({\n * title: '确认删除',\n * content: '删除后无法恢复',\n * });\n * };\n *\n * return (\n * <>\n * <button onClick={handleDelete}>删除</button>\n * {modalHolder}\n * </>\n * );\n * }\n */\nexport function useModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createModalPropsAdapter<T>(context?.defaultModalProps),\n [context?.defaultModalProps],\n );\n return useOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Modal 管理 Hook\n *\n * 与 useModal 的区别:\n * - 无需手动渲染 contextHolder\n * - Modal 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n * @param options - 配置选项\n *\n * @returns 打开 Modal 的函数\n *\n * @example\n * function DeleteButton() {\n * const openConfirm = useGlobalModal(ConfirmModal);\n *\n * return (\n * <button onClick={() => openConfirm({ title: '确认删除?' })}>\n * 删除\n * </button>\n * );\n * }\n */\nexport function useGlobalModal<T extends CustomModalProps>(\n ModalComponent: React.FC<T>,\n options?: UseModalOptions,\n): OverlayOpener<T> {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createModalPropsAdapter<T>(context?.defaultModalProps),\n [context?.defaultModalProps],\n );\n return useGlobalOverlay(ModalComponent, {\n ...options,\n keyPrefix: 'use-modal',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Modal 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Modal 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Modal 的默认配置\n *\n * @template T - Modal 组件的属性类型\n *\n * @param ModalComponent - Modal 组件\n *\n * @returns 包含 useModal 和 useGlobalModal 的对象\n *\n * @example\n * // 在 Modal 组件文件中导出专用 Hook\n * const ConfirmModal: React.FC<CustomModalProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useModal: useConfirmModal,\n * useGlobalModal: useGlobalConfirmModal,\n * } = generateUseModalHook(ConfirmModal);\n *\n * // 在其他组件中使用\n * function MyPage() {\n * const openConfirm = useGlobalConfirmModal();\n * return <button onClick={() => openConfirm()}>确认</button>;\n * }\n */\nexport function generateUseModalHook<T extends CustomModalProps>(ModalComponent: React.FC<T>) {\n return {\n useModal: (options?: UseModalOptions) => useModal(ModalComponent, options),\n useGlobalModal: (options?: UseModalOptions) => useGlobalModal(ModalComponent, options),\n };\n}\n\nexport default useModal;\n","/**\n * @file useDrawer - Ant Design Drawer 管理 Hook\n * @description\n * 基于 useOverlay 封装的 Drawer 专用管理方案。\n * 提供命令式 API 来控制 Drawer 的显示、隐藏和属性更新。\n *\n * 主要特性:\n * - 命令式调用,无需管理 open 状态\n * - 支持动态更新 Drawer 属性\n * - 支持全局挂载,跨组件调用\n * - 正确处理关闭动画(通过 afterOpenChange 回调)\n *\n * @example\n * // 基础用法\n * const [openDrawer, holder] = useDrawer(MyDrawer);\n *\n * // 全局用法\n * const openDrawer = useGlobalDrawer(MyDrawer);\n *\n * // 为特定组件生成专用 Hook\n * const { useGlobalDrawer: useGlobalMyDrawer } = generateUseDrawerHook(MyDrawer);\n */\n\nimport { DrawerProps } from 'antd';\nimport { useMemo } from 'react';\n\nimport { useAntdOverlayContext, DefaultDrawerProps } from './AntdOverlayContext';\nimport {\n CustomOverlayProps,\n OverlayOpener,\n useGlobalOverlay,\n useOverlay,\n UseOverlayOptions,\n} from './useOverlay';\n\n/**\n * 自定义 Drawer 组件的属性接口\n * 继承 Ant Design DrawerProps 并添加自定义属性\n *\n * @template T - customOk 回调的参数类型\n * @template R - customOk 回调的返回类型\n *\n * @example\n * const MyDrawer: React.FC<CustomDrawerProps<{ id: number }>> = ({\n * open,\n * customClose,\n * customOk,\n * }) => {\n * return (\n * <Drawer open={open} onClose={customClose}>\n * <Button onClick={() => customOk?.({ id: 1 })}>确认</Button>\n * </Drawer>\n * );\n * };\n */\nexport interface CustomDrawerProps<T = any, R = void>\n extends DrawerProps, CustomOverlayProps<T, R> {}\n\n/**\n * useDrawer Hook 的配置选项\n * 排除了 propsAdapter 和 keyPrefix,这些由内部自动处理\n */\nexport type UseDrawerOptions = Omit<\n UseOverlayOptions<CustomDrawerProps>,\n 'propsAdapter' | 'keyPrefix'\n>;\n\n/**\n * 创建 Drawer 专用的属性适配器\n *\n * 主要职责:\n * 1. 注入 open 和 customClose\n * 2. 包装 afterOpenChange 以处理动画结束\n * 3. 包装 customOk 以实现自动关闭\n *\n * @template T - Drawer 组件的属性类型\n * @param defaultProps - 默认 Drawer 属性\n * @returns 属性适配器函数\n */\nconst createDrawerPropsAdapter = <T extends CustomDrawerProps>(\n defaultProps?: DefaultDrawerProps,\n) => {\n return (\n props: Omit<T, 'customClose'> | undefined,\n state: { open: boolean; onClose: () => void; onAnimationEnd: () => void },\n ): T => {\n const result = {\n ...defaultProps,\n ...props,\n open: state.open,\n customClose: state.onClose,\n // Drawer 的动画回调,打开和关闭时都会触发\n afterOpenChange: (open: boolean) => {\n props?.afterOpenChange?.(open);\n // 仅在关闭动画结束时触发卸载\n if (!open) {\n state.onAnimationEnd();\n }\n },\n } as unknown as T;\n\n // 包装 customOk,调用后自动关闭 Drawer\n if (result.customOk) {\n const originalCustomOk = result?.customOk;\n result.customOk = ((value: unknown) => {\n originalCustomOk?.(value);\n state.onClose();\n }) as T['customOk'];\n }\n\n return result;\n };\n};\n\n/**\n * Drawer 管理 Hook\n *\n * @template T - Drawer 组件的属性类型,必须继承 CustomDrawerProps\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 元组 [openDrawer, contextHolder]\n * - openDrawer: 打开 Drawer 的函数\n * - contextHolder: 需要渲染到组件树中的 React 节点\n *\n * @example\n * function MyPage() {\n * const [openDrawer, drawerHolder] = useDrawer(UserDetailDrawer);\n *\n * const handleViewUser = (userId: number) => {\n * openDrawer({ userId, title: '用户详情' });\n * };\n *\n * return (\n * <>\n * <button onClick={() => handleViewUser(1)}>查看用户</button>\n * {drawerHolder}\n * </>\n * );\n * }\n */\nexport function useDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): [OverlayOpener<T>, React.ReactNode] {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createDrawerPropsAdapter<T>(context?.defaultDrawerProps),\n [context?.defaultDrawerProps],\n );\n return useOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 全局 Drawer 管理 Hook\n *\n * 与 useDrawer 的区别:\n * - 无需手动渲染 contextHolder\n * - Drawer 会自动挂载到全局容器\n * - 适合需要跨组件调用的场景\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n * @param options - 配置选项\n *\n * @returns 打开 Drawer 的函数\n *\n * @example\n * function UserCard({ userId }: { userId: number }) {\n * const openDetail = useGlobalDrawer(UserDetailDrawer);\n *\n * return (\n * <Card onClick={() => openDetail({ userId })}>\n * 查看详情\n * </Card>\n * );\n * }\n */\nexport function useGlobalDrawer<T extends CustomDrawerProps>(\n DrawerComponent: React.FC<T>,\n options?: UseDrawerOptions,\n): OverlayOpener<T> {\n const context = useAntdOverlayContext();\n const propsAdapter = useMemo(\n () => createDrawerPropsAdapter<T>(context?.defaultDrawerProps),\n [context?.defaultDrawerProps],\n );\n return useGlobalOverlay(DrawerComponent, {\n ...options,\n keyPrefix: 'use-drawer',\n propsAdapter,\n });\n}\n\n/**\n * 生成绑定了特定 Drawer 组件的 Hook 工厂函数\n *\n * 适用场景:\n * - 某个 Drawer 在多处使用\n * - 希望简化调用代码\n * - 需要统一管理某个 Drawer 的默认配置\n *\n * @template T - Drawer 组件的属性类型\n *\n * @param DrawerComponent - Drawer 组件\n *\n * @returns 包含 useDrawer 和 useGlobalDrawer 的对象\n *\n * @example\n * // 在 Drawer 组件文件中导出专用 Hook\n * const ProjectMemberDrawer: React.FC<CustomDrawerProps> = (props) => {\n * // ...\n * };\n *\n * export const {\n * useDrawer: useProjectMemberDrawer,\n * useGlobalDrawer: useGlobalProjectMemberDrawer,\n * } = generateUseDrawerHook(ProjectMemberDrawer);\n *\n * // 在其他组件中使用\n * function ProjectPage() {\n * const openMemberDrawer = useGlobalProjectMemberDrawer();\n * return <button onClick={() => openMemberDrawer()}>管理成员</button>;\n * }\n */\nexport function generateUseDrawerHook<T extends CustomDrawerProps>(DrawerComponent: React.FC<T>) {\n return {\n useDrawer: (options?: UseDrawerOptions) => useDrawer(DrawerComponent, options),\n useGlobalDrawer: (options?: UseDrawerOptions) => useGlobalDrawer(DrawerComponent, options),\n };\n}\n\nexport default useDrawer;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antd-overlay",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Ant Design Modal/Drawer 命令式调用方案",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -8,14 +8,9 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
"require": {
|
|
16
|
-
"types": "./dist/index.d.cts",
|
|
17
|
-
"default": "./dist/index.cjs"
|
|
18
|
-
}
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
19
14
|
}
|
|
20
15
|
},
|
|
21
16
|
"files": [
|
|
@@ -36,6 +31,9 @@
|
|
|
36
31
|
"type": "git",
|
|
37
32
|
"url": "https://github.com/RaineySpace/antd-overlay"
|
|
38
33
|
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"registry": "https://registry.npmjs.org"
|
|
36
|
+
},
|
|
39
37
|
"peerDependencies": {
|
|
40
38
|
"antd": ">=5.0.0",
|
|
41
39
|
"react": ">=18.0.0"
|
|
@@ -44,7 +42,7 @@
|
|
|
44
42
|
"@changesets/cli": "^2.27.10",
|
|
45
43
|
"@eslint/js": "^9.17.0",
|
|
46
44
|
"@types/react": "^19.2.7",
|
|
47
|
-
"antd": "^6.
|
|
45
|
+
"antd": "^6.2.2",
|
|
48
46
|
"eslint": "^9.17.0",
|
|
49
47
|
"eslint-config-prettier": "^10.0.1",
|
|
50
48
|
"eslint-plugin-react-hooks": "^5.1.0",
|