{"id":47702760,"url":"https://github.com/wavedotso/wave-ui","last_synced_at":"2026-07-04T03:05:26.336Z","repository":{"id":341392955,"uuid":"1169599667","full_name":"wavedotso/wave-ui","owner":"wavedotso","description":"Wave UI is a component library built on Base UI primitives and Tailwind CSS v4.","archived":false,"fork":false,"pushed_at":"2026-05-25T16:39:01.000Z","size":327,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T18:27:58.600Z","etag":null,"topics":["base-ui","baseui","components","motion","react","storybook","tailwind","tailwindcss","ui","wave"],"latest_commit_sha":null,"homepage":"https://wave.so","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/wavedotso.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-02-28T23:24:05.000Z","updated_at":"2026-05-25T16:39:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wavedotso/wave-ui","commit_stats":null,"previous_names":["wavedotso/wave-ui"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/wavedotso/wave-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavedotso%2Fwave-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavedotso%2Fwave-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavedotso%2Fwave-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavedotso%2Fwave-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wavedotso","download_url":"https://codeload.github.com/wavedotso/wave-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wavedotso%2Fwave-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33716339,"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-05-31T02:00:06.040Z","response_time":95,"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":["base-ui","baseui","components","motion","react","storybook","tailwind","tailwindcss","ui","wave"],"created_at":"2026-04-02T17:43:19.776Z","updated_at":"2026-07-04T03:05:26.330Z","avatar_url":"https://github.com/wavedotso.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" alt=\"Wave UI\" width=\"220\" /\u003e\n\n  \u003cp\u003e\u003cstrong\u003eA modern React component library built on Base UI and Tailwind CSS,\u003cbr /\u003ewith a 3-tier semantic theme system.\u003c/strong\u003e\u003c/p\u003e\n\n  [![npm](https://img.shields.io/npm/v/@waveso/ui)](https://www.npmjs.com/package/@waveso/ui)\n  [![license](https://img.shields.io/npm/l/@waveso/ui)](./LICENSE)\n  ![React 19](https://img.shields.io/badge/React-19-149ECA?logo=react\u0026logoColor=white)\n  ![Tailwind CSS v4](https://img.shields.io/badge/Tailwind-v4-38BDF8?logo=tailwindcss\u0026logoColor=white)\n\n  \u003cbr /\u003e\n\n  \u003c!-- TODO: replace assets/showcase-placeholder.svg with a real screenshot of the Showcase story across the three themes --\u003e\n  \u003cimg src=\"assets/showcase-placeholder.svg\" alt=\"Wave UI across its three themes — Graphite, Ink, and Paper\" width=\"760\" /\u003e\n\n  \u003cbr /\u003e\u003cbr /\u003e\n\n  Full documentation coming soon at **[ui.wave.so](https://ui.wave.so)**\n\n\u003c/div\u003e\n\n---\n\n## Why Wave UI\n\nA production-ready design-token architecture that's modern, semantic, and highly maintainable.\n\nMost UI libraries carry two structural problems:\n\n1. **Redundant token names** (`border-border`, `ring-ring`) — which read backwards the moment background and text swap roles: a background becomes `bg-foreground`, text becomes `text-background`.\n2. **Material-style paired tokens** (`card` + `card-foreground`, `popover` + `popover-foreground`) — flexible per layer, but they add complexity, kill the emphasis ladder, and lose free composability. `foreground-muted` is meant as \"text _on_ muted,\" yet most people read it as \"muted text.\" The result is ~14 tokens, half of them redundant.\n\nBoth models work, and end users never notice. But for the people _building_ on the system, the shape matters.\n\nWave builds around an intuitive, intentional **3-tier hierarchy** — for almost everything:\n\n- 3 themes — Paper, Graphite, Ink palettes\n- 3 background colors for surfaces\n- 3 content colors for text\n- 3 identity colors for brand\n- 3 border colors for structural luminance\n- 3 duration tiers for transitions\n- 3 blur values\n- 3 scale sizes\n- 3 stagger times\n- 3 shadows with adaptable color\n- 3 offset amounts for transforms\n- …and more\n\nIt also builds around 3 semantic intents:\n\n- **Background** colors focus on elevation — how deep a surface sits\n- **Content** colors focus on emphasis — how strongly something reads\n- **Border** colors focus on structure — how functional a boundary is\n\nThis is the right shape for a system centered on an emphasis ladder: clean and minimal, but flexible.\n\n### Themes\n\nThe three themes are a homage to the **pre-digital writing desk** — the _surface_, the _pen_, the _pencil_ — and each maps to its color: cream ***Paper***, blue-black ***Ink***, gray ***Graphite***.\n\n**Graphite** is the default **neutral pencil-gray** theme, built on a low-saturation dark-neutral family with a subtle blue bias. That bias keeps the light steps from going flat — a tiny cool cast instead of pure gray.\n\n**Paper** and **Ink** are an elegant classic pair, each with a purpose: Paper is tuned for daytime and bright spaces; Ink for night and dark spaces. In every theme the _structure_ (text and borders) stays a cool-biased neutral, while the _surface_ carries the identity.\n\n## Taxonomy\n\nWave pays close attention to token taxonomy. Surfaces encode elevation; borders act as _light interference rather than geometry_.\n\n### Background\n\n- `--foundation` — the deepest layer, the base where elevation starts\n- `--surface` — the middle layer: cards, sidebars, content boxes\n- `--elevated` — the highest layer: floating windows, modals, dropdowns, dialogs\n\n### Foreground\n\n- `--contrast` — titles, primary text\n- `--muted` — body text, icons, any mark\n- `--soft` — placeholders, hints\n\n### Borders\n\n- `--line` — subtle separators\n- `--edge` — component boundary\n- `--solid` — structural definition\n\n### Ring\n\n- `--focus` — active / focus states\n\n### Brand\n\n- `--primary` — wired to the Wave ramp\n- `--secondary` — neutral fill\n- `--accent` — alternative emphasis\n\n### Border strategy\n\nThis is the sophisticated move most libraries skip.\n\nWave biases heavily toward **transparent (alpha) borders as the default**, with a **solid token reserved for functional states**.\n\nWave's palette behaves like a layered _material system_, not a flat UI. Dark surfaces, a soft text hierarchy, and subtle elevation shifts (low-contrast steps) mean borders should not introduce a new \"color layer\" — that would break the illusion of depth — yet structure still needs a solid option.\n\nAlpha borders **inherit the surface beneath them**, take the **content color as their luminance source**, keep hue consistent across surfaces, and scale naturally.\n\nSolid borders compete with the surface ladder and create visual \"grid noise\" if overused, so use them sparingly. Overusing them flattens everything into \"outlined boxes\" with reduced perceived elevation — the \"Bootstrap feel.\"\n\nThe default **alpha** borders are ideal for:\n\n- Cards\n- Panels\n- Inputs\n- Subtle separators\n\nThe **solid** borders are ideal for:\n\n- Layout definition (sidebar vs. content)\n- Component grouping\n- Focus containment\n- \"Frame-like\" boundaries\n\n**Rule of thumb:**\n\n- If it separates **surface from surface** → alpha border\n- If it separates **layout regions** → solid border\n- If it indicates **interaction / state** → colored alpha border\n\n---\n\n## Installation\n\n```bash\nnpm install @waveso/ui @base-ui/react class-variance-authority clsx tailwind-merge\n```\n\n## Setup\n\nAdd the theme preset and Tailwind to your CSS entry point:\n\n```css\n@import \"@waveso/ui/styles.css\";\n@import \"tailwindcss\";\n```\n\nThe preset provides every CSS variable (colors, radii, motion, shadows) with light and dark support. Override any variable in your own `:root` / `.dark` blocks to customize the theme.\n\n## Usage\n\nEvery component is its own entry point, so you ship only what you import:\n\n```tsx\nimport { Button } from '@waveso/ui/button';\nimport { Card, CardHeader, CardTitle, CardContent } from '@waveso/ui/card';\n\nexport function Example() {\n  return (\n    \u003cCard\u003e\n      \u003cCardHeader\u003e\n        \u003cCardTitle\u003eGet started\u003c/CardTitle\u003e\n      \u003c/CardHeader\u003e\n      \u003cCardContent\u003e\n        \u003cButton\u003eClick me\u003c/Button\u003e\n      \u003c/CardContent\u003e\n    \u003c/Card\u003e\n  );\n}\n```\n\nEvery component is built on a [Base UI](https://base-ui.com) primitive — full keyboard and ARIA support — and styled entirely through the theme tokens above, so overriding a token propagates everywhere.\n\n## Components\n\nA comprehensive set spanning **actions, forms, layout, navigation, overlays, feedback, data display, and motion effects** — all built on Base UI primitives and driven by the theme tokens.\n\nBrowse every component, with live variants and source, in **Storybook** (`npm run storybook`). A full documentation site is on the way at **[ui.wave.so](https://ui.wave.so)**.\n\n## Requirements\n\n| Dependency | Version |\n|---|---|\n| React | ^19.0.0 |\n| React DOM | ^19.0.0 |\n| Base UI | ^1.6.0 |\n| Tailwind CSS | v4 |\n| CVA | ^0.7.0 |\n| clsx | ^2.0.0 |\n| tailwind-merge | ^3.0.0 |\n\nSome components have optional peer dependencies — install only what you use:\n\n- **Form** — `react-hook-form`\n- **Input OTP** — `input-otp`\n- **Animations** — `motion`\n- **Sidebar** — `usehooks-ts`\n\n## Development\n\n```bash\nnpm install\nnpm run storybook    # Start Storybook\nnpm run build        # Build the library\nnpm run typecheck    # Type-check\nnpm run dev          # Watch mode\n```\n\n### Project structure\n\n```\n.changeset/          # Changesets config\n.storybook/          # Storybook config + theme CSS\nassets/              # README / brand assets\nsrc/\n  *.tsx              # Component source files\n  *.stories.tsx      # Storybook stories\n  styles.css         # Theme preset (CSS variables + Tailwind mapping)\n  hooks/             # Custom hooks\n  lib/               # Utilities (cn, internal icons)\n```\n\n## Releasing\n\nThis project uses [Changesets](https://github.com/changesets/changesets) with GitHub Actions.\n\n1. Run `npx changeset` to describe your changes (patch, minor, or major)\n2. Commit the generated changeset file with your PR\n3. When merged to `main`, CI automatically versions and publishes to npm\n\n\u003cdetails\u003e\n\u003csummary\u003eManual release (without CI)\u003c/summary\u003e\n\nIf you're not using the GitHub Actions workflow, you can publish manually. Changesets skips versions already published to npm, so this won't conflict if CI has already run.\n\n```bash\nnpx changeset              # Create a changeset\nnpx changeset version      # Apply version bump\nnpm run release            # Build and publish to npm\n```\n\n\u003c/details\u003e\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavedotso%2Fwave-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwavedotso%2Fwave-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwavedotso%2Fwave-ui/lists"}