{"id":50993122,"url":"https://github.com/seangeng/glace","last_synced_at":"2026-06-20T05:30:51.070Z","repository":{"id":363358602,"uuid":"1262987371","full_name":"seangeng/glace","owner":"seangeng","description":"🧊 Beautiful frosted-glass toasts for React — an opinionated, themeable child of sonner with real glass, springy motion, and optional haptics.","archived":false,"fork":false,"pushed_at":"2026-06-08T16:17:36.000Z","size":63,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T16:18:32.935Z","etag":null,"topics":["dark-mode","glassmorphism","haptics","notifications","react","sonner","toast","typescript","ui"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seangeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-08T14:08:39.000Z","updated_at":"2026-06-08T16:17:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/seangeng/glace","commit_stats":null,"previous_names":["seangeng/glace"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/seangeng/glace","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangeng%2Fglace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangeng%2Fglace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangeng%2Fglace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangeng%2Fglace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seangeng","download_url":"https://codeload.github.com/seangeng/glace/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangeng%2Fglace/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34558892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dark-mode","glassmorphism","haptics","notifications","react","sonner","toast","typescript","ui"],"created_at":"2026-06-20T05:30:50.398Z","updated_at":"2026-06-20T05:30:51.062Z","avatar_url":"https://github.com/seangeng.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Glacé 🧊\n\n**A frosted-glass UI kit for React.** Real edge refraction, springy motion, light/dark, and optional haptics — as a tiny, opinionated kit. Ships toasts, a glass button, and a `\u003cGlass\u003e` surface primitive you can wrap anything in. Think [sonner](https://sonner.emilkowal.ski/), wearing glass.\n\n**[glaceui.com](https://glaceui.com)** — live demo, playground, and docs.\n\n[![Glacé glass cards refracting a gradient](https://cdn.jsdelivr.net/gh/seangeng/glace@main/assets/cards.png)](https://glaceui.com/panels)\n\n\u003cp\u003e\n  \u003cimg src=\"https://cdn.jsdelivr.net/gh/seangeng/glace@main/assets/buttons.png\" width=\"49%\" alt=\"Glass buttons\" /\u003e\n  \u003cimg src=\"https://cdn.jsdelivr.net/gh/seangeng/glace@main/assets/profiles.png\" width=\"49%\" alt=\"Edge profiles: convex, concave, bevel\" /\u003e\n\u003c/p\u003e\n\n[![Glass Lab — tune the refraction](https://cdn.jsdelivr.net/gh/seangeng/glace@main/assets/lab.png)](https://glaceui.com/primitives)\n\n```bash\nnpm i glaceui\n```\n\n```tsx\nimport { Toaster, toast } from \"glaceui\";\nimport \"glaceui/styles.css\";\n\nexport default function App() {\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={() =\u003e toast.success(\"Saved to your library\")}\u003eSave\u003c/button\u003e\n      \u003cToaster position=\"bottom-right\" /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\nThat's the whole setup: drop one `\u003cToaster /\u003e` near the root, call `toast()` from anywhere.\n\n---\n\n## Why\n\nMost toast libraries are either gorgeous-but-rigid or flexible-but-plain. Glacé is opinionated about the *look* — proper frosted glass that blurs whatever's behind it, with a specular top edge, a faint grain, and a soft shadow — and unopinionated about everything else. It's themeable with plain CSS variables, has no styling dependency, and ships a single stylesheet, so it drops into a Tailwind/shadcn app or a plain one without touching your config.\n\n## Features\n\n- 🧊 **Real glass** — edges that *refract*: an SVG displacement map bends the backdrop at the rim (the [Aave glass recipe](https://aave.com/design/building-glass-for-the-web)), with a specular highlight and only a little blur. Degrades to frosted blur where unsupported.\n- 🌗 **Light / dark / system** — looks right on both, automatically.\n- 🪄 **Springy stack** — toasts collapse behind each other and fan open on hover, sonner-style.\n- 👆 **Swipe to dismiss** — pointer-driven, works on touch and trackpad.\n- 📳 **Optional haptics** — a buzz on appear / action / dismiss where the device supports it (inspired by [web-haptics](https://github.com/lochie/web-haptics)).\n- 🎨 **Themeable** — every color, blur, radius, and gap is a CSS variable.\n- ⚡ **Tiny \u0026 dependency-free** — just React as a peer. Promise, loading, action buttons, custom render included.\n- ♿ **Accessible** — `aria-live` region, reduced-motion aware.\n\n## Toast API\n\n```ts\ntoast(\"Plain message\");\ntoast.success(\"Profile updated\");\ntoast.error(\"Couldn't reach the server\");\ntoast.warning(\"Storage almost full\");\ntoast.info(\"New version available\");\n\nconst id = toast.loading(\"Uploading…\");\ntoast.success(\"Uploaded\", { id }); // update in place\n\n// with description + action\ntoast(\"Invite sent\", {\n  description: \"alex@acme.com will get an email.\",\n  action: { label: \"Undo\", onClick: () =\u003e revoke() },\n});\n\n// promise — loading → success / error automatically\ntoast.promise(saveProfile(), {\n  loading: \"Saving…\",\n  success: (data) =\u003e `Saved ${data.name}`,\n  error: (err) =\u003e `Failed: ${err.message}`,\n});\n\n// render anything\ntoast.custom(\u003cMyCard /\u003e);\n\ntoast.dismiss(id); // or toast.dismiss() to clear all\n```\n\n## `\u003cToaster /\u003e` props\n\n| Prop | Type | Default | |\n|---|---|---|---|\n| `position` | `top-left \\| top-center \\| top-right \\| bottom-left \\| bottom-center \\| bottom-right` | `bottom-right` | where the stack sits |\n| `theme` | `light \\| dark \\| system` | `system` | follows the OS unless pinned |\n| `richColors` | `boolean` | `false` | tinted glass per type instead of neutral |\n| `expand` | `boolean` | `true` | fan the stack open on hover |\n| `visibleToasts` | `number` | `3` | how many show before older ones collapse out |\n| `gap` | `number` | `14` | px between toasts when expanded |\n| `offset` | `number` | `24` | px from the screen edge |\n| `duration` | `number` | `4000` | default ms before auto-dismiss |\n| `closeButton` | `boolean` | `false` | show an × on every toast |\n| `blur` | `number` | `16` | glass blur radius in px |\n| `haptics` | `boolean \\| HapticsOptions` | `true` | vibration feedback (no-op where unsupported) |\n| `toastOptions` | `{ duration, className, style, closeButton }` | — | defaults applied to every toast |\n\n## Buttons — `\u003cGlassButton\u003e`\n\nA frosted button on the glass surface, with a springy liquid press. Docs: [glaceui.com/buttons](https://glaceui.com/buttons).\n\n```tsx\nimport { GlassButton } from \"glaceui\";\n\n\u003cGlassButton onClick={save}\u003eSave\u003c/GlassButton\u003e\n\u003cGlassButton size=\"lg\" tone=\"light\"\u003eLarge light\u003c/GlassButton\u003e\n\u003cGlassButton morph\u003e{open ? \"Collapse\" : \"Expand\"}\u003c/GlassButton\u003e  // width springs on change\n```\n\nEvery button has a specular **sheen** that sweeps on hover and a **3D press** that tips the glass back. Props: `tone` (`light`/`dark`), `size` (`sm`/`md`/`lg`), `refract` (`false`/`true`/px), `aberration`, `bezel`, `saturation`, `morph`, plus all `\u003cbutton\u003e` props.\n\n`GlassCard` / `Glass` take a **`sheen`** prop for the same swept highlight on hover/press.\n\n## Panels — `\u003cGlassCard\u003e`\n\nA padded glass container — drop anything inside. Docs: [glaceui.com/panels](https://glaceui.com/panels).\n\n```tsx\nimport { GlassCard, GlassButton } from \"glaceui\";\n\n\u003cGlassCard tone=\"dark\" interactive\u003e\n  \u003ch3\u003ePricing\u003c/h3\u003e\n  \u003cp\u003eWrap anything in real glass.\u003c/p\u003e\n  \u003cGlassButton size=\"sm\"\u003eUpgrade\u003c/GlassButton\u003e\n\u003c/GlassCard\u003e\n```\n\n## Primitives — `\u003cGlass\u003e`\n\nThe raw surface every component is built on. Render any element via `as`. Docs: [glaceui.com/primitives](https://glaceui.com/primitives).\n\n```tsx\nimport { Glass, useGlassFilter } from \"glaceui\";\n\n\u003cGlass as=\"section\" tone=\"light\" radius={24}\u003e…\u003c/Glass\u003e\n\u003cGlass as=\"aside\" morph\u003e…liquid-resizes without distortion…\u003c/Glass\u003e\n```\n\n**Tuning the refraction** — the same knobs the [Glass Lab](https://glaceui.com/primitives) exposes are props on every surface (`Glass`, `GlassCard`, `GlassButton`, `Toaster`):\n\n```tsx\n\u003cGlass\n  refract={80}     // edge displacement in px — or true (auto) / false (off)\n  aberration={6}   // chromatic fringe at the rim\n  bezel={0.16}     // rim thickness, as a fraction of the shorter side\n  blur={3}         // backdrop blur\n  radius={28}      // corner radius\n/\u003e\n```\n\nFull `\u003cGlass\u003e` props: `as` (default `div`), `tone`, `radius`, `refract` (`false`/`true`/px), `aberration` (1), `bezel` (0.16), `blur` (3), `saturation` (180), `fallbackBlur` (14), `interactive`, `morph`. Displacement maps + their SVG filters are generated per element size and **cached by size+tuning**, so every same-sized surface — including the toasts — shares one filter.\n\n## Theming\n\nGlacé is driven entirely by CSS variables on `[data-glace-toaster]`. Override any of them — they map cleanly onto shadcn's token system, so you can wire them to your existing palette:\n\n```css\n[data-glace-toaster][data-theme=\"dark\"] {\n  --glace-bg: rgba(20, 20, 28, 0.55);\n  --glace-border: rgba(255, 255, 255, 0.1);\n  --glace-text: hsl(var(--foreground));\n  --glace-radius: 14px;\n}\n```\n\nPer-toast styling is just `className` / `style`:\n\n```tsx\ntoast(\"Custom\", { className: \"my-toast\", style: { \"--glace-radius\": \"22px\" } });\n```\n\n## Haptics\n\nOn by default — a light buzz on appear / action / dismiss, a no-op where the\nVibration API isn't available (iOS Safari, most desktops). Pass `haptics={false}`\nto turn it off, or tune the patterns:\n\n```tsx\n\u003cToaster haptics /\u003e\n\u003cToaster haptics={{ enabled: true, show: 8, action: [6, 10, 6], dismiss: 4 }} /\u003e\n```\n\nUses the Vibration API where available (Android Chrome and others). iOS Safari doesn't expose it, so it's a progressive enhancement — never required, never throws.\n\n## Credits\n\nStanding on the shoulders of work I admire:\n\n- [**sonner**](https://sonner.emilkowal.ski/) by Emil Kowalski — the toast API and stacking behavior this follows.\n- [**Building glass for the web**](https://aave.com/design/building-glass-for-the-web) by Aave — the layered-glass recipe.\n- [**Sileo**](https://sileo.aaryan.design/) by Aaryan — glass-notification aesthetic inspiration.\n- [**web-haptics**](https://github.com/lochie/web-haptics) by Lochie — the case for tactile web feedback.\n\n## License\n\nMIT © [Sean Geng](https://seangeng.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangeng%2Fglace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseangeng%2Fglace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangeng%2Fglace/lists"}