CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-radix-ui--react-dialog

A high-quality, accessible dialog component for React applications, providing overlay modals, focus management, keyboard navigation, and screen reader support as part of the Radix UI primitives collection

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

triggers-controls.mddocs/

Triggers and Controls

Components for opening and closing dialogs with proper accessibility, keyboard navigation, and focus management.

Capabilities

DialogTrigger

Button component that opens the dialog when activated, with automatic accessibility attributes.

/**
 * Button component that opens the dialog when activated
 * Extends all standard button props and automatically adds accessibility attributes
 */
type DialogTriggerElement = React.ComponentRef<typeof Primitive.button>;
interface DialogTriggerProps extends React.ComponentPropsWithoutRef<typeof Primitive.button> {}

const DialogTrigger: React.ForwardRefExoticComponent<
  DialogTriggerProps & React.RefAttributes<DialogTriggerElement>
>;

Usage Examples:

import { Dialog, DialogTrigger, DialogContent } from "@radix-ui/react-dialog";

// Basic trigger
function BasicTrigger() {
  return (
    <Dialog>
      <DialogTrigger>Open Dialog</DialogTrigger>
      <DialogContent>Content here</DialogContent>
    </Dialog>
  );
}

// Custom styled trigger
function StyledTrigger() {
  return (
    <Dialog>
      <DialogTrigger className="custom-button" disabled={false}>
        <span className="icon">📋</span>
        Open Settings
      </DialogTrigger>
      <DialogContent>Settings content</DialogContent>
    </Dialog>
  );
}

// Trigger with custom click handler
function TriggerWithHandler() {
  const handleClick = (event: React.MouseEvent) => {
    console.log('Trigger clicked');
    // Dialog will still open automatically
  };

  return (
    <Dialog>
      <DialogTrigger onClick={handleClick}>
        Open with Custom Handler
      </DialogTrigger>
      <DialogContent>Content here</DialogContent>
    </Dialog>
  );
}

// Using asChild pattern with existing element
function AsChildTrigger() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <button className="existing-button-class">
          Open Dialog
        </button>
      </DialogTrigger>
      <DialogContent>Content here</DialogContent>
    </Dialog>
  );
}

DialogClose

Button component that closes the dialog when activated, can be placed anywhere within the dialog content.

/**
 * Button component that closes the dialog when activated
 * Can be placed anywhere within dialog content
 * Extends all standard button props
 */
type DialogCloseElement = React.ComponentRef<typeof Primitive.button>;
interface DialogCloseProps extends React.ComponentPropsWithoutRef<typeof Primitive.button> {}

const DialogClose: React.ForwardRefExoticComponent<
  DialogCloseProps & React.RefAttributes<DialogCloseElement>
>;

Usage Examples:

import { Dialog, DialogTrigger, DialogContent, DialogClose } from "@radix-ui/react-dialog";

// Basic close button
function BasicClose() {
  return (
    <Dialog>
      <DialogTrigger>Open</DialogTrigger>
      <DialogContent>
        <p>Dialog content</p>
        <DialogClose>Close</DialogClose>
      </DialogContent>
    </Dialog>
  );
}

// Multiple close buttons
function MultipleCloseButtons() {
  return (
    <Dialog>
      <DialogTrigger>Open</DialogTrigger>
      <DialogContent>
        <div className="dialog-header">
          <h2>Confirm Action</h2>
          <DialogClose className="close-icon">×</DialogClose>
        </div>
        <p>Are you sure you want to continue?</p>
        <div className="dialog-actions">
          <DialogClose className="cancel-btn">Cancel</DialogClose>
          <DialogClose className="confirm-btn">Confirm</DialogClose>
        </div>
      </DialogContent>
    </Dialog>
  );
}

// Close button with custom handler
function CloseWithHandler() {
  const handleClose = (event: React.MouseEvent) => {
    console.log('Dialog closing');
    // Dialog will still close automatically
  };

  return (
    <Dialog>
      <DialogTrigger>Open</DialogTrigger>
      <DialogContent>
        <p>Content here</p>
        <DialogClose onClick={handleClose}>
          Close with Handler
        </DialogClose>
      </DialogContent>
    </Dialog>
  );
}

// Using asChild pattern
function AsChildClose() {
  return (
    <Dialog>
      <DialogTrigger>Open</DialogTrigger>
      <DialogContent>
        <p>Content here</p>
        <DialogClose asChild>
          <button className="existing-close-class">
            Close Dialog
          </button>
        </DialogClose>
      </DialogContent>
    </Dialog>
  );
}

Accessibility Features

DialogTrigger Accessibility

The DialogTrigger component automatically provides:

  • type="button" for proper button semantics
  • aria-haspopup="dialog" to indicate it opens a dialog
  • aria-expanded that reflects the current dialog state
  • aria-controls that references the dialog content ID
  • data-state attribute with "open" or "closed" values

DialogClose Accessibility

The DialogClose component automatically provides:

  • type="button" for proper button semantics
  • Proper event handling for keyboard activation (Enter, Space)
  • Focus restoration to the trigger when dialog closes

Event Handling

Both components compose event handlers, meaning you can add your own click handlers and they will be called alongside the built-in dialog control logic:

// Your handler is called first, then the built-in logic
<DialogTrigger onClick={(e) => {
  console.log('Custom logic before opening');
  // Dialog opens automatically after this
}}>
  Open
</DialogTrigger>

<DialogClose onClick={(e) => {
  console.log('Custom logic before closing');
  // Dialog closes automatically after this
}}>
  Close
</DialogClose>

Styling and Customization

Both components render as buttons by default but can be customized:

CSS Classes and Styling

<DialogTrigger className="btn btn-primary" style={{ fontSize: '16px' }}>
  Styled Trigger
</DialogTrigger>

<DialogClose className="btn btn-secondary" data-testid="close-btn">
  Styled Close
</DialogClose>

AsChild Pattern

Use the asChild prop to render the functionality on your own element:

<DialogTrigger asChild>
  <YourCustomButton>Open</YourCustomButton>
</DialogTrigger>

<DialogClose asChild>
  <YourCustomCloseIcon />
</DialogClose>

Install with Tessl CLI

npx tessl i tessl/npm-radix-ui--react-dialog

docs

advanced-context.md

content-accessibility.md

dialog-root.md

index.md

portal-layout.md

triggers-controls.md

tile.json