Skip to content

Details

An accessible accordion or toggle component for details and summary elements.
Uses small external library slide-element for smooth toggle animations.

It is unstyled by default, so you can apply your own styles.

View Source 

Dependencies

Usage

shell
npm i slide-element
html
<details class="x-details group bg-body-secondary rounded">
    <summary class="flex-center text-primary p-4" data-action="toggleDetails">
        <span class="x-title">Show more</span>
        <svg class="size-4 group-open:-scale-y-100 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
    </summary>
    <div style="display: none">
        <div class="p-4">
            Details content
        </div>
    </div>
</details>
js
import { toggleDetails } from 'winduum/src/components/details'

document.querySelectorAll('[data-action="toggleDetails"]').forEach(summary => {
    summary.addEventListener('click', event => {
        if (event.currentTarget.tagName !== 'INPUT') event.preventDefault()

        toggleDetails(summary)
    })
})

Installation

Follow instructions for individual framework usage below

  • winduum 
  • winduum-stimulus 

Examples

Default

html
<details class="x-details group bg-body-secondary rounded">
    <summary class="flex items-center gap-2 text-primary p-4" data-action="toggleDetails">
        <span class="x-title">Show more</span>
        <svg class="size-4 group-open:-scale-y-100 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
    </summary>
    <div style="display: none">
        <div class="p-4">
            Details content
        </div>
    </div>
</details>
liquid
<script type="module">
    import { toggleDetails } from 'winduum/src/components/details/index.js'

    document.querySelectorAll('[data-action="toggleDetails"]').forEach(summary => {
        summary.addEventListener('click', event => {
            if (event.currentTarget.tagName !== 'INPUT') event.preventDefault()

            toggleDetails(summary)
        })
    })
</script>

Checkbox

html
<details class="x-details group bg-body-secondary p-4 rounded">
    <summary class="w-fit flex">
        <label class="x-check">
            <input type="checkbox" data-action="toggleDetails" autocomplete="off">
            Fill more
        </label>
    </summary>
    <div style="display: none">
        <div class="x-control max-w-96 mt-4">
            <input>
        </div>
    </div>
</details>
liquid
<script type="module">
    import { toggleDetails } from 'winduum/src/components/details/index.js'

    document.querySelectorAll('[data-action="toggleDetails"]').forEach(summary => {
        summary.addEventListener('click', event => {
            if (event.currentTarget.tagName !== 'INPUT') event.preventDefault()

            toggleDetails(summary)
        })
    })
</script>

Accordion

html
<details class="x-details group bg-body-secondary rounded" open>
    <summary class="flex items-center  gap-2 p-4 text-primary" data-action="accordionDetails">
        <span class="x-title">Accordion 1</span>
        <svg class="size-4 group-open:-scale-y-100 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
    </summary>
    <div>
        <div class="p-4">
            Details content
        </div>
    </div>
</details>
<details class="x-details group bg-body-secondary rounded">
    <summary class="flex items-center  gap-2 p-4 text-primary" data-action="accordionDetails">
        <span class="x-title">Accordion 2</span>
        <svg class="size-4 group-open:-scale-y-100 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
    </summary>
    <div style="display: none">
        <div class="p-4">
            Details content
        </div>
    </div>
</details>
<details class="x-details group bg-body-secondary rounded">
    <summary class="flex items-center  gap-2 p-4 text-primary" data-action="accordionDetails">
        <span class="x-title">Accordion 3</span>
        <svg class="size-4 group-open:-scale-y-100 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
        </svg>
    </summary>
    <div style="display: none">
        <div class="p-4">
            Details content
        </div>
    </div>
</details>
liquid
<script type="module">
    import { toggleDetails, closeDetails } from 'winduum/src/components/details/index.js'

    document.querySelectorAll('[data-action="accordionDetails"]').forEach(summary => {
        summary.addEventListener('click', event => {
            event.preventDefault()

            const { currentTarget } = event

            closeDetails(currentTarget.closest('body').querySelector('details[open]:has([data-action="accordionDetails"]) summary'))

            toggleDetails(currentTarget)
        })
    })
</script>

Javascript API

typescript
interface DefaultOptions {
    selector?: string
    summarySelector?: string
}

toggleDetails

  • Type: (selector: HTMLInputElement | HTMLElement, options?: DefaultOptions) => Promise<void>
  • Kind: async

Toggles a details element, should be added on summary or anywhere inside the details element.

showDetails

  • Type: (selector: HTMLInputElement | HTMLElement, options?: DefaultOptions) => Promise<void>
  • Kind: async

Shows a details element, should be added on summary or anywhere inside the details element.

closeDetails

  • Type: (selector: HTMLInputElement | HTMLElement, options?: DefaultOptions) => Promise<void>
  • Kind: async

Closes a details element, should be added on summary or anywhere inside the details element.

Released under the MIT License.