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

advanced-context.mddocs/

Advanced Context Management

Utilities for advanced use cases like nested dialogs, custom context scoping, and development-time warnings.

Capabilities

createDialogScope

Creates a scoped context for dialog components, enabling advanced patterns like nested dialogs or multiple dialog instances.

/**
 * Creates a scoped context for dialog components
 * Enables advanced patterns like nested dialogs and multiple instances
 * @returns Tuple of context scope and provider functions
 */
const createDialogScope: () => {
  /**
   * Creates a scoped provider for dialog context
   * @param scope - The scope identifier for this dialog context
   * @param scopeProps - Props to pass through to child contexts
   */
  Provider: React.Provider<any>;
  
  /**
   * Hook to consume the scoped dialog context
   * @param scope - The scope identifier to consume from
   */
  useScope: (scope?: any) => any;
};

Usage Examples:

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

// Create a custom scope for nested dialogs
const [createNestedDialogScope, useNestedDialogScope] = createDialogScope();

function NestedDialogs() {
  const nestedScope = createNestedDialogScope();
  
  return (
    <Dialog>
      <DialogTrigger>Open Parent Dialog</DialogTrigger>
      <DialogContent>
        <h2>Parent Dialog</h2>
        <Dialog __scopeDialog={nestedScope}>
          <DialogTrigger>Open Child Dialog</DialogTrigger>
          <DialogContent>
            <h3>Child Dialog</h3>
            <p>This dialog is nested within the parent</p>
          </DialogContent>
        </Dialog>
      </DialogContent>
    </Dialog>
  );
}

// Multiple independent dialog systems
function MultipleDialogSystems() {
  const systemAScope = createDialogScope();
  const systemBScope = createDialogScope();
  
  return (
    <div>
      {/* Dialog System A */}
      <Dialog __scopeDialog={systemAScope}>
        <DialogTrigger>Open System A</DialogTrigger>
        <DialogContent>
          <p>Dialog from System A</p>
        </DialogContent>
      </Dialog>
      
      {/* Dialog System B */}
      <Dialog __scopeDialog={systemBScope}>
        <DialogTrigger>Open System B</DialogTrigger>
        <DialogContent>
          <p>Dialog from System B</p>
        </DialogContent>
      </Dialog>
    </div>
  );
}

WarningProvider

Context provider for development-time accessibility warnings and validation.

/**
 * Context provider for development-time accessibility warnings
 * Provides configuration for warning messages and validation
 * Internal component typically not used directly
 */
interface WarningContextValue {
  contentName: string;
  titleName: string;
  docsSlug: string;
}

const WarningProvider: React.Provider<WarningContextValue>;

Usage Examples:

// Typically used internally, but can be customized for advanced cases
import { WarningProvider } from "@radix-ui/react-dialog";

function CustomWarningProvider({ children }: { children: React.ReactNode }) {
  const warningConfig = {
    contentName: "CustomDialog",
    titleName: "CustomTitle",
    docsSlug: "custom-dialog"
  };
  
  return (
    <WarningProvider value={warningConfig}>
      {children}
    </WarningProvider>
  );
}

Advanced Patterns

Nested Dialogs

Create dialogs that can open other dialogs without conflicts:

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

function NestedDialogExample() {
  // Create separate scopes for each dialog level
  const [createLevel2Scope, useLevel2Scope] = createDialogScope();
  const [createLevel3Scope, useLevel3Scope] = createDialogScope();
  
  return (
    <Dialog>
      <DialogTrigger>Open Level 1</DialogTrigger>
      <DialogContent>
        <DialogTitle>Level 1 Dialog</DialogTitle>
        
        <Dialog __scopeDialog={createLevel2Scope()}>
          <DialogTrigger>Open Level 2</DialogTrigger>
          <DialogContent>
            <DialogTitle>Level 2 Dialog</DialogTitle>
            
            <Dialog __scopeDialog={createLevel3Scope()}>
              <DialogTrigger>Open Level 3</DialogTrigger>
              <DialogContent>
                <DialogTitle>Level 3 Dialog</DialogTitle>
                <p>Deeply nested dialog</p>
              </DialogContent>
            </Dialog>
          </DialogContent>
        </Dialog>
      </DialogContent>
    </Dialog>
  );
}

