Collapsible
Thymeleaf source
<sl:collapsible> <sl:collapsible-trigger>@peduarte starred 3 repositories <sl:icon name="chevrons-up-down"/></sl:collapsible-trigger> <sl:collapsible-content> <p>@radix-ui/primitives</p> <p>@radix-ui/colors</p> <p>@stitches/react</p> </sl:collapsible-content></sl:collapsible>Rendered HTML
<details class="collapsible"> <summary class="collapsible-trigger"> @peduarte starred 3 repositories <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="m7 15 5 5 5-5"></path> <path d="m7 9 5-5 5 5"></path> </svg> </summary> <div class="collapsible-content"> <p>@radix-ui/primitives</p> <p>@radix-ui/colors</p> <p>@stitches/react</p> </div></details>Built from parts
Section titled “Built from parts”A collapsible is <sl:collapsible> with an <sl:collapsible-trigger> and an <sl:collapsible-content>:
<sl:collapsible> <sl:collapsible-trigger>@peduarte starred 3 repositories <sl:icon name="chevrons-up-down"/></sl:collapsible-trigger> <sl:collapsible-content> <p>@radix-ui/primitives</p> <p>@radix-ui/colors</p> </sl:collapsible-content></sl:collapsible>It is a <details> element with the
trigger as its <summary>, so it needs no JavaScript: the browser opens and closes it, from the keyboard too, and
tells a screen reader whether it is expanded. Two consequences for porting a shadcn/ui example:
- The trigger comes first, and the content after it, both inside
<sl:collapsible>. shadcn/ui’s examples can put the trigger anywhere in the collapsible, even after the content; asummarymust be the first child. - Everything else goes in the trigger or the content. Text next to the trigger (shadcn’s “@peduarte starred 3 repositories” heading) can be part of the trigger.
open renders it open. As with the accordion, find-in-page and a link to an element inside open a
closed collapsible on a match (Chrome and Edge 97, Firefox 148, Safari 26.2). It does not animate, as shadcn/ui’s does
not.
Drawn as a button
Section titled “Drawn as a button”The trigger is plain text by default. variant or size draws it as a button, with the button’s
variants and sizes, where shadcn/ui writes <CollapsibleTrigger asChild><Button …>. An icon-only trigger
(size="icon") needs an aria-label.
Thymeleaf source
<sl:collapsible open> <sl:collapsible-trigger variant="outline" size="sm"><sl:icon name="sliders-horizontal"/> Filters</sl:collapsible-trigger> <sl:collapsible-content> <sl:field orientation="horizontal" for="collapsible-in-stock"> <sl:checkbox checked/> <sl:field-label>In stock only</sl:field-label> </sl:field> </sl:collapsible-content></sl:collapsible>Rendered HTML
<details class="collapsible" open> <summary class="button collapsible-trigger" data-variant="outline" data-size="sm"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="M10 5H3"></path> <path d="M12 19H3"></path> <path d="M14 3v4"></path> <path d="M16 17v4"></path> <path d="M21 12h-9"></path> <path d="M21 19h-5"></path> <path d="M21 5h-7"></path> <path d="M8 10v4"></path> <path d="M8 12H3"></path> </svg> Filters </summary> <div class="collapsible-content"> <div class="field" data-orientation="horizontal"> <span class="checkbox-wrapper"> <input type="checkbox" class="checkbox" checked id="collapsible-in-stock"> <svg xmlns="http://www.w3.org/2000/svg" class="icon checkbox-indicator" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="M20 6 9 17l-5-5"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" class="icon checkbox-indeterminate-indicator" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="M5 12h14"></path> </svg> </span> <label class="label field-label" for="collapsible-in-stock">In stock only</label> </div> </div></details>Disabled
Section titled “Disabled”disabled keeps it closed (or open, with open): the trigger fades, leaves the tab order and ignores the pointer, and
a closed disabled collapsible renders no content, so find-in-page cannot open it.
Thymeleaf source
<sl:collapsible disabled> <sl:collapsible-trigger variant="ghost" size="sm">Order history</sl:collapsible-trigger> <sl:collapsible-content>Your past orders.</sl:collapsible-content></sl:collapsible>Rendered HTML
<details class="collapsible" data-disabled="true"> <summary class="button collapsible-trigger" data-variant="ghost" data-size="sm" aria-disabled="true" tabindex="-1">Order history</summary></details>Left out
Section titled “Left out”asChildon the trigger:variantandsizedraw it as a button; the element stays asummary.open/onOpenChangestate:openrenders it open; the browser’stoggleevent reports changes.- A trigger outside the collapsible, or after the content: a
detailselement has itssummaryfirst. - Styling the trigger’s icon by state (shadcn’s
group-data-[state=open]:rotate-90): the bundle has no utility classes. In your own CSS,.collapsible[open] > .collapsible-trigger svg { rotate: 90deg; }does it.
Attributes
Section titled “Attributes”sl:collapsible
Section titled “sl:collapsible”| Attribute | Values | Default | Description |
|---|---|---|---|
open | boolean | — | Render it open. |
disabled | boolean | — | It cannot be opened or closed: its trigger is out of the tab order and ignores the pointer, and closed it renders no content, so find-in-page cannot open it. |
Every prop can also be set from an expression: th:open="${...}". Any other attribute passes through to the rendered element, and class is appended.
sl:collapsible-trigger
Section titled “sl:collapsible-trigger”| Attribute | Values | Default | Description |
|---|---|---|---|
variant | default outline ghost destructive secondary link | — | Draw the trigger as a button of this variant, as on sl:button. |
size | xs sm default lg icon icon-xs icon-sm icon-lg | — | Draw the trigger as a button of this size, as on sl:button. The icon sizes need an aria-label. |
Every prop can also be set from an expression: th:variant="${...}". Any other attribute passes through to the rendered element, and class is appended. An aria-label or aria-labelledby is required when size is icon, icon-xs, icon-sm or icon-lg; rendering fails without one.
sl:collapsible-content
Section titled “sl:collapsible-content”sl:collapsible-content declares no props; every attribute passes through.