Ir al contenido

Details

Sección desplegable nativa: raíz `<details>`, activador `<summary>` y cuerpo de contenido.

0 kB client JS≤ 0.4 kB gzipped

Anatomy

<Details.Root name="faq">
  <Details.Summary>Shipping</Details.Summary>
  <Details.Content>Ships in 2-3 days.</Details.Content>
</Details.Root>

Live demo

This demo also runs with JavaScript disabled.

Details

Minimal

Shipping
Ships in 2–3 days.

Composition — exclusive group

Shipping
Ships in 2–3 days.
Returns
30-day return window.
Warranty (unavailable)
Not offered in your region.

Details.Root

Renders <details>. Emits data-uiify-details="", plus data-disabled="" when disabled.

NameTypeDefaultNotes
defaultOpenbooleanApplies the native `open` attribute on first render.
namestringGroups sibling `<details name>` into an exclusive set. Must be unique per group and stable across SSR.
disabledbooleanSets `data-disabled` on the root. Blocking the click itself is a CSS responsibility — see the CSS contract below.

Details.Summary

Renders <summary>. Emits data-part when given; aria-disabled="true" and tabIndex={-1} when disabled.

NameTypeDefaultNotes
disabledbooleanThe browser has no native disabled state for `<summary>` — this loses focusability and gets `aria-disabled`.
partstringSets `data-part`; omitted when not given, because not every consumer needs one.

Details.Content

Renders <div> (polymorphic via `as`/`render`). Emits data-part when given.

NameTypeDefaultNotes
asElementType"div"The disclosure body isn't always a `<div>` — e.g. an `<ol>` for a list.
renderRenderPropEscape hatch for a custom element.
partstringSets `data-part`; omitted when not given.

Rendered DOM

<details data-uiify-details="" name="faq"><summary>Shipping</summary><div>Ships in 2-3 days.</div></details>

CSS contract

details[open] > summary::after {
  /* flip a disclosure marker, e.g. rotate an arrow */
}

[data-uiify-details][data-disabled] > summary {
  pointer-events: none; /* the element marks it disabled; blocking the click is your CSS */
}

Build your own

import { Details } from "@gunkin/uiify/elements/details";

export function Faq() {
  return (
    <Details.Root name="faq">
      <Details.Summary>
        What browsers are supported?
        <span aria-hidden="true" className="faq-chevron" />
      </Details.Summary>
      <Details.Content>
        Every evergreen browser, plus the last two Safari majors.
      </Details.Content>
    </Details.Root>
  );
}

// details[open] > summary .faq-chevron { transform: rotate(180deg); }

Used by

Gotchas

  • `name` groups sibling `<details>` into an exclusive, single-open set with zero JS — it must be unique per group and stable across SSR.
  • `disabled` sets `data-disabled`/`aria-disabled`/`tabIndex=-1`, but you still need `pointer-events: none` in your own CSS to actually block the click (see the CSS contract).
  • `Details.Content` is polymorphic (`as`/`render`) because the disclosure body isn't always a `<div>`.

Import

import { Details } from "@gunkin/uiify/elements/details";