{"id":50606504,"url":"https://github.com/productdevbook/dokuma","last_synced_at":"2026-06-05T23:31:11.516Z","repository":{"id":351951996,"uuid":"1213201915","full_name":"productdevbook/dokuma","owner":"productdevbook","description":"Framework-agnostic, zero-dependency headless UI primitives. Vanilla / React / Vue / native shells.","archived":false,"fork":false,"pushed_at":"2026-04-17T07:24:28.000Z","size":153,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T08:30:43.721Z","etag":null,"topics":["accessibility","aria","headless-ui","primitives","react","typescript","ui-components","vanilla-js","vue","zero-dependencies"],"latest_commit_sha":null,"homepage":"","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/productdevbook.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["productdevbook"]}},"created_at":"2026-04-17T06:25:31.000Z","updated_at":"2026-04-17T07:24:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/productdevbook/dokuma","commit_stats":null,"previous_names":["productdevbook/dokuma"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/productdevbook/dokuma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fdokuma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fdokuma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fdokuma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fdokuma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/productdevbook","download_url":"https://codeload.github.com/productdevbook/dokuma/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/productdevbook%2Fdokuma/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33964367,"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-05T02:00:06.157Z","response_time":120,"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":["accessibility","aria","headless-ui","primitives","react","typescript","ui-components","vanilla-js","vue","zero-dependencies"],"created_at":"2026-06-05T23:31:10.927Z","updated_at":"2026-06-05T23:31:11.509Z","avatar_url":"https://github.com/productdevbook.png","language":"TypeScript","funding_links":["https://github.com/sponsors/productdevbook"],"categories":[],"sub_categories":[],"readme":"# dokuma\n\n\u003e Framework-agnostic, zero-dependency headless UI primitives. The weave (Turkish: _dokuma_) that ties your design system to any framework.\n\n`radix-ui`, `@base-ui-components/react`, `@headlessui/react` — all React-only.\n`dokuma` is the same idea, but the primitives are plain TypeScript functions and reactive stores, with framework integrations layered on top.\n\n- **Agnostic.** Works in vanilla HTML via CDN, in React, Vue, Svelte, Solid, Angular, Preact, Qwik, Lit, web components, and inside native mobile shells (Capacitor, React Native WebView, Tauri).\n- **Zero runtime dependencies.** Pure ESM. No CJS.\n- **SSR-safe.** No top-level DOM access.\n- **Accessibility-first.** WAI-ARIA, keyboard, focus management baked in.\n- **Tree-shakeable.** Each primitive is a separate sub-path export.\n- **Tiny.** Whole package under 100 KB raw, gzip ≈ 1/3 of that.\n\n\u003e **Status:** v0.2 — 29 primitives shipped. APIs are settling but may still change before 1.0.\n\n## Install\n\n```bash\npnpm add dokuma\n```\n\nOr use it directly from a CDN — no build step:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import { mountDisclosure } from \"https://esm.sh/dokuma/vanilla\"\n\n  mountDisclosure({\n    trigger: \"#my-button\",\n    panel: \"#my-panel\",\n  })\n\u003c/script\u003e\n```\n\n## Quickstart\n\n### Vanilla\n\n```html\n\u003cbutton id=\"trigger\"\u003eToggle\u003c/button\u003e\n\u003cdiv id=\"panel\"\u003eHello.\u003c/div\u003e\n\n\u003cscript type=\"module\"\u003e\n  import { mountDisclosure } from \"dokuma/vanilla\"\n\n  mountDisclosure({\n    trigger: \"#trigger\",\n    panel: \"#panel\",\n    defaultOpen: false,\n    onOpenChange: (open) =\u003e console.log(\"open:\", open),\n  })\n\u003c/script\u003e\n```\n\n### React\n\n```tsx\nimport { useDisclosure } from \"dokuma/react-hooks\"\n\nfunction Demo() {\n  const d = useDisclosure({ defaultOpen: false })\n  return (\n    \u003c\u003e\n      \u003cbutton {...d.getTriggerProps()}\u003eToggle\u003c/button\u003e\n      \u003cdiv {...d.getPanelProps()}\u003eHello from React.\u003c/div\u003e\n    \u003c/\u003e\n  )\n}\n```\n\nFor Preact compat or an isolated React copy, use the factory entry instead:\n\n```tsx\nimport * as React from \"react\"\nimport { createUseDisclosure } from \"dokuma/react\"\nconst useDisclosure = createUseDisclosure(React)\n```\n\n### Vue\n\n```vue\n\u003cscript setup\u003e\nimport { useDisclosure } from \"dokuma/vue-composables\"\nconst d = useDisclosure({ defaultOpen: false })\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cbutton v-bind=\"d.triggerProps\"\u003eToggle\u003c/button\u003e\n  \u003cdiv v-bind=\"d.panelProps\"\u003eHello from Vue.\u003c/div\u003e\n\u003c/template\u003e\n```\n\n## Primitives\n\n| Primitive       | Path                     | What it does                                                             |\n| --------------- | ------------------------ | ------------------------------------------------------------------------ |\n| Disclosure      | `dokuma/disclosure`      | Show/hide a panel via a button. The foundation primitive.                |\n| Accordion       | `dokuma/accordion`       | Stack of collapsible items. Single or multiple open. Arrow-key nav.      |\n| Tabs            | `dokuma/tabs`            | Tablist with roving focus, automatic or manual activation.               |\n| Switch          | `dokuma/switch`          | On/off control. `role=\"switch\"`, optional hidden checkbox for forms.     |\n| Toggle          | `dokuma/toggle`          | Single pressed-state button (`aria-pressed`).                            |\n| Toggle Group    | `dokuma/toggle-group`    | Coordinated set of Toggles. Single (alignment) or multiple (formatting). |\n| Dialog          | `dokuma/dialog`          | Modal/non-modal dialog. Focus trap, scroll lock, escape, click-outside.  |\n| Tooltip         | `dokuma/tooltip`         | Hover/focus floating label. Viewport-aware positioning.                  |\n| Popover         | `dokuma/popover`         | Click-triggered floating panel. Focus trap, escape, click-outside.       |\n| Avatar          | `dokuma/avatar`          | Image with fallback. Status state machine, eager preload.                |\n| Progress        | `dokuma/progress`        | ARIA progressbar with indeterminate, loading, complete states.           |\n| Menu            | `dokuma/menu`            | Click-triggered actions menu. Typeahead, focus-based navigation.         |\n| Context Menu    | `dokuma/context-menu`    | Right-click + long-press menu anchored to cursor. Composes Menu.         |\n| Slider          | `dokuma/slider`          | Range input. Single value or two-thumb range. Pointer + full keyboard.   |\n| Radio Group     | `dokuma/radio-group`     | Single-selection radio group. Roving tabindex, arrows navigate + select. |\n| Checkbox        | `dokuma/checkbox`        | Three-state: true / false / indeterminate. ARIA mixed.                   |\n| Combobox        | `dokuma/combobox`        | Searchable single-select. WAI-ARIA 1.2 with `aria-activedescendant`.     |\n| Toaster         | `dokuma/toaster`         | Notification queue, auto-dismiss, hover/focus pause, ARIA live region.   |\n| Separator       | `dokuma/separator`       | Section divider. `role=\"separator\"` or `role=\"none\"` when decorative.    |\n| Visually Hidden | `dokuma/visually-hidden` | Screen-reader-only content via the standard `.sr-only` style block.      |\n| Collapsible     | `dokuma/collapsible`     | Disclosure under a different name, for design systems that prefer it.    |\n| Alert Dialog    | `dokuma/alert-dialog`    | Dialog with `role=\"alertdialog\"` and outside-click closing forced off.   |\n| Hover Card      | `dokuma/hover-card`      | Tooltip with longer delays + `role=\"dialog\"` for interactive content.    |\n| Label           | `dokuma/label`           | `\u003clabel\u003e` association helper. Emits `for` + optional `id`.               |\n| Aspect Ratio    | `dokuma/aspect-ratio`    | Modern `aspect-ratio` CSS wrapper for media slots.                       |\n| Breadcrumb      | `dokuma/breadcrumb`      | Pure ARIA wrapper for a breadcrumb trail. Marks separators decorative.   |\n| Pagination      | `dokuma/pagination`      | Page list with ellipsis algorithm. `aria-current` on the active page.    |\n| Number Input    | `dokuma/number-input`    | Stepper with min/max/step, hold-to-repeat, hidden form input.            |\n| OTP Input       | `dokuma/otp-input`       | N-cell pin input with auto-advance, paste distribution, isComplete.      |\n\nCross-cutting helpers exported from the package root: `createPresence` (animate-out), `getDefaultPortalTarget` / `resolvePortalTarget` (portal helpers), `DokumaError`, `createSignal`. Internal layer stacks (`FocusScope`, `DismissibleLayer`) are handled automatically by every dismissible primitive — no setup needed for nested modals.\n\n## Adapters\n\n| Adapter           | Path                     | Use                                                            |\n| ----------------- | ------------------------ | -------------------------------------------------------------- |\n| Vanilla           | `dokuma/vanilla`         | `mount*` helpers for every primitive.                          |\n| React (factory)   | `dokuma/react`           | `createUse*(React)` factories — pass your own React instance.  |\n| React (pre-bound) | `dokuma/react-hooks`     | Pre-bound `useDisclosure`, `useDialog`, etc. Skip the factory. |\n| Vue (factory)     | `dokuma/vue`             | `createUse*(Vue)` composables, mirror of the React API.        |\n| Vue (pre-bound)   | `dokuma/vue-composables` | Pre-bound composables. Skip the factory.                       |\n\nSvelte / Solid / Angular / Lit adapters are out of scope for this maintainer — the framework-agnostic `create*` functions in `dokuma` (root entry) make a thin wrapper for any reactive runtime a small project. Community contributions welcome.\n\n## Why \"dokuma\"?\n\nIn Turkish, _dokuma_ means **the weave** — the cloth where independent threads are bound into a single fabric. That is what these primitives are: the weave that binds your design system to whatever framework happens to be on the other side.\n\n## License\n\nMIT — © productdevbook\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproductdevbook%2Fdokuma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fproductdevbook%2Fdokuma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fproductdevbook%2Fdokuma/lists"}