An open API service indexing awesome lists of open source software.

https://github.com/bejamas/data-slot

vanilla JS behavior primitives for accessible components
https://github.com/bejamas/data-slot

accessibility component-library design-systems headless-ui ui ui-components ui-kit vanilla-js

Last synced: 2 months ago
JSON representation

vanilla JS behavior primitives for accessible components

Awesome Lists containing this project

README

          




data-slot logo

# data-slot

Headless UI components for vanilla JavaScript. Tiny, accessible, unstyled.

## Features

- **Zero dependencies** - No npm package dependencies, works everywhere
- **Tree-shakeable** - Import only what you use, keep bundles small
- **Accessible** - WAI-ARIA compliant with keyboard navigation built-in
- **Small bundles** - Packages stay compact and tree-shake cleanly
- **Framework-agnostic** - Works with vanilla JavaScript, no framework required
- **TypeScript** - Full TypeScript support with type definitions included

## Quick Start

Add `data-slot` attributes to your HTML and initialize with JavaScript:

```html



Tab One
Tab Two

Content One

Content Two

import { create } from "@data-slot/tabs";

const controllers = create();
controllers[0]?.select("two");

```

The `create()` function auto-discovers all tabs in the DOM and binds them. Use the controller to programmatically control the component.

## Installation

Install individual packages as needed:

```bash
# npm
npm install @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog

# pnpm
pnpm add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog

# yarn
yarn add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog

# bun
bun add @data-slot/tabs @data-slot/dialog @data-slot/alert-dialog
```

## Packages

All packages are independently installable. Each package includes its own README with detailed documentation.

| Package | Size | Description | Documentation |
| ---------------------------- | ------ | --------------------------- | -------------------------------------------- |
| `@data-slot/navigation-menu` | 7.2 KB | Dropdown navigation menus | [README](packages/navigation-menu/README.md) |
| `@data-slot/core` | 5.5 KB | Shared utilities | [README](packages/core/README.md) |
| `@data-slot/command` | 4.7 KB | Command palette with search | [README](packages/command/README.md) |
| `@data-slot/hover-card` | 2.6 KB | Hover/focus preview cards | [README](packages/hover-card/README.md) |
| `@data-slot/tabs` | 2.3 KB | Tabbed interfaces, kbd nav | [README](packages/tabs/README.md) |
| `@data-slot/radio-group` | 2.3 KB | Single-select radios, form-ready | [README](packages/radio-group/README.md) |
| `@data-slot/tooltip` | 2.2 KB | Hover/focus tooltips | [README](packages/tooltip/README.md) |
| `@data-slot/popover` | 2.0 KB | Anchored floating content | [README](packages/popover/README.md) |
| `@data-slot/dialog` | 1.9 KB | Modal dialogs, focus trap | [README](packages/dialog/README.md) |
| `@data-slot/alert-dialog` | 1.8 KB | Blocking confirmation dialogs | [README](packages/alert-dialog/README.md) |
| `@data-slot/collapsible` | 1.6 KB | Simple show/hide toggle | [README](packages/collapsible/README.md) |
| `@data-slot/accordion` | 1.4 KB | Collapsible sections | [README](packages/accordion/README.md) |

## API

All components follow the same pattern. You can either auto-discover all instances or create controllers for specific elements.

### Auto-discovery

The `create()` function finds all component instances in the DOM (or within a scope):

```typescript
import { create } from "@data-slot/tabs";

// Find all tabs in the document
const controllers = create(); // Returns TabsController[]

// Or scope to a specific element
const controllers = create(document.querySelector(".my-app"));
```

### Manual creation

Create a controller for a specific element with options:

```typescript
import { createTabs } from "@data-slot/tabs";

const tabs = createTabs(document.querySelector('[data-slot="tabs"]'), {
defaultValue: "news",
onValueChange: (value) => console.log("Selected:", value),
});

tabs.select("sports"); // Programmatic control
tabs.destroy(); // Cleanup when done
```

### Other components

The same pattern applies to all components:

```typescript
import { createDialog } from "@data-slot/dialog";
import { createAlertDialog } from "@data-slot/alert-dialog";
import { createAccordion } from "@data-slot/accordion";
import { createPopover } from "@data-slot/popover";
import { createHoverCard } from "@data-slot/hover-card";
import { createCommand } from "@data-slot/command";

const dialog = createDialog(element);
const alertDialog = createAlertDialog(element);
const accordion = createAccordion(element);
const popover = createPopover(element);
const hoverCard = createHoverCard(element);
const command = createCommand(element);
```

## Styling

Components are unstyled by default. Use `data-state` attributes and ARIA attributes for styling.

### CSS

```css
/* Active tab trigger */
[data-slot="tabs-trigger"][aria-selected="true"] {
font-weight: bold;
border-bottom: 2px solid currentColor;
}

/* Using data-state */
[data-slot="tabs-trigger"][data-state="active"] {
color: blue;
}

[data-slot="tabs-trigger"][data-state="inactive"] {
color: gray;
}

/* Dialog overlay */
[data-slot="dialog"][data-state="open"] [data-slot="dialog-overlay"] {
background: rgba(0, 0, 0, 0.5);
}

/* Accordion content */
[data-slot="accordion-content"][hidden] {
display: none;
}
```

### Tailwind CSS

Use Tailwind's `aria-*` and `data-*` variants:

```html

Tab


Dialog content

```

## Examples

See live examples and component demos at **[data-slot.com](https://data-slot.com)**.

## Browser Support

data-slot uses ES modules and modern JavaScript features. It works in all modern browsers that support:

- ES modules (``)
- `querySelector` and DOM APIs
- Modern JavaScript (ES2017+)

For older browsers, use a bundler like Vite, Rollup, or Webpack with appropriate transpilation.

## Development

This is a monorepo managed with Bun workspaces. Each package is independently buildable and testable.

```bash
# Install dependencies
bun install

# Run tests
bun test

# Type check
bun run typecheck

# Build all packages
bun run build
```

Each package has its own directory in `packages/` with its own `package.json`, source code, and tests.

## License

MIT