Collapse
An collapse is a vertically stacked set of interactive headings containing a title, content snippet, or thumbnail representing a section of content.
Experience the thrill of cutting-edge marine vessels, from luxury yachts to high-performance speedboats.
Discover our premium selection of automobiles, featuring the latest in automotive technology and design.
Explore our range of aircraft, from private jets to commercial airliners, all equipped with state-of-the-art technology.
Experience the thrill of cutting-edge marine vessels, from luxury yachts to high-performance speedboats.
Discover our premium selection of automobiles, featuring the latest in automotive technology and design.
Explore our range of aircraft, from private jets to commercial airliners, all equipped with state-of-the-art technology.
Features
Install
Install the component from your command line.
Anatomy
Import all parts and piece them together.
<script setup lang="ts">import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/vue'import { computed, useId } from 'vue'
const data = [ ... ]
const [state, send] = useMachine(collapse.machine({ id: useId() }))
const api = computed(() => collapse.connect(state.value, send, normalizeProps),)</script>
<template> <div v-bind="api.getRootProps()"> <div v-for="item in data" :key="item.title" v-bind="api.getItemProps({ value: item.title })" > <button v-bind="api.getItemTriggerProps({ value: item.title })"></button> <div v-bind="api.getItemContentProps({ value: item.title })"></div> </div> </div></template>import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/react'import { useId } from 'react'
const data = [ ... ]
export default function Collapse() { const [state, send] = useMachine(collapse.machine({ id: useId() })) const api = collapse.connect(state, send, normalizeProps)
return ( <div {...api.getRootProps()}> {data.map(item => ( <div key={item.title} {...api.getItemProps({ value: item.title })}> <button {...api.getItemTriggerProps({ value: item.title })}></button> <div {...api.getItemContentProps({ value: item.title })}></div> </div> ))} </div> )}<script lang="ts"> import * as collapse from '@destyler/collapse' import { normalizeProps, useMachine } from '@destyler/svelte'
const data = [ ... ]
const id = $props.id() const [state, send] = useMachine(collapse.machine({ id })) const api = $derived(collapse.connect(state, send, normalizeProps))</script>
<div {...api.getRootProps()}> {#each data as item (item.title)} <div {...api.getItemProps({ value: item.title })}> <button {...api.getItemTriggerProps({ value: item.title })}></button> <div {...api.getItemContentProps({ value: item.title })}></div> </div> {/each}</div>import * as collapse from '@destyler/collapse'import { normalizeProps, useMachine } from '@destyler/solid'import { createUniqueId } from 'solid-js'
const data = [ ... ]
export default function Collapse() { const [state, send] = useMachine(collapse.machine({ id: createUniqueId() })) const api = collapse.connect(state, send, normalizeProps)
return ( <div {...api.getRootProps()}> {data.map(item => ( <div {...api.getItemProps({ value: item.title })}> <button {...api.getItemTriggerProps({ value: item.title })} ></button> <div {...api.getItemContentProps({ value: item.title })}></div> </div> ))} </div> )}You may have noticed we wrapped each collapse trigger within an h3.
This is recommended by the WAI-ARIA design pattern to ensure the collapse
has the appropriate hierarchy on the page.
Open multiple collapse at once
To allow multiple items to be expanded at once, set multiple to true.
This mode implicitly sets collapsible to true and ensures that each collapse can be expanded.
const [state, send] = useMachine( collapse.machine({ multiple: true, }),)Opening specific collapse
To set the value of the collapse that should be opened initially,
pass the value property to the machine function.
const [state, send] = useMachine( collapse.machine({ multiple: true, value: ["home"], }),)const [state, send] = useMachine( collapse.machine({ value: ["home"], }),)Toggle each collapse item
To collapse an already expanded collapse item by clicking on it,
set the context’s collapsible property to true.
If multiple is true, we internally set collapsible to be true.
const [state, send] = useMachine( collapse.machine({ collapsible: true, }),)Listening for changes
When the collapse value changes, the onValueChange callback is invoked.
const [state, send] = useMachine( collapse.machine({ onValueChange(details) { // details => { value: string[] } console.log("selected collapse:", details.value) }, }),)Disabling an collapse item
To disable a specific collapse item, pass the disabled: true property to the getItemProps,
getItemTriggerProps and getItemContentProps.
When an collapse item is disabled, it is skipped from keyboard navigation and can’t be interacted with.
<template> <!-- ... --> <div v-bind="api.getItemProps({ value: 'item-1', disabled: true })"> <button v-bind="api.getItemTriggerProps({ value: 'item-1', disabled: true })"></button> <div v-bind="api.getItemContentProps({ value: 'item-1', disabled: true })"></div> </div> <!-- ... --></template>export default function Collapse() {
return ( // ... <div {...api.getItemProps({ value: 'item-1', disabled: true })}> <button {...api.getItemTriggerProps({ value: 'item-1', disabled: true })}></button> <div {...api.getItemContentProps({ value: 'item-1', disabled: true })}></div> </div> // ... )}<!-- ... --><div {...api.getItemProps({ value: 'item-1', disabled: true })}> <button {...api.getItemTriggerProps({ value: 'item-1', disabled: true })}></button> <div {...api.getItemContentProps({ value: 'item-1', disabled: true })}></div></div><!-- ... -->export default function Collapse() { return ( // ... <div {...api.getItemProps({ value: 'item-1', disabled: true })}> <button {...api.getItemTriggerProps({ value: 'item-1', disabled: true })} ></button> <div {...api.getItemContentProps({ value: 'item-1', disabled: true })}></div> </div> // ... )}You can also disable the entire collapse items by passing disabled to the machine’s context.
const [state, send] = useMachine( collapse.machine({ disabled: true, }),)Styling Guide
Earlier, we mentioned that each collapse part has a
data-partattribute added to them to select and style them in the DOM.
Open and closed state
When an collapse item is expanded or collapsed, a data-state attribute is set on the item, trigger and content elements. This attribute is removed when it is closed.
[data-part="item"][data-state="open"] { /* styles for the item is open or closed state */}
[data-part="item-trigger"][data-state="open"] { /* styles for the item is open or closed state */}
[data-part="item-content"][data-state="open"] { /* styles for the item is open or closed state */}Focused state
When an collapse item’s trigger is focused, a data-focus attribute is set on the item and content.
[data-part="item"][data-focus] { /* styles for the item's focus state */}
[data-part="item-trigger"]:focus { /* styles for the trigger's focus state */}
[data-part="item-content"][data-focus] { /* styles for the content's focus state */}Methods and Properties
Machine Context
The collapse machine exposes the following context properties:
Partial<{ root: string; item: (value: string) => string; itemContent: (value: string) => string; itemTrigger: (value: string) => string; }>booleanbooleanstring[]boolean(details: ValueChangeDetails) => void(details: FocusChangeDetails) => void"horizontal" | "vertical""ltr" | "rtl"string() => ShadowRoot | Node | DocumentMachine API
The collapse api exposes the following methods:
stringstring[](value: string[]) => void(props: ItemProps) => ItemStateData Attributes
Root
data-scopedata-partdata-orientationItem
data-scopedata-partdata-statedata-focusdata-disableddata-orientationItemContent
data-scopedata-partdata-statedata-disableddata-focusdata-orientationItemIndicator
data-scopedata-partdata-statedata-disableddata-focusdata-orientationItemTrigger
data-scopedata-partdata-orientationdata-stateAccessibility
Keyboard Interaction
SpaceEnterTabShift + TabArrowDownArrowUpHomeEnd