# 可选卡片

## 使用方法

`SelectableCard` 是带选中状态的卡片。键盘焦点落在一个视觉上隐藏的复选框上。单张卡片用 `v-model:is-selected`。几张卡片共用一个值时，传入 `:is-selected`，再处理 `update:isSelected`。

选中后画出强调色边框和一条内描边。`elevation` 仍是阴影，描边叠在阴影上面。`variant` 会换这道强调色。

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

const selected = ref('pro')
</script>

<template>
  <SelectableCard
    :is-selected="selected === 'pro'"
    label="Pro"
    @update:is-selected="(next) => { if (next) selected = 'pro' }"
  >
    Pro
  </SelectableCard>
</template>
```

### 结构

- **容器**: 选中时带强调边框的可交互区域。
- **内容**: 画在卡片里的内容。

## 示例

### 抬升

Starter 和 Pro 停在低阴影上。选中描边叠在阴影上面。

```vue
<script setup lang="ts">
import { Grid } from '@astryx-vue/core/Grid'
import { SelectableCard } from '@astryx-vue/core/SelectableCard'
import { Text } from '@astryx-vue/core/Text'
import { ref } from 'vue'

const plans = [
  { id: 'starter', name: 'Starter' },
  { id: 'pro', name: 'Pro' },
]

const selected = ref('pro')

function choose(id: string, next: boolean) {
  if (next)
    selected.value = id
}
</script>

<template>
  <Grid :columns="2" :gap="3" :width="420">
    <SelectableCard
      v-for="plan in plans"
      :key="plan.id"
      elevation="low"
      :is-selected="selected === plan.id"
      :label="plan.name"
      @update:is-selected="choose(plan.id, $event)"
    >
      <Text type="body" weight="bold">
        {{ plan.name }}
      </Text>
      <Text color="secondary" type="supporting">
        The resting shadow stays put — the selection ring layers on top.
      </Text>
    </SelectableCard>
  </Grid>
</template>
```
### 多选

React、TypeScript、Node.js、Python、Rust、Go。每张卡片保留自己的颜色，可以同时选中多张。

```vue
<script setup lang="ts">
import type { CardVariant } from '@astryx-vue/core/Card'
import { Grid } from '@astryx-vue/core/Grid'
import { SelectableCard } from '@astryx-vue/core/SelectableCard'
import { Text } from '@astryx-vue/core/Text'
import { ref } from 'vue'

const tags: Array<{ id: string, name: string, variant: CardVariant }> = [
  { id: 'react', name: 'React', variant: 'blue' },
  { id: 'typescript', name: 'TypeScript', variant: 'cyan' },
  { id: 'node', name: 'Node.js', variant: 'green' },
  { id: 'python', name: 'Python', variant: 'yellow' },
  { id: 'rust', name: 'Rust', variant: 'orange' },
  { id: 'go', name: 'Go', variant: 'teal' },
]

const selected = ref(new Set(['react', 'typescript']))

function toggle(id: string, next: boolean) {
  const copy = new Set(selected.value)
  if (next)
    copy.add(id)
  else
    copy.delete(id)
  selected.value = copy
}
</script>

<template>
  <Grid :columns="3" :gap="2" :width="400">
    <SelectableCard
      v-for="tag in tags"
      :key="tag.id"
      :is-selected="selected.has(tag.id)"
      :label="tag.name"
      :variant="tag.variant"
      @update:is-selected="toggle(tag.id, $event)"
    >
      <Text type="body" weight="bold">
        {{ tag.name }}
      </Text>
    </SelectableCard>
  </Grid>
</template>
```

## 属性

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 隐藏复选框的无障碍名称。 |
| `isSelected` | `boolean` | - | 是否选中。用 `v-model:isSelected` 绑定。 |
| `isDisabled` | `boolean` | `false` | 卡片不再响应激活。 |
| `variant` | `CardVariant` | `'default'` | 背景变体。选中后的描边用这个色相。 |
| `elevation` | `CardElevation` | `'none'` | 静止阴影。选中描边和它叠在一起。 |
| `padding` | `SpacingStep` | - | 传给 `Card` 的内边距。 |
| `width` | `number \| string` | - | 宽度。数字按像素。 |
| `height` | `number \| string` | - | 高度。数字按像素。 |
| `maxWidth` | `number \| string` | - | 最大宽度。 |

## 事件

| 名称 | 参数 | 说明 |
| --- | --- | --- |
| `update:isSelected` | `boolean` | 下一次的选中状态。 |
| `change` | `boolean` | 和 `update:isSelected` 一起发出。 |

## 插槽

默认插槽是卡片内容。里面的按钮和链接仍走自己的点击。
