# 堆叠项

## 使用方法

`Stack` 把子项排成一行或者一列，间距始终一致。子项之间的距离交给 `gap` 属性，不用自己算。

```ts
import { StackItem } from '@astryx-vue/core/Stack'
```

某个子项需要单独定尺寸时，用 `StackItem` 把它包一层。`size` 默认是 `static`，保持它本来该多大；改成 `fill`，它就把其他项剩下的空间占满。`crossAlignSelf` 只改这一项在交叉轴上的对齐，不影响同层其他项。`isScrollable` 让这一项自己成为一块滚动区域。

这层包装还顺手清掉了 flex 的默认最小尺寸（`min-width` 和 `min-height` 归零），所以里面塞一长串内容也不会把整行撑宽。

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

<template>
  <HStack :gap="3">
    <StackItem size="static">
      固定宽度
    </StackItem>
    <StackItem size="fill">
      占满剩余空间
    </StackItem>
  </HStack>
</template>
```

### 结构

- **堆叠容器**: 沿一条 flex 轴排列内容的布局容器。
- **项**: 可选的 StackItem，用来控制堆叠里的一项。
- **内容**: Stack 或 StackItem 画出的、由使用方提供的内容。

## 最佳实践

| 指引 | 实践 |
| --- | --- |
| 推荐 | 用 `gap` 属性控制项目间距，而不是给子元素手动添加外边距，间距更容易保持一致。 |
| 推荐 | 希望某个项目拉伸并填满剩余空间时，给它包一层 `size="fill"` 的 `StackItem`，其余项目仍保持固有尺寸。 |
| 避免 | 为了换行而嵌套堆叠布局，优先给 `Stack` 设置 `wrap="wrap"` 让项目自动换行，结构会更扁平。 |

## 示例

### 填满剩余空间

一个固定宽度的项，旁边是一个占满剩余空间的项。子项需要单独控制尺寸时，就用 StackItem 包一层。

```vue
<script setup lang="ts">
import { Card } from '@astryx-vue/core/Card'
import { HStack, StackItem } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
</script>

<template>
  <HStack :gap="3">
    <StackItem size="static">
      <Card>
        <Text type="supporting" color="secondary">
          Static
        </Text>
      </Card>
    </StackItem>
    <StackItem size="fill">
      <Card>
        <Text type="supporting" color="secondary">
          Fills remaining space
        </Text>
      </Card>
    </StackItem>
  </HStack>
</template>
```

## 属性

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `as` | `string \| Component` | `'div'` | 根元素或者根组件。 |
| `crossAlignSelf` | `StackCrossAlignment` | — | 只改这一项在交叉轴上的对齐，盖掉父级堆叠的设置：`start`、`center`、`end`、`stretch`。 |
| `isScrollable` | `boolean` | `false` | 内容超出时允许滚动。这层包装已经把 flex 的最小尺寸清掉了，所以 `size="fill"` 配上 `isScrollable` 就是一块完整的滚动区域。 |
| `size` | `'static' \| 'fill'` | `'static'` | `static` 保持本来该多大；`fill` 把其他项剩下的空间占满。 |

`StackCrossAlignment` 可以取这些值：

```ts
type StackCrossAlignment = 'start' | 'center' | 'end' | 'stretch'
```

## 插槽

- `default`：这一项的内容。

## 原生属性

根元素会接收 HTML 属性、`aria-*` 属性、`data-*` 属性、`class` 和 `style`。`class` 会和组件自己的类合并。
