SolidJS Dismissible Layers Utility

0.1.1 · active · verified Sun Apr 19

solid-dismissible is a foundational utility for SolidJS applications, designed to manage the dismissal behavior of UI layers such as dialogs, dropdowns, or tooltips. It provides a headless API, allowing developers to integrate dismissible logic without imposing specific styling or DOM structure. Key features include support for arbitrarily nested dismissible layers, where only the topmost active layer responds to dismiss actions, and multiple dismissal strategies such as outside pointer events (down/up), loss of focus outside the component, and the Escape key. Each strategy can be individually enabled, disabled, or customized. The current version is 0.1.1, and its last publish date was 2 years ago, indicating it is an early-stage library, part of the broader @corvu UI primitives ecosystem for SolidJS. Due to its early version, the API is subject to potential breaking changes in future minor releases, though its core functionality for handling dismissal logic is well-defined. This utility differentiates itself by offering robust nesting capabilities and fine-grained control over dismissal events, making it a powerful tool for complex interactive UIs.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to create a basic dismissible dialog component using `solid-dismissible`, managing its open state and dismissal logic.

import { createSignal, Show, type Component } from 'solid-js';
import Dismissible from 'solid-dismissible';

const DialogContent: Component<{ open: boolean; setOpen: (open: boolean) => void }> = (props) => {
  const [contentRef, setContentRef] = createSignal<HTMLElement | null>(null);

  return (
    <Dismissible
      element={contentRef}
      enabled={props.open()}
      onDismiss={() => props.setOpen(false)}
      // Optional: Prevent dismissal on outside focus
      // dismissOnOutsideFocus={false}
      // Optional: Prevent dismissal on escape key
      // dismissOnEscape={false}
    >
      <Show when={props.open()}>
        <div
          ref={setContentRef}
          tabIndex={-1} // Make div focusable for testing focus dismissal
          style={{
            border: '1px solid gray',
            padding: '20px',
            background: 'white',
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            zIndex: 1000
          }}
        >
          <h2>Dismissible Dialog</h2>
          <p>Click outside or press Escape to dismiss.</p>
          <button onClick={() => props.setOpen(false)}>Close</button>
        </div>
      </Show>
    </Dismissible>
  );
};

const App: Component = () => {
  const [dialogOpen, setDialogOpen] = createSignal(false);

  return (
    <div>
      <button onClick={() => setDialogOpen(true)}>Open Dialog</button>
      <DialogContent open={dialogOpen} setOpen={setDialogOpen} />
      <p>This is content behind the dialog.</p>
      <p>Try opening the dialog and clicking outside or pressing Escape.</p>
    </div>
  );
};

export default App;

view raw JSON →