Skip to content

Latest commit

 

History

History
119 lines (76 loc) · 2.52 KB

File metadata and controls

119 lines (76 loc) · 2.52 KB

@data-slot/core

Shared utilities for data-slot headless UI components.

Installation

npm install @data-slot/core

API

DOM Utilities

getPart(root, slot)

Query a single part/slot within a component root.

const trigger = getPart<HTMLButtonElement>(root, "dialog-trigger");

getParts(root, slot)

Query all parts/slots within a component root.

const items = getParts<HTMLElement>(root, "accordion-item");

getRoots(scope, slot)

Find all component roots within a scope by data-slot value.

const dialogs = getRoots(document, "dialog");

ARIA Utilities

ensureId(element, prefix)

Ensure an element has an id, generating one if needed.

const id = ensureId(content, "dialog-content");
// Returns existing id or generates "dialog-content-1"

setAria(element, name, value)

Set or remove an ARIA attribute. Boolean values are converted to strings.

setAria(trigger, "expanded", true);  // aria-expanded="true"
setAria(trigger, "expanded", null);  // removes aria-expanded

linkLabelledBy(content, title, description)

Link content element to its label and description via ARIA.

linkLabelledBy(dialogContent, titleElement, descriptionElement);
// Sets aria-labelledby and aria-describedby

Event Utilities

on(element, type, handler, options?)

Add an event listener and return a cleanup function.

const cleanup = on(button, "click", () => console.log("clicked"));
// Later: cleanup() to remove listener

emit(element, name, detail?)

Dispatch a custom event with optional detail.

emit(root, "tabs:change", { value: "tab-2" });

composeHandlers(...handlers)

Compose multiple event handlers into one. Stops if event.defaultPrevented.

const handler = composeHandlers(onClickProp, internalHandler);

Usage in Components

This package is used internally by all @data-slot/* component packages. You typically don't need to import it directly unless building custom components.

import { getPart, setAria, on } from "@data-slot/core";

function createCustomComponent(root: Element) {
  const trigger = getPart(root, "custom-trigger");
  const content = getPart(root, "custom-content");
  
  const cleanup = on(trigger, "click", () => {
    const isOpen = content.hidden;
    content.hidden = !isOpen;
    setAria(trigger, "expanded", isOpen);
  });
  
  return { destroy: cleanup };
}

License

MIT