# 选择

提供给用户选择的选项列表 - 通过一个按钮触发。

```jsx
<Select.Root defaultValue="apple">
  <Select.Trigger />

  <Select.Content>
    <Select.Group>
      <Select.Label>水果</Select.Label>

      <Select.Item value="orange">橘子</Select.Item>

      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="grape" disabled>
        葡萄
      </Select.Item>
    </Select.Group>

    <Select.Separator />

    <Select.Group>
      <Select.Label>蔬菜</Select.Label>

      <Select.Item value="carrot">胡萝卜</Select.Item>

      <Select.Item value="potato">土豆</Select.Item>
    </Select.Group>
  </Select.Content>
</Select.Root>
```

## [API 参考](#api-参考)

### [Root](#root)

包含选择器的所有部分。它从选择基础部分 [Root](/primitives/docs/components/select#root) 继承属性。

| Prop   | Type                            | Default |
| ------ | ------------------------------- | ------- |
| `size` | `Responsive<"1" \| "2" \| "3">` | `"2"`   |

### [Trigger](#trigger)

用于切换选择器的按钮。该组件从选择基础部分 [Trigger](/primitives/docs/components/select#trigger) 和 [Value](/primitives/docs/components/select#value) 继承属性。它支持 [常见的边距属性](/themes/docs/overview/layout#margin-props)。

| Prop          | Type                                                 | Default          |
| ------------- | ---------------------------------------------------- | ---------------- |
| `variant`     | `"classic" \| "surface" \| "soft" \| "ghost"`        | `"surface"`      |
| `color`       | `enum`                                               | No default value |
| `radius`      | `"none" \| "small" \| "medium" \| "large" \| "full"` | No default value |
| `placeholder` | `string`                                             | No default value |

### [Content](#content)

当选择器打开时弹出的组件。它从 [Select.Portal primitive](/primitives/docs/components/select#portal) 和 [Select.Content primitive](/primitives/docs/components/select#content) 继承属性。

| Prop           | Type                | Default          |
| -------------- | ------------------- | ---------------- |
| `variant`      | `"solid" \| "soft"` | `"solid"`        |
| `color`        | `enum`              | No default value |
| `highContrast` | `boolean`           | No default value |

### [Item](#item)

包含选择项的组件。它从 [Select.Item primitive](/primitives/docs/components/select#item) 部分继承属性。

### [Group](#group)

用于分组多个项。它从 [Select.Group primitive](/primitives/docs/components/select#group) 部分继承属性。与 `Select.Label` 一起使用，以确保通过自动标签实现良好的可访问性。

### [Label](#label)

用于渲染组的标签，无法通过方向键聚焦。它从 [Select.Label primitive](/primitives/docs/components/select#label) 部分继承属性。

### [Separator](#separator)

用于在选择器中视觉上分隔项。它从 [Select.Separator primitive](/primitives/docs/components/select#separator) 部分继承属性。

## [示例](#示例)

### [尺寸](#尺寸)

使用 `size` 属性来控制大小。

```jsx
<Flex gap="3" align="center">
  <Select.Root size="1" defaultValue="apple">
    <Select.Trigger />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root size="2" defaultValue="apple">
    <Select.Trigger />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root size="3" defaultValue="apple">
    <Select.Trigger />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

### [变体](#变体)

在 `Trigger` 和 `Content` 上使用 `variant` 属性以自定义视觉样式。

```jsx
<Flex gap="3" align="center">
  <Select.Root defaultValue="apple">
    <Select.Trigger variant="surface" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger variant="classic" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger variant="soft" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

#### 幽灵

使用 `ghost` 触发器变体可以在没有视觉包含元素的情况下渲染触发器。幽灵触发器在布局中表现不同，因为它们使用负边距与其兄弟元素在视觉上对齐，同时保持其填充的活动和悬停状态。

```jsx
<Flex gap="3" align="center">
  <Select.Root defaultValue="apple">
    <Select.Trigger variant="surface" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger variant="ghost" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

### [颜色](#颜色)

在 `Trigger` 和 `Content` 上使用 `color` 属性指定特定的颜色值。

```jsx
<Flex gap="3">
  <Select.Root defaultValue="apple">
    <Select.Trigger color="indigo" variant="soft" />

    <Select.Content color="indigo">
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger color="cyan" variant="soft" />

    <Select.Content color="cyan">
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger color="orange" variant="soft" />

    <Select.Content color="orange">
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger color="crimson" variant="soft" />

    <Select.Content color="crimson">
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

### [高对比](#高对比)

在 `Content` 上使用 `highContrast` 属性以增加项的对比度。

```jsx
<Flex gap="3">
  <Select.Root defaultValue="apple">
    <Select.Trigger color="gray" />

    <Select.Content color="gray" variant="solid">
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger color="gray" />

    <Select.Content color="gray" variant="solid" highContrast>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

### [半径](#半径)

使用 `radius` 属性来赋予特定的半径值。

```jsx
<Flex gap="3">
  <Select.Root defaultValue="apple">
    <Select.Trigger radius="none" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger radius="large" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>

  <Select.Root defaultValue="apple">
    <Select.Trigger radius="full" />

    <Select.Content>
      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="orange">橘子</Select.Item>
    </Select.Content>
  </Select.Root>
</Flex>
```

### [占位符](#占位符)

使用 `placeholder` 属性创建一个不需要初始值的 `Trigger`。

```jsx
<Select.Root>
  <Select.Trigger placeholder="选择一个水果" />

  <Select.Content>
    <Select.Group>
      <Select.Label>水果</Select.Label>

      <Select.Item value="orange">橘子</Select.Item>

      <Select.Item value="apple">苹果</Select.Item>

      <Select.Item value="grape" disabled>
        葡萄
      </Select.Item>
    </Select.Group>

    <Select.Separator />

    <Select.Group>
      <Select.Label>蔬菜</Select.Label>

      <Select.Item value="carrot">胡萝卜</Select.Item>

      <Select.Item value="potato">土豆</Select.Item>
    </Select.Group>
  </Select.Content>
</Select.Root>
```

### [位置](#位置)

设置 `position="popper"` 属性使选择菜单位于触发器下方。

```jsx
<Select.Root defaultValue="apple">
  <Select.Trigger />

  <Select.Content position="popper">
    <Select.Item value="apple">苹果</Select.Item>

    <Select.Item value="orange">橘子</Select.Item>
  </Select.Content>
</Select.Root>
```

### [与服务端渲染一起使用](#与服务端渲染一起使用)

在使用服务器端渲染时，您可能会注意到在水合后布局发生移动。这是因为触发器执行客户端代码以显示所选项的文本。为了避免这种布局移动，您可以通过映射值手动渲染它。

```jsx
() => {
  const data = {
    apple: "苹果",

    orange: "橘子",
  };

  const [value, setValue] = React.useState("apple");

  return (
    <Select.Root value={value} onValueChange={setValue}>
      <Select.Trigger>{data[value]}</Select.Trigger>

      <Select.Content>
        <Select.Item value="apple">苹果</Select.Item>

        <Select.Item value="orange">橘子</Select.Item>
      </Select.Content>
    </Select.Root>
  );
};
```

### [带图标](#带图标)

您可以通过手动控制子元素来自定义触发器如何渲染值。例如，您可以在所选项的文本旁边渲染一个图标。

```jsx
() => {
  const data = {
    light: { label: "光明", icon: <SunIcon /> },

    dark: { label: "黑暗", icon: <MoonIcon /> },
  };

  const [value, setValue] = React.useState("light");

  return (
    <Flex direction="column" maxWidth="160px">
      <Select.Root value={value} onValueChange={setValue}>
        <Select.Trigger>
          <Flex as="span" align="center" gap="2">
            {data[value].icon}

            {data[value].label}
          </Flex>
        </Select.Trigger>

        <Select.Content position="popper">
          <Select.Item value="light">光明</Select.Item>

          <Select.Item value="dark">黑暗</Select.Item>
        </Select.Content>
      </Select.Root>
    </Flex>
  );
};
```

<!--$-->

<!--/$-->
