-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: Fix typo * docs: Update en document
- Loading branch information
Showing
25 changed files
with
682 additions
and
432 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Assigning custom id | ||
|
||
You can inject a custom `overlayId` by specifying a `string`. | ||
|
||
```tsx | ||
function Demo() { | ||
const openDialog = () => { | ||
overlay.open( | ||
({ isOpen, close, unmount }) => { | ||
return <Dialog open={isOpen} onClose={close} onExit={unmount} />; | ||
}, | ||
{ overlayId: 'customId' } | ||
); | ||
}; | ||
|
||
return <Button onClick={openDialog}>Open dialog</Button>; | ||
} | ||
``` | ||
|
||
::: warning Caution | ||
|
||
overlay-kit uses `overlayId` as the `key` for the component. Ensure that the custom ID is unique to avoid conflicts. | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Opening Outside of React | ||
|
||
With overlay-kit, you can open overlays even outside of React. | ||
|
||
For example, if you want to open an overlay when an API error occurs, you can write the code as follows. If the status code is 400 or above, the `<ErrorDialog />` overlay will be rendered. | ||
|
||
```tsx{8-12} | ||
import ky from 'ky'; | ||
import { overlay } from 'overlay-kit'; | ||
const api = ky.extend({ | ||
hooks: { | ||
afterResponse: [ | ||
(_, __, response) => { | ||
if (response.status >= 400) { | ||
overlay.open(({ isOpen, close }) => ( | ||
<ErrorDialog open={isOpen} onClose={close} /> | ||
)); | ||
} | ||
}, | ||
], | ||
}, | ||
}); | ||
``` | ||
|
||
In addition to API errors, you can freely use overlays in various situations such as user authentication failures or system warnings. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Using with Promise | ||
|
||
Using overlay-kit with Promises is straightforward. Even for complex use cases linked with overlays, you can handle the results directly from the overlay without needing to define multiple states or create complex callback structures. | ||
|
||
There are two ways to use overlays with Promises in overlay-kit: the basic method using `new Promise`, and using the built-in [`overlay.openAsync()`](../reference/overlay.md#overlay-openasync) method provided by overlay-kit. | ||
|
||
Let's look at both methods with example code that renders a `<Dialog />` and processes the result provided by the user. | ||
|
||
## 1. Using `new Promise` | ||
|
||
The basic method involves using JavaScript's built-in Promise object to handle the overlay's result. With `new Promise`, you can receive the resolved value when the overlay is closed and perform subsequent actions. It's similar to using the DOM API's [confirm()](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm), where you handle the user's choice. | ||
|
||
```tsx | ||
const result = await new Promise<boolean>(resolve => { | ||
overlay.open(({ isOpen, close }) => { | ||
return ( | ||
<Dialog open={isOpen} onClose={() => close(false)}> | ||
<DialogTitle> | ||
Do you want to proceed? | ||
</DialogTitle> | ||
<DialogActions> | ||
<Button onClick={() => { | ||
resolve(true); | ||
close(); | ||
}}>Yes</Button> | ||
<Button onClick={() => { | ||
resolve(false); | ||
close(); | ||
}}>No</Button> | ||
</DialogActions> | ||
</Dialog> | ||
); | ||
}); | ||
}); | ||
|
||
if (result) { | ||
// Handle the case when the user clicked "Yes" | ||
} else { | ||
// Handle the case when the user clicked "No" | ||
} | ||
``` | ||
|
||
## 2. `overlay.openAsync()` 사용하기 | ||
|
||
For a simpler way to use overlays with Promises, you can use [`overlay.openAsync()`](../reference/overlay.md#overlay-openasync). | ||
|
||
[`overlay.openAsync()`](../reference/overlay.md#overlay-openasync) works similarly to [`overlay.open()`](../reference/overlay.md#overlay-open) but returns a Promise, allowing you to pass a resolve value from [`overlay.close()`](../reference/overlay.md#overlay-close). | ||
|
||
```tsx | ||
const result = await overlay.openAsync<boolean>(({ isOpen, close }) => { | ||
const agree = () => close(true); | ||
const cancel = () => close(false); | ||
|
||
return ( | ||
<Dialog open={isOpen} onClose={cancel}> | ||
<DialogTitle> | ||
Do you want to proceed? | ||
</DialogTitle> | ||
<DialogActions> | ||
<Button onClick={agree}>Yes</Button> | ||
<Button onClick={cancel}>No</Button> | ||
</DialogActions> | ||
</Dialog> | ||
); | ||
}); | ||
|
||
if (result) { | ||
// Handle the case when the user clicked "Yes" | ||
} else { | ||
// Handle the case when the user clicked "No" | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Unmount with animation | ||
|
||
Most overlays have animation effects when closing. In overlay-kit, overlays remain mounted even after they are closed to allow animations to continue. **However, to avoid memory leaks, you must unmount the overlay after the closing animation has finished.** | ||
|
||
To ensure smooth operation, you can completely unmount the component after the closing animation is done. | ||
|
||
## Using the `onExit` Prop | ||
|
||
By implementing the `onExit` prop, which indicates that the overlay's closing animation has ended, you can remove the overlay after the animation finishes. Let's look at an example. | ||
|
||
In the following code, the `<Dialog />` component uses the `onExit` prop to call the `unmount` function after the animation finishes. | ||
|
||
```tsx{6} | ||
import { overlay } from 'overlay-kit'; | ||
function Demo() { | ||
const openDialog = () => { | ||
overlay.open(({ isOpen, close, unmount }) => { | ||
return <Dialog open={isOpen} onClose={close} onExit={unmount} /> | ||
}); | ||
}; | ||
return <Button onClick={openDialog}>Open dialog</Button>; | ||
} | ||
``` | ||
|
||
## Using `setTimeout` | ||
|
||
If the `onExit` prop is not available, you can use `setTimeout` to remove the overlay after the animation ends. Set an appropriate timeout duration matching the animation duration. | ||
|
||
In the following code, the `close` function closes the overlay, and `setTimeout` is used to call the `unmount` function after 150ms. | ||
|
||
```tsx{12-16} | ||
import { overlay } from 'overlay-kit'; | ||
function Demo() { | ||
const openModal = () => { | ||
overlay.open(({ isOpen, close, unmount }) => { | ||
return ( | ||
<Dialog | ||
open={isOpen} | ||
onClose={() => { | ||
close(); | ||
// `unmount` is called after 150ms. | ||
// Adjust the timeout to match the animation duration. | ||
setTimeout(() => { | ||
unmount() | ||
}, 150); | ||
}} | ||
/> | ||
); | ||
}); | ||
}; | ||
return <Button onClick={openModal}>Open confirm modal</Button>; | ||
} | ||
``` | ||
|
||
### When There Is No Animation | ||
|
||
If there is no animation when the overlay closes, you can call the `unmount` function immediately when closing the overlay to remove the component. | ||
|
||
In the following code, the `onClose` prop of the `<Dialog />` component calls the `unmount` function to remove the overlay immediately. | ||
|
||
|
||
```tsx{9} | ||
import { overlay } from 'overlay-kit'; | ||
function Demo() { | ||
const openModal = () => { | ||
overlay.open(({ isOpen, unmount }) => { | ||
return ( | ||
<Dialog | ||
open={isOpen} | ||
onClose={unmount} | ||
/> | ||
); | ||
}); | ||
}; | ||
return <Button onClick={openModal}>Open confirm modal</Button>; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Code Comparison | ||
|
||
Using overlay-kit makes managing React overlays much simpler. Let's take a look at the changes through example code. | ||
|
||
## Before: Traditional React Overlay Implementation | ||
|
||
Before using overlay-kit, there is a lot of boilerplate code, and due to React's Hook rules, the state declaration, state change, and rendering logic are separated, disrupting the code flow. The `isOpen` state declaration, the `onClick` state change, and the `<Dialog />` component that renders based on the state are far apart. | ||
|
||
```tsx{4,10-12,17-22} | ||
import { useState } from 'react'; | ||
function MyPage() { | ||
const [isOpen, setIsOpen] = useState(false); | ||
/* Other Hook calls... */ | ||
return ( | ||
<> | ||
{/* Other components... */} | ||
<Button | ||
onClick={() => { | ||
setIsOpen(true); | ||
}} | ||
> | ||
Open | ||
</Button> | ||
{/* Other components... */} | ||
<Dialog | ||
open={isOpen} | ||
onClose={() => { | ||
setIsOpen(false); | ||
}} | ||
/> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
## After: Overlay Implementation with overlay-kit | ||
|
||
In contrast, the code using overlay-kit is more cohesive and intuitive. The flow of the code, which states that clicking the button opens the overlay, is clear at a glance. | ||
|
||
```tsx{10-14} | ||
import { overlay } from 'overlay-kit'; | ||
function MyPage() { | ||
/* Other Hook calls... */ | ||
return ( | ||
<> | ||
{/* Other components... */} | ||
<Button | ||
onClick={() => { | ||
overlay.open(({ isOpen, close }) => { | ||
return <Dialog open={isOpen} onClose={close} />; | ||
}); | ||
}} | ||
> | ||
Open | ||
</Button> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
The boilerplate code is significantly reduced. You no longer need to manage the overlay state directly. |
Oops, something went wrong.