CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zag-js--dialog

Core logic for the dialog widget implemented as a state machine

Overview
Eval results
Files

connect.mddocs/

API Connection Methods

The connect function transforms the dialog state machine into framework-agnostic prop functions that provide complete accessibility, interaction handling, and ARIA attributes for UI elements.

Capabilities

Connect Function

Connects a dialog service to UI framework normalization, returning an API object with prop functions for each dialog element.

/**
 * Connects dialog service to UI framework, returning prop functions
 * @param service - Dialog state machine service
 * @param normalize - Framework-specific prop normalization function
 * @returns API object with prop functions for dialog elements
 */
function connect<T extends PropTypes>(
  service: Service,
  normalize: NormalizeProps<T>
): Api<T>;

interface Service {
  /** Current machine state */
  state: State;
  /** Send events to machine */
  send: (event: MachineEvent) => void;
  /** Machine context */
  context: Context;
  /** Get prop value */
  prop: (key: string) => any;
  /** DOM scope for element access */
  scope: Scope;
}

interface Api<T extends PropTypes> {
  /** Current open state */
  open: boolean;
  /** Programmatically set open state */
  setOpen: (open: boolean) => void;
  
  // Element prop functions
  getTriggerProps: () => T["button"];
  getBackdropProps: () => T["element"];
  getPositionerProps: () => T["element"];  
  getContentProps: () => T["element"];
  getTitleProps: () => T["element"];
  getDescriptionProps: () => T["element"];
  getCloseTriggerProps: () => T["button"];
}

Usage Example:

import { machine, connect } from "@zag-js/dialog";
import { normalizeProps } from "@zag-js/react";

const service = useMachine(machine({ id: "dialog-1" }));
const api = connect(service, normalizeProps);

// Use api.getTriggerProps(), api.getContentProps(), etc.

Open State Management

Direct access to dialog open state and programmatic control.

interface OpenStateAPI {
  /** Whether dialog is currently open */
  open: boolean;
  
  /**
   * Set dialog open state programmatically
   * @param open - True to open dialog, false to close
   */
  setOpen: (open: boolean) => void;
}

Usage Examples:

// Check if dialog is open
if (api.open) {
  console.log("Dialog is currently open");
}

// Open dialog programmatically
api.setOpen(true);

// Close dialog programmatically  
api.setOpen(false);

// Toggle dialog
api.setOpen(!api.open);

Trigger Element Props

Props for the button that opens the dialog, with proper ARIA attributes and click handling.

/**
 * Get props for dialog trigger button
 * @returns Button props with accessibility and click handling
 */
getTriggerProps(): ButtonProps;

interface ButtonProps {
  /** Element ID */
  id: string;
  /** Button type */
  type: "button";
  /** Text direction */
  dir: "ltr" | "rtl";
  /** ARIA popup type */
  "aria-haspopup": "dialog";
  /** ARIA expanded state */
  "aria-expanded": boolean;
  /** Data state attribute */
  "data-state": "open" | "closed";
  /** Controls relationship */
  "aria-controls": string;
  /** Click handler */
  onClick: (event: MouseEvent) => void;
}

Usage Example:

<button {...api.getTriggerProps()}>
  Open Dialog
</button>

Backdrop Element Props

Props for the modal backdrop that appears behind the dialog content.

/**
 * Get props for dialog backdrop
 * @returns Element props for backdrop
 */
getBackdropProps(): ElementProps;

interface ElementProps {
  /** Element ID */
  id: string;
  /** Text direction */
  dir: "ltr" | "rtl";
  /** Hidden state */
  hidden: boolean;
  /** Data state attribute */
  "data-state": "open" | "closed";
}

Usage Example:

<div {...api.getBackdropProps()} />

Positioner Element Props

Props for the element that positions the dialog content, typically a full-screen container.

/**
 * Get props for dialog positioner
 * @returns Element props for positioner container
 */
getPositionerProps(): PositionerProps;

