Navigation · Anchor

Anchor

The Anchor component is used to create a hyper Link navigation bar.

Demos

How to import

import { Anchor } from '@fibrous/semi-ui-solid';

Basic Usage

Use Link to create an anchor, click it to jump to the hash tag location.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <Anchor>
            <Anchor.Link href="#基本示例" title="基本示例" />
            <Anchor.Link href="#组件" title="组件" />
            <Anchor.Link href="#设计语言" title="设计语言" />
            <Anchor.Link href="#物料平台" title="物料平台" />
            <Anchor.Link href="#主题商店" title="主题商店" />
        </Anchor>
    );
}

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 getContainer property. Its default value is window.

  • 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 style object, for example position: fixed.

  • offsetTop:offsetTop can trigger the current Link switch when the scrolling content reaches a specified offset from the top of the container.

import { Anchor } from '@fibrous/semi-ui-solid';

function AnchorExample() {
    const getContainer = () => window;
    return (
        <div>
            <span>See the fixed Anchor on the right </span>
            <Anchor getContainer={getContainer} offsetTop={100} targetOffset={100} style={{ position: 'fixed', right: '20px', top: '100px', width: '200px', 'z-index': '3' }}>
                <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>
    );
}

Size

You can change Anchor size with size property.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <Anchor size="default">
            <Anchor.Link href="#组件" title="组件" />
            <Anchor.Link href="#设计语言" title="设计语言" />
            <Anchor.Link href="#物料平台" title="物料平台" />
            <Anchor.Link href="#主题商店" title="主题商店" />
        </Anchor>
    );
}
Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <Anchor size="small">
            <Anchor.Link href="#组件" title="组件" />
            <Anchor.Link href="#设计语言" title="设计语言" />
            <Anchor.Link href="#物料平台" title="物料平台" />
            <Anchor.Link href="#主题商店" title="主题商店" />
        </Anchor>
    );
}

Rail Theme

You can change rail color with railTheme property. Three themes are supported and the default value is primary.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor railTheme="primary" targetOffset={60} offsetTop={100}>
                <Anchor.Link href="#尺寸" title="尺寸" />
                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
                <Anchor.Link href="#设计语言" title="设计语言" />
                <Anchor.Link href="#物料平台" title="物料平台" />
                <Anchor.Link href="#主题商店" title="主题商店" />
            </Anchor>
        </div>
    );
}
Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor railTheme="tertiary" targetOffset={60} offsetTop={100}>
                <Anchor.Link href="#尺寸" title="尺寸" />
                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
                <Anchor.Link href="#设计语言" title="设计语言" />
                <Anchor.Link href="#物料平台" title="物料平台" />
                <Anchor.Link href="#主题商店" title="主题商店" />
            </Anchor>
        </div>
    );
}
Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor railTheme="muted" targetOffset={60} offsetTop={100}>
                <Anchor.Link href="#尺寸" title="尺寸" />
                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
                <Anchor.Link href="#设计语言" title="设计语言" />
                <Anchor.Link href="#物料平台" title="物料平台" />
                <Anchor.Link href="#主题商店" title="主题商店" />
            </Anchor>
        </div>
    );
}

Auto Collapse

Anchor can dynamically display child links with autoCollapse property. The default is false.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor autoCollapse targetOffset={60} offsetTop={100}>
                <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>
    );
}
Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor autoCollapse={false} targetOffset={60} offsetTop={100}>
                <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>
    );
}

Show Tooltip

showTooltip can display the title of link when it exceeds the max-width. The default value is false.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor showTooltip targetOffset={60} offsetTop={100}>
                <Anchor.Link href="#显示工具提示" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
                <Anchor.Link href="#组件" title="组件" />
                <Anchor.Link href="#设计语言" title="设计语言" />
                <Anchor.Link href="#物料平台" title="物料平台" />
                <Anchor.Link href="#主题商店" title="主题商店" />
            </Anchor>
        </div>
    );
}

Tooltip Position

You can change the Tooltip position with position property. It only works when showTooltip is true.

Code
import { Anchor } from '@fibrous/semi-ui-solid';

export default function AnchorDemo() {
    return (
        <div>
            <Anchor showTooltip position="right" targetOffset={60} offsetTop={100}>
                <Anchor.Link href="#工具提示位置" title="工具提示是一个有用的工具,它可以在文字缩略时展示全部内容。" />
                <Anchor.Link href="#组件" title="组件" />
                <Anchor.Link href="#设计语言" title="设计语言" />
                <Anchor.Link href="#物料平台" title="物料平台" />
                <Anchor.Link href="#主题商店" title="主题商店" />
            </Anchor>
        </div>
    );
}

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.

  • scrollMotion still decides whether the scroll is animated (behavior), and targetOffset still shifts the position block produces, when passed together with scrollIntoViewOptions.
  • Only the innermost vertically scrollable container is scrolled; the horizontal position is adjusted only when inline is passed.
点击链接后,章节 1 会滚动到容器中间
点击链接后,章节 2 会滚动到容器中间
点击链接后,章节 3 会滚动到容器中间
Code
import { For } from 'solid-js';
import { Anchor } from '@fibrous/semi-ui-solid';

const sections = ['section-a', 'section-b', 'section-c'];

