Collapsible

ui-collapsible wraps a native <details> element. Its ui-collapsible-trigger becomes the <summary>, and its ui-collapsible-content is shown when it opens. The trigger lays out its content in a row with the ends pushed apart, so a label and an icon need no extra markup. For a group of sections where only one is open at a time, use Accordion.

Previewindex.html
3 starred repositories realm/core realm/ui realm/site
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Collapsible demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-narrow {
      width: min(100%, calc(var(--spacing) * 88));
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/collapsible.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/item.html"></import-element>

  <div class="demo-narrow">
    <ui-collapsible>
      <ui-collapsible-trigger>
        3 starred repositories
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="m7 15 5 5 5-5M7 9l5-5 5 5" /></svg>
      </ui-collapsible-trigger>
      <ui-collapsible-content>
        <ui-item variant="outline" size="sm">realm/core</ui-item>
        <ui-item variant="outline" size="sm">realm/ui</ui-item>
        <ui-item variant="outline" size="sm">realm/site</ui-item>
      </ui-collapsible-content>
    </ui-collapsible>
  </div>
</body>
</html>

Examples

Open by default

Add open to start expanded. The attribute reflects, so it also tracks the current state.

Previewindex.html
Release notes

Faster startup, smaller bundle and a new sidebar.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Collapsible demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-narrow {
      width: min(100%, calc(var(--spacing) * 88));
    }
    .demo-muted {
      margin: 0;
      font-size: var(--text-sm);
      color: var(--muted-foreground);
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/collapsible.html"></import-element>

  <div class="demo-narrow">
    <ui-collapsible open>
      <ui-collapsible-trigger>Release notes</ui-collapsible-trigger>
      <ui-collapsible-content>
        <p class="demo-muted">Faster startup, smaller bundle and a new sidebar.</p>
      </ui-collapsible-content>
    </ui-collapsible>
  </div>
</body>
</html>

Disabled

disabled stops the user from toggling it. The trigger is dimmed.

Previewindex.html
Advanced options (locked) Only administrators can change these.
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Collapsible demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
  <style>
    .demo-narrow {
      width: min(100%, calc(var(--spacing) * 88));
    }
  </style>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/collapsible.html"></import-element>

  <div class="demo-narrow">
    <ui-collapsible disabled>
      <ui-collapsible-trigger>Advanced options (locked)</ui-collapsible-trigger>
      <ui-collapsible-content>Only administrators can change these.</ui-collapsible-content>
    </ui-collapsible>
  </div>
</body>
</html>

Controlled from state

Bind open with _open and listen for toggle to keep state in sync.

Previewindex.htmlcollapsible-state-demo.html
Toggle from outside Filters Status, owner and date range.
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Collapsible demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/button.html"></import-element>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/collapsible.html"></import-element>

  <import-element from="./collapsible-state-demo.html"></import-element>
  <collapsible-state-demo></collapsible-state-demo>
</body>
</html>
<custom-element name="collapsible-state-demo">
  <script>
    const panel = useState({ open: false });

    function toggled(event) {
      panel.open = event.target.open;
    }

    function flip() {
      panel.open = !panel.open;
    }
  </script>
  <style>
    :host {
      display: grid;
      gap: calc(var(--spacing) * 3);
      width: min(100%, calc(var(--spacing) * 80));
    }
  </style>
  <ui-button variant="outline" size="sm" onclick="flip()">Toggle from outside</ui-button>
  <ui-collapsible _open="#panel.open" ontoggle="toggled(event)">
    <ui-collapsible-trigger>Filters</ui-collapsible-trigger>
    <ui-collapsible-content>Status, owner and date range.</ui-collapsible-content>
  </ui-collapsible>
</custom-element>

API

Parts

Element Fills Renders
ui-collapsible A native <details>. Fills its container's width.
ui-collapsible-trigger the <summary> of ui-collapsible A row with its content spread to both ends, in small semibold text. Icons are sized to calc(var(--spacing) * 4).
ui-collapsible-content the body of ui-collapsible A column with calc(var(--spacing) * 2) gaps, shown when open.

Attributes

ui-collapsible

Attribute Type Default Description
open boolean false Whether the content is shown. Reflects.
disabled boolean false Stops the user from toggling. Setting open from script still works.

ui-collapsible-trigger and ui-collapsible-content have no attributes.

Events

Event Element Description
toggle ui-collapsible Fires when the user opens or closes it. Bubbles. Read event.target.open. Not fired when open is set from script.

CSS parts

Part Element Description
trigger ui-collapsible The native <summary>.

Accessibility

Edit this page on GitHub · View as Markdown