interface PositionerProps {
  /** Element ID */
  id: string;
  /** Text direction */
  dir: "ltr" | "rtl";
  /** CSS styles */
  style: {
    pointerEvents: "none" | undefined;
  };
}

Usage Example:

<div {...api.getPositionerProps()}>
  {/* Dialog content container */}
</div>

Content Element Props

Props for the main dialog content container with full accessibility attributes.

/**
 * Get props for dialog content container
 * @returns Element props with full ARIA attributes
 */
getContentProps(): ContentProps;

interface ContentProps {
  /** Element ID */
  id: string;
  /** Text direction */
  dir: "ltr" | "rtl";
  /** ARIA role */
  role: "dialog" | "alertdialog";
  /** Hidden state */
  hidden: boolean;
  /** Tab index for focus */
  tabIndex: -1;
  /** Data state attribute */
  "data-state": "open" | "closed";
  /** Modal flag */
  "aria-modal": true;
  /** Accessible label */
  "aria-label"?: string;
  /** Labeled by title element */
  "aria-labelledby"?: string;
  /** Described by description element */
  "aria-describedby"?: string;
}

Usage Example:

<div {...api.getContentProps()}>
  <h2 {...api.getTitleProps()}>Dialog Title</h2>
  <p {...api.getDescriptionProps()}>Dialog description</p>
  {/* Dialog content */}
</div>

Title Element Props

Props for the dialog title element, used for ARIA labeling.

/**
 * Get props for dialog title element
 * @returns Element props for title
 */
getTitleProps(): TitleProps;

interface TitleProps {
  /** Element ID */
  id: string;
  /** Text direction */
  dir: "ltr" | "rtl";
}

Usage Example:

<h2 {...api.getTitleProps()}>
  My Dialog Title
</h2>

Description Element Props

Props for the dialog description element, used for ARIA descriptions.

/**
 * Get props for dialog description element
 * @returns Element props for description
 */
getDescriptionProps(): DescriptionProps;

interface DescriptionProps {
  /** Element ID */
  id: string;
  /** Text direction */
  dir: "ltr" | "rtl";
}

Usage Example:

<p {...api.getDescriptionProps()}>
  This dialog contains important information.
</p>

Close Trigger Props

Props for the button that closes the dialog, with proper event handling.

/**
 * Get props for dialog close button
 * @returns Button props with close handling
 */
getCloseTriggerProps(): CloseButtonProps;

interface CloseButtonProps {
  /** Element ID */
  id: string;
  /** Button type */
  type: "button";
  /** Text direction */
  dir: "ltr" | "rtl";
  /** Click handler with event propagation control */
  onClick: (event: MouseEvent) => void;
}

Usage Example:

<button {...api.getCloseTriggerProps()}>
  ✕ Close
</button>

Complete Integration Example

import { machine, connect } from "@zag-js/dialog";
import { normalizeProps } from "@zag-js/react"; // or your framework

function MyDialog() {
  const [state, send] = useMachine(
    machine({
      id: "my-dialog",
      modal: true,
      closeOnEscape: true,
      onOpenChange: (details) => {
        console.log("Dialog open state:", details.open);
      }
    })
  );

  const api = connect(state, normalizeProps);

  return (
    <div>
      {/* Trigger */}
      <button {...api.getTriggerProps()}>
        Open Dialog
      </button>

      {/* Dialog Portal */}
      {api.open && (
        <div {...api.getPositionerProps()}>
          {/* Backdrop */}
          <div {...api.getBackdropProps()} />
          
          {/* Content */}
          <div {...api.getContentProps()}>
            <h2 {...api.getTitleProps()}>
              Confirmation
            </h2>
            
            <p {...api.getDescriptionProps()}>
              Are you sure you want to delete this item?
            </p>
            
            <div>
              <button {...api.getCloseTriggerProps()}>
                Cancel
              </button>
              <button onClick={() => {
                // Perform action
                api.setOpen(false);
              }}>
                Delete
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-zag-js--dialog

docs

connect.md

index.md

machine.md

tile.json