From 5f7ecce83655049f5d16bae4bfdb6d08a9f50701 Mon Sep 17 00:00:00 2001 From: myoungho-pak Date: Wed, 20 May 2026 14:49:36 +0900 Subject: [PATCH] docs: Add ai.txt, llms.txt, and llms-full.txt for LLM discovery Publishes machine-readable docs at the site root following the llmstxt.org and aitxt.ing standards so LLM crawlers and agents can index overlay-kit's public API directly. - llms.txt: navigable index of guides, API, and design-system integrations. - ai.txt: canonical facts plus "do not hallucinate" guardrails for the public API surface. - llms-full.txt: inlined core English docs (guides, more, API reference). Marketing landing, verbose test code, and per-design- system walkthroughs are excluded as noise. - middleware: exempt the three text files from nextra/locales i18n routing so they respond at the site root instead of being 307-redirected to /en/.... Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/public/ai.txt | 83 ++++ docs/public/llms-full.txt | 920 ++++++++++++++++++++++++++++++++++++++ docs/public/llms.txt | 53 +++ docs/src/middleware.ts | 2 +- 4 files changed, 1057 insertions(+), 1 deletion(-) create mode 100644 docs/public/ai.txt create mode 100644 docs/public/llms-full.txt create mode 100644 docs/public/llms.txt diff --git a/docs/public/ai.txt b/docs/public/ai.txt new file mode 100644 index 0000000..fa575d8 --- /dev/null +++ b/docs/public/ai.txt @@ -0,0 +1,83 @@ +--- +updated: 2026-05-20 +scope: / +parent: https://overlay-kit.slash.page +--- + +# overlay-kit + +overlay-kit is a React library for declaratively managing overlays — modals, popups, dialogs, alerts, toasts — built by Toss (Viva Republica, Inc.). + +## What it is + +- An npm package: `overlay-kit`. Install with `npm install overlay-kit`. +- One context provider, ``, mounted exactly once at the React root. +- One imperative object, `overlay`, with six methods: `open`, `openAsync`, `close`, `closeAll`, `unmount`, `unmountAll`. +- Two hooks: `useCurrentOverlay` (returns the top overlay's id), `useOverlayData` (returns the full overlay registry). +- UI-library agnostic. There is no built-in dialog UI — you supply the component, overlay-kit manages mounting, async results, and lifecycle. Verified integrations: Material UI, Chakra UI v3, Ant Design. Any React-based UI library works. + +## Canonical facts + +- License: MIT, © Viva Republica, Inc. +- Source: https://github.com/toss/overlay-kit +- Docs: https://overlay-kit.slash.page (locales: `en` default, `ko`) +- Peer dependency: React only. `react-dom` is **not** a peer dependency (it was removed in PR #219). +- Discord: https://discord.gg/vGXbVjP2nY + +## Minimum-viable usage + +```tsx +import { OverlayProvider, overlay } from 'overlay-kit'; + +// Root setup — once per app + + + + +// Anywhere — open an overlay +overlay.open(({ isOpen, close, unmount }) => ( + +)); + +// Anywhere — await a result +const result = await overlay.openAsync(({ isOpen, close }) => ( + close(true)} + onClose={() => close(false)} + /> +)); +``` + +## close vs unmount (the most-asked question) + +- `close(value?)`: dismisses the overlay; the controller stays in memory so closing animations run and component state is preserved if the overlay is reopened with the same id. With `openAsync`, the argument passed to `close` becomes the Promise's resolved value. +- `unmount()`: removes the overlay from the React tree and memory. Skips the closing animation when called directly. +- Recommended pattern when an exit animation matters: call `close` first, then `unmount` via the underlying component's animation-complete callback. Library-specific callbacks: + - MUI `Dialog` → `TransitionProps.onExited` + - Ant Design `Modal` → `afterClose` + - Chakra v3 `Dialog.Root` → no dedicated callback; `setTimeout(unmount, 200)` inside `onOpenChange` + +## Outside-React entry points + +`overlay.open` can be called from any code path, including HTTP client hooks, event emitters, or service modules. This is the canonical way to surface global error dialogs from `fetch` / `ky` / `axios` response interceptors without prop-drilling. + +## Do not hallucinate + +- The public API surface is fixed to the items listed in **What it is**. There is **no** `useOverlay`, `OverlayConsumer`, `overlay.update`, `overlay.replace`, or `overlay.toast` helper. +- `overlay.open(controller, options?)` — `options.overlayId` is the only documented option. A second positional argument is not supported. +- `overlay.openAsync` provides a third controller argument, `reject`, in addition to `close` and `unmount`. Calling `reject(error)` rejects the Promise. +- The provider must be mounted **only once**. Multiple `` instances cause context-propagation issues. + +## Discovery + +- Machine-readable index: https://overlay-kit.slash.page/llms.txt +- Full inlined documentation: https://overlay-kit.slash.page/llms-full.txt + +## Links to deeper context + +- Concepts and rationale: https://overlay-kit.slash.page/en/docs/guides/think-in-overlay-kit +- Full API reference: https://overlay-kit.slash.page/en/api +- Testing recipes (Jest/Vitest + React Testing Library): https://overlay-kit.slash.page/en/docs/guides/testing +- FAQ: https://overlay-kit.slash.page/en/docs/guides/faq +- Opening overlays from outside React: https://overlay-kit.slash.page/en/docs/more/open-outside-react diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt new file mode 100644 index 0000000..cbfd989 --- /dev/null +++ b/docs/public/llms-full.txt @@ -0,0 +1,920 @@ +# overlay-kit — full documentation + +> Concatenated, LLM-friendly snapshot of the English documentation hosted at https://overlay-kit.slash.page. Each section is prefixed by its canonical URL. MDX-only wrappers (``, frontmatter `import`s) have been stripped; all prose, code blocks, and tables are preserved verbatim. For the navigable index, see https://overlay-kit.slash.page/llms.txt. For high-confidence facts and "do not hallucinate" guardrails, see https://overlay-kit.slash.page/ai.txt. + +Source: https://github.com/toss/overlay-kit (branch: `main`, license: MIT, © Viva Republica, Inc.) + +Intentionally excluded as noise (the canonical pages remain reachable via the index): + +- The marketing landing page at `/en` — value-prop cards rather than API documentation. +- Verbose test code samples in the Testing guide — replaced by a short scenario index pointing back to the canonical URL. +- Per-design-system integration walkthroughs for Material UI, Chakra UI, and Ant Design — these document third-party UI libraries, not overlay-kit's API. + +--- + +# Guides + +## Introduction to overlay-kit + +URL: https://overlay-kit.slash.page/en/docs/guides/introduction + +`overlay-kit` is a library for declaratively managing overlays like **modals, popups, and dialogs** in React. + +You can efficiently implement overlays without complex state management or unnecessary event handling. + +### Installation + +```sh +npm install overlay-kit +``` + +### Key Features + +#### Declarative API + +- Define overlay UI and behavior declaratively with simple code. +- Reduce state management and event handling code for easier development. + +#### Promise-based API + +- Return overlay results as `Promises`. +- Handle user input results or combine with asynchronous logic. + +#### Extensible Components + +- Freely define your desired overlay components. +- Use with various UI libraries. + +### Using overlay-kit + +Let's learn how to use `overlay-kit` with a simple example. + +#### Overlays + +Any component that renders above the screen can be an overlay. Below is a minimal confirmation dialog (using MUI `Dialog` to illustrate; any React UI library works). + +```tsx +// confirm-dialog.tsx +export function ConfirmDialog({ isOpen, close }) { + return ( + + Are you sure you want to continue? + + + + + + ); +} +``` + +#### Setting Overlay Position + +Overlays should be rendered in an appropriate position on the screen. Generally, it's best to render at the app root using `OverlayProvider`. + +```tsx +import { OverlayProvider } from 'overlay-kit'; +import { createRoot } from 'react-dom/client'; + +export function Example() { + return ( + + + + ); +} + +const root = createRoot(document.getElementById('root')); +root.render(); +``` + +#### Opening Overlays + +```tsx +import { overlay } from 'overlay-kit'; +import { ConfirmDialog } from './confirm-dialog'; + + +``` + +#### Opening Asynchronous Overlays + +`overlay.openAsync` returns the result as a `Promise`. The value passed to `close(value)` becomes the resolved value. + +```tsx +const result = await overlay.openAsync(({ isOpen, close }) => { + return ( + close(false)} + confirm={() => close(true)} + /> + ); +}); +``` + +#### Closing Overlays — `close` vs `unmount` + +`overlay.open` and `overlay.openAsync` provide `close` and `unmount` functions to the controller. Both dismiss the overlay but behave differently: + +1. **`close`** — runs the close animation, and state (e.g., `count`) is retained. When reopened with the same id, the previous state is restored. +2. **`unmount`** — immediately removes the overlay from memory, skipping the close animation. When reopened, state is reset. + +If a close animation is needed, use `close` first, then call `unmount` after the animation completes. + +#### Releasing Overlay Memory + +Because `close` retains state in memory after the animation, opening and closing many overlays may leak memory. Call `unmount` after the close animation ends. If the component exposes an `onExit`-style callback, pass `unmount` there. MUI doesn't expose `onExit` directly, but React's `useEffect` cleanup can call it on unmount: + +```tsx +// confirm-dialog.tsx +import { useEffect } from 'react'; + +export function ConfirmDialog({ isOpen, close, onExit }) { + useEffect(() => { + return () => onExit(); + }, []); + + return ( + + {/* ... */} + + ); +} +``` + +```tsx +overlay.open(({ isOpen, close, unmount }) => { + return ; +}); +``` + +--- + +## Think in overlay-kit + +URL: https://overlay-kit.slash.page/en/docs/guides/think-in-overlay-kit + +`overlay-kit` is based on React's philosophy. The **Declarative Overlay Pattern** is its embodiment. + +### Why Use overlay-kit + +#### Problems with Traditional Overlay Management + +1. **Complexity of State Management** — overlay state was managed directly with `useState` or global state; state management and UI logic became entangled. +2. **Repetitive Event Handling** — event handling for opening, closing, and returning results had to be rewritten repeatedly. +3. **Lack of Reusability** — UI and logic were tightly coupled through callback functions used to return values from overlays. + +#### Goals of overlay-kit + +1. **Design Following React Philosophy** — React favors declarative code; overlay-kit helps manage overlays declaratively. +2. **Improve Development Productivity** — by encapsulating state management and event handling, developers can focus on UI and business logic. +3. **Enhance Extensibility and Reusability** — by separating UI and behavior and returning Promises. + +### Declarative Overlay Pattern + +Traditional overlay management used an **Imperative** approach — complex, hard to maintain, with `useState` and mixed event handling. The **Declarative Overlay Pattern** lets you write more intuitive code by managing overlays based on **behavior** rather than state. + +#### Imperative Approach + +```tsx +import { useState } from 'react'; + +function Overlay() { + const [isOpen, setIsOpen] = useState(false); + + function handleOpen() { + setIsOpen(true); + } + + function handleClose() { + setIsOpen(false); + } + + return ( + <> + + + Imperative Overlay + + + + + + + ); +} +``` + +#### Declarative Approach + +```tsx +import { overlay } from 'overlay-kit'; + +function Overlay() { + return ( + + + + + )); + }} + > + Open + + ); +} +``` + +### Core Principles + +#### Co-location + +Related code is placed close together. Overlay calls, state management, and component definition live in one place, improving readability. + +#### Minimum API + +overlay-kit provides a simple and concise API. The core APIs are two: + +1. `overlay.open` — opens and closes overlays. +2. `overlay.openAsync` — processes asynchronous logic by returning values. + +These leverage general JavaScript patterns. For example, `overlay.openAsync` returns a `Promise`, making chaining patterns easy to apply. + +--- + +## Code Comparison + +URL: https://overlay-kit.slash.page/en/docs/guides/code-comparison + +### Before: Traditional React Overlay Implementation + +```tsx +import { useState } from 'react'; + +function MyPage() { + const [isOpen, setIsOpen] = useState(false); + return ( + <> + + setIsOpen(false)} /> + + ); +} +``` + +State declaration, state change, and rendering logic are pushed apart by React's Hook rules, disrupting the flow. + +### After: Overlay Implementation with overlay-kit + +```tsx +import { overlay } from 'overlay-kit'; + +function MyPage() { + return ( + + ); +} +``` + +Boilerplate is significantly reduced. You no longer need to manage the overlay state directly. + +--- + +## Hooks + +URL: https://overlay-kit.slash.page/en/docs/guides/hooks + +`overlay-kit` exposes `useCurrentOverlay` and `useOverlayData` for global overlay state. They enable state-based UX control, focusing, and conditional rendering outside of overlays. + +### useCurrentOverlay + +Returns the ID of the currently top-most overlay. + +The overlay ID can be specified by passing `overlayId` as the second argument to `overlay.open()` or `overlay.openAsync()`: + +```tsx +overlay.open( + ({ isOpen, close }) => , + { overlayId: 'custom-overlayId' } +); +``` + +If `overlayId` is omitted, an id is generated internally as `overlay-kit-[random number]`. + +Example: + +```tsx +import { overlay, useCurrentOverlay } from 'overlay-kit'; + +function App() { + const current = useCurrentOverlay(); + + return ( +
+ +