export default function AnchorDemo() {
    return (
        <div style={{ display: 'flex', gap: '24px' }}>
            <Anchor getContainer={() => document.getElementById('scroll-box')} scrollMotion scrollIntoViewOptions={{ block: 'center' }} style={{ width: '160px' }}>
                <For each={sections}>{(id, index) => <Anchor.Link href={`#${id}`} title={`章节 ${index() + 1}`} />}</For>
            </Anchor>
            {/* 可聚焦,键盘也能滚动这个容器 */}
            <section id="scroll-box" aria-label="章节" tabIndex={0} style={{ height: '240px', width: '320px', overflow: 'auto', border: '1px solid #ddd' }}>
                <For each={sections}>
                    {(id, index) => (
                        <div id={id} style={{ height: '200px', padding: '8px' }}>
                            点击链接后,章节 {index() + 1} 会滚动到容器中间
                        </div>
                    )}
                </For>
            </section>
        </div>
    );
}

API Reference

Anchor

Props

PropertyDescriptionTypeDefault
autoCollapseWhether child links are shown dynamically: only the branch that holds the highlighted link is expanded.booleanfalse
defaultAnchorLink highlighted on mount. It does not call onChange or onClick.string""
getContainerReturns the scrolling container, window when omitted. Returning null also falls back to window.Type() => HTMLElement | Window | nullType() => window
maxHeightmax-height of the component, with a scrollbar when exceeded. This prop overrides max-height in style.string | number"750px"
maxWidthmax-width of the component, truncating when exceeded. This prop overrides max-width in style.string | number"200px"
offsetTopOffset from the top of the container at which the current link switches while content scrolls.number0
onChangeCalled when the highlighted link changes, with the current and the previous link.Type(currentLink: string, previousLink: string) => void-
onClickCalled when a link is clicked or activated with Enter, with the native MouseEvent or KeyboardEvent and the current link.Type(e: AnchorClickEvent, currentLink: string) => void-
positionPosition of the Tooltip when showTooltip is on, with the same values as the Tooltip position.Position-
railThemeTheme of the rail: primary, tertiary or muted.'primary' | 'tertiary' | 'muted'"primary"
scrollIntoViewOptionsOptions passed to scroll-into-view-if-needed when a link is clicked, combined with scrollMotion and targetOffset. Without block the value is start; the horizontal position changes only when inline is passed.AnchorBaseProps['scrollIntoViewOptions']-
scrollMotionWhether scrolling after a click is animated (behavior is smooth).booleanfalse
showTooltipWhether 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 | ShowTooltipfalse
sizeSize of the anchor: small or default.'small' | 'default'"default"
targetOffsetDistance between the target and the top of the container when scrolling ends.number0

class, style, ref and native attributes (such as data-* and aria-*) land on the root element (role="navigation"). onClick is a component callback, not a native click listener on the root element. maxWidth and maxHeight override the max-width and max-height in style.

Props

PropertyDescriptionTypeDefault
disabledWhether the link is disabled and ignores clicks.boolean-
hrefTarget of the link. A value starting with # is looked up by element id, anything else as a CSS selector. Defaults to # when unset.string-
titleText of the link, which can be a node. When showTooltip is off and the value is a non-empty string, it is also the native title.JSX.Element-

class, style, ref and native attributes (such as data-*) land on the outermost div (role="listitem") of the link.

Content Guidelines

  • Write in sentence case
  • Keep it concise and avoid line breaks

Design Tokens

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$transition_duration-anchor_title-textvar(--semi-transition_duration-none)锚点标题文字-文字-动画持续时间
$transition_function-anchor_title-textvar(--semi-transition_function-easeIn)锚点标题文字-文字-过渡曲线
$transition_delay-anchor_title-textvar(--semi-transition_delay-none)锚点标题文字-文字-延迟时间
$transform_scale-anchor_title-textvar(--semi-transform_scale-none)锚点-放大
$color-anchor_slide_default-bg-defaultvar(--semi-color-border)滑轨背景颜色
$color-anchor_slide_primary-bg-activevar(--semi-color-primary)选中颜色 - Primary
$color-anchor_slide_tertiary-bg-activevar(--semi-color-tertiary)选中颜色 - Tietrary
$color-anchor_title-text-defaultvar(--semi-color-text-2)文字颜色 - 未选中
$color-anchor_title-text-hovervar(--semi-color-tertiary-hover)文字颜色 - 未选中悬浮态
$color-anchor_title_active-text-hover$color-anchor_title-text-hover文字颜色 - 选中悬浮态
$color-anchor_title-text-activevar(--semi-color-text-0)文字颜色 - 选中
$color-anchor_title-text-disabledvar(--semi-color-disabled-text)文字颜色 - 禁用
$color-anchor_title-bg-defaulttransparent背景色
$color-anchor_title-bg-activetransparent背景色 - 选中
$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_default2px滑轨宽度
$height-anchor_slide_default20px选项高度 - 默认
$height-anchor_slide_small16px选项高度 - 小尺寸
$radius-anchor_slide1px滑轨圆角
$width-anchor-outline$width-focus-ringanchor轮廓宽度
$width-anchor-outlineOffset-2pxanchor轮廓 outline-offset 宽度
$width-anchor-outline_border_radius3pxanchor轮廓圆角

FAQ

  1. 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.
import { Anchor } from '@fibrous/semi-ui-solid';

// 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');

function App() {
    return (
        <Anchor getContainer={getContainer}>
            {/* Links */}
        </Anchor>
    );
}