Collapsible

An interactive component which expands/collapses a panel.

Examples

Basic

PropDefaultTypeDescription
defaultOpenfalsebooleanThe open state of the collapsible when it is initially rendered. Use when you do not need to control its open state.
disabled-booleanWhen true, prevents the user from interacting with the collapsible.
open-booleanThe controlled open state of the collapsible. Can be binded with v-model.
Preview
Code

@peduarte starred 3 repositories

@radix-ui/primitives

Slots

NamePropsDescription
defaultopenThe collapsible root slot.
content-The collapsible content slot.
triggeropenThe button trigger slot.
Preview
Code

Presets

shortcuts/collapsible.ts
type CollapsiblePrefix = 'collapsible'

export const staticCollapsible: Record<`${CollapsiblePrefix}-${string}`, string> = {
  'collapsible-content': 'overflow-hidden transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down',
}

export const dynamicCollapsible: [RegExp, (params: RegExpExecArray) => string][] = [
  // dynamic preset
]

export const collapsible = [
  ...dynamicCollapsible,
  staticCollapsible,
]

Props

types/collapsible.ts
import type { CollapsibleContentProps, CollapsibleRootProps } from 'radix-vue'
import type { HTMLAttributes } from 'vue'

interface BaseExtensions { class?: HTMLAttributes['class'] }

export interface NCollapsibleProps extends CollapsibleRootProps {
  /** Props for the collapsible content */
  _collapsibleContent?: NCollapsibleContentProps
}

export interface NCollapsibleContentProps extends CollapsibleContentProps, BaseExtensions {
}

Components

Collapsible.vue
CollapsibleTrigger.vue
CollapsibleContent.vue
<script setup lang="ts">
import type { CollapsibleRootEmits } from 'radix-vue'
import type { NCollapsibleProps } from '../../../types'
import { CollapsibleRoot, useForwardPropsEmits } from 'radix-vue'
import CollapsibleContent from './CollapsibleContent.vue'
import CollapsibleTrigger from './CollapsibleTrigger.vue'

const props = defineProps<NCollapsibleProps>()
const emits = defineEmits<CollapsibleRootEmits>()

const forwarded = useForwardPropsEmits(props, emits)
</script>

<template>
  <CollapsibleRoot v-slot="{ open }" v-bind="forwarded">
    <slot :open>
      <CollapsibleTrigger>
        <slot name="trigger" :open />
      </CollapsibleTrigger>

      <CollapsibleContent
        v-bind="_collapsibleContent"
      >
        <slot name="content" />
      </CollapsibleContent>
    </slot>
  </CollapsibleRoot>
</template>