Multiple Dialog Systems

Create independent dialog systems that don't interfere with each other:

function MultiSystemExample() {
  const settingsScope = createDialogScope();
  const confirmationScope = createDialogScope();
  
  return (
    <div>
      {/* Settings Dialog System */}
      <div className="settings-section">
        <Dialog __scopeDialog={settingsScope}>
          <DialogTrigger>Settings</DialogTrigger>
          <DialogContent>
            <DialogTitle>Application Settings</DialogTitle>
            {/* Settings content */}
          </DialogContent>
        </Dialog>
      </div>
      
      {/* Confirmation Dialog System */}
      <div className="actions-section">
        <Dialog __scopeDialog={confirmationScope}>
          <DialogTrigger>Delete All</DialogTrigger>
          <DialogContent>
            <DialogTitle>Confirm Deletion</DialogTitle>
            {/* Confirmation content */}
          </DialogContent>
        </Dialog>
      </div>
    </div>
  );
}

Custom Context Integration

Integrate dialog scoping with your own context systems:

interface AppContextValue {
  dialogScope: any;
  theme: string;
}

const AppContext = React.createContext<AppContextValue | null>(null);

function AppWithCustomContext({ children }: { children: React.ReactNode }) {
  const dialogScope = createDialogScope();
  
  const contextValue = {
    dialogScope,
    theme: 'dark'
  };
  
  return (
    <AppContext.Provider value={contextValue}>
      {children}
    </AppContext.Provider>
  );
}

function DialogWithAppContext() {
  const appContext = React.useContext(AppContext);
  
  return (
    <Dialog __scopeDialog={appContext?.dialogScope}>
      <DialogTrigger>Open Contextual Dialog</DialogTrigger>
      <DialogContent>
        <DialogTitle>App Context Dialog</DialogTitle>
        <p>This dialog uses the app's dialog scope</p>
      </DialogContent>
    </Dialog>
  );
}

Scope Prop Usage

All dialog components accept a __scopeDialog prop for custom scoping:

// Scope applied to all components in the dialog tree
<Dialog __scopeDialog={customScope}>
  <DialogTrigger __scopeDialog={customScope}>Open</DialogTrigger>
  <DialogPortal __scopeDialog={customScope}>
    <DialogOverlay __scopeDialog={customScope} />
    <DialogContent __scopeDialog={customScope}>
      <DialogTitle __scopeDialog={customScope}>Title</DialogTitle>
      <DialogDescription __scopeDialog={customScope}>Description</DialogDescription>
      <DialogClose __scopeDialog={customScope}>Close</DialogClose>
    </DialogContent>
  </DialogPortal>
</Dialog>

Development Warnings

Accessibility Warnings

In development mode, the dialog system provides warnings for:

  • Missing DialogTitle components
  • Missing DialogDescription when aria-describedby is expected
  • Improper nesting or context usage

Warning Customization

You can customize warning messages by providing your own WarningProvider:

const customWarningContext = {
  contentName: "MyDialog",
  titleName: "MyDialogTitle", 
  docsSlug: "my-dialog"
};

<WarningProvider value={customWarningContext}>
  <Dialog>
    {/* Dialog components */}
  </Dialog>
</WarningProvider>

Best Practices

When to Use Scoping

  • Nested Dialogs: Always use scoping for dialogs within dialogs
  • Multiple Systems: Use scoping when you have different types of dialogs
  • Component Libraries: Use scoping to avoid conflicts with consumer code
  • Complex Apps: Use scoping to isolate dialog contexts in different app sections

Scope Management

  • Create scopes at the highest level needed
  • Don't create unnecessary scopes for simple use cases
  • Pass scopes down through props or context
  • Document your scoping strategy for team members

Performance Considerations

  • Scopes are lightweight and don't significantly impact performance
  • Avoid creating new scopes on every render
  • Memoize scope creation when necessary:
const dialogScope = React.useMemo(() => createDialogScope(), []);

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