Demos
How to import
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
Anchor.Link can also be imported by name as AnchorLink.
Basic Usage
Use Link to create an anchor, click it to jump to the hash tag location.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<Anchor>
<Anchor.Link href="#基本示例" title="基本示例" />
<Anchor.Link href="#组件" title="组件" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</template>Integrated Usage
You can use getContainer, targetOffset, offsetTop, and style to create a out of the box hyperAnchor.Link navigation bar.
-
getContainer:you can set the container of scroll content with
getContainerproperty. Its default value iswindow. -
targetOffset: you can set the distance between the anchor point and the top of the container by setting
targetOffset. -
style:Anchor does not position itself. Position it yourself with the
styleobject, for exampleposition: fixed. -
offsetTop:
offsetTopcan trigger the current Link switch when the scrolling content reaches a specified offset from the top of the container.
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
const getContainer = () => window;
</script>
<template>
<div>
<span>See the fixed Anchor on the right </span>
<Anchor :getContainer="getContainer" :offsetTop="100" :style="{ position: 'fixed', right: '20px', top: '100px', width: '200px', zIndex: 3 }" :targetOffset="100">
<Anchor.Link href="#Basic_Usage" title="Fixed Anchor" />
<Anchor.Link href="#Integrated_Usage" title="Integrated Usage" />
<Anchor.Link href="#Size" title="Size" />
<Anchor.Link href="#Rail_Theme" title="Rail Theme" />
<Anchor.Link href="#Auto_Collapse" title="Auto Collapse" />
<Anchor.Link href="#Show_Tooltip" title="Show Tooltip" />
<Anchor.Link href="#Tooltip_Position" title="Tooltip Position" />
<Anchor.Link href="#API_Reference" title="API Reference">
<Anchor.Link href="#Anchor" title="Anchor" />
<Anchor.Link href="#Anchor.Link" title="Anchor.Link" />
</Anchor.Link>
</Anchor>
</div>
</template>
Size
You can change Anchor size with size property.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<Anchor size="default">
<Anchor.Link href="#组件" title="组件" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</template>Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<Anchor size="small">
<Anchor.Link href="#组件" title="组件" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</template>Rail Theme
You can change rail color with railTheme property. Three themes are supported and the default value is primary.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :offsetTop="100" railTheme="primary" :targetOffset="60">
<Anchor.Link href="#尺寸" title="尺寸" />
<Anchor.Link href="#滑轨主题" title="滑轨主题" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</div>
</template>Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :offsetTop="100" railTheme="tertiary" :targetOffset="60">
<Anchor.Link href="#尺寸" title="尺寸" />
<Anchor.Link href="#滑轨主题" title="滑轨主题" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</div>
</template>Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :offsetTop="100" railTheme="muted" :targetOffset="60">
<Anchor.Link href="#尺寸" title="尺寸" />
<Anchor.Link href="#滑轨主题" title="滑轨主题" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</div>
</template>Auto Collapse
Anchor can dynamically display child links with autoCollapse property. The default is false.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor autoCollapse :offsetTop="100" :targetOffset="60">
<Anchor.Link href="#动态展示" title="1. 动态展示">
<Anchor.Link href="#组件" title="1.1 组件">
<Anchor.Link href="#头像" title="1.1.1 Avatar" />
<Anchor.Link href="#按钮" title="1.1.2 Button" />
<Anchor.Link href="#图标" title="1.1.3 Icon" />
</Anchor.Link>
<Anchor.Link href="#物料" title="1.2 物料" />
<Anchor.Link href="#主题商店" title="1.3 主题商店" />
</Anchor.Link>
<Anchor.Link href="#设计语言" title="2. 设计语言" />
</Anchor>
</div>
</template>Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :autoCollapse="false" :offsetTop="100" :targetOffset="60">
<Anchor.Link href="#动态展示" title="1. 动态展示">
<Anchor.Link href="#组件" title="1.1 组件">
<Anchor.Link href="#头像" title="1.1.1 Avatar" />
<Anchor.Link href="#按钮" title="1.1.2 Button" />
<Anchor.Link href="#图标" title="1.1.3 Icon" />
</Anchor.Link>
<Anchor.Link href="#物料" title="1.2 物料" />
<Anchor.Link href="#主题商店" title="1.3 主题商店" />
</Anchor.Link>
<Anchor.Link href="#设计语言" title="2. 设计语言" />
</Anchor>
</div>
</template>Show Tooltip
showTooltip can display the title of link when it exceeds the max-width. The default value is false.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :offsetTop="100" showTooltip :targetOffset="60">
<Anchor.Link href="#显示工具提示" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
<Anchor.Link href="#组件" title="组件" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</div>
</template>Tooltip Position
You can change the Tooltip position with position property. It only works when showTooltip is true.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Anchor :offsetTop="100" position="right" showTooltip :targetOffset="60">
<Anchor.Link href="#工具提示位置" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
<Anchor.Link href="#组件" title="组件" />
<Anchor.Link href="#设计语言" title="设计语言" />
<Anchor.Link href="#物料平台" title="物料平台" />
<Anchor.Link href="#主题商店" title="主题商店" />
</Anchor>
</div>
</template>Custom Scroll Position
scrollIntoViewOptions adjusts where the target ends up in the container after a link is clicked. Its type is the Options of scroll-into-view-if-needed: block, inline, scrollMode, boundary and skipOverflowHiddenElements. Without it block is start, which scrolls the target to the top of the container.
scrollMotionstill decides whether the scroll is animated (behavior), andtargetOffsetstill shifts the positionblockproduces, when passed together withscrollIntoViewOptions.- Only the innermost vertically scrollable container is scrolled; the horizontal position is adjusted only when
inlineis passed.
Code
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
const sections = ['section-a', 'section-b', 'section-c'];
const getContainer = () => document.getElementById('scroll-box');
</script>
<template>
<div :style="{ display: 'flex', gap: '24px' }">
<Anchor :getContainer="getContainer" :scrollIntoViewOptions="{ block: 'center' }" scrollMotion :style="{ width: '160px' }">
<Anchor.Link v-for="(id, index) in sections" :key="id" :href="`#${id}`" :title="`章节 ${index + 1}`" />
</Anchor>
<!-- Focusable so the keyboard can scroll this container -->
<section id="scroll-box" aria-label="章节" :style="{ height: '240px', width: '320px', overflow: 'auto', border: '1px solid #ddd' }" tabindex="0">
<div v-for="(id, index) in sections" :id="id" :key="id" :style="{ height: '200px', padding: '8px' }">点击链接后,章节 {{ index + 1 }} 会滚动到容器中间</div>
</section>
</div>
</template>API Reference
Anchor
Props
| Property | Description | Type | Default |
|---|---|---|---|
| autoCollapse | Whether the next level of links is shown dynamically while scrolling. | boolean | semiDefault("Anchor", "autoCollapse", false) |
| defaultAnchor | Link highlighted by default. | string | semiDefault("Anchor", "defaultAnchor", "") |
| getContainer | Returns the scrolling container, window when omitted. When it returns the value of a template ref, the listener follows the container as it appears or is replaced. | Type(() => HTMLElement | Window | null) | undefined |
| maxHeight | max-height of the component, with a scrollbar when exceeded. A max-height in style wins. | string | number | semiDefault("Anchor", "maxHeight", strings.MAX_HEIGHT) |
| maxWidth | max-width of the component, truncating when exceeded. A max-width in style wins. | string | number | semiDefault("Anchor", "maxWidth", strings.MAX_WIDTH) |
| offsetTop | Offset from the top of the container at which the current link switches while content scrolls. | number | semiDefault("Anchor", "offsetTop", 0) |
| position | Position of the Tooltip when showTooltip is on, with the same values as the Tooltip position. | Type"top" | "bottom" | "left" | "right" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver" | semiGlobalDefault("Anchor", "position") |
| railTheme | Theme of the rail: primary, tertiary or muted. | "muted" | "primary" | "tertiary" | semiDefault("Anchor", "railTheme", "primary") |
| scrollMotion | Whether scrolling after a click is animated. | boolean | semiDefault("Anchor", "scrollMotion", false) |
| scrollIntoViewOptions | Options passed to scroll-into-view-if-needed when a link is clicked, combined with scrollMotion and targetOffset. | TypeOptions<any> | semiGlobalDefault("Anchor", "scrollIntoViewOptions") |
| showTooltip | Whether a Tooltip shows when the text is truncated, with its options: type is the popup component, tooltip (default) or popover, and opts are passed to it. | boolean | ShowTooltip | semiDefault("Anchor", "showTooltip", false) |
| size | Size of the anchor: small or default. | "small" | "default" | semiDefault("Anchor", "size", "default") |
| targetOffset | Distance between the target and the top of the container when scrolling ends. | number | semiDefault("Anchor", "targetOffset", 0) |
Events
| Event | Description | Callback parameters |
|---|---|---|
| change | Emitted when the highlighted link changes, with the current and the previous link. | [currentLink: string, previousLink: string] |
| click | Emitted when a link is clicked or activated with Enter, with the native MouseEvent or KeyboardEvent and the current link. As a component event, @click no longer listens for native clicks on the root element. | [event: AnchorClickEvent, currentLink: string] |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| default | Children made of Anchor.Link. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
class, style and native attributes land on the root element through attrs. A max-width or max-height in style takes precedence over the maxWidth and maxHeight props. As a component event, @click no longer listens for native clicks on the root element.
Anchor.Link
Props
| Property | Description | Type | Default |
|---|---|---|---|
| disabled | Whether the link is disabled and ignores clicks. | boolean | false |
| href | Target of the link. A value starting with # is looked up by element id, anything else as a CSS selector. | string | "#" |
| title | Plain-text title, also the native title when showTooltip is off. The title slot wins when it is provided. | string | undefined |
Events
| Event | Description | Callback parameters |
|---|---|---|
| None |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| default | Nested Anchor.Link of the next level. | any |
| title | Title as nodes. Takes precedence over the title prop. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
class, style and native attributes land on the outermost div (role="listitem") of the link through attrs. Anchor.Link must be used inside Anchor, otherwise an error is thrown.
Content Guidelines
- Write in sentence case
- Keep it concise and avoid line breaks
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $transition_duration-anchor_title-text | var(--semi-transition_duration-none) | 锚点标题文字-文字-动画持续时间 |
| $transition_function-anchor_title-text | var(--semi-transition_function-easeIn) | 锚点标题文字-文字-过渡曲线 |
| $transition_delay-anchor_title-text | var(--semi-transition_delay-none) | 锚点标题文字-文字-延迟时间 |
| $transform_scale-anchor_title-text | var(--semi-transform_scale-none) | 锚点-放大 |
| $color-anchor_slide_default-bg-default | var(--semi-color-border) | 滑轨背景颜色 |
| $color-anchor_slide_primary-bg-active | var(--semi-color-primary) | 选中颜色 - Primary |
| $color-anchor_slide_tertiary-bg-active | var(--semi-color-tertiary) | 选中颜色 - Tietrary |
| $color-anchor_title-text-default | var(--semi-color-text-2) | 文字颜色 - 未选中 |
| $color-anchor_title-text-hover | var(--semi-color-tertiary-hover) | 文字颜色 - 未选中悬浮态 |
| $color-anchor_title_active-text-hover | $color-anchor_title-text-hover | 文字颜色 - 选中悬浮态 |
| $color-anchor_title-text-active | var(--semi-color-text-0) | 文字颜色 - 选中 |
| $color-anchor_title-text-disabled | var(--semi-color-disabled-text) | 文字颜色 - 禁用 |
| $color-anchor_title-bg-default | transparent | 背景色 |
| $color-anchor_title-bg-active | transparent | 背景色 - 选中 |
| $color-anchor_title-outline-focus | $color-focus-ring | 轮廓 - 聚焦 |
| $spacing-anchor_slide-left | $spacing-none | 滑轨左侧位置 |
| $spacing-anchor_slide-top | $spacing-none | 滑轨顶部位置 |
| $spacing-anchor_slide_default-Y | $spacing-extra-tight | 选项间距 - 默认 |
| $spacing-anchor_slide_small-Y | $spacing-extra-tight | 选项间距 - 紧凑 |
| $spacing-anchor_link_title-paddingTop | $spacing-extra-tight | 选项文字顶部内边距 |
| $spacing-anchor_link_title-paddingBottom | $spacing-extra-tight | 选项文字底部内边距 |
| $width-anchor_slide_default | 2px | 滑轨宽度 |
| $height-anchor_slide_default | 20px | 选项高度 - 默认 |
| $height-anchor_slide_small | 16px | 选项高度 - 小尺寸 |
| $radius-anchor_slide | 1px | 滑轨圆角 |
| $width-anchor-outline | $width-focus-ring | anchor轮廓宽度 |
| $width-anchor-outlineOffset | -2px | anchor轮廓 outline-offset 宽度 |
| $width-anchor-outline_border_radius | 3px | anchor轮廓圆角 |
FAQ
- Why didn't my link highlight and slide to follow?
Check whether you can scroll to the specified position by clicking the anchor:- No, it means there is a problem with the id. check whether the id exists in the document;
- Yes, it may be that the scrolling container is not set correctly to ensure that the content of the document is wrapped in the scrolling container. The default scrolling container is window. If your container is a div of .my-container, you should set the scrolling container to this div.
<script setup lang="ts">
import { Anchor } from '@fibrous/semi-ui-vue';
// This is the container of the document content, not of Anchor: the current id is computed against it
const getContainer = () => document.querySelector<HTMLElement>('.my-container');
</script>
<template>
<Anchor :getContainer="getContainer">
<!-- Links -->
</Anchor>
</template>