# 区块

## 使用方法

`Section` 用来划分页面上的一块区域，例如一组设置、表单里的一段，或需要强调的一块。它负责背景、按间距刻度设置内边距，并可以在任意一边画分隔线。

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

<template>
  <Section :padding="4">
    <p>账户</p>
  </Section>
</template>
```

`variant` 取 `section`（表面色）、`muted` 或 `transparent`。`padding` 默认是刻度 4。单边覆盖轴向，轴向覆盖统一的 `padding`。`dividers` 接受 `top`、`bottom`、`start`、`end`，`start` 和 `end` 随书写方向翻转。

外层用负外边距，让区块能逃出父级容器（例如 `Card` 或 `LayoutContent`）的内边距。

### 结构

- **区块容器**: 把页面里的一块区域分组的着色容器。
- **使用方内容**: 画在区块容器里、由使用方提供的内容。

## 最佳实践

| 指引 | 实践 |
| --- | --- |
| 推荐 | 页面上的一块区域用 Section。单独一项，例如一条通知或一张资料卡，用 Card。 |
| 推荐 | 先用默认变体。只有某一块需要被注意到时再用 muted。 |
| 推荐 | 相邻且背景相同的区块，用分隔线隔开。 |
| 避免 | 在子元素上再加外边距去重复主题内边距。内边距设在区块上。 |

## 示例

### 默认与弱化背景

默认区块下面接一整条弱化背景，用来把升级提示这类区域单独提出来。

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

const features = [
  '10 team members',
  'Unlimited projects',
  'Priority support',
  'Advanced analytics',
]
</script>

<template>
  <VStack :gap="2">
    <Section :padding="4" variant="section">
      <VStack :gap="3" h-align="center">
        <VStack :gap="1" h-align="center">
          <Text type="display-3">
            Pro Plan
          </Text>
          <Text color="secondary" type="body">
            Everything you need to scale your team.
          </Text>
        </VStack>
        <VStack :gap="2">
          <HStack v-for="feature in features" :key="feature" :gap="2" align="center">
            <span class="i-carbon-checkmark nav-mark" />
            <Text type="body">
              {{ feature }}
            </Text>
          </HStack>
        </VStack>
      </VStack>
    </Section>
    <Section :padding="6" variant="muted">
      <VStack :gap="2" h-align="center">
        <HStack :gap="2" align="center">
          <Text type="display-3">
            $49
          </Text>
          <Text color="secondary" type="supporting">
            / month
          </Text>
        </HStack>
        <Button label="Upgrade" variant="primary" />
      </VStack>
    </Section>
  </VStack>
</template>
```

### 带分隔线

相邻且背景相同的区块用底部分隔线分开，像设置页那样。

```vue
<script setup lang="ts">
import { Heading } from '@astryx-vue/core/Heading'
import { Section } from '@astryx-vue/core/Section'
import { VStack } from '@astryx-vue/core/Stack'
import { Text } from '@astryx-vue/core/Text'
</script>

<template>
  <VStack :gap="0">
    <Section :dividers="['bottom']" :padding="5" variant="section">
      <VStack :gap="1">
        <Heading :level="4">
          Account
        </Heading>
        <Text color="secondary" type="body">
          Manage your profile, email, and password.
        </Text>
      </VStack>
    </Section>
    <Section :dividers="['bottom']" :padding="5" variant="section">
      <VStack :gap="1">
        <Heading :level="4">
          Notifications
        </Heading>
        <Text color="secondary" type="body">
          Choose what updates you receive and how.
        </Text>
      </VStack>
    </Section>
    <Section :padding="5" variant="section">
      <VStack :gap="1">
        <Heading :level="4">
          Privacy
        </Heading>
        <Text color="secondary" type="body">
          Control who can see your activity and data.
        </Text>
      </VStack>
    </Section>
  </VStack>
</template>
```

## Section Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `variant` | `'section' \| 'transparent' \| 'muted'` | `'section'` | 背景。`section` 用表面色，`muted` 用弱化底，`transparent` 不铺底。 |
| `padding` | `SpacingStep` | `4` | 四边内边距。`0` 表示内容贴边。 |
| `paddingInline` | `SpacingStep` | - | 行向内边距，覆盖这一轴上的 `padding`。 |
| `paddingInlineStart` | `SpacingStep` | - | 行起始边内边距，只覆盖这一边。物理方向随书写方向翻转。 |
| `paddingInlineEnd` | `SpacingStep` | - | 行结束边内边距，只覆盖这一边。 |
| `paddingBlock` | `SpacingStep` | - | 块向内边距，覆盖这一轴上的 `padding`。 |
| `paddingBlockStart` | `SpacingStep` | - | 块起始边内边距，只覆盖这一边。 |
| `paddingBlockEnd` | `SpacingStep` | - | 块结束边内边距，只覆盖这一边。 |
| `dividers` | `Array<'top' \| 'bottom' \| 'start' \| 'end'>` | - | 哪些边画 1px 分隔线。`start` 和 `end` 随书写方向翻转。 |
| `width` | `number \| string` | - | 宽度。数字按像素处理，字符串原样使用。 |
| `height` | `number \| string` | - | 高度。数字按像素处理，字符串原样使用。 |
| `maxWidth` | `number \| string` | - | 最大宽度。数字按像素处理，字符串原样使用。 |
| `minHeight` | `number \| string` | - | 最小高度。数字按像素处理，字符串原样使用。 |

`SpacingStep` 的取值是 `0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10`。

## 插槽

| 名称 | 说明 |
| --- | --- |
| `default` | 区块里的内容。 |

## 原生属性

`Section` 的根元素是 `<div>`。

以下内容落到这个元素上：

- HTML 属性。
- `aria-*` 属性。
- `data-*` 属性。
- `class`。
- `style`。

`class` 会合并。内层元素写 `data-variant`，并为每一条请求的边写 `data-divider-*`。
