Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/src/pages/en/docs/more/_meta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ export default {
'open-outside-react': {
title: 'Opening Overlays Outside React',
},
'with-design-systems': {
title: 'With Design Systems',
},
};
11 changes: 11 additions & 0 deletions docs/src/pages/en/docs/more/with-design-systems/_meta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default {
mui: {
title: 'Material UI',
},
'chakra-ui': {
title: 'Chakra UI',
},
'ant-design': {
title: 'Ant Design',
},
};
156 changes: 156 additions & 0 deletions docs/src/pages/en/docs/more/with-design-systems/ant-design.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { Sandpack } from '@/components';

# With Ant Design

Learn how to use Ant Design's `Modal` component together with `overlay-kit`.

## Installation

Install the `antd` package.

```sh npm2yarn filename="shell" copy
npm install overlay-kit antd
```

## Basic Usage

Ant Design `Modal` uses an `open` prop for visibility plus `onCancel` / `onOk` handlers. Passing `close` to both handlers lets `overlay-kit` manage the state.

<br />

<Sandpack dependencies={{ antd: '^5.22.0' }}>

```tsx Example.tsx active
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, Modal } from 'antd';

function App() {
return (
<Button
type="primary"
onClick={() => {
overlay.open(({ isOpen, close }) => (
<Modal
title="Are you sure you want to continue?"
open={isOpen}
onCancel={close}
onOk={close}
cancelText="No"
okText="Yes"
/>
));
}}
>
Open Confirm Dialog
</Button>
);
}

export function Example() {
return (
<OverlayProvider>
<App />
</OverlayProvider>
);
}
```

</Sandpack>

## Receiving Async Results

With `overlay.openAsync`, you can tell whether the user pressed "OK" or "Cancel" through the resolved `Promise`.

<br />

<Sandpack dependencies={{ antd: '^5.22.0' }}>

```tsx Example.tsx active
import { useState } from 'react';
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, Modal } from 'antd';

function App() {
const [result, setResult] = useState<boolean | null>(null);

return (
<div>
<p>Result: {result === null ? 'Not selected' : result ? 'Yes' : 'No'}</p>
<Button
type="primary"
onClick={async () => {
const confirmed = await overlay.openAsync<boolean>(({ isOpen, close }) => (
<Modal
title="Are you sure you want to continue?"
open={isOpen}
onCancel={() => close(false)}
onOk={() => close(true)}
cancelText="No"
okText="Yes"
/>
));
setResult(confirmed);
}}
>
Open Confirm Dialog
</Button>
</div>
);
}

export function Example() {
return (
<OverlayProvider>
<App />
</OverlayProvider>
);
}
```

</Sandpack>

## Releasing Memory After Animation

Ant Design `Modal` fires an `afterClose` callback once the close animation completes. Passing `unmount` there keeps the animation visible while safely releasing overlay memory.

<br />

<Sandpack dependencies={{ antd: '^5.22.0' }}>

```tsx Example.tsx active
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, Modal } from 'antd';

function App() {
return (
<Button
type="primary"
onClick={() => {
overlay.open(({ isOpen, close, unmount }) => (
<Modal
title="Are you sure you want to continue?"
open={isOpen}
onCancel={close}
onOk={close}
afterClose={unmount}
cancelText="No"
okText="Yes"
/>
));
}}
>
Open Confirm Dialog
</Button>
);
}

export function Example() {
return (
<OverlayProvider>
<App />
</OverlayProvider>
);
}
```

</Sandpack>
206 changes: 206 additions & 0 deletions docs/src/pages/en/docs/more/with-design-systems/chakra-ui.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import { Sandpack } from '@/components';

# With Chakra UI

Learn how to use Chakra UI v3's `Dialog` component together with `overlay-kit`.

## Installation

Chakra UI v3 only needs `@emotion/react` (unlike v2, you no longer need `@emotion/styled` or `framer-motion`).

```sh npm2yarn filename="shell" copy
npm install overlay-kit @chakra-ui/react @emotion/react
```

## Basic Usage

