# Collapsible Group

## Usage

`CollapsibleGroup` coordinates the `Collapsible` sections inside it. Give each section a `value`. Inside the group, that section's own `isOpen` is ignored.

`type="single"` keeps one section open. Opening another closes the previous one, and clicking the open section closes it. The value is a string, or `''` when everything is closed. `type="multiple"` toggles each section on its own, and the value is a list. `hasDividers` draws a hairline between sections. With dividers and no `density`, the padding is `balanced`.

```vue
<script setup lang="ts">
import { Collapsible, CollapsibleGroup } from '@astryx-vue/core/Collapsible'
</script>

<template>
  <CollapsibleGroup default-value="account" type="single">
    <Collapsible trigger="Account" value="account">
      Profile, email, and password.
    </Collapsible>
    <Collapsible trigger="Billing" value="billing">
      Invoices and payment method.
    </Collapsible>
  </CollapsibleGroup>
</template>
```

## Examples

### Density

density sets the block padding on every row in the group, so a list of sections can be tuned to the surface it sits on. compact for dense surfaces, balanced for page content, spacious for a short list that is the main thing on the page.

```vue
<script setup lang="ts">
import type { CollapsibleGroupDensity } from '@astryx-vue/core/Collapsible'
import { Collapsible, CollapsibleGroup } from '@astryx-vue/core/Collapsible'
import { Stack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'

const densities: Array<{ value: CollapsibleGroupDensity, label: string }> = [
  { value: 'compact', label: 'compact' },
  { value: 'balanced', label: 'balanced — the default' },
  { value: 'spacious', label: 'spacious' },
]

const sections = [
  { value: 'a', trigger: 'Region', body: 'Where your data is stored and processed. Changing region migrates existing data and can take up to an hour.' },
  { value: 'b', trigger: 'Retention', body: 'How long deleted items stay recoverable before being purged.' },
  { value: 'c', trigger: 'Audit log', body: 'Who can read the log, and how far back it reaches.' },
]
</script>

<template>
  <Stack :gap="5" :max-width="420">
    <Stack v-for="density in densities" :key="density.value" :gap="1">
      <Text type="supporting">
        {{ density.label }}
      </Text>
      <CollapsibleGroup type="single" has-dividers :density="density.value" default-value="a">
        <Collapsible v-for="section in sections" :key="section.value" :value="section.value">
          <template #trigger>
            <Text type="body" weight="semibold">
              {{ section.trigger }}
            </Text>
          </template>
          <Text type="body" color="secondary">
            {{ section.body }}
          </Text>
        </Collapsible>
      </CollapsibleGroup>
    </Stack>
  </Stack>
</template>
```

## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `'single' \| 'multiple'` | `'single'` | `single` keeps one section open. `multiple` toggles each section on its own. |
| `defaultValue` | `string \| string[]` | - | Open section when the group owns its state. |
| `value` | `string \| string[]` | - | Controlled open section. Bind with `v-model:value`. |
| `hasDividers` | `boolean` | `false` | Draw a hairline between sections. |
| `density` | `'compact' \| 'balanced' \| 'spacious'` | `'balanced'` with dividers | Trigger and content padding. |
| `chevronPosition` | `'start' \| 'end'` | `'end'` | Chevron side for every section. A section can still set its own `chevronPosition`. |

## Events

| Name | Payload | Description |
| --- | --- | --- |
| `update:value` | `string \| string[]` | The next open value. Single mode uses `''` when everything is closed. |
| `change` | `string \| string[]` | Emitted with `update:value`. |

## Slots

The default slot is the `Collapsible` sections. Each one needs a `value`.
