@ahmiao666/ahmiao-react-dialog-element
v1.0.0
Published
react18+ dialog组件
Maintainers
Readme
🎉 ahmiao React18 Dialog
高性能React18 Dialog组件,支持完整的性能控制和诊断功能。
🚀 安装
npm install @ahmiao666/ahmiao-react-dialog-element📖 快速开始
# amDialogCustom 弹窗组件使用说明 仅支持React18+ 因为底层订阅使用了 useSyncExternalStore
## 基本使用
### 使用之前需要先把提供者组件 DialogCustomProvider 挂在到 app 里
```tsx
// 在应用根组件中挂载一次
import { DialogCustomProvider } from '@ahmiao666/ahmiao-react-dialog-element'
import '@ahmiao666/ahmiao-react-dialog-element/index.css'
function AppRoot() {
return (
<>
{/* 你的 App */}
<DialogCustomProvider />
</>
)
}import { DialogCustomStaticMethods } from '@ahmiao666/ahmiao-react-dialog-element'
// 方式1: await 方式
const result = await DialogCustomStaticMethods.open(
({ onClose }) => (
<div>
<p>确定要删除吗?</p>
<button onClick={() => onClose(true)}>确定</button>
<button onClick={() => onClose(false)}>取消</button>
</div>
),
{
title: "确认删除",
width: 400
}
)
if (result) {
console.log('用户确认删除')
}
// 方式2: .then() 方式
DialogCustomStaticMethods.open(
({ onClose }) => (
<div>
<p>确定要删除吗?</p>
<button onClick={() => onClose(true)}>确定</button>
<button onClick={() => onClose(false)}>取消</button>
</div>
),
{
title: "确认删除",
width: 400
}
).then(result => {
if (result) {
console.log('用户确认删除')
}
}).catch(() => {
console.log('弹窗被取消')
})配置选项
DialogCustomStaticMethods.open(Component, {
title: '弹窗标题', // 标题文本
width: 500, // 宽度:number=vw,string=任意CSS宽度
showIcon: true, // 是否显示标题图标
showClose: true, // 是否显示关闭按钮
icon: '📣', // 自定义标题图标(可选)
maskClosable: true, // 点击遮罩是否可关闭
maskBg: 'rgba(0,0,0,0.6)', // 遮罩背景色(仅颜色)
familyName: 'settings', // 弹窗命名空间(用于多弹窗并存)
onNext: (v) => {}, // 可选的下一步回调(会传给内容组件)
props: { data: '数据' } // 传递给内容组件的自定义 props
})遮罩与样式
- 仅支持通过
maskBg修改遮罩颜色,默认值:rgba(0, 0, 0, 0.4)。 - 当同时打开多个弹窗时,遮罩只渲染一次,颜色取“最上层弹窗”的
maskBg。
DialogCustomStaticMethods.open(Comp, {
maskBg: 'rgba(0,0,0,0.6)'
})多弹窗
// 打开多个弹窗
DialogCustomStaticMethods.openWithFamily("settings", SettingsComponent)
DialogCustomStaticMethods.openWithFamily("profile", ProfileComponent)
// 或者通过 options.familyName 指定
DialogCustomStaticMethods.open(SettingsComponent, { familyName: 'settings' })
DialogCustomStaticMethods.open(ProfileComponent, { familyName: 'profile' })
// 关闭指定弹窗
DialogCustomStaticMethods.close("settings")
// 关闭所有弹窗
DialogCustomStaticMethods.closeAll()回调方式
方式1: onClose回调
const result = await DialogCustomStaticMethods.open(
({ onClose }) => (
<div>
<button onClick={() => onClose("保存")}>保存</button>
<button onClick={() => onClose(null)}>取消</button>
</div>
)
)
// result = "保存" 或 null方式2: props回调
const handleSave = (data) => console.log("保存:", data)
await DialogCustomStaticMethods.open(
({ onSave, onClose }) => (
<div>
<button onClick={() => onSave("数据")}>保存</button>
<button onClick={() => onClose()}>关闭</button>
</div>
),
{
props: { onSave: handleSave }
}
)状态读取与订阅
这些 Hook/方法用于“读取弹窗状态”。推荐优先使用只读选择器,避免直接接触底层 Map。
useHasOpenDialog
是否存在任意弹窗打开(订阅式)。
import { useHasOpenDialog } from '@/am-ui/am-dialog'
export function Header() {
const hasOpen = useHasOpenDialog()
return hasOpen ? null : <TopBar />
}useFamilyVisible
指定 family 是否打开(订阅式)。
import { useFamilyVisible } from '@/am-ui/am-dialog'
const profileOpen = useFamilyVisible('profile')useDialogSelector
通用选择器 Hook:订阅式返回派生值,避免暴露底层 Map。
import { useDialogSelector } from '@/am-ui/am-dialog'
// 打开中的 family 列表
const openFamilies = useDialogSelector((states) =>
Array.from(states.entries())
.filter(([, s]) => s.visible)
.map(([family]) => family),
)
// 顶层弹窗标题(示例)
const topTitle = useDialogSelector((states) => {
const visible = Array.from(states.values()).filter((s) => s.visible && s.options)
const top = visible[visible.length - 1]
return top?.options?.title ?? ''
})getDialogFrozenSnapshot
一次性只读快照(非订阅)。适合在非 React 或初始化时读取。
import { getDialogFrozenSnapshot } from '@/am-ui/am-dialog'
const snap = getDialogFrozenSnapshot()
for (const [family, state] of snap) {
console.log(family, state.visible, state.options?.title)
}subscribeHasOpen
非 React 环境订阅“是否有弹窗打开”的变化(会立即回调一次当前值)。
import { subscribeHasOpen } from '@/am-ui/am-dialog'
const unsubscribe = subscribeHasOpen((hasOpen) => {
console.log('hasOpen changed:', hasOpen)
})
// 需要时机合适地取消订阅
unsubscribe()写操作请始终使用现有 API:
DialogCustomStaticMethods.open/openWithFamily/close/closeAll或内容组件内的onClose/onNext,不要直接修改底层 Map。
## 🔗 相关链接
- [完整文档](https://github.com/ahmiao666/ahmiao-react-dialog-element)
- [GitHub仓库](https://github.com/ahmiao666/ahmiao-react-dialog-element)