feat(overlays): add managed overlay package
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: 生命周期与路由拦截
|
||||
description: 理解结果、队列、Host 生命周期以及路由库适配。
|
||||
order: 20
|
||||
toc:
|
||||
- id: result-contracts
|
||||
title: 结果约定
|
||||
- id: queue
|
||||
title: 队列与 Host
|
||||
- id: dismissal
|
||||
title: 关闭行为
|
||||
- id: navigation
|
||||
title: 路由拦截
|
||||
---
|
||||
|
||||
## 结果约定 {#result-contracts}
|
||||
|
||||
`openConfirm` 使用 `false` 表示取消,`openPrompt` 使用 `null`,自定义 Modal、Sheet 和 Drawer 使用 `undefined` 表示没有结果。`close(value)` 会根据 `openModal<Result>()` 的泛型检查结果。
|
||||
|
||||
```tsx
|
||||
import { openModal } from "@workspace/overlays/modal"
|
||||
|
||||
const productId = await openModal<string>({
|
||||
title: "选择产品",
|
||||
content: ({ close }) => (
|
||||
<ProductPicker onSelect={(product) => close(product.id)} />
|
||||
),
|
||||
})
|
||||
```
|
||||
|
||||
## 队列与 Host {#queue}
|
||||
|
||||
同一个 Scope 中,每种 feature 都有一个按需创建的 channel 和 Base UI handle。同类调用进入 FIFO 队列,前一个关闭动画结束后才显示下一个。不同 feature 可以同时显示,例如 Modal 内可以继续打开 Confirm。
|
||||
|
||||
Host 卸载时会用取消值结算它仍在等待的请求。React Strict Mode 的模拟卸载不会错误取消请求。
|
||||
|
||||
## 关闭行为 {#dismissal}
|
||||
|
||||
自定义内容可以调用 `dismiss()`。关闭按钮、Escape 和遮罩点击也进入取消路径。设置 `dismissible: false` 会阻止外部关闭,但内容仍可以显式调用 `close(result)` 或 `dismiss()`。
|
||||
|
||||
## 路由拦截 {#navigation}
|
||||
|
||||
`@workspace/overlays/navigation` 只依赖 Scope,不依赖具体 overlay feature 或路由库:
|
||||
|
||||
```tsx
|
||||
import { OverlayNavigationGuard } from "@workspace/overlays/navigation"
|
||||
|
||||
const adapter: OverlayNavigationAdapter = {
|
||||
subscribe(listener) {
|
||||
return router.block((transition) => {
|
||||
listener({
|
||||
cancel: transition.reset,
|
||||
proceed: transition.retry,
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
<OverlayNavigationGuard adapter={adapter} />
|
||||
```
|
||||
|
||||
默认 Guard 检查当前和命名局部 Scope,找到最后打开的浮层。如果允许 dismiss,则关闭浮层并取消跳转;`dismissible: false` 会保留浮层并继续阻止跳转;没有浮层时才调用 `proceed()`。
|
||||
|
||||
适配器的 `proceed()` 必须继续已经被阻塞的同一次跳转,不能重新发起一个会再次触发 blocker 的导航。需要不同策略时,可以传入自定义 `interceptor`。
|
||||
Reference in New Issue
Block a user