137 lines
3.6 KiB
Plaintext
137 lines
3.6 KiB
Plaintext
---
|
|
title: Setup and basic interactions
|
|
description: Mount atomic Hosts on demand and open overlays in global or local scopes.
|
|
order: 10
|
|
toc:
|
|
- id: atomic-hosts
|
|
title: Atomic Hosts
|
|
- id: global-scope
|
|
title: Default global scope
|
|
- id: local-scopes
|
|
title: Local and named scopes
|
|
- id: message-overlays
|
|
title: Message overlays
|
|
- id: toast
|
|
title: Toast
|
|
---
|
|
|
|
## Atomic Hosts {#atomic-hosts}
|
|
|
|
Import the Tailwind source from the application stylesheet:
|
|
|
|
```css
|
|
@import "@workspace/overlays/globals.css";
|
|
```
|
|
|
|
Mount only the Hosts used by the application. This application does not import Sheet, Drawer, or 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 />
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
Applications that intentionally use every feature may import the convenience `OverlayHost` from `@workspace/overlays/all`. It eagerly imports every feature and is therefore not the default recommendation.
|
|
|
|
## Default global scope {#global-scope}
|
|
|
|
`openXxx()` functions and Hosts without a `scope` prop use `globalOverlayScope`. The caller does not need React context:
|
|
|
|
```tsx
|
|
import { openAlert } from "@workspace/overlays/alert"
|
|
|
|
await openAlert({
|
|
title: "Export complete",
|
|
description: "The file is ready to download.",
|
|
})
|
|
```
|
|
|
|
The application must still mount the matching `AlertHost`. A request may be opened before its Host mounts; the Base UI handle renders it when the Host appears.
|
|
|
|
## Local and named scopes {#local-scopes}
|
|
|
|
Scopes are real objects rather than names in a global registry:
|
|
|
|
```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: "Choose an asset", content: <AssetPicker /> })
|
|
}
|
|
>
|
|
Choose an asset
|
|
</button>
|
|
)
|
|
}
|
|
```
|
|
|
|
`<OverlayScopeProvider name="editor">` can create a local scope automatically. Non-React modules should retain and explicitly pass the object returned by `createOverlayScope()`.
|
|
|
|
## Message overlays {#message-overlays}
|
|
|
|
```tsx
|
|
import { openConfirm } from "@workspace/overlays/confirm"
|
|
|
|
async function removeProject() {
|
|
const accepted = await openConfirm({
|
|
title: "Delete project?",
|
|
description: "This action cannot be undone.",
|
|
destructive: true,
|
|
})
|
|
|
|
if (accepted) await deleteProject()
|
|
}
|
|
```
|
|
|
|
`openAlert()` returns `Promise<void>`, `openConfirm()` returns a boolean, and `openPrompt()` returns a string or `null` after cancellation.
|
|
|
|
## Toast {#toast}
|
|
|
|
```tsx
|
|
import { dismissToast, openToast, updateToast } from "@workspace/overlays/toast"
|
|
|
|
const id = openToast({
|
|
title: "Saved",
|
|
description: "Your changes are synchronized.",
|
|
type: "success",
|
|
})
|
|
|
|
updateToast(id, { description: "All devices are synchronized." })
|
|
dismissToast({ id })
|
|
```
|
|
|
|
Toast is also isolated by Scope and rendered by the matching `ToastHost`.
|