{"_id":"@opentui-ui/toast","_rev":"5-d8dec6bf16aa9397314021db940d7133","name":"@opentui-ui/toast","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.1":{"name":"@opentui-ui/toast","version":"0.0.1","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"author":{"name":"Matt Simpson"},"license":"MIT","_id":"@opentui-ui/toast@0.0.1","maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"homepage":"https://github.com/msmps/opentui-ui#readme","bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"dist":{"shasum":"e00dd05791bf971f454df58960d287791edacb42","tarball":"https://registry.npmjs.org/@opentui-ui/toast/-/toast-0.0.1.tgz","fileCount":24,"integrity":"sha512-tVhZmc/zElR3EI5FF4+ELvkartqTybMRKXmk6IfuVFBN9Ki4qfZPnQaMYCLwes5DdfbiWtiT/6/DLvJ6BeCsqA==","signatures":[{"sig":"MEYCIQDaAbp/z19+XXwore9M69x4NEUCAnrfVBHtBsQgG7jRFwIhANP0RrIJNswUnq2w5niXdSgiYWUopkqoiyGa8GsBkP0J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentui-ui%2ftoast@0.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":161077},"type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./icons":{"types":"./dist/icons.d.mts","import":"./dist/icons.mjs"},"./react":{"types":"./dist/react.d.mts","import":"./dist/react.mjs"},"./themes":{"types":"./dist/themes.d.mts","import":"./dist/themes.mjs"}},"gitHead":"bbf0b8645948094581efe8b3b7786bec3ea50790","scripts":{"build":"tsdown","clean":"rm -rf dist"},"_npmUser":{"name":"msmps","email":"hello@msmp.me"},"repository":{"url":"git+https://github.com/msmps/opentui-ui.git","type":"git","directory":"packages/toast"},"_npmVersion":"10.8.2","description":"A beautiful toast library for terminal UIs built on OpenTUI","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.18.2","@types/bun":"latest","typescript":"^5","@opentui/core":"^0.1.63","@opentui/react":"^0.1.63"},"peerDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63"},"peerDependenciesMeta":{"@opentui/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/toast_0.0.1_1766750158791_0.9117199197363011","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@opentui-ui/toast","version":"0.0.2","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"author":{"name":"Matt Simpson"},"license":"MIT","_id":"@opentui-ui/toast@0.0.2","maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"homepage":"https://github.com/msmps/opentui-ui#readme","bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"dist":{"shasum":"199df923a26925bfc2bb76c27b2491b6bbfdba13","tarball":"https://registry.npmjs.org/@opentui-ui/toast/-/toast-0.0.2.tgz","fileCount":24,"integrity":"sha512-Mll6Nyd7r4QXddMdPBXGUBaaFele33KcBIHsFI/Oc/DXV3THKKMXI96z24G3BlEABqgMts16/sklOcnaJUJ3qQ==","signatures":[{"sig":"MEQCIFOTbgyUkGdpHUSSLG1WK5Ggmib+fbaLfwKASO7qtYzXAiApk5DzINAbcESUEPqBsJZCR+WMNbfN7/wzI34DFj+zew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentui-ui%2ftoast@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":161075},"type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./icons":{"types":"./dist/icons.d.mts","import":"./dist/icons.mjs"},"./react":{"types":"./dist/react.d.mts","import":"./dist/react.mjs"},"./themes":{"types":"./dist/themes.d.mts","import":"./dist/themes.mjs"}},"gitHead":"4891a9c9b34bfb58cb5546747d528075828d091a","scripts":{"build":"tsdown","clean":"rm -rf dist"},"_npmUser":{"name":"msmps","email":"hello@msmp.me"},"repository":{"url":"git+https://github.com/msmps/opentui-ui.git","type":"git","directory":"packages/toast"},"_npmVersion":"10.8.2","description":"A beautiful toast library for terminal UIs built on OpenTUI","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.18.2","@types/bun":"latest","typescript":"^5","@opentui/core":"^0.1.63","@opentui/react":"^0.1.63"},"peerDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63"},"peerDependenciesMeta":{"@opentui/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/toast_0.0.2_1766751094372_0.5138423461695529","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@opentui-ui/toast","version":"0.0.3","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"author":{"name":"Matt Simpson"},"license":"MIT","_id":"@opentui-ui/toast@0.0.3","maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"homepage":"https://github.com/msmps/opentui-ui#readme","bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"dist":{"shasum":"65a98e4473e2d2c5c2662eed750033916cdcf94c","tarball":"https://registry.npmjs.org/@opentui-ui/toast/-/toast-0.0.3.tgz","fileCount":28,"integrity":"sha512-SraqA70A0rgu5+uaG7AIrdu3AyE5VbUsL/NzQ3XXUbyGHg5pwpDVQ5s//TkEpjUPf73tXZ3O76m5CJOB9OPLoQ==","signatures":[{"sig":"MEUCIQC6RuxeARCIPpD4jj7t5b5gITDMqEFMS0trPUg/CKd/uQIgLuUw7n0521xrk+LiJ/rQ5EqAMn5AG42Ym3rXLL61NgQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentui-ui%2ftoast@0.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":167567},"type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./icons":{"types":"./dist/icons.d.mts","import":"./dist/icons.mjs"},"./react":{"types":"./dist/react.d.mts","import":"./dist/react.mjs"},"./solid":{"types":"./dist/solid.d.mts","import":"./dist/solid.mjs"},"./themes":{"types":"./dist/themes.d.mts","import":"./dist/themes.mjs"}},"gitHead":"4e002c16ea7f804a3fc2e71a793f13c6c0a96af2","scripts":{"build":"tsdown","clean":"rm -rf dist"},"_npmUser":{"name":"msmps","email":"hello@msmp.me"},"repository":{"url":"git+https://github.com/msmps/opentui-ui.git","type":"git","directory":"packages/toast"},"_npmVersion":"10.8.2","description":"A beautiful toast library for terminal UIs built on OpenTUI","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.18.2","@types/bun":"latest","typescript":"^5","@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63"},"peerDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63"},"peerDependenciesMeta":{"@opentui/react":{"optional":true},"@opentui/solid":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/toast_0.0.3_1766779779676_0.48720970271558195","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@opentui-ui/toast","version":"0.0.4","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"author":{"name":"Matt Simpson"},"license":"MIT","_id":"@opentui-ui/toast@0.0.4","maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"homepage":"https://github.com/msmps/opentui-ui#readme","bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"dist":{"shasum":"236c20d766184e968911518043e0eb1319272e7f","tarball":"https://registry.npmjs.org/@opentui-ui/toast/-/toast-0.0.4.tgz","fileCount":28,"integrity":"sha512-o+OU8gbWOicZ195ydtrZEu4DLCexa2if68eXXxbC+i4UFWdyIuAUf5IBlK9pyoQg75ok8c4rfaFvqSAoU9Tjkw==","signatures":[{"sig":"MEUCIE4wApUvDE423pfbwbhsefIt0NauJ9MCGtbc2mm1S/L9AiEA8yjgjKpXXiyzSlhwshoY2QMqq5I7e+00Q02t+e6snfo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentui-ui%2ftoast@0.0.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":172231},"type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./icons":{"types":"./dist/icons.d.mts","import":"./dist/icons.mjs"},"./react":{"types":"./dist/react.d.mts","import":"./dist/react.mjs"},"./solid":{"types":"./dist/solid.d.mts","import":"./dist/solid.mjs"},"./themes":{"types":"./dist/themes.d.mts","import":"./dist/themes.mjs"}},"gitHead":"de9ba3c96246a9b861a7e1aec2ebc6d4727297f4","scripts":{"build":"tsdown","clean":"rm -rf dist"},"_npmUser":{"name":"msmps","email":"hello@msmp.me"},"repository":{"url":"git+https://github.com/msmps/opentui-ui.git","type":"git","directory":"packages/toast"},"_npmVersion":"10.8.2","description":"A beautiful toast library for terminal UIs built on OpenTUI","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.3","tsdown":"^0.18.2","@types/bun":"latest","typescript":"^5","@types/react":"^19.2.7","@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63"},"peerDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63"},"peerDependenciesMeta":{"@opentui/react":{"optional":true},"@opentui/solid":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/toast_0.0.4_1767123003477_0.10184286512923224","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@opentui-ui/toast","version":"0.0.5","description":"A beautiful toast library for terminal UIs built on OpenTUI","author":{"name":"Matt Simpson"},"license":"MIT","sideEffects":false,"repository":{"type":"git","url":"git+https://github.com/msmps/opentui-ui.git","directory":"packages/toast"},"type":"module","module":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./themes":{"types":"./dist/themes.d.mts","import":"./dist/themes.mjs"},"./icons":{"types":"./dist/icons.d.mts","import":"./dist/icons.mjs"},"./react":{"types":"./dist/react.d.mts","import":"./dist/react.mjs"},"./solid":{"types":"./dist/solid.d.mts","import":"./dist/solid.mjs"}},"bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"homepage":"https://github.com/msmps/opentui-ui#readme","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"scripts":{"build":"tsdown","clean":"rm -rf dist"},"devDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63","@opentui-ui/utils":"workspace:^","@types/bun":"latest","@types/react":"^19.2.7","react":"^19.2.3","tsdown":"^0.18.2","typescript":"^5"},"peerDependencies":{"@opentui/core":"^0.1.63","@opentui/react":"^0.1.63","@opentui/solid":"^0.1.63"},"peerDependenciesMeta":{"@opentui/react":{"optional":true},"@opentui/solid":{"optional":true}},"_id":"@opentui-ui/toast@0.0.5","gitHead":"d77567db240a5c6200d16caf0c7c3d92ee6ea183","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-LOT5Bw0F5AEyhjSqpKgS7aSe7M7v+ahaAa4t3/K2dtWiT0CJ711UHXqM31KKN6yuHoUKRNs+g+643ety/a3lEw==","shasum":"34afc3191f9125dd25498c7de49c039ba3b70154","tarball":"https://registry.npmjs.org/@opentui-ui/toast/-/toast-0.0.5.tgz","fileCount":28,"unpackedSize":174703,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@opentui-ui%2ftoast@0.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD4S36C8DowUwzE01oBsH3AiXi7Q3rGMFbJalqJWGl4HQIgRg8wxYjk1WfozM/AqTVnZ1FcSUSW9gqSAiWKK38JvBI="}]},"_npmUser":{"name":"msmps","email":"hello@msmp.me"},"directories":{},"maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toast_0.0.5_1767288533847_0.37164621871016257"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-26T11:55:58.682Z","modified":"2026-01-01T17:28:54.428Z","0.0.1":"2025-12-26T11:55:58.953Z","0.0.2":"2025-12-26T12:11:34.538Z","0.0.3":"2025-12-26T20:09:39.844Z","0.0.4":"2025-12-30T19:30:03.636Z","0.0.5":"2026-01-01T17:28:53.992Z"},"bugs":{"url":"https://github.com/msmps/opentui-ui/issues"},"author":{"name":"Matt Simpson"},"license":"MIT","homepage":"https://github.com/msmps/opentui-ui#readme","keywords":["toast","notification","tui","terminal","cli","opentui","sonner"],"repository":{"type":"git","url":"git+https://github.com/msmps/opentui-ui.git","directory":"packages/toast"},"description":"A beautiful toast library for terminal UIs built on OpenTUI","maintainers":[{"name":"msmps","email":"hello@msmp.me"}],"readme":"<div align=\"center\">\n  <img width=\"512\" src=\"https://github.com/msmps/opentui-ui/raw/main/packages/toast/assets/banner.png\" />\n</div>\n\n<br />\n\n<div align=\"center\"><strong>A beautiful toast library for terminal UIs built on OpenTUI</strong></div>\n<div align=\"center\">\n  <sub>Built by <a href=\"https://x.com/msmps_\">Matt Simpson</a> | Inspired by <a href=\"https://sonner.emilkowal.ski/\">Sonner</a></sub>\n</div>\n\n<br />\n\n## Installation\n\n```bash\nbun add @opentui-ui/toast\n```\n\n## Quick Start\n\n```ts\nimport { toast, ToasterRenderable } from \"@opentui-ui/toast\";\n\n// 1. Add the toaster to your app (one line!)\nctx.root.add(new ToasterRenderable(ctx));\n\n// 2. Show toasts from anywhere!\ntoast(\"Hello World\");\n```\n\nThat's it! No providers, no context, no configuration required.\n\n## Quick Reference\n\n```ts\n// Toast Types\ntoast(\"message\");           // default\ntoast.success(\"message\");   // green checkmark\ntoast.error(\"message\");     // red X\ntoast.warning(\"message\");   // yellow warning\ntoast.info(\"message\");      // blue info\ntoast.loading(\"message\");   // animated spinner\n\n// Common Patterns\ntoast(\"msg\", { description: \"details\" }); // Two-line toast\ntoast(\"msg\", { duration: Infinity });     // Persistent (manual dismiss)\ntoast(\"msg\", { action: { label: \"Undo\", onClick: fn } }); // With button\n\n// Dismiss\nconst id = toast(\"Hello\");\ntoast.dismiss(id);  // Dismiss one\ntoast.dismiss();    // Dismiss all\n\n// Update existing toast\nconst id = toast.loading(\"Uploading...\");\ntoast.success(\"Done!\", { id }); // Updates in place\n```\n\n## Toast Types\n\n```ts\ntoast(\"Default notification\");\ntoast.success(\"Operation completed!\");\ntoast.error(\"Something went wrong\");\ntoast.warning(\"Please check your input\");\ntoast.info(\"Did you know?\");\ntoast.loading(\"Processing...\");\n```\n\n## With Descriptions\n\n```ts\ntoast.success(\"File uploaded\", {\n  description: \"Your file has been saved to the cloud\",\n});\n```\n\n## Promise Toast\n\nThe `toast.promise()` API automatically shows loading, success, and error states:\n\n```ts\ntoast.promise(fetchData(), {\n  loading: \"Fetching data...\",\n  success: \"Data loaded successfully!\",\n  error: \"Failed to load data\",\n});\n\n// With dynamic messages\ntoast.promise(saveUser(data), {\n  loading: \"Saving user...\",\n  success: (user) => `${user.name} has been saved`,\n  error: (err) => `Error: ${err.message}`,\n});\n```\n\n## Actions\n\nAdd interactive buttons to your toasts:\n\n```ts\ntoast(\"File deleted\", {\n  action: {\n    label: \"Undo\",\n    onClick: () => restoreFile(),\n  },\n});\n```\n\n## Updating Toasts\n\nUpdate an existing toast by passing its ID:\n\n```ts\nconst id = toast.loading(\"Uploading...\");\n\n// Later...\ntoast.success(\"Upload complete!\", { id });\n\n// Or on error\ntoast.error(\"Upload failed\", { id });\n```\n\n## Dismissing Toasts\n\n```ts\n// Dismiss a specific toast\nconst id = toast(\"Hello\");\ntoast.dismiss(id);\n\n// Dismiss all toasts\ntoast.dismiss();\n```\n\n## Duration\n\n### Duration Presets\n\nUse the built-in `TOAST_DURATION` presets for consistent, readable duration values:\n\n```ts\nimport { toast, TOAST_DURATION } from \"@opentui-ui/toast\";\n\n// Quick confirmation (2s)\ntoast.success(\"Copied!\", { duration: TOAST_DURATION.SHORT });\n\n// Standard duration (4s) - this is the default\ntoast(\"Hello\", { duration: TOAST_DURATION.DEFAULT });\n\n// Important message (6s)\ntoast.warning(\"Check your settings\", { duration: TOAST_DURATION.LONG });\n\n// Critical information (10s)\ntoast.error(\"Connection lost\", { duration: TOAST_DURATION.EXTENDED });\n\n// Manual dismiss only\ntoast.info(\"Click to continue\", { duration: TOAST_DURATION.PERSISTENT });\n```\n\n### Duration Preset Values\n\n| Preset       | Duration | Use Case                  |\n| ------------ | -------- | ------------------------- |\n| `SHORT`      | 2000ms   | Brief confirmations       |\n| `DEFAULT`    | 4000ms   | Standard notifications    |\n| `LONG`       | 6000ms   | Important messages        |\n| `EXTENDED`   | 10000ms  | Critical information      |\n| `PERSISTENT` | Infinity | Requires manual dismissal |\n\n### Custom Duration\n\nYou can also pass any number in milliseconds:\n\n```ts\n// Custom duration (in milliseconds)\ntoast(\"This disappears in 10 seconds\", {\n  duration: 10000,\n});\n\n// Persistent toast (won't auto-dismiss)\ntoast(\"I'll stay until dismissed\", {\n  duration: Infinity,\n});\n```\n\n## Themes\n\nOptional theme presets are available via a separate import. These override the built-in defaults with alternative visual styles.\n\n```ts\nimport { ToasterRenderable } from \"@opentui-ui/toast\";\nimport { minimal } from \"@opentui-ui/toast/themes\";\n\nconst toaster = new ToasterRenderable(ctx, minimal);\n```\n\n### Available Themes\n\n| Theme        | Description                       |\n| ------------ | --------------------------------- |\n| `minimal`    | Clean and unobtrusive, no borders |\n| `monochrome` | Grayscale only, no colors         |\n\n### Customizing Themes\n\nSpread a theme and override specific options:\n\n```ts\nimport { minimal } from \"@opentui-ui/toast/themes\";\n\nconst toaster = new ToasterRenderable(ctx, {\n  ...minimal,\n  position: \"bottom-right\",\n  stackingMode: \"stack\",\n});\n```\n\n### Theme Utilities\n\n```ts\nimport { themes } from \"@opentui-ui/toast/themes\";\n\n// Access all themes\nthemes.minimal;\nthemes.monochrome;\n```\n\n### Theme Types\n\n```ts\nimport type { ToasterTheme } from \"@opentui-ui/toast/themes\";\n```\n\n## Toaster Configuration\n\nCustomize the toaster appearance and behavior:\n\n```ts\nconst toaster = new ToasterRenderable(ctx, {\n  // Position on screen\n  position: \"bottom-right\", // 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'\n\n  // Gap between toasts (terminal rows)\n  gap: 1,\n\n  // How to handle multiple toasts\n  stackingMode: \"single\", // 'single' | 'stack'\n\n  // Max visible toasts in stack mode\n  visibleToasts: 3,\n\n  // Show close button on toasts\n  closeButton: false,\n\n  // Maximum width for toasts\n  maxWidth: 60,\n\n  // Offset from screen edges\n  offset: {\n    top: 1,\n    right: 2,\n    bottom: 1,\n    left: 2,\n  },\n\n  // Custom icons\n  icons: {\n    success: \"✓\",\n    error: \"✗\",\n    warning: \"⚠\",\n    info: \"ℹ\",\n    loading: \"◌\",\n    close: \"×\",\n  },\n\n  // Toast styling and duration options\n  toastOptions: {\n    style: {\n      /* base styles */\n    },\n    duration: 4000,\n    success: {\n      style: {\n        /* overrides */\n      },\n      duration: 3000,\n    },\n    // ... other types\n  },\n});\n```\n\n### ToasterOptions Reference\n\n| Option          | Type                           | Default                                    | Description                                                  |\n| --------------- | ------------------------------ | ------------------------------------------ | ------------------------------------------------------------ |\n| `position`      | `Position`                     | `\"bottom-right\"`                           | Position on screen                                           |\n| `gap`           | `number`                       | `1`                                        | Gap between toasts (terminal rows)                           |\n| `stackingMode`  | `StackingMode`                 | `\"single\"`                                 | How to handle multiple toasts: `\"single\"` or `\"stack\"`       |\n| `visibleToasts` | `number`                       | `3`                                        | Max visible toasts in stack mode                             |\n| `closeButton`   | `boolean`                      | `false`                                    | Show close button on toasts                                  |\n| `maxWidth`      | `number`                       | `60`                                       | Maximum width for toasts (terminal columns)                  |\n| `offset`        | `ToasterOffset`                | `{ top: 1, right: 2, bottom: 1, left: 2 }` | Offset from screen edges                                     |\n| `icons`         | `Partial<ToastIcons> \\| false` | -                                          | Custom icons for each toast type, or `false` to disable      |\n| `toastOptions`  | `ToastOptions`                 | -                                          | Default toast options (styles, duration, per-type overrides) |\n\n## Styling\n\nConfigure toast styles using the `toastOptions` prop:\n\n```ts\nconst toaster = new ToasterRenderable(ctx, {\n  toastOptions: {\n    // Base styles applied to all toasts\n    style: {\n      backgroundColor: \"#1a1a1a\",\n      foregroundColor: \"#ffffff\",\n      borderColor: \"#333333\",\n      borderStyle: \"rounded\", // 'single' | 'double' | 'rounded' | 'heavy'\n      paddingX: 1,\n      paddingY: 0,\n    },\n    // Default duration for all toasts\n    duration: 4000,\n    // Per-type overrides\n    success: {\n      style: { borderColor: \"#22c55e\" },\n      duration: 3000,\n    },\n    error: {\n      style: { borderColor: \"#ef4444\" },\n      duration: 6000,\n    },\n    warning: {\n      style: { borderColor: \"#f59e0b\" },\n    },\n    info: {\n      style: { borderColor: \"#3b82f6\" },\n    },\n    loading: {\n      style: { borderColor: \"#6b7280\" },\n    },\n  },\n});\n```\n\n### ToastStyle Reference\n\n| Property            | Type                       | Default     | Description                                                                                 |\n| ------------------- | -------------------------- | ----------- | ------------------------------------------------------------------------------------------- |\n| `border`            | `boolean \\| BorderSides[]` | `true`      | Border configuration. `true` = all sides, `false` = none, or array like `[\"left\", \"right\"]` |\n| `borderColor`       | `string`                   | `\"#333333\"` | Border color (hex, rgb, or named)                                                           |\n| `borderStyle`       | `BorderStyle`              | `\"single\"`  | Border style: `\"single\"` \\| `\"double\"` \\| `\"rounded\"` \\| `\"heavy\"`                          |\n| `customBorderChars` | `BorderCharacters`         | -           | Custom border characters (overrides `borderStyle`)                                          |\n| `minHeight`         | `number`                   | `3`         | Minimum height in terminal rows                                                             |\n| `maxWidth`          | `number`                   | -           | Maximum width in terminal columns                                                           |\n| `minWidth`          | `number`                   | -           | Minimum width in terminal columns                                                           |\n| `padding`           | `number`                   | -           | Uniform padding (all sides)                                                                 |\n| `paddingX`          | `number`                   | `1`         | Horizontal padding (left + right)                                                           |\n| `paddingY`          | `number`                   | `0`         | Vertical padding (top + bottom)                                                             |\n| `paddingTop`        | `number`                   | -           | Top padding                                                                                 |\n| `paddingBottom`     | `number`                   | -           | Bottom padding                                                                              |\n| `paddingLeft`       | `number`                   | -           | Left padding                                                                                |\n| `paddingRight`      | `number`                   | -           | Right padding                                                                               |\n| `backgroundColor`   | `string`                   | `\"#1a1a1a\"` | Background color                                                                            |\n| `foregroundColor`   | `string`                   | `\"#ffffff\"` | Text/foreground color                                                                       |\n| `mutedColor`        | `string`                   | `\"#6b7280\"` | Muted text color (for descriptions)                                                         |\n| `iconColor`         | `string`                   | -           | Icon color (defaults to `borderColor`)                                                      |\n\n### Custom Border Characters\n\nFor full control over border rendering, use `customBorderChars` to define each border character:\n\n```ts\nconst toaster = new ToasterRenderable(ctx, {\n  toastOptions: {\n    style: {\n      border: [\"left\", \"right\"],\n      customBorderChars: {\n        topLeft: \"\",\n        topRight: \"\",\n        bottomLeft: \"\",\n        bottomRight: \"\",\n        horizontal: \" \",\n        vertical: \"┃\",\n        topT: \"\",\n        bottomT: \"\",\n        leftT: \"\",\n        rightT: \"\",\n        cross: \"\",\n      },\n    },\n  },\n});\n```\n\nThis is useful for creating unique border styles, like a vertical bar accent:\n\n```ts\n// Vertical bar on left and right only\nborder: [\"left\", \"right\"],\ncustomBorderChars: {\n  vertical: \"┃\",\n  // Other characters can be empty strings\n  topLeft: \"\", topRight: \"\", bottomLeft: \"\", bottomRight: \"\",\n  horizontal: \" \", topT: \"\", bottomT: \"\", leftT: \"\", rightT: \"\", cross: \"\",\n},\n```\n\n### Per-Toast Styles\n\nOverride styles on individual toasts:\n\n```ts\ntoast.success(\"Custom styled!\", {\n  style: {\n    borderColor: \"#8b5cf6\",\n    backgroundColor: \"#1e1b4b\",\n  },\n});\n```\n\n## Icon Sets\n\nChoose from built-in icon sets based on terminal capabilities:\n\n```ts\nimport {\n  DEFAULT_ICONS, // Unicode icons (default)\n  ASCII_ICONS, // ASCII-only for limited terminals\n  MINIMAL_ICONS, // Single character icons\n  EMOJI_ICONS, // Emoji icons\n} from \"@opentui-ui/toast\";\n\n// Use ASCII icons for terminals with limited Unicode support\nconst toaster = new ToasterRenderable(ctx, {\n  icons: ASCII_ICONS,\n});\n\n// Use emoji icons for terminals with good emoji support\nconst toaster = new ToasterRenderable(ctx, {\n  icons: EMOJI_ICONS,\n});\n```\n\n### Custom Loading Spinner\n\nThe `loading` icon can be either a static string or an animated spinner configuration:\n\n```ts\nconst toaster = new ToasterRenderable(ctx, {\n  icons: {\n    // Static loading icon (no animation)\n    loading: \"...\",\n\n    // Or animated spinner\n    loading: {\n      frames: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n      interval: 80,\n    },\n  },\n});\n```\n\nSome spinner examples:\n\n```ts\n// Dots spinner\n{ frames: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"], interval: 80 }\n\n// Circle spinner (default)\n{ frames: [\"◜\", \"◠\", \"◝\", \"◞\", \"◡\", \"◟\"], interval: 100 }\n\n// Simple ASCII spinner\n{ frames: [\"-\", \"\\\\\", \"|\", \"/\"], interval: 100 }\n\n// Bouncing bar\n{ frames: [\"[    ]\", \"[=   ]\", \"[==  ]\", \"[=== ]\", \"[ ===]\", \"[  ==]\", \"[   =]\", \"[    ]\"], interval: 120 }\n```\n\n### Disabling Icons\n\nTo disable icons entirely, set `icons: false`:\n\n```ts\nconst toaster = new ToasterRenderable(ctx, {\n  icons: false,\n});\n```\n\nIndividual toasts can still override this by providing a custom `icon`:\n\n```ts\n// Icons are disabled globally, but this toast will show a custom icon\ntoast.success(\"Done!\", { icon: \"✓\" });\n```\n\n## API Reference\n\n### `toast(message, options?)`\n\nShow a default toast.\n\n### `toast.success(message, options?)`\n\nShow a success toast with a checkmark icon.\n\n### `toast.error(message, options?)`\n\nShow an error toast with an X icon.\n\n### `toast.warning(message, options?)`\n\nShow a warning toast with a warning icon.\n\n### `toast.info(message, options?)`\n\nShow an info toast with an info icon.\n\n### `toast.loading(message, options?)`\n\nShow a loading toast with an animated spinner.\n\n### `toast.promise(promise, options)`\n\nShow a toast that updates based on promise state.\n\n### `toast.dismiss(id?)`\n\nDismiss a specific toast by ID, or all toasts if no ID provided.\n\n### `toast.getToasts()`\n\nGet all currently active toasts.\n\n### `toast.getHistory()`\n\nGet all toasts ever created (including dismissed).\n\n### Toast Options\n\n| Option        | Type                       | Default    | Description                        |\n| ------------- | -------------------------- | ---------- | ---------------------------------- |\n| `id`          | `string \\| number`         | auto       | Unique identifier for the toast    |\n| `description` | `string \\| (() => string)` | -          | Secondary text below the title     |\n| `duration`    | `number`                   | `4000`     | Time in ms before auto-dismiss     |\n| `dismissible` | `boolean`                  | `true`     | Whether the toast can be dismissed |\n| `icon`        | `string`                   | type-based | Custom icon to display             |\n| `action`      | `{ label, onClick }`       | -          | Action button configuration        |\n| `closeButton` | `boolean`                  | `false`    | Show close button                  |\n| `style`       | `ToastStyle`               | -          | Per-toast style overrides          |\n| `onDismiss`   | `(toast) => void`          | -          | Callback when dismissed            |\n| `onAutoClose` | `(toast) => void`          | -          | Callback when auto-closed          |\n\n## Examples\n\n### Basic Example\n\n```ts\nimport { createCliRenderer } from \"@opentui/core\";\nimport { toast, ToasterRenderable } from \"@opentui-ui/toast\";\n\nconst renderer = await createCliRenderer();\n\n// Add toaster\nconst toaster = new ToasterRenderable(renderer, {\n  position: \"bottom-right\",\n});\nrenderer.root.add(toaster);\n\n// Show some toasts\ntoast.success(\"Application started!\");\n\nsetTimeout(() => {\n  toast.info(\"Press 'q' to quit\");\n}, 1000);\n```\n\n### Async Operation\n\n```ts\nasync function saveData(data: unknown) {\n  toast.promise(\n    fetch(\"/api/save\", {\n      method: \"POST\",\n      body: JSON.stringify(data),\n    }),\n    {\n      loading: \"Saving...\",\n      success: \"Saved!\",\n      error: \"Failed to save\",\n    }\n  );\n}\n```\n\n### Manual Loading State\n\n```ts\nasync function uploadFile(file: File) {\n  const id = toast.loading(\"Uploading...\");\n\n  try {\n    const result = await upload(file);\n    toast.success(`Uploaded ${result.filename}`, { id });\n  } catch (error) {\n    toast.error(\"Upload failed\", { id });\n  }\n}\n```\n\n## React\n\nFor React applications, use the `Toaster` component and `useToasts` hook:\n\n```tsx\nimport { Toaster, useToasts, toast } from \"@opentui-ui/toast/react\";\n\nfunction App() {\n  return (\n    <>\n      <Toaster position=\"bottom-right\" />\n      <MyComponent />\n    </>\n  );\n}\n\nfunction MyComponent() {\n  const { toasts } = useToasts();\n\n  useKeyboard((key) => {\n    if (key.name === \"1\") {\n      toast.success(\"Hello World\");\n    }\n  });\n\n  return (\n    <box>\n      <text>Active toasts: {toasts.length}</text>\n    </box>\n  );\n}\n```\n\nThe `useToasts` hook provides **reactive access** to the current toast state, re-rendering your component whenever toasts are added, updated, or dismissed.\n\n## Solid\n\nFor Solid applications, use the `Toaster` component and `useToasts` hook:\n\n```tsx\nimport { Toaster, useToasts, toast } from \"@opentui-ui/toast/solid\";\n\nfunction App() {\n  return (\n    <>\n      <Toaster position=\"bottom-right\" />\n      <MyComponent />\n    </>\n  );\n}\n\nfunction MyComponent() {\n  const toasts = useToasts();\n\n  useKeyboard((key) => {\n    if (key.name === \"1\") {\n      toast.success(\"Hello World\");\n    }\n  });\n\n  return (\n    <box>\n      <text>Active toasts: {toasts().length}</text>\n    </box>\n  );\n}\n```\n\nThe `useToasts` hook returns a **reactive accessor** that updates whenever toasts change. Call it as a function (`toasts()`) to access the current array.\n\n## TypeScript\n\nFull TypeScript support with exported types:\n\n```ts\nimport type {\n  Action,           // Action button configuration\n  ExternalToast,    // Options for toast() calls\n  Position,         // Toaster position type\n  PromiseData,      // Configuration for toast.promise()\n  SpinnerConfig,    // Animated spinner configuration { frames, interval }\n  StackingMode,     // Stacking mode ('single' | 'stack')\n  ToasterOffset,    // Offset configuration for positioning\n  ToasterOptions,   // Configuration for ToasterRenderable\n  ToastIcons,       // Custom icon set type\n  ToastOptions,     // Default toast options (styles, duration, per-type overrides)\n  ToastStyle,       // Per-toast styling options\n  ToastType,        // Toast type variants\n  TypeToastOptions, // Per-type options (style + duration)\n} from \"@opentui-ui/toast\";\n\n// Border types (for customBorderChars) come from @opentui/core\nimport type { BorderCharacters, BorderSides, BorderStyle } from \"@opentui/core\";\n\n// Type guards\nimport { isAction, isSpinnerConfig } from \"@opentui-ui/toast\";\n```\n\n### Constants\n\n```ts\nimport { TOAST_DURATION } from \"@opentui-ui/toast\";\n\n// Duration presets\nTOAST_DURATION.SHORT;      // 2000ms - brief confirmations\nTOAST_DURATION.DEFAULT;    // 4000ms - standard notifications\nTOAST_DURATION.LONG;       // 6000ms - important messages\nTOAST_DURATION.EXTENDED;   // 10000ms - critical information\nTOAST_DURATION.PERSISTENT; // Infinity - manual dismiss only\n```\n\n## Acknowledgments\n\nInspired by [Sonner](https://sonner.emilkowal.ski/) by Emil Kowalski.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}