Current value: {current}

+
+ ); +} +``` + +### useOverlayData + +Returns information about all overlays currently in memory, including open and closed-but-not-yet-unmounted overlays. + +Each overlay item has: + +| Property | Type | Description | +| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | `string` | Unique ID that identifies the overlay. Specified as `overlayId` when calling `overlay.open()`, or automatically generated if omitted. | +| `componentKey` | `string` | Internal unique key React uses to render and distinguish overlay UI. A new value is assigned each time the overlay opens. | +| `isOpen` | `boolean` | Whether the overlay is currently open. Becomes `false` when `close()` is called, and remains in memory until `unmount()`. | +| `controller` | `FC` | React component that renders the overlay. The UI function passed to `overlay.open()` is stored here. | + +```tsx +const overlayData = useOverlayData(); + +Object.entries(overlayData).forEach(([id, item]) => { + console.log(id); // overlayId + console.log(item.isOpen); // true / false + console.log(item.controller); // component rendering function +}); +``` + +--- + +## Testing + +URL: https://overlay-kit.slash.page/en/docs/guides/testing + +### Prerequisites + +#### Test Runner + +- Jest — [Getting Started](https://jestjs.io/docs/getting-started), [Configuration](https://jestjs.io/docs/configuration#testenvironment-string) +- Vitest — [Getting Started](https://vitest.dev/guide/#getting-started), [Configuration](https://vitest.dev/config/) + +#### UI Testing Tools + +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) + +### Scenarios covered on the docs page + +The published guide demonstrates the following recipes with Jest/Vitest + React Testing Library. Full code samples live at the URL above; the index here is what an LLM typically needs to reason about test design. + +- **Closing overlays via `overlay.unmount`** — render a component that opens an overlay imperatively, click a button calling `overlay.unmount(overlayId)`, and assert the overlay leaves the DOM with `waitFor`. +- **Opening multiple overlays via `overlay.open`** — open N overlays in a single `useEffect` and assert all of their contents are in the DOM. +- **Async result via `overlay.openAsync`** — assert that the value passed to `close(value)` resolves as the awaited result; mock with `vi.fn()` and verify with `toHaveBeenCalledWith`. +- **Sequential unmount across overlays** — open multiple overlays, unmount them in a non-LIFO order, and assert `useCurrentOverlay` / DOM state stays consistent. +- **Active overlay tracking via `useCurrentOverlay`** — assert that the hook returns the id of the top overlay across `open` / `close` / `unmount` transitions. +- **Closing/removing all overlays** — `overlay.closeAll()` removes them from the screen while `useOverlayData()` still reports them; `overlay.unmountAll()` removes them from memory and the DOM entirely. + +Rule of thumb: assert via `waitFor` (overlays mount/unmount asynchronously) and use `userEvent` for clicks so portaled overlays receive events correctly. + +--- + +## FAQ + +URL: https://overlay-kit.slash.page/en/docs/guides/faq + +### Q. When is overlay-kit most useful? + +`overlay-kit` is particularly useful in: + +- **Complex Overlay Management** — chained dialogs and nested overlays. +- **Alignment with React Philosophy** — declarative UI instead of state-driven UI. +- **Performance Optimization** — heavy overlays that frequently open and close. +- **Large Applications** — consistent overlay management across the team. + +### Q. What's the difference between `overlay.open` and `overlay.openAsync`? + +- **`overlay.open`** — basic open/close. +- **`overlay.openAsync`** — returns a Promise for handling results asynchronously. + +```tsx +// overlay.open +overlay.open(({ isOpen, close }) => ( + +

Simple overlay

+
+)); + +// overlay.openAsync +const result = await overlay.openAsync(({ isOpen, close }) => ( + close(false)}> + + +)); + +console.log(result ? 'Yes' : 'No'); +``` + +### Q. What's the difference between `close` and `unmount`? + +- **`close`** — closes the overlay but keeps state in memory; previous state is restored on reopen. +- **`unmount`** — completely removes the overlay from memory; starts with initial state on reopen. + +**Use cases:** + +- **`close`** — performance optimization with frequently opened/closed overlays. +- **`unmount`** — prevent memory leaks by removing overlays no longer needed. + +### Q. What's the difference between `overlay.closeAll` and `overlay.unmountAll`? + +- **`overlay.closeAll`** — closes all open overlays but keeps state in memory. +- **`overlay.unmountAll`** — completely removes all overlays from memory. + +### Q. Why does state persist when reopening a closed overlay? + +`close` keeps state in memory. To reset state, use `unmount` to fully remove the overlay. + +### Q. When should I use `unmount`? + +- For lightweight overlays, `close` alone is usually sufficient. +- Use `unmount` (or `unmountAll`) when overlays are no longer needed or you must free memory. + +### Q. Which UI libraries can I use with overlay-kit? + +`overlay-kit` is not tied to any specific UI library and works with any React-based UI library — Material-UI, Chakra UI, Ant Design, and others. + +### Q. Does overlay-kit support TypeScript? + +Yes, with full TypeScript support. + +```tsx +const result = await overlay.openAsync(({ isOpen, close }) => ( + close(false)}> + + +)); +``` + +### Q. Why isn't my closing animation showing? + +Calling `unmount` immediately skips the closing animation. To preserve the animation, call `close` first, then `unmount` after the animation completes. + +```tsx +overlay.open(({ isOpen, close, unmount }) => ( + { + close(); // Run closing animation + setTimeout(() => unmount(), 300); // Remove from memory after animation + }} + > +

