---
title: "SigmaControls"
description: "控件容器，负责八向停靠与排布方向，替使用方做掉绝对定位这件事。"
canonical_url: "https://sigma.mhaibaraai.cn/docs/components/controls"
---
# SigmaControls

> 控件容器，负责八向停靠与排布方向，替使用方做掉绝对定位这件事。

## 用法

`SigmaGraph` 的默认插槽排在占满高度的画布之后，走的是正常文档流——直接往里塞控件会被挤到容器之外并被 `overflow` 裁掉。`SigmaControls` 就是替你把绝对定位这件事做掉的容器。

组件完全不碰 sigma 上下文，只渲染一个带 `data-position` / `data-direction` 的 `div`，停靠与排布全由 CSS 消费这两个属性。因此它也能装任何自定义内容，不限于内置控件。

### `position`

停靠位的语序固定为「纵向-横向」，四角之外还有四条边的中点，共八个：

```vue [ControlsPositionExample.vue]
<script setup lang="ts">
defineProps<{
  position?:
    | 'top-left' | 'top-center' | 'top-right'
    | 'middle-left' | 'middle-right'
    | 'bottom-left' | 'bottom-center' | 'bottom-right'
}>()

const { data } = await useFetch('/api/small.json')
</script>

<template>
  <SigmaGraph :data="data">
    <SigmaControls :position="position">
      <SigmaZoomControl />
    </SigmaControls>
  </SigmaGraph>
</template>
```

四角停靠靠 `--sigma-control-inset` 与画布边缘留距；居中的那条轴改由 `50%` 加位移接管，`inset` 只作用于另一条轴。

> [!NOTE]
> 
> 停靠位置还会影响子控件的行为：
> 
> data-position
> 
>  以 
> 
> bottom
> 
>  开头时，
> 
> SigmaSearchControl
> 
>  的结果列表改为
> 
> 向上
> 
> 展开，避免溢出画布底边。
> 
> middle-left
> 
>  / 
> 
> middle-right
> 
>  停在画布中部，向下展开的空间足够，不触发这条规则。

### `direction`

除 `vertical` / `horizontal` 外还有两个 reverse 变体，对应 `column-reverse` 与 `row-reverse`。控件组用的是 `flex-direction: inherit`，所以 reverse 会一路下钻——`SigmaZoomControl` 内部的放大、缩小、重置三个按钮也跟着翻转，语义是整个堆叠方向反过来：

```vue [ControlsDirectionExample.vue]
<script setup lang="ts">
defineProps<{
  direction?: 'vertical' | 'vertical-reverse' | 'horizontal' | 'horizontal-reverse'
}>()

const { data } = await useFetch('/api/small.json')
</script>

<template>
  <SigmaGraph :data="data">
    <SigmaControls position="top-right" :direction="direction">
      <SigmaZoomControl />
      <SigmaFullscreenControl />
    </SigmaControls>
  </SigmaGraph>
</template>
```

容器是 flex，但刻意禁用了交叉轴拉伸——否则一个窄按钮会被最宽的兄弟撑开。纵向排布时按停靠位对齐：停右侧右对齐，停 `*-center` 居中对齐，其余左对齐；横向排布一律居中对齐。

## 示例

### 默认插槽

默认插槽没有作用域，放什么都可以。一张图上也可以放多个容器，各停各的角：

```vue [ControlsSlotExample.vue]
<script setup lang="ts">
const { data } = await useFetch('/api/small.json')

const starred = shallowRef<string[]>([])

function star(key: string) {
  starred.value = starred.value.includes(key)
    ? starred.value.filter(item => item !== key)
    : [...starred.value, key]
}
</script>

<template>
  <SigmaGraph :data="data">
    <SigmaControls direction="horizontal">
      <UButton
        v-for="node in data?.nodes"
        :key="node.key"
        size="xs"
        :variant="starred.includes(node.key) ? 'solid' : 'soft'"
        :label="node.attributes.label"
        @click="star(node.key)"
      />
    </SigmaControls>

    <SigmaControls position="bottom-right">
      <UBadge color="neutral" variant="subtle" :label="`已标记 ${starred.length} 个`" />
      <SigmaZoomControl :reset="false" />
    </SigmaControls>
  </SigmaGraph>
</template>
```

> [!NOTE]
> 
> 控件之间的间距由 
> 
> --sigma-control-gap
> 
>  控制，与画布边缘的距离由 
> 
> --sigma-control-inset
> 
>  控制，层级是 
> 
> --sigma-control-z
> 
> （默认 
> 
> 5
> 
> ，低于覆盖层的 
> 
> 10
> 
> ）。

## API

### Props

```ts
/**
 * Props for the SigmaControls component
 */
interface SigmaControlsProps {
  /**
   * 停靠位，语序为「纵向-横向」，四角之外还有四条边的中点
   * @default 'top-left'
   */
  position?: "top-left" | "top-center" | "top-right" | "middle-left" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right" | undefined;
  /**
   * 内部控件的排布方向，reverse 变体会连同控件组内部一起翻转
   * @default 'vertical'
   */
  direction?: "vertical" | "vertical-reverse" | "horizontal" | "horizontal-reverse" | undefined;
}
```

### Slots

```ts
/**
 * Slots for the SigmaControls component
 */
interface SigmaControlsSlots {
  default(): any;
}
```


## Sitemap

See the full [sitemap](https://sigma.mhaibaraai.cn/sitemap.md) for all pages.