Chakra v3's `Dialog.Root` uses `open` and `onOpenChange`. Since `onOpenChange` receives a `{ open: boolean }` object, calling `close()` whenever `!e.open` handles backdrop clicks and ESC dismissal automatically. Wrap the app root in `ChakraProvider value={defaultSystem}`.

<br />

<Sandpack dependencies={{ '@chakra-ui/react': '^3.2.0' }}>

```tsx Example.tsx active
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, ChakraProvider, Dialog, Portal, defaultSystem } from '@chakra-ui/react';

function App() {
return (
<Button
colorPalette="blue"
onClick={() => {
overlay.open(({ isOpen, close }) => (
<Dialog.Root open={isOpen} onOpenChange={(e) => !e.open && close()}>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Are you sure you want to continue?</Dialog.Title>
</Dialog.Header>
<Dialog.Footer gap={2}>
<Button variant="outline" onClick={close}>
No
</Button>
<Button colorPalette="blue" onClick={close}>
Yes
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
));
}}
>
Open Confirm Dialog
</Button>
);
}

export function Example() {
return (
<ChakraProvider value={defaultSystem}>
<OverlayProvider>
<App />
</OverlayProvider>
</ChakraProvider>
);
}
```

</Sandpack>

## Receiving Async Results

Use `overlay.openAsync` to capture the user's choice as a `Promise`. Each button passes its own value through `close(value)`.

<br />

<Sandpack dependencies={{ '@chakra-ui/react': '^3.2.0' }}>

```tsx Example.tsx active
import { useState } from 'react';
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, ChakraProvider, Dialog, Portal, defaultSystem } from '@chakra-ui/react';

function App() {
const [result, setResult] = useState<boolean | null>(null);

return (
<div>
<p>Result: {result === null ? 'Not selected' : result ? 'Yes' : 'No'}</p>
<Button
colorPalette="blue"
onClick={async () => {
const confirmed = await overlay.openAsync<boolean>(({ isOpen, close }) => (
<Dialog.Root open={isOpen} onOpenChange={(e) => !e.open && close(false)}>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Are you sure you want to continue?</Dialog.Title>
</Dialog.Header>
<Dialog.Footer gap={2}>
<Button variant="outline" onClick={() => close(false)}>
No
</Button>
<Button colorPalette="blue" onClick={() => close(true)}>
Yes
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
));
setResult(confirmed);
}}
>
Open Confirm Dialog
</Button>
</div>
);
}

export function Example() {
return (
<ChakraProvider value={defaultSystem}>
<OverlayProvider>
<App />
</OverlayProvider>
</ChakraProvider>
);
}
```

</Sandpack>

## Releasing Memory After Animation

Unlike MUI's `onExited` or Ant Design's `afterClose`, Chakra v3 `Dialog` doesn't expose a dedicated animation-complete callback. The simplest approach is to call `close()` inside `onOpenChange` and schedule `unmount` with `setTimeout` matching the animation duration. This covers button clicks, backdrop clicks, and ESC dismissal uniformly.

<br />

<Sandpack dependencies={{ '@chakra-ui/react': '^3.2.0' }}>

```tsx Example.tsx active
import { OverlayProvider, overlay } from 'overlay-kit';
import { Button, ChakraProvider, Dialog, Portal, defaultSystem } from '@chakra-ui/react';

function App() {
return (
<Button
colorPalette="blue"
onClick={() => {
overlay.open(({ isOpen, close, unmount }) => (
<Dialog.Root
open={isOpen}
onOpenChange={(e) => {
if (!e.open) {
close();
// Chakra v3's scale animation takes ~200ms.
setTimeout(unmount, 200);
}
}}
>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Are you sure you want to continue?</Dialog.Title>
</Dialog.Header>
<Dialog.Footer gap={2}>
<Button variant="outline" onClick={close}>
No
</Button>
<Button colorPalette="blue" onClick={close}>
Yes
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
));
}}
>
Open Confirm Dialog
</Button>
);
}

export function Example() {
return (
<ChakraProvider value={defaultSystem}>
<OverlayProvider>
<App />
</OverlayProvider>
</ChakraProvider>
);
}
```

</Sandpack>
Loading
Loading