Maintain animation

+
+)); +``` + +--- + +# Learn More + +## Opening Overlays + +URL: https://overlay-kit.slash.page/en/docs/more/basic + +### Opening Simple Overlays + +```tsx +import { overlay } from 'overlay-kit'; + +overlay.open(({ isOpen, close }) => ( + + Are you sure you want to continue? + + + + + +)); +``` + +### Opening Asynchronous Overlays + +```tsx +const result = await overlay.openAsync(({ isOpen, close }) => ( + close(false)}> + Are you sure you want to continue? + + + + + +)); +``` + +### Releasing Overlay Memory + +You can remove overlays from memory using `unmount`. If there is a closing animation, calling `unmount` immediately can skip the animation; call `close` first and `unmount` after the animation completes. + +#### Using the `onExit` prop + +Pass `unmount` to the component's `onExit`-style callback so the overlay is removed once the close animation finishes. + +```tsx +overlay.open(({ isOpen, close, unmount }) => { + return ; +}); + +// In ConfirmDialog, wire onExit to fire after the close transition: +// useEffect(() => () => onExit(), []); +``` + +#### Using `setTimeout` + +If there's no `onExit` prop, use `setTimeout` to call `unmount` after the animation duration. + +```tsx +overlay.open(({ isOpen, close, unmount }) => ( + { + close(); + setTimeout(unmount, 600); + }} + /> +)); +``` + +--- + +## Opening Overlays Outside React + +URL: https://overlay-kit.slash.page/en/docs/more/open-outside-react + +`overlay.open` can be called from outside React components — for example, an HTTP client hook that opens an error dialog whenever a request fails. + +```tsx +import ky from 'ky'; +import { overlay } from 'overlay-kit'; + +const api = ky.extend({ + hooks: { + afterResponse: [ + (_, __, response) => { + if (response.status >= 400) { + overlay.open(({ isOpen, close }) => ( + + )); + } + }, + ], + }, +}); +``` + +The same pattern works with `fetch` wrappers, `axios` interceptors, event emitters, or service modules — anywhere outside React's render tree. The only requirement is that `` is mounted somewhere in the running React tree at the time the call fires. + +--- + +# API Reference + +## `` + +URL: https://overlay-kit.slash.page/en/api/components/overlay-provider + +`OverlayProvider` determines where overlays are rendered in your React application. + +```tsx + + + +``` + +### Reference + +Place `OverlayProvider` at the root of your application. + +#### Important Notes + +- `OverlayProvider` should be rendered **only once** in your React application. Multiple instances may prevent overlays from working correctly due to context propagation issues. + +### Usage + +`` provides the context needed to render all overlays. Any component that renders overlays must be placed under ``. + +```tsx +import React from 'react'; +import { OverlayProvider, overlay } from 'overlay-kit'; +import { Modal } from '@src/components'; + +function App() { + const notify = () => + overlay.open(({ isOpen, close, unmount }) => ( + + {/* Modal content */} + + )); + + return ; +} + +export function Root() { + return ( + + + {/* All overlays will be rendered here */} + + ); +} +``` + +--- + +## `overlay.open` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-open + +```ts +const overlayId = overlay.open(controller, options); +``` + +### Reference + +`overlay.open(controller, options?)` — call when you need to open an overlay. + +```tsx +overlay.open(({ isOpen, close, unmount }) => { + return ; +}); +``` + +#### Parameters + +- `controller` — the overlay controller function. Returns JSX and receives parameters for overlay state and control: + - `isOpen` — whether the overlay is open. + - `close` — closes the overlay. The overlay information remains in memory so closing animations can run. Call `unmount` to completely remove it. + - `unmount` — removes the overlay. If called immediately with a closing animation, the component may be removed before the animation completes. +- **optional** `options`: + - `overlayId` — a unique ID for the overlay; used to identify it. + +#### Return Value + +The unique ID for the overlay as a string. If `overlayId` is not specified, a random string is returned. + +#### Important Notes + +When manually specifying an ID, avoid duplicates. Opening multiple overlays with duplicate IDs may cause unexpected behavior. + +### Usage + +```tsx +const overlayId = 'unique-overlay-id'; + +overlay.open( + ({ isOpen, close, unmount }) => { + return ; + }, + { overlayId } +); +``` + +--- + +## `overlay.openAsync` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-open-async + +```ts +const result = await overlay.openAsync(controller, options); +``` + +### Reference + +`overlay.openAsync(controller, options?)` — open an overlay that returns a value. + +```tsx +const result = await overlay.openAsync(({ isOpen, close, unmount }) => { + function confirm() { + close(true); + } + function cancel() { + close(false); + } + + return ( + + ); +}); +``` + +#### Parameters + +- `controller` — the overlay controller function. Returns JSX and receives: + - `isOpen` — whether the overlay is open. + - `close` — closes the overlay. The argument passed to `close` is delivered as the resolved value of the `Promise` returned by `overlay.openAsync`. + - `unmount` — removes the overlay. If called immediately with a closing animation, the component may be removed before the animation completes. + - `reject` — when called, the argument passed is delivered as the rejected value of the `Promise` returned by `overlay.openAsync`, and the overlay closes. +- **optional** `options`: + - `overlayId` — a unique ID for the overlay. + +#### Return Value + +The value passed to the `close` function. + +### Usage + +```tsx +const result = await overlay.openAsync(({ isOpen, close, unmount }) => { + return ( + close(true)} + close={() => close(false)} + onExit={unmount} + /> + ); +}); + +if (result === true) { + console.log('User selected confirm.'); +} else { + console.log('User selected cancel.'); +} +``` + +--- + +## `overlay.close` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-close + +`overlay.close` closes a specific overlay using the provided `overlayId`. It removes the overlay from the screen but doesn't completely delete it from memory. + +```ts +overlay.close(overlayId); +``` + +### Reference + +#### Parameters + +- `overlayId` — the unique ID of the overlay to close. The ID is either returned from `overlay.open` or directly specified via `options.overlayId`. + +#### Important Notes + +When this function is called, the overlay disappears from the screen but remains in memory and the React element tree. To completely remove the overlay, call `overlay.unmount` after the animation ends. + +### Usage + +```tsx +const overlayId = overlay.open(({ isOpen, close, unmount }) => { + return ; +}); + +overlay.close(overlayId); +``` + +```tsx +const overlayId = 'unique-id'; + +overlay.open( + ({ isOpen, close, unmount }) => { + return ; + }, + { overlayId } +); + +overlay.close(overlayId); +``` + +--- + +## `overlay.closeAll` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-close-all + +`overlay.closeAll` closes all currently open overlays. It removes overlays from the screen but doesn't completely delete them from memory. + +```ts +overlay.closeAll(); +``` + +### Important Notes + +To completely remove overlays, call `overlay.unmountAll` after the animations end. + +### Usage + +```tsx +overlay.open(({ isOpen, close, unmount }) => ( + +)); +overlay.open(({ isOpen, close, unmount }) => ( + +)); + +// Closes all of the above +overlay.closeAll(); +``` + +--- + +## `overlay.unmount` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-unmount + +`overlay.unmount` completely removes a specific overlay from memory. The overlay with the specified `overlayId` is removed from both the React element tree and memory. + +```ts +overlay.unmount(overlayId); +``` + +### Important Notes + +- The overlay is immediately removed from memory, which may cause closing animations not to be displayed. +- For overlays with animations, call `overlay.close` first and then `overlay.unmount` after the closing animation completes. + +### Usage + +```tsx +const overlayId = overlay.open(({ isOpen, close, unmount }) => { + return ; +}); + +overlay.close(overlayId); + +setTimeout(() => { + overlay.unmount(overlayId); +}, 1000); +``` + +--- + +## `overlay.unmountAll` + +URL: https://overlay-kit.slash.page/en/api/utils/overlay-unmount-all + +`overlay.unmountAll` completely removes all open overlays from both the React element tree and memory. + +```ts +overlay.unmountAll(); +``` + +### Important Notes + +- Overlays are immediately removed from memory, which may cause closing animations not to be displayed. +- For overlays with animations, call `overlay.closeAll` first and then `overlay.unmountAll` after the closing animations complete. + +### Interface + +```tsx +function unmountAll(): void; +``` + +### Usage + +```tsx +overlay.open(({ isOpen, close, unmount }) => ( + +)); +overlay.open(({ isOpen, close, unmount }) => ( + +)); + +// Removes all of the above +overlay.unmountAll(); +``` + +```tsx +overlay.closeAll(); + +setTimeout(() => { + overlay.unmountAll(); +}, 1000); +``` diff --git a/docs/public/llms.txt b/docs/public/llms.txt new file mode 100644 index 0000000..5efcc85 --- /dev/null +++ b/docs/public/llms.txt @@ -0,0 +1,53 @@ +# overlay-kit + +> overlay-kit is a React library for declaratively managing overlays — modals, popups, dialogs, alerts, toasts — built by Toss. It exposes a minimal imperative API (`overlay.open`, `overlay.openAsync`) that returns Promises, removes `useState` / `onClose` boilerplate, and works with any React-based UI library. Docs are hosted at https://overlay-kit.slash.page. + +overlay-kit is published as the [`overlay-kit`](https://www.npmjs.com/package/overlay-kit) npm package. The public surface is small and intentionally stable: + +- ``: a context provider mounted once at the React root that determines where overlays render. +- `overlay.open`, `overlay.openAsync`, `overlay.close`, `overlay.closeAll`, `overlay.unmount`, `overlay.unmountAll`: imperative API for opening and disposing overlays from inside or outside React (e.g., HTTP client hooks). +- `useCurrentOverlay`, `useOverlayData`: hooks that expose the current top overlay id and the full registry of mounted overlays. + +The library is UI-library agnostic. There is no built-in dialog UI — you supply the component, overlay-kit manages mounting, async results, and lifecycle. Documentation is bilingual (English at `/en`, Korean at `/ko`); English is the default locale and the canonical content surfaced here. The project is MIT-licensed and developed openly in the [toss/overlay-kit](https://github.com/toss/overlay-kit) GitHub repository. + +## Docs + +- [Getting Started](https://overlay-kit.slash.page/en/docs/guides/introduction): install, OverlayProvider setup, and a complete `overlay.open` / `overlay.openAsync` walkthrough. +- [Think in overlay-kit](https://overlay-kit.slash.page/en/docs/guides/think-in-overlay-kit): rationale for the Declarative Overlay Pattern, imperative vs declarative comparison, and core design principles (Co-location, Minimum API). +- [Code Comparison](https://overlay-kit.slash.page/en/docs/guides/code-comparison): before/after of overlay code with and without overlay-kit. +- [Hooks](https://overlay-kit.slash.page/en/docs/guides/hooks): `useCurrentOverlay` returns the top overlay's id; `useOverlayData` returns the full `{ id, componentKey, isOpen, controller }` registry. +- [Testing](https://overlay-kit.slash.page/en/docs/guides/testing): Jest/Vitest + React Testing Library recipes for closing overlays, multiple overlays, async results, `closeAll`/`unmountAll`, and hook-based state assertions. +- [FAQ](https://overlay-kit.slash.page/en/docs/guides/faq): common questions about `open` vs `openAsync`, `close` vs `unmount`, supported UI libraries, TypeScript support, and animation handling. +- [Opening Overlays](https://overlay-kit.slash.page/en/docs/more/basic): expanded examples of `overlay.open`, `overlay.openAsync`, and memory-release patterns (`onExit`, `setTimeout`). +- [Opening Overlays Outside React](https://overlay-kit.slash.page/en/docs/more/open-outside-react): triggering overlays from non-React code, e.g., `ky` `afterResponse` hooks for global error dialogs. + +## API + +- [``](https://overlay-kit.slash.page/en/api/components/overlay-provider): provider component; must be mounted exactly once at the application root. +- [`overlay.open`](https://overlay-kit.slash.page/en/api/utils/overlay-open): `overlay.open(controller, options?)`. Returns the overlay id (string). `options.overlayId` allows specifying a custom id. +- [`overlay.openAsync`](https://overlay-kit.slash.page/en/api/utils/overlay-open-async): `overlay.openAsync(controller, options?)`. Returns `Promise` resolved by the value passed to `close(value)`; the controller also receives `reject` to reject the Promise. +- [`overlay.close`](https://overlay-kit.slash.page/en/api/utils/overlay-close): close a specific overlay by id; controller stays in memory so closing animations and state survive. +- [`overlay.closeAll`](https://overlay-kit.slash.page/en/api/utils/overlay-close-all): close every open overlay; state stays in memory. +- [`overlay.unmount`](https://overlay-kit.slash.page/en/api/utils/overlay-unmount): completely remove a specific overlay from the React tree and memory. +- [`overlay.unmountAll`](https://overlay-kit.slash.page/en/api/utils/overlay-unmount-all): completely remove every overlay from the React tree and memory. + +## Design system integrations + +- [Material UI](https://overlay-kit.slash.page/en/docs/more/with-design-systems/mui): MUI `Dialog` with `open`/`onClose`; pass `unmount` through `TransitionProps.onExited` to release memory after the exit animation. +- [Chakra UI](https://overlay-kit.slash.page/en/docs/more/with-design-systems/chakra-ui): Chakra v3 `Dialog.Root` with `open`/`onOpenChange`; call `close()` on `!e.open` and schedule `setTimeout(unmount, 200)` to release memory after the ~200ms scale animation. +- [Ant Design](https://overlay-kit.slash.page/en/docs/more/with-design-systems/ant-design): antd `Modal` with `open`/`onCancel`/`onOk`; pass `unmount` to `afterClose` to release memory after the close animation. + +## Project + +- [GitHub repository](https://github.com/toss/overlay-kit): source code, issues, releases, changelog. +- [Discord](https://discord.gg/vGXbVjP2nY): community chat. +- [English README](https://github.com/toss/overlay-kit/blob/main/README.md): quick-start in English. +- [Korean README](https://github.com/toss/overlay-kit/blob/main/README-ko_kr.md): quick-start in Korean. +- [npm package](https://www.npmjs.com/package/overlay-kit): published versions and metadata. + +## Optional + +- [Inlined full documentation](https://overlay-kit.slash.page/llms-full.txt): all guide, API, and integration pages concatenated into a single text file for LLM ingestion. +- [Korean docs root](https://overlay-kit.slash.page/ko): the same documentation tree in Korean. +- [DeepWiki](https://deepwiki.com/toss/overlay-kit): auto-generated wiki of the repository for codebase exploration. +- [License](https://github.com/toss/overlay-kit/blob/main/LICENSE): MIT, © Viva Republica, Inc. diff --git a/docs/src/middleware.ts b/docs/src/middleware.ts index 97c0d93..e51ee60 100644 --- a/docs/src/middleware.ts +++ b/docs/src/middleware.ts @@ -10,6 +10,6 @@ export const config = { * - favicon.ico (favicon file) * - img (image files) */ - '/((?!api|_next/static|_next/image|favicon.ico|img).*)', + '/((?!api|_next/static|_next/image|favicon.ico|img|ai\\.txt|llms\\.txt|llms-full\\.txt).*)', ], };