{"id":36650851,"url":"https://github.com/bejamas/data-slot","last_synced_at":"2026-04-01T19:51:24.493Z","repository":{"id":332057355,"uuid":"1129993421","full_name":"bejamas/data-slot","owner":"bejamas","description":"vanilla JS behavior primitives for accessible components","archived":false,"fork":false,"pushed_at":"2026-03-30T09:51:03.000Z","size":1992,"stargazers_count":31,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-30T11:35:29.497Z","etag":null,"topics":["accessibility","component-library","design-systems","headless-ui","ui","ui-components","ui-kit","vanilla-js"],"latest_commit_sha":null,"homepage":"https://data-slot.com","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/bejamas.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-01-07T21:59:16.000Z","updated_at":"2026-03-30T09:51:05.000Z","dependencies_parsed_at":"2026-03-13T08:02:02.326Z","dependency_job_id":null,"html_url":"https://github.com/bejamas/data-slot","commit_stats":null,"previous_names":["bejamas/data-slot"],"tags_count":166,"template":false,"template_full_name":null,"purl":"pkg:github/bejamas/data-slot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bejamas%2Fdata-slot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bejamas%2Fdata-slot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bejamas%2Fdata-slot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bejamas%2Fdata-slot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bejamas","download_url":"https://codeload.github.com/bejamas/data-slot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bejamas%2Fdata-slot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","component-library","design-systems","headless-ui","ui","ui-components","ui-kit","vanilla-js"],"created_at":"2026-01-12T10:06:14.846Z","updated_at":"2026-04-01T19:51:24.487Z","avatar_url":"https://github.com/bejamas.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://data-slot\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://assets.bejamas.com/static/image/data-slot/logo-dark.svg\"\u003e\n    \u003cimg alt=\"data-slot logo\" src=\"https://assets.bejamas.com/static/image/data-slot/logo-light.svg\" height=\"64\"\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n# data-slot\n\nHeadless UI components for vanilla JavaScript. Tiny, accessible, unstyled.\n\n## Features\n\n- **Zero dependencies** - No npm package dependencies, works everywhere\n- **Tree-shakeable** - Import only what you use, keep bundles small\n- **Accessible** - WAI-ARIA compliant with keyboard navigation built-in\n- **Small bundles** - Packages stay compact and tree-shake cleanly\n- **Framework-agnostic** - Works with vanilla JavaScript, no framework required\n- **TypeScript** - Full TypeScript support with type definitions included\n\n## Quick Start\n\nAdd `data-slot` attributes to your HTML and initialize with JavaScript:\n\n```html\n\u003cdiv data-slot=\"tabs\" data-default-value=\"one\"\u003e\n  \u003cdiv data-slot=\"tabs-list\"\u003e\n    \u003cbutton data-slot=\"tabs-trigger\" data-value=\"one\"\u003eTab One\u003c/button\u003e\n    \u003cbutton data-slot=\"tabs-trigger\" data-value=\"two\"\u003eTab Two\u003c/button\u003e\n  \u003c/div\u003e\n  \u003cdiv data-slot=\"tabs-content\" data-value=\"one\"\u003eContent One\u003c/div\u003e\n  \u003cdiv data-slot=\"tabs-content\" data-value=\"two\"\u003eContent Two\u003c/div\u003e\n\u003c/div\u003e\n\n\u003cscript type=\"module\"\u003e\n  import { create } from \"@data-slot/tabs\";\n\n  const controllers = create();\n  controllers[0]?.select(\"two\");\n\u003c/script\u003e\n```\n\nThe `create()` function auto-discovers all tabs in the DOM and binds them. Use the controller to programmatically control the component.\n\n## Installation\n\nInstall individual packages as needed:\n\n```bash\n# npm\nnpm install @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog\n\n# pnpm\npnpm add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog\n\n# yarn\nyarn add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog\n\n# bun\nbun add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog\n```\n\n## Packages\n\nAll packages are independently installable. Each package includes its own README with detailed documentation.\n\n| Package                      | Size   | Description                 | Documentation                                |\n| ---------------------------- | ------ | --------------------------- | -------------------------------------------- |\n| `@data-slot/navigation-menu` | 7.2 KB | Dropdown navigation menus   | [README](packages/navigation-menu/README.md) |\n| `@data-slot/core`            | 5.5 KB | Shared utilities            | [README](packages/core/README.md)            |\n| `@data-slot/command`         | 4.7 KB | Command palette with search | [README](packages/command/README.md)         |\n| `@data-slot/hover-card`      | 2.6 KB | Hover/focus preview cards   | [README](packages/hover-card/README.md)      |\n| `@data-slot/tabs`            | 2.3 KB | Tabbed interfaces, kbd nav  | [README](packages/tabs/README.md)            |\n| `@data-slot/radio-group`     | 2.3 KB | Single-select radios, form-ready | [README](packages/radio-group/README.md) |\n| `@data-slot/tooltip`         | 2.2 KB | Hover/focus tooltips        | [README](packages/tooltip/README.md)         |\n| `@data-slot/popover`         | 2.0 KB | Anchored floating content   | [README](packages/popover/README.md)         |\n| `@data-slot/dialog`          | 1.9 KB | Modal dialogs, focus trap   | [README](packages/dialog/README.md)          |\n| `@data-slot/alert-dialog`    | 1.8 KB | Blocking confirmation dialogs | [README](packages/alert-dialog/README.md)  |\n| `@data-slot/collapsible`     | 1.6 KB | Simple show/hide toggle     | [README](packages/collapsible/README.md)     |\n| `@data-slot/accordion`       | 1.4 KB | Collapsible sections        | [README](packages/accordion/README.md)       |\n\n## API\n\nAll components follow the same pattern. You can either auto-discover all instances or create controllers for specific elements.\n\n### Auto-discovery\n\nThe `create()` function finds all component instances in the DOM (or within a scope):\n\n```typescript\nimport { create } from \"@data-slot/tabs\";\n\n// Find all tabs in the document\nconst controllers = create(); // Returns TabsController[]\n\n// Or scope to a specific element\nconst controllers = create(document.querySelector(\".my-app\"));\n```\n\n### Manual creation\n\nCreate a controller for a specific element with options:\n\n```typescript\nimport { createTabs } from \"@data-slot/tabs\";\n\nconst tabs = createTabs(document.querySelector('[data-slot=\"tabs\"]'), {\n  defaultValue: \"news\",\n  onValueChange: (value) =\u003e console.log(\"Selected:\", value),\n});\n\ntabs.select(\"sports\"); // Programmatic control\ntabs.destroy(); // Cleanup when done\n```\n\n### Other components\n\nThe same pattern applies to all components:\n\n```typescript\nimport { createDialog } from \"@data-slot/dialog\";\nimport { createAlertDialog } from \"@data-slot/alert-dialog\";\nimport { createAccordion } from \"@data-slot/accordion\";\nimport { createPopover } from \"@data-slot/popover\";\nimport { createHoverCard } from \"@data-slot/hover-card\";\nimport { createCommand } from \"@data-slot/command\";\n\nconst dialog = createDialog(element);\nconst alertDialog = createAlertDialog(element);\nconst accordion = createAccordion(element);\nconst popover = createPopover(element);\nconst hoverCard = createHoverCard(element);\nconst command = createCommand(element);\n```\n\n## Styling\n\nComponents are unstyled by default. Use `data-state` attributes and ARIA attributes for styling.\n\n### CSS\n\n```css\n/* Active tab trigger */\n[data-slot=\"tabs-trigger\"][aria-selected=\"true\"] {\n  font-weight: bold;\n  border-bottom: 2px solid currentColor;\n}\n\n/* Using data-state */\n[data-slot=\"tabs-trigger\"][data-state=\"active\"] {\n  color: blue;\n}\n\n[data-slot=\"tabs-trigger\"][data-state=\"inactive\"] {\n  color: gray;\n}\n\n/* Dialog overlay */\n[data-slot=\"dialog\"][data-state=\"open\"] [data-slot=\"dialog-overlay\"] {\n  background: rgba(0, 0, 0, 0.5);\n}\n\n/* Accordion content */\n[data-slot=\"accordion-content\"][hidden] {\n  display: none;\n}\n```\n\n### Tailwind CSS\n\nUse Tailwind's `aria-*` and `data-*` variants:\n\n```html\n\u003cbutton\n  data-slot=\"tabs-trigger\"\n  class=\"px-4 py-2 aria-selected:font-bold aria-selected:border-b-2 aria-selected:text-blue-600\"\n\u003e\n  Tab\n\u003c/button\u003e\n\n\u003cdiv\n  data-slot=\"dialog-content\"\n  class=\"data-[state=open]:flex data-[state=closed]:hidden\"\n\u003e\n  Dialog content\n\u003c/div\u003e\n```\n\n## Examples\n\nSee live examples and component demos at **[data-slot.com](https://data-slot.com)**.\n\n## Browser Support\n\ndata-slot uses ES modules and modern JavaScript features. It works in all modern browsers that support:\n\n- ES modules (`\u003cscript type=\"module\"\u003e`)\n- `querySelector` and DOM APIs\n- Modern JavaScript (ES2017+)\n\nFor older browsers, use a bundler like Vite, Rollup, or Webpack with appropriate transpilation.\n\n## Development\n\nThis is a monorepo managed with Bun workspaces. Each package is independently buildable and testable.\n\n```bash\n# Install dependencies\nbun install\n\n# Run tests\nbun test\n\n# Type check\nbun run typecheck\n\n# Build all packages\nbun run build\n```\n\nEach package has its own directory in `packages/` with its own `package.json`, source code, and tests.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbejamas%2Fdata-slot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbejamas%2Fdata-slot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbejamas%2Fdata-slot/lists"}