[
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/workflows/eslint.yml",
    "content": "name: \"ESLint\"\non: [pull_request]\njobs:\n  eslint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile --recursive\n      - name: Run ESLint\n        run: pnpm lint\n"
  },
  {
    "path": ".github/workflows/pending-changes.yml",
    "content": "name: \"Pending changes\"\non: [pull_request]\njobs:\n  pending-changes:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile --recursive\n      - uses: nickcharlton/diff-check@main\n        with:\n          command: pnpm run compile\n"
  },
  {
    "path": ".github/workflows/prettier.yml",
    "content": "name: \"Prettier\"\non: [pull_request]\njobs:\n  prettier:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile --recursive\n      - name: Run Prettier\n        run: pnpm run prettier:ci\n"
  },
  {
    "path": ".github/workflows/typescript.yml",
    "content": "name: \"TypeScript\"\non: [pull_request]\njobs:\n  typescript:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile --recursive\n      - name: Build NPM package\n        run: pnpm build\n      - name: Run TypeScript\n        run: pnpm tsc\n"
  },
  {
    "path": ".github/workflows/vitest.yml",
    "content": "name: \"Vitest\"\non: [pull_request]\njobs:\n  unit-tests:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 10\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile --recursive\n      - name: Build NPM packages\n        run: pnpm run build\n      - name: Run tests\n        run: pnpm run test:ci\n"
  },
  {
    "path": ".gitignore",
    "content": "dist\ndocs\nnode_modules\n\n.DS_Store\n.cache\n*.log\n.parcel-cache\n.pnp.*"
  },
  {
    "path": ".nvmrc",
    "content": "18\n"
  },
  {
    "path": ".prettierignore",
    "content": "/dist\n/docs\n/generated\n/public\n/src/routes/examples\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# CHANGELOG\n\nSee the [releases page](../../releases).\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or advances of\n  any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\nme+coc@kentcdodds.com. All complaints will be reviewed and investigated promptly\nand fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThanks for your interest in contributing to this project!\n\nHere are a couple of guidelines to keep in mind before opening a Pull Request:\n\n- Please open a GitHub issue for discussion _before_ submitting any significant changes to this API (including new features or functionality).\n- Please don't submit code that has been written by code-generation tools such as Copilot or Claude. (There's nothing wrong with these tools, but I'd prefer them not be a part of this project.)\n\n## Local development\n\nTo get started:\n```sh\npnpm install\n```\n\n### Running the documentation site locally\n\nThe documentation site is a great place to test pending changes. It runs on localhost port 3000 and can be started by running:\n```sh\npnpm dev \n```\n\n### Running tests locally\n\nTo run unit tests locally:\n```sh\npnpm test\n```\n\n### Updating assets\n\nBefore submitting, also make sure to update generated docs/examples:\n```\npnpm compile\npnpm prettier\npnpm lint\n```\n\n> [!NOTE]\n> If you forget this step, CI will remind you!"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\nCopyright (c) 2020 Brian Vaughn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<img src=\"https://react-error-boundary-lib.vercel.app/og.png\" alt=\"react-error-boundary logo\" width=\"400\" height=\"210\" />\n\n`react-error-boundary`: Reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component. Supports all React renderers (including React DOM and React Native).\n\n### If you like this project, 🎉 [become a sponsor](https://github.com/sponsors/bvaughn/) or ☕ [buy me a coffee](http://givebrian.coffee/)\n\n## Getting started\n\n```sh\n# npm\nnpm install react-error-boundary\n\n# pnpm\npnpm add react-error-boundary\n\n# yarn\nyarn add react-error-boundary\n```\n\n## FAQs\n\nFrequently asked questions can be found [here](https://react-error-boundary-lib.vercel.app/common-questions).\n\n## API\n\n### ErrorBoundary\n\n<!-- ErrorBoundary:description:begin -->\nA reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.\nWrap this component around other React components to \"catch\" errors and render a fallback UI.\n\nThis package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),\nso it has all of the advantages and constraints of that API.\nThis means that it can't catch errors during:\n- Server side rendering</li>\n- Event handlers\n- Asynchronous code (including effects)\n\nℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.\nRefer to the documentation to determine which is best for your application.\n\nℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `\"use client\";` directive.\n<!-- ErrorBoundary:description:end -->\n\n#### Required props\n\n<!-- ErrorBoundary:required-props:begin -->\nNone\n<!-- ErrorBoundary:required-props:end -->\n\n#### Optional props\n\n<!-- ErrorBoundary:optional-props:begin -->\n\n<table>\n  <thead>\n    <tr>\n      <th>Name</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>onError</td>\n      <td><p>Optional callback to enable e.g. logging error information to a server.\n@param error Value that was thrown; typically an instance of <code>Error</code>\n@param info React &quot;component stack&quot; identifying where the error was thrown</p>\n</td>\n    </tr>\n    <tr>\n      <td>onReset</td>\n      <td><p>Optional callback to to be notified when an error boundary is &quot;reset&quot; so React can retry the failed render.</p>\n</td>\n    </tr>\n    <tr>\n      <td>resetKeys</td>\n      <td><p>When changed, these keys will reset a triggered error boundary.\nThis can be useful when an error condition may be tied to some specific state (that can be uniquely identified by key).\nSee the the documentation for examples of how to use this prop.</p>\n</td>\n    </tr>\n    <tr>\n      <td>fallback</td>\n      <td><p>Static content to render in place of an error if one is thrown.</p>\n<pre><code class=\"language-tsx\">&lt;ErrorBoundary fallback={&lt;div className=&quot;text-red&quot;&gt;Something went wrong&lt;/div&gt;} /&gt;\n</code></pre>\n</td>\n    </tr>\n    <tr>\n      <td>FallbackComponent</td>\n      <td><p>React component responsible for returning a fallback UI based on a thrown value.</p>\n<pre><code class=\"language-tsx\">&lt;ErrorBoundary FallbackComponent={Fallback} /&gt;\n</code></pre>\n</td>\n    </tr>\n    <tr>\n      <td>fallbackRender</td>\n      <td><p><a href=\"https://react.dev/reference/react/Children#calling-a-render-prop-to-customize-rendering\">Render prop</a> function responsible for returning a fallback UI based on a thrown value.</p>\n<pre><code class=\"language-tsx\">&lt;ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) =&gt; &lt;div&gt;...&lt;/div&gt;} /&gt;\n</code></pre>\n</td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- ErrorBoundary:optional-props:end -->\n\n# FAQ\n## `ErrorBoundary` cannot be used as a JSX component\nThis error can be caused by a version mismatch between [react](https://npmjs.com/package/react) and [@types/react](https://npmjs.com/package/@types/react). To fix this, ensure that both match exactly, e.g.:\n\nIf using NPM:\n```json\n{\n  ...\n  \"overrides\": {\n    \"@types/react\": \"17.0.60\"\n  },\n  ...\n}\n```\n\nIf using Yarn:\n```json\n{\n  ...\n  \"resolutions\": {\n    \"@types/react\": \"17.0.60\"\n  },\n  ...\n}\n```\n\n---\n\n[This blog post](https://kentcdodds.com/blog/use-react-error-boundary-to-handle-errors-in-react) shows more examples of how this package can be used, although it was written for the [version 3 API](https://github.com/bvaughn/react-error-boundary/releases/tag/v3.1.4).\n"
  },
  {
    "path": "eslint.config.js",
    "content": "import js from \"@eslint/js\";\nimport reactHooks from \"eslint-plugin-react-hooks\";\nimport reactRefresh from \"eslint-plugin-react-refresh\";\nimport { globalIgnores } from \"eslint/config\";\nimport globals from \"globals\";\nimport tseslint from \"typescript-eslint\";\n\nexport default tseslint.config([\n  globalIgnores([\"dist\", \"docs\", \"public/generated\"]),\n  {\n    files: [\"**/*.{ts,tsx}\"],\n    ignores: [\"**/examples/*.{ts,tsx}\"],\n    extends: [\n      js.configs.recommended,\n      tseslint.configs.recommended,\n      reactHooks.configs[\"recommended-latest\"],\n      reactRefresh.configs.vite,\n    ],\n    languageOptions: {\n      ecmaVersion: 2020,\n      globals: globals.browser,\n      parserOptions: {\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n    rules: {\n      \"no-restricted-imports\": [\n        \"error\",\n        {\n          patterns: [\"*/../lib/*\", \"node:test\"],\n        },\n      ],\n      \"no-restricted-properties\": [\n        \"error\",\n        {\n          property: \"clientHeight\",\n          message:\n            \"Using clientHeight is restricted; prefer offsetHeight or getBoundingClientRect()\",\n        },\n        {\n          property: \"clientWidth\",\n          message:\n            \"Using clientWidth is restricted; prefer offsetWidth or getBoundingClientRect()\",\n        },\n      ],\n      \"react-hooks/exhaustive-deps\": [\n        \"error\",\n        {\n          additionalHooks: \"useIsomorphicLayoutEffect\",\n        },\n      ],\n      \"@typescript-eslint/no-unused-vars\": [\n        \"error\",\n        {\n          args: \"all\",\n          argsIgnorePattern: \"^_\",\n          caughtErrors: \"all\",\n          caughtErrorsIgnorePattern: \"^_\",\n          destructuredArrayIgnorePattern: \"^_\",\n          varsIgnorePattern: \"^_\",\n          ignoreRestSiblings: true,\n        },\n      ],\n    },\n  },\n]);\n"
  },
  {
    "path": "index.css",
    "content": "@source \"node_modules/react-lib-tools\";\n\n@import \"tailwindcss\";\n@import \"react-lib-tools/styles.css\";\n\n@theme {\n  --color-background-gradient-1: var(--color-fuchsia-400);\n  --color-background-gradient-2: var(--color-purple-700);\n  --color-background-gradient-3: var(--color-pink-500);\n  --color-common-question-header: var(--color-fuchsia-200);\n  --color-focus-1: var(--color-sky-300);\n  --color-focus-2: var(--color-sky-400);\n  --color-focus-3: var(--color-sky-600);\n}\n"
  },
  {
    "path": "index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <title>react-error-boundary | runtime error handler</title>\n\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n\n    <meta charset=\"UTF-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"\n    />\n\n    <meta property=\"og:type\" content=\"website\" />\n    <meta property=\"og:site_name\" content=\"react-error-boundary\" />\n    <meta\n      property=\"og:title\"\n      content=\"react-error-boundary: runtime error handler\"\n    />\n    <meta\n      name=\"description\"\n      content=\"Documentation for the react-error-boundary NPM package\"\n    />\n    <meta\n      property=\"og:url\"\n      content=\"https://react-error-boundary-lib.vercel.app/\"\n    />\n    <meta\n      property=\"og:image\"\n      content=\"https://react-error-boundary-lib.vercel.app/og.png\"\n    />\n    <meta property=\"og:image:width\" content=\"1200\" />\n    <meta property=\"og:image:height\" content=\"630\" />\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/index.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "index.tsx",
    "content": "import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport \"./index.css\";\nimport App from \"./src/App.tsx\";\n\ncreateRoot(document.getElementById(\"root\")!).render(\n  <StrictMode>\n    <App />\n  </StrictMode>,\n);\n"
  },
  {
    "path": "integrations/vite/README.md",
    "content": "# React + TypeScript + Vite\n\nThis template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.\n\nCurrently, two official plugins are available:\n\n- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh\n- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh\n\n## Expanding the ESLint configuration\n\nIf you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:\n\n```js\nexport default tseslint.config({\n  extends: [\n    // Remove ...tseslint.configs.recommended and replace with this\n    ...tseslint.configs.recommendedTypeChecked,\n    // Alternatively, use this for stricter rules\n    ...tseslint.configs.strictTypeChecked,\n    // Optionally, add this for stylistic rules\n    ...tseslint.configs.stylisticTypeChecked,\n  ],\n  languageOptions: {\n    // other options...\n    parserOptions: {\n      project: ['./tsconfig.node.json', './tsconfig.app.json'],\n      tsconfigRootDir: import.meta.dirname,\n    },\n  },\n})\n```\n\nYou can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:\n\n```js\n// eslint.config.js\nimport reactX from 'eslint-plugin-react-x'\nimport reactDom from 'eslint-plugin-react-dom'\n\nexport default tseslint.config({\n  plugins: {\n    // Add the react-x and react-dom plugins\n    'react-x': reactX,\n    'react-dom': reactDom,\n  },\n  rules: {\n    // other rules...\n    // Enable its recommended typescript rules\n    ...reactX.configs['recommended-typescript'].rules,\n    ...reactDom.configs.recommended.rules,\n  },\n})\n```\n"
  },
  {
    "path": "integrations/vite/eslint.config.js",
    "content": "import js from \"@eslint/js\";\nimport globals from \"globals\";\nimport reactHooks from \"eslint-plugin-react-hooks\";\nimport reactRefresh from \"eslint-plugin-react-refresh\";\nimport tseslint from \"typescript-eslint\";\n\nexport default tseslint.config(\n  { ignores: [\"dist\"] },\n  {\n    extends: [js.configs.recommended, ...tseslint.configs.recommended],\n    files: [\"**/*.{ts,tsx}\"],\n    languageOptions: {\n      ecmaVersion: 2020,\n      globals: globals.browser,\n      parserOptions: {\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n    plugins: {\n      \"react-hooks\": reactHooks,\n      \"react-refresh\": reactRefresh,\n    },\n    rules: {\n      ...reactHooks.configs.recommended.rules,\n      \"@typescript-eslint/no-unused-vars\": [\n        \"error\",\n        {\n          args: \"all\",\n          argsIgnorePattern: \"^_\",\n          caughtErrors: \"all\",\n          caughtErrorsIgnorePattern: \"^_\",\n          destructuredArrayIgnorePattern: \"^_\",\n          varsIgnorePattern: \"^_\",\n          ignoreRestSiblings: true,\n        },\n      ],\n      \"react-refresh/only-export-components\": [\n        \"warn\",\n        { allowConstantExport: true },\n      ],\n    },\n  },\n);\n"
  },
  {
    "path": "integrations/vite/index.html",
    "content": "<!doctype html>\n<html class=\"dark\" lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>[Vite] react-error-boundary integration</title>\n  </head>\n  <body class=\"bg-black text-white\">\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "integrations/vite/package.json",
    "content": "{\n  \"name\": \"vite\",\n  \"private\": true,\n  \"version\": \"0.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite --port 3012\",\n    \"build\": \"tsc -b && vite build\",\n    \"test\": \"npx playwright test\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"react\": \"^19.2.3\",\n    \"react-dom\": \"^19.2.3\",\n    \"react-error-boundary\": \"workspace:*\",\n    \"react-router\": \"^7\"\n  },\n  \"devDependencies\": {\n    \"@eslint/js\": \"^9.25.0\",\n    \"@playwright/test\": \"^1\",\n    \"@tailwindcss/vite\": \"^4.1.17\",\n    \"@types/react\": \"^19.1.2\",\n    \"@types/react-dom\": \"^19.1.2\",\n    \"@vitejs/plugin-react\": \"^4.4.1\",\n    \"eslint\": \"^9.25.0\",\n    \"eslint-plugin-react-hooks\": \"^5.2.0\",\n    \"eslint-plugin-react-refresh\": \"^0.4.19\",\n    \"globals\": \"^16.0.0\",\n    \"tailwindcss\": \"^4.1.17\",\n    \"typescript\": \"~5.8.3\",\n    \"typescript-eslint\": \"^8.30.1\",\n    \"vite\": \"^6.3.5\"\n  }\n}\n"
  },
  {
    "path": "integrations/vite/playwright.config.ts",
    "content": "import { defineConfig, devices } from \"@playwright/test\";\n\nexport default defineConfig({\n  projects: [\n    {\n      name: \"chromium\",\n      timeout: 5_000,\n      use: {\n        ...devices[\"Desktop Chrome\"],\n        viewport: { width: 1000, height: 600 },\n\n        // Uncomment to visually debug\n        // headless: false,\n        // launchOptions: {\n        //   slowMo: 500\n        // }\n      },\n    },\n  ],\n});\n"
  },
  {
    "path": "integrations/vite/src/components/Children.tsx",
    "content": "import { useLayoutEffect, useState } from \"react\";\n\nexport type SizeProps = {\n  height: number | undefined;\n  width: number | undefined;\n};\n\nexport const Children = function Children({\n  height,\n  onCommitLogsChange,\n  width,\n}: SizeProps & {\n  onCommitLogsChange: (logs: SizeProps[]) => void;\n}) {\n  const [commitLogs, setCommitLogs] = useState<SizeProps[]>([]);\n\n  useLayoutEffect(() => {\n    setCommitLogs((prev) => [\n      ...prev,\n      {\n        height:\n          height === undefined ? undefined : parseFloat(height.toFixed(1)),\n        width: width === undefined ? undefined : parseFloat(width.toFixed(1)),\n      } as SizeProps,\n    ]);\n  }, [height, width]);\n\n  useLayoutEffect(() => onCommitLogsChange(commitLogs));\n\n  // Account for StrictMode double rendering on mount\n  useLayoutEffect(\n    () => () => {\n      setCommitLogs([]);\n    },\n    [],\n  );\n\n  return (\n    <div className=\"w-full h-full flex flex-col items-center justify-center p-1 text-white\">\n      {width} x {height} pixels\n    </div>\n  );\n};\n"
  },
  {
    "path": "integrations/vite/src/components/Container.tsx",
    "content": "import { type PropsWithChildren } from \"react\";\n\nexport type ContainerProps = PropsWithChildren<{\n  className?: string | undefined;\n}>;\n\nexport function Container({ children, className }: ContainerProps) {\n  return <div className={className}>{children}</div>;\n}\n"
  },
  {
    "path": "integrations/vite/src/components/DebugData.tsx",
    "content": "import { cn } from \"../utils/cn\";\n\nexport function DebugData({ data }: { data: object }) {\n  return (\n    <pre\n      className={cn(\n        \"p-2 resize-none rounded-md font-mono text-xs\",\n        \"border border-2 border-slate-800 focus:outline-none focus:border-sky-700\",\n      )}\n    >\n      <code className=\"text-xs\">{JSON.stringify(data, replacer, 2)}</code>\n    </pre>\n  );\n}\n\nfunction replacer(_key: string, value: unknown) {\n  if (typeof value === \"number\") {\n    return Math.round(value);\n  }\n\n  return value;\n}\n"
  },
  {
    "path": "integrations/vite/src/components/Resizer.tsx",
    "content": "import { type PropsWithChildren } from \"react\";\n\nexport type ResizerProps = PropsWithChildren;\n\nexport function Resizer({ children: childrenProp }: ResizerProps) {\n  // TODO\n  return childrenProp;\n}\n"
  },
  {
    "path": "integrations/vite/src/index.css",
    "content": "@import \"tailwindcss\";\n\n@layer base {\n  h1 {\n    @apply mb-4 text-4xl font-bold tracking-tight text-gray-900;\n  }\n  ul {\n    @apply list-disc pl-6;\n  }\n  ol {\n    @apply list-decimal pl-6;\n  }\n  p {\n    @apply mb-2 mt-2;\n  }\n  a {\n    @apply text-blue-600 hover:text-pink-400 visited:text-blue-900;\n  }\n}\n\n#root {\n  height: 100vh;\n}\n"
  },
  {
    "path": "integrations/vite/src/main.tsx",
    "content": "import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { BrowserRouter, Route, Routes } from \"react-router\";\nimport \"./index.css\";\nimport { Home } from \"./routes/Home\";\n\ncreateRoot(document.getElementById(\"root\")!).render(\n  <StrictMode>\n    <BrowserRouter>\n      <Routes>\n        <Route path=\"/\" element={<Home />} />\n      </Routes>\n    </BrowserRouter>\n  </StrictMode>,\n);\n"
  },
  {
    "path": "integrations/vite/src/routes/Home.tsx",
    "content": "export function Home() {\n  return <div className=\"w-full h-full\">Coming soon...</div>;\n}\n"
  },
  {
    "path": "integrations/vite/src/utils/assert.ts",
    "content": "export function assert(\n  expectedCondition: unknown,\n  message: string = \"Assertion error\",\n): asserts expectedCondition {\n  if (!expectedCondition) {\n    console.error(message);\n\n    throw Error(message);\n  }\n}\n"
  },
  {
    "path": "integrations/vite/src/utils/cn.ts",
    "content": "import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
  },
  {
    "path": "integrations/vite/src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "integrations/vite/test-results/.last-run.json",
    "content": "{\n  \"status\": \"passed\",\n  \"failedTests\": []\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/calculateBoxBetween.ts",
    "content": "import type { Box } from \"./types\";\n\nexport function calculateBoxBetween(boxA: Box, boxB: Box): Box {\n  if (boxA.y === boxB.y) {\n    return {\n      x: boxA.x + boxA.width,\n      y: boxA.y,\n      height: boxA.height,\n      width: boxB.x - (boxA.x + boxA.width),\n    };\n  } else {\n    return {\n      x: boxA.x,\n      y: boxA.y + boxA.height,\n      height: boxB.y - (boxA.y + boxA.height),\n      width: boxA.width,\n    };\n  }\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/calculateHitArea.ts",
    "content": "import type { Page } from \"@playwright/test\";\nimport { calculateBoxBetween } from \"./calculateBoxBetween\";\n\nexport async function calculateHitArea(page: Page, panelIds: [string, string]) {\n  const panelA = page.getByText(`id: ${panelIds[0]}`);\n  const panelB = page.getByText(`id: ${panelIds[1]}`);\n\n  const panelBoxA = (await panelA.boundingBox())!;\n  const panelBoxB = (await panelB.boundingBox())!;\n\n  return calculateBoxBetween(panelBoxA, panelBoxB);\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/debugging/logDebugState.ts",
    "content": "import type { Page } from \"@playwright/test\";\n\nexport async function logDebugState(page: Page, prefix?: string) {\n  const string = await page.evaluate(() =>\n    Array.from(document.querySelectorAll(\"code\"))\n      .map((element) => element.outerHTML)\n      .join(\"\\n\\n\"),\n  );\n\n  console.log(prefix ? `${prefix}\\n\\n${string}` : string);\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/debugging/logGroup.ts",
    "content": "import type { Page } from \"@playwright/test\";\n\nexport async function logGroup(page: Page) {\n  console.log(\n    await page.evaluate(\n      () => document.querySelector(\"[data-group]\")?.outerHTML,\n    ),\n  );\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/expectLayout.ts",
    "content": "import { expect, type Page } from \"@playwright/test\";\nimport type { Layout } from \"react-resizable-panels\";\n\nexport async function expectLayout({\n  layout,\n  mainPage,\n  onLayoutCount,\n}: {\n  layout: Layout;\n  mainPage: Page;\n  onLayoutCount: number;\n}) {\n  await expect(mainPage.getByText('\"layout\"')).toHaveText(\n    JSON.stringify(\n      {\n        layout,\n        onLayoutCount,\n      },\n      null,\n      2,\n    ),\n  );\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/expectPanelSize.ts",
    "content": "import { expect, type Page } from \"@playwright/test\";\nimport type { PanelSize } from \"react-resizable-panels\";\n\nexport async function expectPanelSize({\n  mainPage,\n  onResizeCount,\n  panelId,\n  panelSize,\n  prevPanelSize,\n}: {\n  mainPage: Page;\n  onResizeCount: number;\n  panelId: string | number;\n  panelSize: PanelSize;\n  prevPanelSize?: PanelSize | undefined;\n}) {\n  const locator = mainPage.getByText(`\"panelId\": \"${panelId}\"`);\n\n  const text = JSON.stringify(\n    {\n      panelId,\n      onResizeCount,\n      panelSize,\n      prevPanelSize,\n    },\n    null,\n    2,\n  );\n\n  await expect(locator).toHaveText(text);\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/getCenterCoordinates.ts",
    "content": "import type { Box, Coordinates } from \"./types\";\n\nexport function getCenterCoordinates(box: Box): Coordinates {\n  return {\n    x: box.x + box.width / 2,\n    y: box.y + box.height / 2,\n  };\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/getSeparatorAriaAttributes.ts",
    "content": "import type { Page } from \"@playwright/test\";\n\nexport async function getSeparatorAriaAttributes(page: Page, id?: string) {\n  return page.evaluate(\n    ([id]) => {\n      const element = document.querySelector(\n        id ? `[data-testid=\"${id}\"]` : '[role=\"separator\"]',\n      );\n\n      return {\n        \"aria-controls\": element?.getAttribute(\"aria-controls\"),\n        \"aria-valuemax\": element?.getAttribute(\"aria-valuemax\"),\n        \"aria-valuemin\": element?.getAttribute(\"aria-valuemin\"),\n        \"aria-valuenow\": element?.getAttribute(\"aria-valuenow\"),\n      };\n    },\n    [id],\n  );\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/goToUrl.ts",
    "content": "import type { Page } from \"@playwright/test\";\nimport { createElement, type ReactElement } from \"react\";\nimport { PopupWindow } from \"../../src/components/PopupWindow\";\nimport { encode } from \"./serializer/encode\";\n\nexport async function goToUrl(\n  page: Page,\n  elementProp: ReactElement<unknown>,\n  config: {\n    useGroupCallbackRef?: boolean | undefined;\n    useGroupRef?: boolean | undefined;\n    usePanelCallbackRef?: boolean | undefined;\n    usePanelRef?: boolean | undefined;\n    usePopUpWindow?: boolean | undefined;\n  } = {},\n): Promise<Page> {\n  const {\n    useGroupCallbackRef = false,\n    useGroupRef = false,\n    usePanelCallbackRef = false,\n    usePanelRef = false,\n    usePopUpWindow = false,\n  } = config;\n\n  let element = elementProp;\n  let encodedString = \"\";\n  if (element) {\n    if (usePopUpWindow) {\n      element = createElement(PopupWindow, {\n        children: element,\n        className: \"dark\",\n      });\n    }\n\n    encodedString = encode(element);\n  }\n\n  const queryParams = [\n    useGroupCallbackRef ? \"useGroupCallbackRef\" : undefined,\n    useGroupRef ? \"useGroupRef\" : undefined,\n    usePanelCallbackRef ? \"usePanelCallbackRef\" : undefined,\n    usePanelRef ? \"usePanelRef\" : undefined,\n  ]\n    .filter(Boolean)\n    .join(\"&\");\n\n  const url = new URL(\n    `http://localhost:3012/e2e/decoder/${encodedString}?${queryParams}`,\n  );\n\n  // Uncomment when testing for easier repro\n  console.log(\"\\n\\n\" + url.toString());\n\n  await page.goto(url.toString());\n\n  if (usePopUpWindow) {\n    const popupPromise = page.waitForEvent(\"popup\");\n\n    await page.getByRole(\"button\").click();\n\n    return await popupPromise;\n  }\n\n  return page;\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/goToUrlWithIframe.ts",
    "content": "import type { Page } from \"@playwright/test\";\nimport type { ReactElement } from \"react\";\nimport type { GroupProps } from \"react-resizable-panels\";\nimport { encode } from \"./serializer/encode\";\n\nexport async function goToUrlWithIframe(\n  page: Page,\n  element: ReactElement<GroupProps>,\n  sameOrigin: boolean,\n) {\n  const encodedString = encode(element);\n\n  const url = new URL(\"http://localhost:3012/e2e/decoder/iframe\");\n  url.searchParams.set(\"urlPanelGroup\", encodedString);\n  if (sameOrigin) {\n    url.searchParams.set(\"sameOrigin\", \"\");\n  }\n\n  // Uncomment when testing for easier repros\n  // console.log(url.toString());\n\n  await page.goto(url.toString());\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/pointer-interactions/resizeHelper.ts",
    "content": "import type { Page } from \"@playwright/test\";\nimport { calculateHitArea } from \"../calculateHitArea\";\nimport { getCenterCoordinates } from \"../getCenterCoordinates\";\n\nexport async function resizeHelper(\n  page: Page,\n  panelIds: [string, string],\n  deltaX: number = 0,\n  deltaY: number = 0,\n) {\n  const hitAreaBox = await calculateHitArea(page, panelIds);\n\n  const centerCoordinates = getCenterCoordinates(hitAreaBox);\n  const destinationCoordinates = {\n    x: centerCoordinates.x + deltaX,\n    y: centerCoordinates.y + deltaY,\n  };\n\n  await page.mouse.move(centerCoordinates.x, centerCoordinates.y);\n  await page.mouse.down();\n  await page.mouse.move(destinationCoordinates.x, destinationCoordinates.y, {\n    steps: 1,\n  });\n  await page.mouse.up();\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/serializer/decode.ts",
    "content": "import { createElement, type ReactElement } from \"react\";\nimport type {\n  GroupProps,\n  PanelProps,\n  SeparatorProps,\n} from \"react-resizable-panels\";\nimport { Container } from \"../../../src/components/Container\";\nimport { DisplayModeToggle } from \"../../../src/components/DisplayModeToggle\";\nimport { Group } from \"../../../src/components/Group\";\nimport { Panel } from \"../../../src/components/Panel\";\nimport { PopupWindow } from \"../../../src/components/PopupWindow\";\nimport { Separator } from \"../../../src/components/Separator\";\nimport type {\n  EncodedContainerElement,\n  EncodedDisplayModeToggleElement,\n  EncodedElement,\n  EncodedGroupElement,\n  EncodedPanelElement,\n  EncodedPopupWindowElement,\n  EncodedSeparatorElement,\n  EncodedTextElement,\n  TextProps,\n} from \"./types\";\n\ntype Config = {\n  groupProps?: Partial<GroupProps>;\n  panelProps?: Partial<PanelProps>;\n};\n\nlet key = 0;\n\nexport function decode(stringified: string, config: Config = {}) {\n  const json = JSON.parse(stringified) as EncodedElement[];\n\n  return decodeChildren(json, config);\n}\n\nfunction decodeChildren(\n  children: EncodedElement[],\n  config: Config,\n): ReactElement<unknown>[] {\n  const elements: ReactElement<unknown>[] = [];\n\n  children.forEach((current) => {\n    if (!current) {\n      return;\n    }\n\n    switch (current.type) {\n      case \"Container\": {\n        elements.push(decodeContainer(current, config));\n        break;\n      }\n      case \"DisplayModeToggle\": {\n        elements.push(decodeDisplayModeToggle(current, config));\n        break;\n      }\n      case \"Group\": {\n        elements.push(decodeGroup(current, config));\n        break;\n      }\n      case \"Panel\": {\n        elements.push(decodePanel(current, config));\n        break;\n      }\n      case \"PopupWindow\": {\n        elements.push(decodePopupWindow(current, config));\n        break;\n      }\n      case \"Separator\": {\n        elements.push(decodeSeparator(current));\n        break;\n      }\n      case \"Text\": {\n        elements.push(decodeText(current));\n        break;\n      }\n      default: {\n        console.warn(\"Could not decode type:\", current);\n      }\n    }\n  });\n\n  return elements;\n}\n\nfunction decodeContainer(\n  json: EncodedContainerElement,\n  config: Config,\n): ReactElement<unknown> {\n  const { children, ...props } = json.props;\n\n  return createElement(Container, {\n    key: ++key,\n    ...props,\n    ...config.panelProps,\n    children: children ? decodeChildren(children, config) : undefined,\n  });\n}\n\nfunction decodeDisplayModeToggle(\n  json: EncodedDisplayModeToggleElement,\n  config: Config,\n): ReactElement<unknown> {\n  const { children, ...props } = json.props;\n\n  return createElement(DisplayModeToggle, {\n    key: ++key,\n    ...props,\n    ...config.panelProps,\n    children: children ? decodeChildren(children, config) : undefined,\n  });\n}\n\nfunction decodeGroup(\n  json: EncodedGroupElement,\n  config: Config,\n): ReactElement<PanelProps> {\n  const { children, ...props } = json.props;\n\n  return createElement(Group, {\n    key: ++key,\n    ...props,\n    ...config.groupProps,\n    children: children ? decodeChildren(children, config) : undefined,\n  });\n}\n\nfunction decodePanel(\n  json: EncodedPanelElement,\n  config: Config,\n): ReactElement<PanelProps> {\n  const { children, ...props } = json.props;\n\n  return createElement(Panel, {\n    key: ++key,\n    ...props,\n    ...config.panelProps,\n    children: children ? decodeChildren(children, config) : undefined,\n  });\n}\n\nfunction decodePopupWindow(\n  json: EncodedPopupWindowElement,\n  config: Config,\n): ReactElement<unknown> {\n  const { children, ...props } = json.props;\n\n  return createElement(PopupWindow, {\n    key: ++key,\n    ...props,\n    ...config.panelProps,\n    children: children ? decodeChildren(children, config) : undefined,\n  });\n}\n\nfunction decodeSeparator(\n  json: EncodedSeparatorElement,\n): ReactElement<SeparatorProps> {\n  return createElement(Separator, {\n    key: ++key,\n    ...json.props,\n  });\n}\n\nfunction decodeText(json: EncodedTextElement): ReactElement<TextProps> {\n  return createElement(\"div\", {\n    key: ++key,\n    ...json.props,\n  });\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/serializer/encode.ts",
    "content": "import { type PropsWithChildren, type ReactElement } from \"react\";\nimport {\n  Group,\n  Panel,\n  Separator,\n  type GroupProps,\n  type PanelProps,\n  type SeparatorProps,\n} from \"react-resizable-panels\";\nimport {\n  Container,\n  type ContainerProps,\n} from \"../../../src/components/Container\";\nimport {\n  DisplayModeToggle,\n  type DisplayModeToggleProps,\n} from \"../../../src/components/DisplayModeToggle\";\nimport {\n  PopupWindow,\n  type PopupWindowProps,\n} from \"../../../src/components/PopupWindow\";\nimport type {\n  EncodedContainerElement,\n  EncodedDisplayModeToggleElement,\n  EncodedElement,\n  EncodedGroupElement,\n  EncodedPanelElement,\n  EncodedPopupWindowElement,\n  EncodedSeparatorElement,\n  EncodedTextElement,\n  TextProps,\n} from \"./types\";\n\nexport function encode(element: ReactElement<unknown>) {\n  const json = encodeChildren([element]);\n  const stringified = JSON.stringify(json);\n\n  return encodeURIComponent(stringified);\n}\n\nfunction encodeChildren(children: ReactElement<unknown>[]): EncodedElement[] {\n  const elements: EncodedElement[] = [];\n\n  children.forEach((current) => {\n    if (!current) {\n      return;\n    }\n\n    switch (current.type) {\n      case Container: {\n        elements.push(encodeContainer(current as ReactElement<ContainerProps>));\n        break;\n      }\n      case DisplayModeToggle: {\n        elements.push(\n          encodeDisplayModeToggle(\n            current as ReactElement<DisplayModeToggleProps>,\n          ),\n        );\n        break;\n      }\n      case Group: {\n        elements.push(encodeGroup(current as ReactElement<GroupProps>));\n        break;\n      }\n      case Panel: {\n        elements.push(encodePanel(current as ReactElement<PanelProps>));\n        break;\n      }\n      case PopupWindow: {\n        elements.push(\n          encodePopupWindow(current as ReactElement<PropsWithChildren>),\n        );\n        break;\n      }\n      case Separator: {\n        elements.push(encodeSeparator(current as ReactElement<SeparatorProps>));\n        break;\n      }\n      default: {\n        if (typeof current === \"object\") {\n          const { children } = current.props as TextProps;\n          if (typeof children === \"string\") {\n            elements.push(encodeTextChild(current as ReactElement<TextProps>));\n          } else {\n            console.warn(\"Could not encode type:\", current);\n          }\n        }\n      }\n    }\n  });\n\n  return elements;\n}\n\nfunction encodeContainer(\n  element: ReactElement<ContainerProps>,\n): EncodedContainerElement {\n  const { children, ...props } = element.props;\n\n  const encodedChildren = encodeChildren(\n    Array.isArray(children) ? children : [children],\n  );\n\n  return {\n    props: {\n      ...props,\n      children: encodedChildren.length > 0 ? encodedChildren : undefined,\n    },\n    type: \"Container\",\n  };\n}\n\nfunction encodeDisplayModeToggle(\n  element: ReactElement<DisplayModeToggleProps>,\n): EncodedDisplayModeToggleElement {\n  const { children, ...props } = element.props;\n\n  const encodedChildren = encodeChildren(\n    Array.isArray(children) ? children : [children],\n  );\n\n  return {\n    props: {\n      ...props,\n      children: encodedChildren.length > 0 ? encodedChildren : undefined,\n    },\n    type: \"DisplayModeToggle\",\n  };\n}\n\nfunction encodeGroup(element: ReactElement<GroupProps>): EncodedGroupElement {\n  const { children, onLayoutChange: _, ...props } = element.props;\n\n  const encodedChildren = encodeChildren(\n    Array.isArray(children) ? children : [children],\n  );\n\n  return {\n    props: {\n      ...props,\n      children: encodedChildren.length > 0 ? encodedChildren : undefined,\n    },\n    type: \"Group\",\n  };\n}\n\nfunction encodePanel(element: ReactElement<PanelProps>): EncodedPanelElement {\n  const { children, onResize: __, ...props } = element.props;\n\n  const encodedChildren = encodeChildren(\n    Array.isArray(children) ? children : [children],\n  );\n\n  return {\n    props: {\n      ...props,\n      children: encodedChildren.length > 0 ? encodedChildren : undefined,\n    },\n    type: \"Panel\",\n  };\n}\n\nfunction encodePopupWindow(\n  element: ReactElement<PopupWindowProps>,\n): EncodedPopupWindowElement {\n  const { children, ...props } = element.props;\n\n  const encodedChildren = encodeChildren(\n    Array.isArray(children) ? children : [children],\n  );\n\n  return {\n    props: {\n      ...props,\n      children: encodedChildren.length > 0 ? encodedChildren : undefined,\n    },\n    type: \"PopupWindow\",\n  };\n}\n\nfunction encodeSeparator(\n  element: ReactElement<SeparatorProps>,\n): EncodedSeparatorElement {\n  const { children: _, ...props } = element.props;\n\n  return {\n    type: \"Separator\",\n    props,\n  };\n}\n\nfunction encodeTextChild(element: ReactElement<TextProps>): EncodedTextElement {\n  return {\n    props: {\n      children: element.props.children,\n      className: element.props.className,\n    },\n    type: \"Text\",\n  };\n}\n"
  },
  {
    "path": "integrations/vite/tests/utils/serializer/types.ts",
    "content": "import type {\n  GroupProps,\n  PanelProps,\n  SeparatorProps,\n} from \"react-resizable-panels\";\nimport type { ContainerProps } from \"../../../src/components/Container\";\nimport type { DisplayModeToggleProps } from \"../../../src/components/DisplayModeToggle\";\nimport type { PopupWindowProps } from \"../../../src/components/PopupWindow\";\n\ntype EncodedElementWithChildren<Props extends object = object> = Omit<\n  Props,\n  \"children\"\n> & { children?: EncodedElement[] | undefined };\n\nexport interface EncodedContainerElement {\n  props: EncodedElementWithChildren<ContainerProps>;\n  type: \"Container\";\n}\n\nexport interface EncodedDisplayModeToggleElement {\n  props: EncodedElementWithChildren<DisplayModeToggleProps>;\n  type: \"DisplayModeToggle\";\n}\n\nexport interface EncodedGroupElement {\n  props: EncodedElementWithChildren<GroupProps>;\n  type: \"Group\";\n}\n\nexport interface EncodedPanelElement {\n  props: EncodedElementWithChildren<PanelProps>;\n  type: \"Panel\";\n}\n\nexport interface EncodedPopupWindowElement {\n  props: EncodedElementWithChildren<PopupWindowProps>;\n  type: \"PopupWindow\";\n}\n\nexport interface EncodedSeparatorElement {\n  props: SeparatorProps;\n  type: \"Separator\";\n}\n\nexport type TextProps = {\n  children: string;\n  className?: string | undefined;\n};\n\nexport interface EncodedTextElement {\n  props: TextProps;\n  type: \"Text\";\n}\n\nexport type EncodedElement =\n  | EncodedContainerElement\n  | EncodedDisplayModeToggleElement\n  | EncodedGroupElement\n  | EncodedPanelElement\n  | EncodedPopupWindowElement\n  | EncodedSeparatorElement\n  | EncodedTextElement;\n"
  },
  {
    "path": "integrations/vite/tests/utils/types.ts",
    "content": "export type Box = {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n};\n\nexport type Coordinates = {\n  x: number;\n  y: number;\n};\n"
  },
  {
    "path": "integrations/vite/tests/utils/updateUrl.ts",
    "content": "import type { Page } from \"@playwright/test\";\nimport type { ReactElement } from \"react\";\nimport type { GroupProps } from \"react-resizable-panels\";\nimport { encode } from \"./serializer/encode\";\n\nexport async function updateUrl(\n  page: Page,\n  element: ReactElement<GroupProps> | null,\n) {\n  const encodedString = element ? encode(element) : \"\";\n\n  await page.evaluate(\n    ([encodedString]) => {\n      const url = new URL(window.location.href);\n      url.searchParams.set(\"urlPanelGroup\", encodedString ?? \"\");\n\n      window.history.pushState(\n        { urlPanelGroup: encodedString },\n        \"\",\n        url.toString(),\n      );\n\n      window.dispatchEvent(new Event(\"popstate\"));\n    },\n    [encodedString],\n  );\n}\n"
  },
  {
    "path": "integrations/vite/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2020\", \"DOM\", \"DOM.Iterable\"],\n    \"module\": \"ESNext\",\n    \"skipLibCheck\": true,\n    \"moduleResolution\": \"bundler\",\n    \"allowImportingTsExtensions\": true,\n    \"verbatimModuleSyntax\": true,\n    \"moduleDetection\": \"force\",\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\",\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"erasableSyntaxOnly\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noUncheckedSideEffectImports\": true\n  },\n  \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "integrations/vite/vite.config.ts",
    "content": "import tailwindcss from \"@tailwindcss/vite\";\nimport { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\n// https://vite.dev/config/\nexport default defineConfig({\n  plugins: [react(), tailwindcss()],\n  server: {\n    cors: true,\n  },\n});\n"
  },
  {
    "path": "lib/components/ErrorBoundary.test.tsx",
    "content": "import {\n  createRef,\n  type PropsWithChildren,\n  type ReactElement,\n  type RefObject,\n} from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { act } from \"react-dom/test-utils\";\nimport { beforeEach, describe, expect, it, vi, type Mock } from \"vitest\";\nimport { assert } from \"../utils/assert\";\nimport { ErrorBoundary } from \"./ErrorBoundary\";\nimport type {\n  ErrorBoundaryPropsWithComponent,\n  ErrorBoundaryPropsWithFallback,\n  ErrorBoundaryPropsWithRender,\n  FallbackProps,\n  OnErrorCallback,\n} from \"../types\";\nimport { getErrorMessage } from \"../utils/getErrorMessage\";\n\ndescribe(\"ErrorBoundary\", () => {\n  let container: HTMLDivElement;\n  let root: ReturnType<typeof createRoot>;\n  let shouldThrow = true;\n  let valueToThrow: unknown;\n\n  beforeEach(() => {\n    // @ts-expect-error This is a React internal\n    global.IS_REACT_ACT_ENVIRONMENT = true;\n\n    // Don't clutter the console with expected error text\n    vi.spyOn(console, \"error\").mockImplementation(() => {\n      // No-op\n    });\n\n    container = document.createElement(\"div\");\n    root = createRoot(container);\n    shouldThrow = false;\n    valueToThrow = new Error(\"💥💥💥\");\n  });\n\n  function MaybeThrows({ children }: PropsWithChildren) {\n    if (shouldThrow) {\n      throw valueToThrow;\n    }\n    return children;\n  }\n\n  it(\"should render children\", () => {\n    const container = document.createElement(\"div\");\n    const root = createRoot(container);\n    act(() => {\n      root.render(\n        <ErrorBoundary fallback={<div>Error</div>}>\n          <MaybeThrows>Content</MaybeThrows>\n        </ErrorBoundary>,\n      );\n    });\n\n    expect(container.textContent).toBe(\"Content\");\n  });\n\n  describe(\"fallback props\", () => {\n    let errorBoundaryRef: RefObject<ErrorBoundary | null>;\n\n    beforeEach(() => {\n      errorBoundaryRef = createRef<ErrorBoundary | null>();\n    });\n\n    function render(props: Omit<ErrorBoundaryPropsWithFallback, \"fallback\">) {\n      act(() => {\n        root.render(\n          <ErrorBoundary {...props} fallback=\"Error\" ref={errorBoundaryRef}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n    }\n\n    it('should call \"onError\" prop if one is provided', () => {\n      shouldThrow = true;\n\n      const onError: Mock<OnErrorCallback> = vi.fn();\n\n      render({ onError });\n\n      expect(onError).toHaveBeenCalledTimes(1);\n      expect(getErrorMessage(onError.mock.calls[0][0])).toEqual(\"💥💥💥\");\n    });\n\n    it('should call \"onReset\" when boundary reset via imperative API', () => {\n      shouldThrow = true;\n\n      const onReset: Mock<(...args: unknown[]) => unknown> = vi.fn();\n\n      render({ onReset });\n      expect(onReset).not.toHaveBeenCalled();\n\n      act(() => errorBoundaryRef.current?.resetErrorBoundary(\"abc\", 123));\n\n      expect(onReset).toHaveBeenCalledTimes(1);\n    });\n\n    it('should call \"onReset\" when boundary reset via \"resetKeys\"', () => {\n      shouldThrow = false;\n\n      const onReset: Mock<(...args: unknown[]) => unknown> = vi.fn();\n\n      render({ onReset, resetKeys: [1] });\n      expect(onReset).not.toHaveBeenCalled();\n\n      // It should not be called if the keys change without an error\n      render({ onReset, resetKeys: [2] });\n      expect(onReset).not.toHaveBeenCalled();\n\n      shouldThrow = true;\n\n      render({ onReset, resetKeys: [2] });\n      expect(onReset).not.toHaveBeenCalled();\n\n      shouldThrow = false;\n\n      render({ onReset, resetKeys: [3] });\n      expect(onReset).toHaveBeenCalledTimes(1);\n    });\n  });\n\n  describe('\"fallback\" element', () => {\n    function render(\n      props: Omit<ErrorBoundaryPropsWithFallback, \"fallback\"> = {},\n    ) {\n      act(() => {\n        root.render(\n          <ErrorBoundary {...props} fallback={<div>Error</div>}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n    }\n\n    it(\"should render fallback in the event of an error\", () => {\n      shouldThrow = true;\n      render();\n      expect(container.textContent).toBe(\"Error\");\n    });\n\n    it(\"should re-render children if boundary is reset reset keys\", () => {\n      shouldThrow = true;\n      render({ resetKeys: [1] });\n\n      shouldThrow = false;\n      expect(container.textContent).toBe(\"Error\");\n\n      render({ resetKeys: [2] });\n      expect(container.textContent).toBe(\"Content\");\n    });\n\n    it(\"should render a null fallback if specified\", () => {\n      shouldThrow = true;\n      act(() => {\n        root.render(\n          <ErrorBoundary fallback={null}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n      expect(container.textContent).toBe(\"\");\n    });\n  });\n\n  describe('\"FallbackComponent\"', () => {\n    let fallbackComponent: Mock<(props: FallbackProps) => ReactElement>;\n    let lastRenderedError: unknown | null = null;\n    let lastRenderedResetErrorBoundary:\n      | FallbackProps[\"resetErrorBoundary\"]\n      | null = null;\n\n    function render(\n      props: Omit<ErrorBoundaryPropsWithComponent, \"FallbackComponent\"> = {},\n    ) {\n      act(() => {\n        root.render(\n          <ErrorBoundary {...props} FallbackComponent={fallbackComponent}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n    }\n\n    beforeEach(() => {\n      lastRenderedError = null;\n      lastRenderedResetErrorBoundary = null;\n\n      fallbackComponent = vi.fn();\n      fallbackComponent.mockImplementation(\n        ({ error, resetErrorBoundary }: FallbackProps) => {\n          lastRenderedError = error;\n          lastRenderedResetErrorBoundary = resetErrorBoundary;\n\n          return <div>FallbackComponent</div>;\n        },\n      );\n    });\n\n    it(\"should render fallback in the event of an error\", () => {\n      shouldThrow = true;\n      render();\n      expect(getErrorMessage(lastRenderedError)).toBe(\"💥💥💥\");\n      expect(container.textContent).toBe(\"FallbackComponent\");\n    });\n\n    it(\"should re-render children if boundary is reset via prop\", () => {\n      shouldThrow = true;\n      render();\n      expect(container.textContent).toBe(\"FallbackComponent\");\n\n      expect(lastRenderedResetErrorBoundary).not.toBeNull();\n      act(() => {\n        shouldThrow = false;\n        assert(lastRenderedResetErrorBoundary !== null);\n        lastRenderedResetErrorBoundary();\n      });\n\n      expect(container.textContent).toBe(\"Content\");\n    });\n\n    it(\"should re-render children if boundary is reset reset keys\", () => {\n      shouldThrow = true;\n      render({ resetKeys: [1] });\n      expect(container.textContent).toBe(\"FallbackComponent\");\n\n      shouldThrow = false;\n      render({ resetKeys: [2] });\n      expect(container.textContent).toBe(\"Content\");\n    });\n  });\n\n  describe('\"fallbackRender\" render prop', () => {\n    let lastRenderedError: unknown | null = null;\n    let lastRenderedResetErrorBoundary:\n      | FallbackProps[\"resetErrorBoundary\"]\n      | null = null;\n    let fallbackRender: Mock<(props: FallbackProps) => ReactElement>;\n\n    function render(\n      props: Omit<ErrorBoundaryPropsWithRender, \"fallbackRender\"> = {},\n    ) {\n      act(() => {\n        root.render(\n          <ErrorBoundary {...props} fallbackRender={fallbackRender}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n    }\n\n    beforeEach(() => {\n      lastRenderedError = null;\n      lastRenderedResetErrorBoundary = null;\n\n      fallbackRender = vi.fn();\n      fallbackRender.mockImplementation(\n        ({ error, resetErrorBoundary }: FallbackProps) => {\n          lastRenderedError = error;\n          lastRenderedResetErrorBoundary = resetErrorBoundary;\n\n          return <div>fallbackRender</div>;\n        },\n      );\n    });\n\n    it(\"should render fallback in the event of an error\", () => {\n      shouldThrow = true;\n      render();\n      expect(getErrorMessage(lastRenderedError)).toBe(\"💥💥💥\");\n      expect(fallbackRender).toHaveBeenCalled();\n      expect(container.textContent).toBe(\"fallbackRender\");\n    });\n\n    it(\"should re-render children if boundary is reset via prop\", () => {\n      shouldThrow = true;\n      render();\n      expect(getErrorMessage(lastRenderedError)).toBe(\"💥💥💥\");\n      expect(fallbackRender).toHaveBeenCalled();\n      expect(container.textContent).toBe(\"fallbackRender\");\n\n      act(() => {\n        shouldThrow = false;\n        assert(lastRenderedResetErrorBoundary !== null);\n        lastRenderedResetErrorBoundary();\n      });\n\n      expect(container.textContent).toBe(\"Content\");\n    });\n\n    it(\"should re-render children if boundary is reset reset keys\", () => {\n      shouldThrow = true;\n      render({ resetKeys: [1] });\n      expect(getErrorMessage(lastRenderedError)).toBe(\"💥💥💥\");\n      expect(fallbackRender).toHaveBeenCalled();\n      expect(container.textContent).toBe(\"fallbackRender\");\n\n      shouldThrow = false;\n      render({ resetKeys: [2] });\n      expect(container.textContent).toBe(\"Content\");\n    });\n  });\n\n  describe(\"thrown values\", () => {\n    let lastRenderedError: unknown | null = null;\n    let fallbackRender: (props: FallbackProps) => ReactElement;\n    let onError: Mock<(...args: unknown[]) => unknown>;\n\n    beforeEach(() => {\n      lastRenderedError = null;\n\n      onError = vi.fn();\n\n      fallbackRender = ({ error }: FallbackProps) => {\n        lastRenderedError = error;\n\n        return <div>Error</div>;\n      };\n    });\n\n    function render() {\n      act(() => {\n        root.render(\n          <ErrorBoundary fallbackRender={fallbackRender} onError={onError}>\n            <MaybeThrows>Content</MaybeThrows>\n          </ErrorBoundary>,\n        );\n      });\n    }\n\n    it(\"should support thrown strings\", () => {\n      shouldThrow = true;\n      valueToThrow = \"String error\";\n\n      render();\n\n      expect(lastRenderedError).toBe(\"String error\");\n      expect(onError).toHaveBeenCalledTimes(1);\n      expect(onError.mock.calls[0][0]).toEqual(\"String error\");\n      expect(container.textContent).toBe(\"Error\");\n    });\n\n    it(\"should support thrown null or undefined values\", () => {\n      shouldThrow = true;\n      valueToThrow = null;\n\n      render();\n\n      expect(lastRenderedError).toBe(null);\n      expect(onError).toHaveBeenCalledTimes(1);\n      expect(onError.mock.calls[0][0]).toEqual(null);\n      expect(container.textContent).toBe(\"Error\");\n    });\n  });\n\n  // TODO Various cases with resetKeys changing (length, order, etc)\n  // TODO Errors thrown again after reset are caught\n  // TODO Nested error boundaries if a fallback throws\n});\n"
  },
  {
    "path": "lib/components/ErrorBoundary.tsx",
    "content": "import { Component, createElement, type ErrorInfo } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport type { ErrorBoundaryProps, FallbackProps } from \"../types\";\n\nconst isDevelopment = import.meta.env.DEV;\n\ntype ErrorBoundaryState =\n  | {\n      didCatch: true;\n      error: unknown;\n    }\n  | {\n      didCatch: false;\n      error: null;\n    };\n\nconst initialState: ErrorBoundaryState = {\n  didCatch: false,\n  error: null,\n};\n\n/**\n * A reusable React [error boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) component.\n * Wrap this component around other React components to \"catch\" errors and render a fallback UI.\n *\n * This package is built on top of React [error boundaries](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),\n * so it has all of the advantages and constraints of that API.\n * This means that it can't catch errors during:\n * - Server side rendering</li>\n * - Event handlers\n * - Asynchronous code (including effects)\n *\n * ℹ️ The component provides several ways to render a fallback: `fallback`, `fallbackRender`, and `FallbackComponent`.\n * Refer to the documentation to determine which is best for your application.\n *\n * ℹ️ This is a **client component**. You can only pass props to it that are serializeable or use it in files that have a `\"use client\";` directive.\n */\nexport class ErrorBoundary extends Component<\n  ErrorBoundaryProps,\n  ErrorBoundaryState\n> {\n  constructor(props: ErrorBoundaryProps) {\n    super(props);\n\n    this.resetErrorBoundary = this.resetErrorBoundary.bind(this);\n    this.state = initialState;\n  }\n\n  static getDerivedStateFromError(error: Error) {\n    return { didCatch: true, error };\n  }\n\n  resetErrorBoundary(...args: unknown[]) {\n    const { error } = this.state;\n\n    if (error !== null) {\n      this.props.onReset?.({\n        args,\n        reason: \"imperative-api\",\n      });\n\n      this.setState(initialState);\n    }\n  }\n\n  componentDidCatch(error: unknown, info: ErrorInfo) {\n    this.props.onError?.(error, info);\n  }\n\n  componentDidUpdate(\n    prevProps: ErrorBoundaryProps,\n    prevState: ErrorBoundaryState,\n  ) {\n    const { didCatch } = this.state;\n    const { resetKeys } = this.props;\n\n    // There's an edge case where if the thing that triggered the error happens to *also* be in the resetKeys array,\n    // we'd end up resetting the error boundary immediately.\n    // This would likely trigger a second error to be thrown.\n    // So we make sure that we don't check the resetKeys on the first call of cDU after the error is set.\n\n    if (\n      didCatch &&\n      prevState.error !== null &&\n      hasArrayChanged(prevProps.resetKeys, resetKeys)\n    ) {\n      this.props.onReset?.({\n        next: resetKeys,\n        prev: prevProps.resetKeys,\n        reason: \"keys\",\n      });\n\n      this.setState(initialState);\n    }\n  }\n\n  render() {\n    const { children, fallbackRender, FallbackComponent, fallback } =\n      this.props;\n    const { didCatch, error } = this.state;\n\n    let childToRender = children;\n\n    if (didCatch) {\n      const props: FallbackProps = {\n        error,\n        resetErrorBoundary: this.resetErrorBoundary,\n      };\n\n      if (typeof fallbackRender === \"function\") {\n        childToRender = fallbackRender(props);\n      } else if (FallbackComponent) {\n        childToRender = createElement(FallbackComponent, props);\n      } else if (fallback !== undefined) {\n        childToRender = fallback;\n      } else {\n        if (isDevelopment) {\n          console.error(\n            \"react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop\",\n          );\n        }\n\n        throw error;\n      }\n    }\n\n    return createElement(\n      ErrorBoundaryContext.Provider,\n      {\n        value: {\n          didCatch,\n          error,\n          resetErrorBoundary: this.resetErrorBoundary,\n        },\n      },\n      childToRender,\n    );\n  }\n}\n\nfunction hasArrayChanged(a: unknown[] = [], b: unknown[] = []) {\n  return (\n    a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]))\n  );\n}\n"
  },
  {
    "path": "lib/context/ErrorBoundaryContext.ts",
    "content": "import { createContext } from \"react\";\n\nexport type ErrorBoundaryContextType = {\n  didCatch: boolean;\n  error: unknown | null;\n  resetErrorBoundary: (...args: unknown[]) => void;\n};\n\nexport const ErrorBoundaryContext =\n  createContext<ErrorBoundaryContextType | null>(null);\n"
  },
  {
    "path": "lib/hooks/useErrorBoundary.test.tsx",
    "content": "import { act, useLayoutEffect, type ReactNode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { ErrorBoundary } from \"../components/ErrorBoundary\";\nimport { assert } from \"../utils/assert\";\nimport { getErrorMessage } from \"../utils/getErrorMessage\";\nimport { useErrorBoundary, type UseErrorBoundaryApi } from \"./useErrorBoundary\";\n\ndescribe(\"useErrorBoundary\", () => {\n  let container: HTMLDivElement;\n\n  beforeEach(() => {\n    vi.spyOn(console, \"error\").mockImplementation(() => {\n      // Don't clutter the console with expected error text\n    });\n\n    container = document.createElement(\"div\");\n  });\n\n  function render(content: ReactNode) {\n    const root = createRoot(container);\n    act(() => {\n      root.render(content);\n    });\n    return root;\n  }\n\n  it(\"should activate and deactivate the nearest error boundary\", () => {\n    let resetBoundaryFn: UseErrorBoundaryApi[\"resetBoundary\"] | null = null;\n    let showBoundaryFn: UseErrorBoundaryApi[\"showBoundary\"] | null = null;\n\n    function Child() {\n      const { resetBoundary, showBoundary } = useErrorBoundary();\n\n      useLayoutEffect(() => {\n        resetBoundaryFn = resetBoundary;\n        showBoundaryFn = showBoundary;\n      }, [resetBoundary, showBoundary]);\n\n      return <div>Child</div>;\n    }\n\n    render(\n      <ErrorBoundary\n        fallbackRender={({ error }) => (\n          <div>Fallback: {getErrorMessage(error)}</div>\n        )}\n      >\n        <Child />\n      </ErrorBoundary>,\n    );\n    expect(container.textContent).toBe(\"Child\");\n\n    act(() => {\n      assert(showBoundaryFn != null);\n      showBoundaryFn(new Error(\"Example\"));\n    });\n    expect(container.textContent).toBe(\"Fallback: Example\");\n\n    act(() => {\n      assert(resetBoundaryFn != null);\n      resetBoundaryFn();\n    });\n    expect(container.textContent).toBe(\"Child\");\n  });\n\n  it(\"should expose the current error to a fallback component\", () => {\n    const errorToThrow = new Error(\"Thrown\");\n\n    function Child() {\n      const { error } = useErrorBoundary();\n      expect(error).toBe(null);\n\n      throw errorToThrow;\n\n      return null;\n    }\n\n    function Fallback() {\n      const { error } = useErrorBoundary();\n      expect(error).toBe(errorToThrow);\n\n      return \"Fallback\";\n    }\n\n    render(\n      <ErrorBoundary FallbackComponent={Fallback}>\n        <Child />\n      </ErrorBoundary>,\n    );\n\n    expect(container.textContent).toBe(\"Fallback\");\n  });\n});\n"
  },
  {
    "path": "lib/hooks/useErrorBoundary.ts",
    "content": "import { useContext, useMemo, useState } from \"react\";\nimport { ErrorBoundaryContext } from \"../context/ErrorBoundaryContext\";\nimport { assertErrorBoundaryContext } from \"../utils/assertErrorBoundaryContext\";\n\ntype UseErrorBoundaryState =\n  | { error: unknown; hasError: true }\n  | { error: null; hasError: false };\n\nexport type UseErrorBoundaryApi = {\n  error: unknown | null;\n  resetBoundary: () => void;\n  showBoundary: (error: unknown) => void;\n};\n\n/**\n * Convenience hook for imperatively showing or dismissing error boundaries.\n *\n * ⚠️ This hook must only be used within an `ErrorBoundary` subtree.\n */\nexport function useErrorBoundary(): {\n  /**\n   * The currently visible `Error` (if one has been thrown).\n   */\n  error: unknown | null;\n\n  /**\n   * Method to reset and retry the nearest active error boundary (if one is active).\n   */\n  resetBoundary: () => void;\n\n  /**\n   * Trigger the nearest error boundary to display the error provided.\n   *\n   * ℹ️ React only handles errors thrown during render or during component lifecycle methods (e.g. effects and did-mount/did-update).\n   * Errors thrown in event handlers, or after async code has run, will not be caught.\n   * This method is a way to imperatively trigger an error boundary during these phases.\n   */\n  showBoundary: (error: unknown) => void;\n} {\n  const context = useContext(ErrorBoundaryContext);\n\n  assertErrorBoundaryContext(context);\n\n  const { error, resetErrorBoundary } = context;\n\n  const [state, setState] = useState<UseErrorBoundaryState>({\n    error: null,\n    hasError: false,\n  });\n\n  const memoized = useMemo(\n    () => ({\n      error,\n      resetBoundary: () => {\n        resetErrorBoundary();\n        setState({ error: null, hasError: false });\n      },\n      showBoundary: (error: unknown) =>\n        setState({\n          error,\n          hasError: true,\n        }),\n    }),\n    [error, resetErrorBoundary],\n  );\n\n  if (state.hasError) {\n    throw state.error;\n  }\n\n  return memoized;\n}\n"
  },
  {
    "path": "lib/index.ts",
    "content": "\"use client\";\n\nexport { ErrorBoundary } from \"./components/ErrorBoundary\";\nexport { ErrorBoundaryContext } from \"./context/ErrorBoundaryContext\";\nexport { useErrorBoundary } from \"./hooks/useErrorBoundary\";\nexport { getErrorMessage } from \"./utils/getErrorMessage\";\nexport { withErrorBoundary } from \"./utils/withErrorBoundary\";\n\nexport type { ErrorBoundaryContextType } from \"./context/ErrorBoundaryContext\";\nexport type { UseErrorBoundaryApi } from \"./hooks/useErrorBoundary\";\nexport type {\n  ErrorBoundaryProps,\n  ErrorBoundaryPropsWithComponent,\n  ErrorBoundaryPropsWithFallback,\n  ErrorBoundaryPropsWithRender,\n  FallbackProps,\n  OnErrorCallback,\n} from \"./types\";\n"
  },
  {
    "path": "lib/types.ts",
    "content": "import type {\n  ComponentType,\n  ErrorInfo,\n  PropsWithChildren,\n  ReactNode,\n} from \"react\";\n\nexport type FallbackProps = {\n  error: unknown;\n  resetErrorBoundary: (...args: unknown[]) => void;\n};\n\nexport type OnErrorCallback = (error: unknown, info: ErrorInfo) => void;\n\ntype ErrorBoundarySharedProps = PropsWithChildren<{\n  /**\n   * Optional callback to enable e.g. logging error information to a server.\n   *\n   * @param error Value that was thrown; typically an instance of `Error`\n   * @param info React \"component stack\" identifying where the error was thrown\n   */\n  onError?: (error: unknown, info: ErrorInfo) => void;\n\n  /**\n   * Optional callback to to be notified when an error boundary is \"reset\" so React can retry the failed render.\n   */\n  onReset?: (\n    details:\n      | { reason: \"imperative-api\"; args: unknown[] }\n      | {\n          reason: \"keys\";\n          prev: unknown[] | undefined;\n          next: unknown[] | undefined;\n        },\n  ) => void;\n\n  /**\n   * When changed, these keys will reset a triggered error boundary.\n   * This can be useful when an error condition may be tied to some specific state (that can be uniquely identified by key).\n   * See the the documentation for examples of how to use this prop.\n   */\n  resetKeys?: unknown[];\n}>;\n\nexport type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {\n  fallback?: never;\n  /**\n   * React component responsible for returning a fallback UI based on a thrown value.\n   *\n   * ```tsx\n   * <ErrorBoundary FallbackComponent={Fallback} />\n   * ```\n   */\n  FallbackComponent: ComponentType<FallbackProps>;\n  fallbackRender?: never;\n};\n\nexport type ErrorBoundaryPropsWithRender = ErrorBoundarySharedProps & {\n  fallback?: never;\n  FallbackComponent?: never;\n  /**\n   * [Render prop](https://react.dev/reference/react/Children#calling-a-render-prop-to-customize-rendering) function responsible for returning a fallback UI based on a thrown value.\n   *\n   * ```tsx\n   * <ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) => <div>...</div>} />\n   * ```\n   */\n  fallbackRender: (props: FallbackProps) => ReactNode;\n};\n\nexport type ErrorBoundaryPropsWithFallback = ErrorBoundarySharedProps & {\n  /**\n   * Static content to render in place of an error if one is thrown.\n   *\n   * ```tsx\n   * <ErrorBoundary fallback={<div className=\"text-red\">Something went wrong</div>} />\n   * ```\n   */\n  fallback: ReactNode;\n  FallbackComponent?: never;\n  fallbackRender?: never;\n};\n\nexport type ErrorBoundaryProps =\n  | ErrorBoundaryPropsWithFallback\n  | ErrorBoundaryPropsWithComponent\n  | ErrorBoundaryPropsWithRender;\n"
  },
  {
    "path": "lib/utils/assert.ts",
    "content": "export function assert(\n  expectedCondition: unknown,\n  message: string = \"Assertion error\",\n): asserts expectedCondition {\n  if (!expectedCondition) {\n    throw Error(message);\n  }\n}\n"
  },
  {
    "path": "lib/utils/assertErrorBoundaryContext.ts",
    "content": "import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\nimport { isErrorBoundaryContext } from \"./isErrorBoundaryContext\";\n\nexport function assertErrorBoundaryContext(\n  value: unknown,\n): asserts value is ErrorBoundaryContextType {\n  if (!isErrorBoundaryContext(value)) {\n    throw new Error(\"ErrorBoundaryContext not found\");\n  }\n}\n"
  },
  {
    "path": "lib/utils/getErrorMessage.ts",
    "content": "export function getErrorMessage(thrown: unknown): string | undefined {\n  switch (typeof thrown) {\n    case \"object\": {\n      if (\n        thrown !== null &&\n        \"message\" in thrown &&\n        typeof thrown.message === \"string\"\n      ) {\n        return thrown.message;\n      }\n      break;\n    }\n    case \"string\": {\n      return thrown;\n    }\n  }\n}\n"
  },
  {
    "path": "lib/utils/isErrorBoundaryContext.ts",
    "content": "import type { ErrorBoundaryContextType } from \"../context/ErrorBoundaryContext\";\n\nexport function isErrorBoundaryContext(\n  value: unknown,\n): value is ErrorBoundaryContextType {\n  return (\n    value !== null &&\n    typeof value === \"object\" &&\n    \"didCatch\" in value &&\n    typeof value.didCatch === \"boolean\" &&\n    \"error\" in value &&\n    \"resetErrorBoundary\" in value &&\n    typeof value.resetErrorBoundary === \"function\"\n  );\n}\n"
  },
  {
    "path": "lib/utils/withErrorBoundary.test.tsx",
    "content": "import { Component, createRef, type PropsWithChildren } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { act } from \"react-dom/test-utils\";\nimport { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { withErrorBoundary } from \"./withErrorBoundary\";\n\ndescribe(\"withErrorBoundary\", () => {\n  let container: HTMLDivElement;\n  let root: ReturnType<typeof createRoot>;\n  let shouldThrow = true;\n  let valueToThrow: unknown;\n\n  beforeEach(() => {\n    // @ts-expect-error This is a React internal\n    global.IS_REACT_ACT_ENVIRONMENT = true;\n\n    // Don't clutter the console with expected error text\n    vi.spyOn(console, \"error\").mockImplementation(() => {\n      // No-op\n    });\n\n    container = document.createElement(\"div\");\n    root = createRoot(container);\n    shouldThrow = false;\n    valueToThrow = new Error(\"💥💥💥\");\n  });\n\n  function MaybeThrows({ children = \"Children\" }: PropsWithChildren) {\n    if (shouldThrow) {\n      throw valueToThrow;\n    }\n    return children;\n  }\n\n  function render() {\n    const ErrorBoundary = withErrorBoundary(MaybeThrows, {\n      fallback: <div>Error</div>,\n    });\n\n    act(() => {\n      root.render(<ErrorBoundary />);\n    });\n  }\n\n  it(\"should render children within the created HOC\", () => {\n    render();\n    expect(container.textContent).toBe(\"Children\");\n  });\n\n  it(\"should catch errors with the created HOC\", () => {\n    shouldThrow = true;\n    render();\n    expect(container.textContent).toBe(\"Error\");\n  });\n\n  it(\"should forward refs\", () => {\n    type Props = { foo: string };\n\n    class Inner extends Component<Props> {\n      test() {\n        // No-op\n      }\n      render() {\n        return this.props.foo;\n      }\n    }\n\n    const Wrapped = withErrorBoundary(Inner, {\n      fallback: <div>Error</div>,\n    });\n\n    const ref = createRef<Inner>();\n\n    act(() => {\n      root.render(<Wrapped foo=\"abc\" ref={ref} />);\n    });\n\n    expect(ref.current).not.toBeNull();\n    expect(typeof ref.current?.test).toBe(\"function\");\n  });\n});\n"
  },
  {
    "path": "lib/utils/withErrorBoundary.ts",
    "content": "import {\n  createElement,\n  forwardRef,\n  type ComponentClass,\n  type ComponentType,\n} from \"react\";\nimport { ErrorBoundary } from \"../components/ErrorBoundary\";\nimport type { ErrorBoundaryProps } from \"../types\";\n\nexport function withErrorBoundary<\n  Type extends ComponentClass<unknown>,\n  Props extends object,\n>(Component: ComponentType<Props>, errorBoundaryProps: ErrorBoundaryProps) {\n  const Wrapped = forwardRef<InstanceType<Type>, Props>((props, ref) =>\n    createElement(\n      ErrorBoundary,\n      errorBoundaryProps,\n      createElement(Component, { ...props, ref } as Props),\n    ),\n  );\n\n  // Format for display in DevTools\n  const name = Component.displayName || Component.name || \"Unknown\";\n  Wrapped.displayName = `withErrorBoundary(${name})`;\n\n  return Wrapped;\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-error-boundary\",\n  \"version\": \"6.1.1\",\n  \"type\": \"module\",\n  \"description\": \"Simple reusable React error boundary component\",\n  \"author\": \"Brian Vaughn <brian.david.vaughn@gmail.com>\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/bvaughn/react-error-boundary\"\n  },\n  \"contributors\": [\n    \"Brian Vaughn <brian.david.vaughn@gmail.com> (https://github.com/bvaughn/)\"\n  ],\n  \"homepage\": \"https://react-error-boundary-lib.vercel.app/\",\n  \"keywords\": [\n    \"react\",\n    \"reactjs\",\n    \"virtual\",\n    \"window\",\n    \"windowed\",\n    \"list\",\n    \"scrolling\",\n    \"infinite\",\n    \"virtualized\",\n    \"table\",\n    \"grid\",\n    \"spreadsheet\"\n  ],\n  \"main\": \"dist/react-error-boundary.cjs\",\n  \"module\": \"dist/react-error-boundary.js\",\n  \"types\": \"dist/react-error-boundary.d.ts\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"dev:integrations\": \"pnpm -C integrations/vite/ run dev\",\n    \"build\": \"pnpm run build:lib && pnpm run build:docs\",\n    \"build:docs\": \"TARGET=docs vite build\",\n    \"build:lib\": \"TARGET=lib vite build\",\n    \"compile\": \"pnpm run compile:docs && pnpm run compile:examples\",\n    \"compile:docs\": \"tsx ./scripts/compile-docs\",\n    \"compile:examples\": \"tsx ./scripts/compile-examples\",\n    \"compress:og-image\": \"tsx ./scripts/compress-og-image\",\n    \"lint\": \"eslint .\",\n    \"prerelease\": \"rm -rf dist && pnpm run build:lib\",\n    \"prettier\": \"prettier --write \\\"**/*.{css,html,js,json,jsx,ts,tsx}\\\"\",\n    \"prettier:ci\": \"prettier --check \\\"**/*.{css,html,js,json,jsx,ts,tsx}\\\"\",\n    \"preview\": \"vite preview\",\n    \"test\": \"vitest\",\n    \"test:ci\": \"vitest run\",\n    \"test:debug\": \"vitest --inspect-brk=127.0.0.1:3000 --no-file-parallelism\",\n    \"tsc\": \"tsc -b\"\n  },\n  \"lint-staged\": {\n    \"**/*\": \"prettier --write --ignore-unknown\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^18.0.0 || ^19.0.0\"\n  },\n  \"devDependencies\": {\n    \"@csstools/postcss-oklab-function\": \"^4.0.11\",\n    \"@eslint/js\": \"^9.30.1\",\n    \"@headlessui/react\": \"^2.2.4\",\n    \"@headlessui/tailwindcss\": \"^0.2.2\",\n    \"@heroicons/react\": \"^2.2.0\",\n    \"@tailwindcss/vite\": \"^4.1.11\",\n    \"@tailwindplus/elements\": \"^1.0.5\",\n    \"@testing-library/jest-dom\": \"^6.6.4\",\n    \"@testing-library/react\": \"^16.3.0\",\n    \"@testing-library/user-event\": \"^14.6.1\",\n    \"@types/bytes\": \"^3.1.5\",\n    \"@types/compression\": \"^1.8.1\",\n    \"@types/markdown-it\": \"^14.1.2\",\n    \"@types/node\": \"^24.2.0\",\n    \"@types/react\": \"^19.1.8\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@types/sharp\": \"^0.32.0\",\n    \"@vitejs/plugin-react-swc\": \"^3.10.2\",\n    \"bytes\": \"^3.1.2\",\n    \"clsx\": \"^2.1.1\",\n    \"compression\": \"^1.8.1\",\n    \"csstype\": \"^3.1.3\",\n    \"eslint\": \"^9.30.1\",\n    \"eslint-plugin-react-hooks\": \"^5.2.0\",\n    \"eslint-plugin-react-refresh\": \"^0.4.20\",\n    \"globals\": \"^16.3.0\",\n    \"husky\": \"^9.1.7\",\n    \"jsdom\": \"^26.1.0\",\n    \"lint-staged\": \"^16.1.4\",\n    \"markdown-it\": \"^14.1.0\",\n    \"marked\": \"^16.4.1\",\n    \"postcss\": \"^8.5.6\",\n    \"prettier\": \"3.6.2\",\n    \"prettier-plugin-tailwindcss\": \"^0.7.1\",\n    \"react\": \"^19.2.3\",\n    \"react-docgen-typescript\": \"^2.4.0\",\n    \"react-dom\": \"^19.2.3\",\n    \"react-error-boundary\": \"^6.0.0\",\n    \"react-lib-tools\": \"^0.0.34\",\n    \"react-router-dom\": \"^7.6.3\",\n    \"rollup-plugin-terser\": \"^7.0.2\",\n    \"rollup-plugin-visualizer\": \"^6.0.3\",\n    \"rollup-preserve-directives\": \"^1.1.3\",\n    \"sharp\": \"^0.34.5\",\n    \"sirv\": \"^3.0.2\",\n    \"tailwind-merge\": \"^3.3.1\",\n    \"tailwindcss\": \"^4.1.11\",\n    \"terser\": \"^5.43.1\",\n    \"ts-blank-space\": \"^0.6.2\",\n    \"ts-node\": \"^10.9.2\",\n    \"tsx\": \"^4.21.0\",\n    \"typescript\": \"~5.8.3\",\n    \"typescript-eslint\": \"^8.35.1\",\n    \"typescript-json-schema\": \"^0.65.1\",\n    \"vite\": \"^7.0.4\",\n    \"vite-plugin-dts\": \"^4.5.4\",\n    \"vite-plugin-svgr\": \"^4.3.0\",\n    \"vitest\": \"^3.2.4\",\n    \"vitest-fail-on-console\": \"^0.10.1\",\n    \"zustand\": \"^5.0.7\"\n  }\n}\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - integrations/*\n  - lib/*\n  - src/*"
  },
  {
    "path": "public/generated/examples/AsyncUserCodeErrors.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">useErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">useUserProfileInfo</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">username</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName tok-definition\\\">username</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">string</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-keyword\\\">const</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">showBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">=</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName\\\">useErrorBoundary</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-variableName\\\">useEffect</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-variableName\\\">fetchGreeting</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">username</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-operator\\\">.</span><span class=\\\"tok-propertyName\\\">then</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">response</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">        </span><span class=\\\"tok-comment\\\">// Set data in state and re-render ...</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">error</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">        </span><span class=\\\"tok-comment\\\">// Show error boundary</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">        </span><span class=\\\"tok-variableName\\\">showBoundary</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">error</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/ErrorLogging.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">type</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">ErrorInfo</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">ErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">logError</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">error</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">unknown</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">info</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">ErrorInfo</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Do something with the error, e.g. log to an external API</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">FallbackComponent</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">ErrorFallback</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">onError</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">logError</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">YourApplication</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">/&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/FallbackComponent.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">getErrorMessage</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">type</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">FallbackProps</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">Fallback</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">error</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">resetErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">FallbackProps</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-keyword\\\">return</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">role</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-string\\\">\\\"alert\\\"</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">p</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Something went wrong:</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">p</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">pre</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">style</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName tok-definition\\\">color</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"red\\\"</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">getErrorMessage</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">error</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">pre</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">button</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">onClick</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">resetErrorBoundary</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Retry</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">button</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">FallbackComponent</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">Fallback</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">onReset</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">details</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// Reset the state of your app so the error doesn't happen again</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">YourApplication</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">/&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/FallbackContent.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">ErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">fallback</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Something went wrong</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">YourApplication</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">/&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/GetErrorMessage.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">getErrorMessage</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">type</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">FallbackProps</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">Fallback</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">error</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">FallbackProps</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Because 'error' can be anything, it's safest not to assume it's an Error</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Use the getErrorMessage helper method to extract the message instead.</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-keyword\\\">const</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">message</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">=</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName\\\">getErrorMessage</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">error</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">??</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"Unknown error\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Render fallback UI...</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/NpmResolution.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">\\\"overrides\\\"</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-propertyName\\\">\\\"@types/react\\\"</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"17.0.60\\\"</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/RenderProp.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">getErrorMessage</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">fallbackRender</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">error</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">resetErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">role</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-string\\\">\\\"alert\\\"</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">p</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Something went wrong:</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">p</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">pre</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">style</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName tok-definition\\\">color</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"red\\\"</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">getErrorMessage</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">error</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">pre</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">      </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">button</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">onClick</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-variableName\\\">resetErrorBoundary</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Retry</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">button</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">onReset</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">details</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">=&#62;</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// Reset the state of your app so the error doesn't happen again</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">YourApplication</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">/&#62;</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">ErrorBoundary</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/ResetWithUseErrorBoundary.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">useErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">Example</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-keyword\\\">const</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">resetBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">=</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName\\\">useErrorBoundary</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Call resetBoundary() to reset the nearest ErrorBoundary and retry a failed render</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/UseClient.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-string\\\">\\\"use client\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-comment\\\">// Imports and components code go here...</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/UseErrorBoundary.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">useErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">Example</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-keyword\\\">const</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// The currently visible Error (if one has been thrown).</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-propertyName\\\">error</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// Method to reset and retry the nearest active error boundary (if one is active).</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-propertyName\\\">resetBoundary</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// Trigger the nearest error boundary to display the error provided.</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-propertyName\\\">showBoundary</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">   </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">=</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName\\\">useErrorBoundary</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// ...</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/WithErrorBoundaryA.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">function</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">UserProfile</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">username</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName tok-definition\\\">username</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-typeName\\\">string</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-comment\\\">// Render...</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/WithErrorBoundaryB.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-keyword\\\">import</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">withErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"> </span><span class=\\\"tok-keyword\\\">from</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"react-error-boundary\\\"</span><span class=\\\"tok-punctuation\\\">;</span><span class=\\\"\\\"></span></div>\\n<div>&nbsp;</div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-keyword\\\">const</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">UserProfileWithErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-operator\\\">=</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName\\\">withErrorBoundary</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName\\\">UserProfile</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName tok-definition\\\">fallback</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"\\\">Something went wrong</span><span class=\\\"tok-punctuation\\\">&#60;/</span><span class=\\\"tok-typeName\\\">div</span><span class=\\\"tok-punctuation\\\">&#62;</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName tok-definition\\\">onError</span><span class=\\\"tok-punctuation\\\">(</span><span class=\\\"tok-variableName tok-definition\\\">error</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"> </span><span class=\\\"tok-variableName tok-definition\\\">info</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// Do something with the error</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-comment\\\">// E.g. log to an error logging client here</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">,</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"tok-punctuation\\\">)</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/WithErrorBoundaryC.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-punctuation\\\">&#60;</span><span class=\\\"tok-typeName\\\">UserProfileWithErrorBoundary</span><span class=\\\"\\\"> </span><span class=\\\"tok-propertyName\\\">username</span><span class=\\\"tok-operator\\\">=</span><span class=\\\"tok-string\\\">\\\"Brian\\\"</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">/&#62;</span><span class=\\\"tok-punctuation\\\">;</span></div>\"\n}"
  },
  {
    "path": "public/generated/examples/YarnResolution.json",
    "content": "{\n  \"html\": \"<div><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-propertyName\\\">\\\"resolutions\\\"</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-punctuation\\\">{</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">    </span><span class=\\\"tok-propertyName\\\">\\\"@types/react\\\"</span><span class=\\\"tok-punctuation\\\">:</span><span class=\\\"\\\"> </span><span class=\\\"tok-string\\\">\\\"17.0.60\\\"</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\">  </span><span class=\\\"tok-punctuation\\\">}</span><span class=\\\"\\\"></span></div>\\n<div><span class=\\\"\\\"></span><span class=\\\"tok-punctuation\\\">}</span></div>\"\n}"
  },
  {
    "path": "public/robots.txt",
    "content": "User-agent: *\nAllow: /"
  },
  {
    "path": "scripts/compile-docs.ts",
    "content": "import { compileDocs } from \"react-lib-tools/scripts/compile-docs.ts\";\n\nawait compileDocs({\n  componentNames: [\"ErrorBoundary\"],\n  imperativeHandleNames: [],\n});\n"
  },
  {
    "path": "scripts/compile-examples.ts",
    "content": "import { compileExamples } from \"react-lib-tools/scripts/compile-examples.ts\";\n\nawait compileExamples();\n"
  },
  {
    "path": "scripts/compress-og-image",
    "content": "import { compressOgImage } from \"react-lib-tools/scripts/compress-og-image.ts\";\n\nawait compressOgImage();"
  },
  {
    "path": "src/App.tsx",
    "content": "import {\n  AppRoot,\n  Callout,\n  Code,\n  ExternalLink,\n  NavSection,\n  type CommonQuestion,\n} from \"react-lib-tools\";\nimport { repository } from \"../package.json\";\nimport { html as htmlNpmResolution } from \"../public/generated/examples/NpmResolution.json\";\nimport { html as htmlYarnResolution } from \"../public/generated/examples/YarnResolution.json\";\nimport { Link } from \"./components/Link\";\nimport { NavLink } from \"./components/NavLink\";\nimport { routes } from \"./routes\";\n\nexport default function App() {\n  return (\n    <AppRoot\n      commonQuestions={commonQuestions}\n      navLinks={\n        <div>\n          <NavLink path=\"/\">Getting started</NavLink>\n          <NavSection label=\"Examples\">\n            <NavLink path=\"/examples/fallback\">Fallback content</NavLink>\n            <NavLink path=\"/examples/render-prop\">Render prop</NavLink>\n            <NavLink path=\"/examples/fallback-component\">\n              Fallback component\n            </NavLink>\n            <NavLink path=\"/examples/error-logging\">Error logging</NavLink>\n            <NavLink path=\"/examples/async-user-code-errors\">\n              Async user code errors\n            </NavLink>\n            <NavLink path=\"/examples/retry-nearest-boundary\">\n              Retry nearest boundary\n            </NavLink>\n          </NavSection>\n          <NavSection label=\"API\">\n            <NavLink path=\"/api/error-boundary-props\">ErrorBoundary</NavLink>\n            <NavLink path=\"/api/use-error-boundary-hook\">\n              useErrorBoundary hook\n            </NavLink>\n            <NavLink path=\"/api/with-error-boundary-hoc\">\n              withErrorBoundary HOC\n            </NavLink>\n            <NavLink path=\"/api/get-error-message\">\n              getErrorMessage helper\n            </NavLink>\n          </NavSection>\n          <NavLink path=\"/common-questions\">Common questions</NavLink>\n          <NavLink path=\"/support\">Support</NavLink>\n        </div>\n      }\n      overview={\n        <>\n          <div>\n            React components and utils for managing runtime errors. Supports all\n            React renderers (including React DOM and React Native).\n          </div>\n          <Callout children={clientSideWarning} intent=\"warning\" />\n        </>\n      }\n      packageDescription=\"runtime error handling\"\n      packageName=\"react-error-boundary\"\n      repositoryUrl={repository.url}\n      routes={routes}\n    />\n  );\n}\n\nconst clientSideWarning = (\n  <div className=\"flex flex-col gap-2\">\n    <div>\n      This package is built on top of React{\" \"}\n      <ExternalLink href=\"https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary\">\n        error boundaries\n      </ExternalLink>\n      , so it has all of the advantages and constraints of that API.\n    </div>\n    <div>This means that it can't catch errors during:</div>\n    <ul className=\"pl-8\">\n      <li className=\"list-disc\">Server side rendering</li>\n      <li className=\"list-disc\">Event handlers</li>\n      <li className=\"list-disc\">Asynchronous code (including effects)</li>\n    </ul>\n    <div>\n      You <em>can</em> show an error boundary for asynchronous code, but you\n      have to catch the error yourself.{\" \"}\n      <Link to=\"/examples/async-user-code-errors\">Learn more</Link>.\n    </div>\n  </div>\n);\n\nconst commonQuestions: CommonQuestion[] = [\n  {\n    id: \"uncaught-error\",\n    question: \"Why didn't the boundary catch my error?\",\n    answer: clientSideWarning,\n  },\n  {\n    id: \"react-types-mismatch\",\n    question: (\n      <>\n        <code>ErrorBoundary</code> cannot be used as a JSX component\n      </>\n    ),\n    answer: (\n      <>\n        <p>\n          This error can be caused by a version mismatch between{\" \"}\n          <code>react</code> and <code>@types/react</code>. To fix this, ensure\n          that both match exactly.\n        </p>\n        <p>\n          For NPM, you may need to use an{\" \"}\n          <ExternalLink href=\"https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides\">\n            override\n          </ExternalLink>\n          :\n        </p>\n        <Code html={htmlNpmResolution} />\n        <p>\n          Yarn has a similar mechanism called a{\" \"}\n          <ExternalLink href=\"https://yarnpkg.com/cli/set/resolution\">\n            resolution\n          </ExternalLink>\n          :\n        </p>\n        <Code html={htmlYarnResolution} />\n      </>\n    ),\n  },\n];\n"
  },
  {
    "path": "src/components/ContinueLink.tsx",
    "content": "import type { Path } from \"../routes\";\nimport { Link } from \"./Link\";\n\nexport function ContinueLink({ title, to }: { title: string; to: Path }) {\n  return (\n    <div>\n      Continue to <Link to={to}>{title}</Link>…\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/components/Divider.tsx",
    "content": "export function Divider() {\n  return <hr className=\"h-px bg-slate-800 border-0\" />;\n}\n"
  },
  {
    "path": "src/components/Link.tsx",
    "content": "import type { HTMLAttributes } from \"react\";\nimport { Link as ExternalLink } from \"react-lib-tools\";\nimport type { Path } from \"../routes\";\n\nexport function Link({\n  to,\n  ...rest\n}: HTMLAttributes<HTMLSpanElement> & {\n  to: Path;\n}) {\n  return <ExternalLink to={to} {...rest} />;\n}\n"
  },
  {
    "path": "src/components/NavLink.tsx",
    "content": "import { type PropsWithChildren } from \"react\";\nimport { NavLink as NavLinkExternal, type DefaultPath } from \"react-lib-tools\";\nimport { type Path } from \"../routes\";\n\nexport function NavLink({\n  children,\n  className,\n  path,\n}: PropsWithChildren<{\n  className?: string | undefined;\n  path: Path | DefaultPath;\n}>) {\n  return (\n    <NavLinkExternal children={children} className={className} path={path} />\n  );\n}\n"
  },
  {
    "path": "src/routes/AsyncUserCodeErrorsRoute.tsx",
    "content": "import { Box, Code, Header, Link } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/AsyncUserCodeErrors.json\";\n\nexport default function AsyncUserCodeErrorsRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Async user code errors\" />\n      <div>\n        React only handles errors thrown during render or during component\n        lifecycle methods (e.g. effects and did-mount/did-update). Errors thrown\n        in event handlers, or after async code has run, will not be caught.\n      </div>\n      <div>\n        The <Link to=\"/api/use-error-boundary-hook\">useErrorBoundary</Link> hook\n        can be used to pass those errors to the nearest error boundary:\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/ErrorBoundaryPropsRoute.tsx",
    "content": "import { Box, ComponentProps, type ComponentMetadata } from \"react-lib-tools\";\nimport json from \"../../public/generated/docs/ErrorBoundary.json\";\n\nexport default function ErrorBoundaryPropsRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <ComponentProps json={json as ComponentMetadata} section=\"API\" />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/ErrorLoggingRoute.tsx",
    "content": "import { Box, Code, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/ErrorLogging.json\";\n\nexport default function ErrorLoggingRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Error logging\" />\n      <div>\n        Use the <code>onError</code> callback to log errors to a service like\n        Sentry.\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/FallbackComponentRoute.tsx",
    "content": "import { Box, Code, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/FallbackComponent.json\";\n\nexport default function FallbackComponentRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Fallback component\" />\n      <div>\n        React component responsible for returning a fallback UI based on a\n        thrown value.\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/FallbackContentRoute.tsx",
    "content": "import { Box, Code, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/FallbackContent.json\";\n\nexport default function RenderPropRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Fallback content\" />\n      <div>The simplest way to render a default error message.</div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/GetErrorMessageRoute.tsx",
    "content": "import { Box, Code, ExternalLink, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/GetErrorMessage.json\";\n\nexport default function GetErrorMessageRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"API\" title=\"getErrorMessage helper\" />\n      <div>\n        Typically <em>thrown</em> errors in JavaScript are instances of type{\" \"}\n        <code>Error</code>, but{\" \"}\n        <ExternalLink href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw\">\n          this is not always the case\n        </ExternalLink>\n        . Any value can be thrown- strings, numbers, even <code>null</code> or{\" \"}\n        <code>undefined</code>.\n      </div>\n      <div>\n        To simplify working with thrown values, this library exports a utility\n        method called <code>getErrorMessage</code>.\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/RenderPropRoute.tsx",
    "content": "import { Box, Code, ExternalLink, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/RenderProp.json\";\n\nexport default function RenderPropRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Render props\" />\n      <div>\n        <ExternalLink href=\"https://react.dev/reference/react/Children#calling-a-render-prop-to-customize-rendering\">\n          Render prop\n        </ExternalLink>{\" \"}\n        function responsible for returning a fallback UI based on a thrown\n        value.\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/ResetNearestBoundaryRoute.tsx",
    "content": "import { Box, Code, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/ResetWithUseErrorBoundary.json\";\nimport { Link } from \"../components/Link\";\n\nexport default function ResetNearestBoundaryRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"Examples\" title=\"Reset nearest boundary\" />\n      <div>\n        The <Link to=\"/api/use-error-boundary-hook\">useErrorBoundary</Link> hook\n        can be used to reset the nearest error boundary and retry a failed\n        render attempt.\n      </div>\n      <Code html={html} />\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/UseErrorBoundaryRoute.tsx",
    "content": "import { Box, Callout, Code, Header } from \"react-lib-tools\";\nimport { html } from \"../../public/generated/examples/UseErrorBoundary.json\";\n\nexport default function UseErrorBoundaryRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"API\" title=\"useErrorBoundary hook\" />\n      <div>\n        Convenience hook for imperatively showing or dismissing error\n        boundaries.\n      </div>\n      <Code html={html} />\n      <Callout intent=\"warning\">\n        This hook must only be used within an <code>ErrorBoundary</code>{\" \"}\n        subtree.\n      </Callout>\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/WithErrorBoundaryRoute.tsx",
    "content": "import { Box, Code, ExternalLink, Header } from \"react-lib-tools\";\nimport { html as htmlA } from \"../../public/generated/examples/WithErrorBoundaryA.json\";\nimport { html as htmlB } from \"../../public/generated/examples/WithErrorBoundaryB.json\";\nimport { html as htmlC } from \"../../public/generated/examples/WithErrorBoundaryC.json\";\n\nexport default function WithErrorBoundaryRoute() {\n  return (\n    <Box direction=\"column\" gap={4}>\n      <Header section=\"API\" title=\"withErrorBoundary HOC\" />\n      <div>\n        This package can also be used as a{\" \"}\n        <ExternalLink href=\"https://legacy.reactjs.org/docs/higher-order-components.html\">\n          higher-order component\n        </ExternalLink>\n        . For example, given a component like this:\n      </div>\n      <Code html={htmlA} />\n      <div>\n        You could use the <code>withErrorBoundary</code> HOC to create a wrapper\n        component:\n      </div>\n      <Code html={htmlB} />\n      <div>And then render it like this</div>\n      <Code html={htmlC} />\n      <div>\n        This might be useful for certain types of reusable/library components.\n      </div>\n    </Box>\n  );\n}\n"
  },
  {
    "path": "src/routes/examples/AsyncUserCodeErrors.tsx",
    "content": "import { useEffect } from \"react\"; // hidden\nimport { useErrorBoundary } from \"react-error-boundary\";\n\nfunction useUserProfileInfo({ username }: { username: string }) {\n  const { showBoundary } = useErrorBoundary();\n\n  useEffect(() => {\n    fetchGreeting(username).then(\n      (response) => {\n        // Set data in state and re-render ...\n        response; // hidden\n      },\n      (error) => {\n        // Show error boundary\n        showBoundary(error);\n      }\n    );\n  });\n}\n\n// <end>\n\nexport { useUserProfileInfo };\n\nasync function fetchGreeting(_: string) {}\n"
  },
  {
    "path": "src/routes/examples/ErrorLogging.tsx",
    "content": "import type { ErrorInfo } from \"react\";\nimport { ErrorBoundary } from \"react-error-boundary\";\n\nfunction logError(error: unknown, info: ErrorInfo) {\n  // Do something with the error, e.g. log to an external API\n  error; // hidden\n  info; // hidden\n}\n\n<ErrorBoundary FallbackComponent={ErrorFallback} onError={logError}>\n  <YourApplication />\n</ErrorBoundary>;\n\n// <end>\n\nfunction ErrorFallback() {\n  return null;\n}\n\nfunction YourApplication() {\n  return null;\n}\n"
  },
  {
    "path": "src/routes/examples/FallbackComponent.tsx",
    "content": "import { ErrorBoundary, getErrorMessage, type FallbackProps } from \"react-error-boundary\";\n\nfunction Fallback({ error, resetErrorBoundary }: FallbackProps) {\n  return (\n    <div role=\"alert\">\n      <p>Something went wrong:</p>\n      <pre style={{ color: \"red\" }}>{getErrorMessage(error)}</pre>\n      <button onClick={resetErrorBoundary}>Retry</button>\n    </div>\n  );\n}\n\n<ErrorBoundary\n  FallbackComponent={Fallback}\n  onReset={(details) => {\n    // Reset the state of your app so the error doesn't happen again\n    details; // hidden\n  }}\n>\n  <YourApplication />\n</ErrorBoundary>;\n\n// <end>\n\nfunction YourApplication() {\n  return null;\n}\n"
  },
  {
    "path": "src/routes/examples/FallbackContent.tsx",
    "content": "import { ErrorBoundary } from \"react-error-boundary\";\n\n<ErrorBoundary fallback={<div>Something went wrong</div>}>\n  <YourApplication />\n</ErrorBoundary>;\n\n// <end>\n\nfunction YourApplication() {\n  return null;\n}\n"
  },
  {
    "path": "src/routes/examples/GetErrorMessage.ts",
    "content": "import { getErrorMessage, type FallbackProps } from \"react-error-boundary\";\n\nfunction Fallback({ error }: FallbackProps) {\n  // Because 'error' can be anything, it's safest not to assume it's an Error\n  // Use the getErrorMessage helper method to extract the message instead.\n  const message = getErrorMessage(error) ?? \"Unknown error\";\n\n  // Render fallback UI...\n  return message; // hidden\n}\n\n// <end>\n\nexport { Fallback };\n"
  },
  {
    "path": "src/routes/examples/NpmResolution.json",
    "content": "{\n  \"overrides\": {\n    \"@types/react\": \"17.0.60\"\n  }\n}"
  },
  {
    "path": "src/routes/examples/RenderProp.tsx",
    "content": "import { ErrorBoundary, getErrorMessage } from \"react-error-boundary\";\n\n<ErrorBoundary\n  fallbackRender={({ error, resetErrorBoundary }) => (\n    <div role=\"alert\">\n      <p>Something went wrong:</p>\n      <pre style={{ color: \"red\" }}>{getErrorMessage(error)}</pre>\n      <button onClick={resetErrorBoundary}>Retry</button>\n    </div>\n  )}\n  onReset={(details) => {\n    // Reset the state of your app so the error doesn't happen again\n    details; // hidden\n  }}\n>\n  <YourApplication />\n</ErrorBoundary>;\n\n// <end>\n\nfunction YourApplication() {\n  return null;\n}\n"
  },
  {
    "path": "src/routes/examples/ResetWithUseErrorBoundary.tsx",
    "content": "import { useErrorBoundary } from \"react-error-boundary\";\n\nfunction Example() {\n  const { resetBoundary } = useErrorBoundary();\n\n  // Call resetBoundary() to reset the nearest ErrorBoundary and retry a failed render\n  resetBoundary; // hidden\n}\n\n// <end>\n\nexport { Example };\n"
  },
  {
    "path": "src/routes/examples/UseClient.ts",
    "content": "\"use client\";\n\n// Imports and components code go here..."
  },
  {
    "path": "src/routes/examples/UseErrorBoundary.tsx",
    "content": "import { useErrorBoundary } from \"react-error-boundary\";\n\nfunction Example() {\n  const {\n    // The currently visible Error (if one has been thrown).\n    error,\n\n    // Method to reset and retry the nearest active error boundary (if one is active).\n    resetBoundary,\n\n    // Trigger the nearest error boundary to display the error provided.\n    showBoundary,\n   } = useErrorBoundary();\n\n  // ...\n  error; // hidden\n  resetBoundary; // hidden\n  showBoundary; // hidden\n}\n\n// <end>\n\nexport { Example };\n"
  },
  {
    "path": "src/routes/examples/WithErrorBoundaryA.tsx",
    "content": "function UserProfile({ username }: { username: string }) {\n  username; // hidden\n  return null; // hidden\n  // Render...\n}\n\n// <end>\n\nexport { UserProfile };\n"
  },
  {
    "path": "src/routes/examples/WithErrorBoundaryB.tsx",
    "content": "import { UserProfile } from \"./WithErrorBoundaryA\";\n\n// <begin>\n\nimport { withErrorBoundary } from \"react-error-boundary\";\n\nconst UserProfileWithErrorBoundary = withErrorBoundary(UserProfile, {\n  fallback: <div>Something went wrong</div>,\n  onError(error, info) {\n    // Do something with the error\n    // E.g. log to an error logging client here\n    error; // hidden\n    info; // hidden\n  },\n});\n\n// <end>\n\nexport { UserProfileWithErrorBoundary };\n"
  },
  {
    "path": "src/routes/examples/WithErrorBoundaryC.tsx",
    "content": "import { UserProfileWithErrorBoundary } from \"./WithErrorBoundaryB\";\n\n// <begin>\n\n<UserProfileWithErrorBoundary username=\"Brian\" />;\n"
  },
  {
    "path": "src/routes/examples/YarnResolution.json",
    "content": "{\n  \"resolutions\": {\n    \"@types/react\": \"17.0.60\"\n  }\n}"
  },
  {
    "path": "src/routes.ts",
    "content": "import { lazy, type ComponentType, type LazyExoticComponent } from \"react\";\n\nexport type Route = LazyExoticComponent<ComponentType<unknown>>;\n\nexport const routes = {\n  \"/examples/fallback\": lazy(() => import(\"./routes/FallbackContentRoute\")),\n  \"/examples/render-prop\": lazy(() => import(\"./routes/RenderPropRoute\")),\n  \"/examples/fallback-component\": lazy(\n    () => import(\"./routes/FallbackComponentRoute\"),\n  ),\n  \"/examples/error-logging\": lazy(() => import(\"./routes/ErrorLoggingRoute\")),\n  \"/examples/async-user-code-errors\": lazy(\n    () => import(\"./routes/AsyncUserCodeErrorsRoute\"),\n  ),\n  \"/examples/retry-nearest-boundary\": lazy(\n    () => import(\"./routes/ResetNearestBoundaryRoute\"),\n  ),\n  \"/api/error-boundary-props\": lazy(\n    () => import(\"./routes/ErrorBoundaryPropsRoute\"),\n  ),\n  \"/api/use-error-boundary-hook\": lazy(\n    () => import(\"./routes/UseErrorBoundaryRoute\"),\n  ),\n  \"/api/with-error-boundary-hoc\": lazy(\n    () => import(\"./routes/WithErrorBoundaryRoute\"),\n  ),\n  \"/api/get-error-message\": lazy(() => import(\"./routes/GetErrorMessageRoute\")),\n} satisfies Record<string, Route>;\n\nexport type Routes = Record<keyof typeof routes, Route>;\nexport type Path = keyof Routes;\n"
  },
  {
    "path": "src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n/// <reference types=\"vite-plugin-svgr/client\" />\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n    \"target\": \"ES2022\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n    \"module\": \"ESNext\",\n    \"skipLibCheck\": true,\n\n    \"moduleResolution\": \"bundler\",\n    \"allowImportingTsExtensions\": true,\n    \"verbatimModuleSyntax\": true,\n    \"moduleDetection\": \"force\",\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\",\n\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"erasableSyntaxOnly\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noUncheckedSideEffectImports\": true,\n    \"exactOptionalPropertyTypes\": true,\n\n    \"paths\": {\n      \"react-error-boundary\": [\"./lib\"]\n    },\n    \"types\": [\n      \"csstype\",\n      \"@testing-library/jest-dom\",\n      \"@testing-library/jest-dom/vitest\"\n    ]\n  },\n  \"include\": [\"vitest.d.ts\", \"lib\", \"scripts\", \"src\", \"index.tsx\"],\n  \"exclude\": []\n}\n"
  },
  {
    "path": "vercel.json",
    "content": "{\n  \"rewrites\": [\n    {\n      \"source\": \"/(.*)\",\n      \"destination\": \"/index.html\"\n    }\n  ]\n}\n"
  },
  {
    "path": "vite.config.ts",
    "content": "import tailwindcss from \"@tailwindcss/vite\";\nimport react from \"@vitejs/plugin-react-swc\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { visualizer } from \"rollup-plugin-visualizer\";\nimport preserveDirectives from \"rollup-preserve-directives\";\nimport { defineConfig, type UserConfig } from \"vite\";\nimport dts from \"vite-plugin-dts\";\nimport svgr from \"vite-plugin-svgr\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst libraryConfig: UserConfig = {\n  build: {\n    lib: {\n      entry: resolve(__dirname, \"lib/index.ts\"),\n      name: \"react-error-boundary\",\n      fileName: \"react-error-boundary\",\n      formats: [\"cjs\", \"es\"],\n    },\n    rollupOptions: {\n      external: [\"react\", \"react-dom\", \"react/jsx-runtime\"],\n    },\n    sourcemap: true,\n    terserOptions: {\n      compress: {\n        directives: false,\n      },\n    },\n  },\n  plugins: [react(), dts({ rollupTypes: true }), preserveDirectives()],\n  publicDir: false,\n};\n\nconst websiteConfig: UserConfig = {\n  base: \"/\",\n  build: {\n    minify: \"terser\",\n    outDir: \"docs\",\n    sourcemap: true,\n    terserOptions: {\n      format: {\n        comments: false,\n      },\n    },\n  },\n  plugins: [\n    react(),\n    svgr(),\n    tailwindcss(),\n    visualizer({\n      emitFile: true,\n      filename: \"stats.html\",\n    }),\n  ],\n  resolve: {\n    alias: {\n      \"react-error-boundary\": resolve(__dirname, \"lib\"),\n    },\n  },\n};\n\n// Allow iPhone to connect to the DEV site using a local IP\nif (process.env.NODE_ENV === \"development\") {\n  websiteConfig.server = {\n    host: true,\n    port: 3000,\n  };\n}\n\nlet config: UserConfig = {};\nswitch (process.env.TARGET) {\n  case \"lib\": {\n    config = libraryConfig;\n    break;\n  }\n  default: {\n    config = websiteConfig;\n    break;\n  }\n}\n\n// https://vite.dev/config/\nexport default defineConfig(config);\n"
  },
  {
    "path": "vitest.config.ts",
    "content": "import { defineConfig, mergeConfig } from \"vitest/config\";\nimport viteConfig from \"./vite.config\";\n\nexport default mergeConfig(\n  viteConfig,\n  defineConfig({\n    test: {\n      // onConsoleLog(log, type) {\n      //   console.log(\"[config] onConsoleLog:\", type, log);\n      //   switch (type) {\n      //     case \"stderr\": {\n      //       throw Error(\"Unexpected console error: \" + log);\n      //     }\n      //   }\n      // },\n      environment: \"jsdom\",\n      setupFiles: \"./vitest.setup.js\",\n      exclude: [\"node_modules\", \"integrations\"],\n    },\n  }),\n);\n"
  },
  {
    "path": "vitest.d.ts",
    "content": "import \"vitest\";\n\ndeclare module \"vitest\" {\n  interface Matchers {\n    toLogError: (expectedError: string) => ReturnType;\n  }\n}\n"
  },
  {
    "path": "vitest.setup.ts",
    "content": "import \"@testing-library/jest-dom/vitest\";\nimport { cleanup } from \"@testing-library/react\";\nimport { afterAll, afterEach, beforeAll, expect, vi } from \"vitest\";\nimport failOnConsole from \"vitest-fail-on-console\";\n\nconst PROTOTYPE_PROPS = [\n  \"clientHeight\",\n  \"clientWidth\",\n  \"offsetHeight\",\n  \"offsetWidth\",\n];\n\nfailOnConsole({\n  shouldFailOnError: true,\n});\n\nexpect.addSnapshotSerializer({\n  serialize(value) {\n    const rect = value as DOMRect;\n    return `${rect.x}, ${rect.y} (${rect.width} x ${rect.height})`;\n  },\n  test(value) {\n    return (\n      value !== null &&\n      typeof value === \"object\" &&\n      \"x\" in value &&\n      \"y\" in value &&\n      \"width\" in value &&\n      \"height\" in value\n    );\n  },\n});\n\nexpect.extend({\n  toLogError: (callback: () => unknown, expectedError: string) => {\n    const spy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n\n    callback();\n\n    expect(console.error).toHaveBeenCalledWith(expectedError);\n\n    spy.mockReset();\n\n    return {\n      pass: true,\n      message: () => \"\",\n    };\n  },\n});\n\nbeforeAll(() => {\n  PROTOTYPE_PROPS.forEach((propertyKey) => {\n    Object.defineProperty(HTMLElement.prototype, propertyKey, {\n      configurable: true,\n      value: 0,\n    });\n  });\n\n  vi.spyOn(console, \"warn\").mockImplementation(() => {\n    throw Error(\"Unexpectec console warning\");\n  });\n});\n\nafterAll(() => {\n  PROTOTYPE_PROPS.forEach((propertyKey) => {\n    delete HTMLElement.prototype[\n      propertyKey as keyof typeof HTMLElement.prototype\n    ];\n  });\n});\n\nafterEach(() => {\n  cleanup();\n});\n"
  }
]