137 lines
3.4 KiB
Plaintext
137 lines
3.4 KiB
Plaintext
|
|
---
|
|||
|
|
title: 安装与基础交互
|
|||
|
|
description: 按需挂载原子 Host,并使用全局或局部 Scope 打开浮层。
|
|||
|
|
order: 10
|
|||
|
|
toc:
|
|||
|
|
- id: atomic-hosts
|
|||
|
|
title: 原子 Host
|
|||
|
|
- id: global-scope
|
|||
|
|
title: 默认全局 Scope
|
|||
|
|
- id: local-scopes
|
|||
|
|
title: 局部和命名局部
|
|||
|
|
- id: message-overlays
|
|||
|
|
title: 消息类浮层
|
|||
|
|
- id: toast
|
|||
|
|
title: Toast
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 原子 Host {#atomic-hosts}
|
|||
|
|
|
|||
|
|
在应用样式入口导入 Tailwind source:
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
@import "@workspace/overlays/globals.css";
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
只挂载应用实际使用的 Host。下面的应用不会引入 Sheet、Drawer 或 Toast:
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { AlertHost } from "@workspace/overlays/alert"
|
|||
|
|
import { ConfirmHost } from "@workspace/overlays/confirm"
|
|||
|
|
import { ModalHost } from "@workspace/overlays/modal"
|
|||
|
|
|
|||
|
|
export function Root({ children }: { children: React.ReactNode }) {
|
|||
|
|
return (
|
|||
|
|
<>
|
|||
|
|
{children}
|
|||
|
|
<AlertHost />
|
|||
|
|
<ConfirmHost />
|
|||
|
|
<ModalHost />
|
|||
|
|
</>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
确定会使用全部能力的应用也可以从 `@workspace/overlays/all` 导入便捷的 `OverlayHost`。它会主动引入所有 feature,因此不是默认推荐方式。
|
|||
|
|
|
|||
|
|
## 默认全局 Scope {#global-scope}
|
|||
|
|
|
|||
|
|
`openXxx()` 和没有 `scope` prop 的 Host 默认使用 `globalOverlayScope`。调用方不需要 React Context:
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { openAlert } from "@workspace/overlays/alert"
|
|||
|
|
|
|||
|
|
await openAlert({
|
|||
|
|
title: "导出完成",
|
|||
|
|
description: "文件已经可以下载。",
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
应用仍需挂载对应的 `AlertHost`。打开请求可以发生在 Host 挂载之前,Base UI handle 会在 Host 出现后渲染它。
|
|||
|
|
|
|||
|
|
## 局部和命名局部 {#local-scopes}
|
|||
|
|
|
|||
|
|
Scope 是实际对象,不使用全局字符串注册表:
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import {
|
|||
|
|
createOverlayScope,
|
|||
|
|
OverlayScopeProvider,
|
|||
|
|
useOverlayScope,
|
|||
|
|
} from "@workspace/overlays"
|
|||
|
|
import { ModalHost, openModal } from "@workspace/overlays/modal"
|
|||
|
|
|
|||
|
|
const editorScope = createOverlayScope({ name: "editor" })
|
|||
|
|
const pickerScope = createOverlayScope({ name: "picker" })
|
|||
|
|
|
|||
|
|
function EditorRoot({ children }: { children: React.ReactNode }) {
|
|||
|
|
return (
|
|||
|
|
<OverlayScopeProvider scope={editorScope} scopes={{ picker: pickerScope }}>
|
|||
|
|
{children}
|
|||
|
|
<ModalHost />
|
|||
|
|
<ModalHost scope={pickerScope} />
|
|||
|
|
</OverlayScopeProvider>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function OpenPickerButton() {
|
|||
|
|
const scope = useOverlayScope("picker")
|
|||
|
|
return (
|
|||
|
|
<button
|
|||
|
|
onClick={() =>
|
|||
|
|
openModal({ scope, title: "选择资源", content: <AssetPicker /> })
|
|||
|
|
}
|
|||
|
|
>
|
|||
|
|
选择资源
|
|||
|
|
</button>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`<OverlayScopeProvider name="editor">` 可以自动创建一个局部 Scope。非 React 模块应保存并显式传递 `createOverlayScope()` 返回的对象。
|
|||
|
|
|
|||
|
|
## 消息类浮层 {#message-overlays}
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { openConfirm } from "@workspace/overlays/confirm"
|
|||
|
|
|
|||
|
|
async function removeProject() {
|
|||
|
|
const accepted = await openConfirm({
|
|||
|
|
title: "删除项目?",
|
|||
|
|
description: "此操作无法撤销。",
|
|||
|
|
destructive: true,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (accepted) await deleteProject()
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`openAlert()` 返回 `Promise<void>`;`openConfirm()` 返回布尔值;`openPrompt()` 返回字符串,并在取消时返回 `null`。
|
|||
|
|
|
|||
|
|
## Toast {#toast}
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import { dismissToast, openToast, updateToast } from "@workspace/overlays/toast"
|
|||
|
|
|
|||
|
|
const id = openToast({
|
|||
|
|
title: "保存成功",
|
|||
|
|
description: "修改已经同步。",
|
|||
|
|
type: "success",
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
updateToast(id, { description: "所有设备均已同步。" })
|
|||
|
|
dismissToast({ id })
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Toast 同样按 Scope 隔离,并由对应的 `ToastHost` 渲染。
|