导航类

锚点

创建超链接导航栏。

代码演示

如何引入

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

基本示例

使用 Link 可以创建锚点,点击它会跳转到指定位置。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

综合使用

你可以搭配 getContainer,targetOffset,style,offsetTop 完成一个拆箱即用的超链接导航栏。

  • 滚动容器:你可以通过 getContainer 设置滚动内容的容器,默认值为 window 。

  • 距离顶部的距离:可以通过设置 targetOffset 设置文档滚动结束时,锚点距离容器顶部的距离。

  • 自定义定位方式:Anchor 自身不设置定位,你可以通过 style 对象为它指定定位方式,例如 position: fixed。

  • 偏移距离:offsetTop 可以在滚动内容距离容器顶部达到指定偏移量时触发当前 Link 切换。

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

() => {
    const getContainer = () => {
        return document.querySelector('window');
    };
    return (
        <div>
            <span>请看右侧固定的 Anchor </span>
            <Anchor getContainer={getContainer} offsetTop={100} targetOffset={100} style={{ position: 'fixed', right: '20px', top: '100px', width: '200px', zIndex: 3 }}>
                <Anchor.Link href="#基本示例" title="我是固定的 Anchor" />
                <Anchor.Link href="#综合使用" title="综合使用" />
                <Anchor.Link href="#尺寸" title="尺寸" />
                <Anchor.Link href="#滑轨主题" title="滑轨主题" />
                <Anchor.Link href="#动态展示" title="动态展示" />
                <Anchor.Link href="#显示工具提示" title="显示工具提示" />
                <Anchor.Link href="#工具提示位置" title="工具提示位置" />
                <Anchor.Link href="#API参考" title="API参考">
                    <Anchor.Link href="#Anchor" title="Anchor" />
                    <Anchor.Link href="#Anchor.Link" title="Anchor.Link" />
                </Anchor.Link>
            </Anchor>
        </div>
    );
};

尺寸

Anchor 设置 size 可以控制锚点的尺寸。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}
代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

滑轨主题

Anchor 设置 railTheme 可以控制滑轨的主题色。默认值为 primary。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}
代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}
代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

动态展示

Anchor 设置 autoCollapse 可以动态展示下一级锚点。默认值为 false。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}
代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

显示工具提示

Anchor 设置 showTooltip 可以在 Link 超出最大宽度时显示 Link 的文字内容。默认值为 false, 更多使用参考 API 说明。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

工具提示位置

Anchor 设置 position 可以设置Tooltip的显示位置。它仅在 showTooltip 为 true 时起作用。

代码
import { Anchor } from '@fibrous/semi-ui-react';

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>
    );
}

自定义滚动位置

通过 scrollIntoViewOptions 可以调整点击锚点后目标元素在容器中的位置,类型为 scroll-into-view-if-needed 的 Options,支持 block、inline、scrollMode、boundary、skipOverflowHiddenElements。不传时 block 为 start,即目标元素滚动到容器顶部。

  • scrollMotion 决定滚动是否带动画(behavior),targetOffset 在 block 计算出的位置上再向上偏移,两者与 scrollIntoViewOptions 同时传入时依然生效。
  • 只会滚动离目标最近的、可纵向滚动的容器;仅当传入 inline 时才同时调整横向位置。
点击链接后,章节 1 会滚动到容器中间
点击链接后,章节 2 会滚动到容器中间
点击链接后,章节 3 会滚动到容器中间
代码
import { Anchor } from '@fibrous/semi-ui-react';

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

API 参考

Anchor

Props

属性说明类型默认值
aria-label根导航元素的可访问名称,未设置时使用语言包中的文案。React.AriaAttributes['aria-label']-
autoCollapse是否动态展示下一级锚点:只展开当前高亮链接所在的分支。booleanfalse
childrenAnchor.Link 元素,嵌套的 Anchor.Link 表示下一级锚点。React.ReactNode-
className根导航元素的类名。string""
defaultAnchor挂载后默认高亮并滚动到该锚点,不触发 onChange 与 onClick。string""
getContainer指定滚动的容器;返回 null 时回落到 window。Type() => HTMLElement | Window | nullType() => window
maxHeight组件的 max-height,超出时显示滚动条。该属性覆盖 style 中的 max-height。string | number"750px"
maxWidth组件的 max-width,超出时显示省略。该属性覆盖 style 中的 max-width。string | number"200px"
offsetTop滚动内容距离容器顶部达到指定偏移量时触发当前链接切换。number0
onChange高亮的锚点改变时调用,参数为当前锚点与上一个锚点。Type(currentLink: string, previousLink: string) => void-
onClick点击锚点或在锚点上按 Enter 时调用,参数为原生 MouseEvent 或 KeyboardEvent 与当前锚点。Type(e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, currentLink: string) => void-
positionshowTooltip 开启时 Tooltip 的显示位置,可选值同 Tooltip 的 position。Position-
railTheme滑轨主题,可选 primary、tertiary、muted。'primary' | 'tertiary' | 'muted'"primary"
ref根导航元素(role="navigation")的引用。TypeReact.Ref<HTMLDivElement>-
scrollIntoViewOptions点击锚点滚动时传给 scroll-into-view-if-needed 的选项,与 scrollMotion、targetOffset 合并使用;未传 block 时为 start,仅传入 inline 时才同时调整横向位置。ScrollIntoViewOptions-
scrollMotion点击锚点滚动时是否带动画(behavior 为 smooth)。booleanfalse
showTooltip文字缩略时是否显示浮层及相关配置:type 为浮层组件,支持 tooltip(默认)和 popover,opts 为传给浮层组件的属性。boolean | ShowTooltipfalse
size锚点尺寸,可选 small、default。'small' | 'default'"default"
style根导航元素的样式。React.CSSProperties-
targetOffset锚点滚动结束时,目标距离容器顶部的偏移量。number0

id、data-* 等其他原生属性落在根导航元素(role="navigation")上;onChange 与 onClick 是锚点的回调,不绑定到根元素。

Props

属性说明类型默认值
children下一级的 Anchor.Link,仅在链接展开时渲染。React.ReactNode-
className链接项的类名,落在最外层的 div 上。string-
disabled是否禁用,禁用后不响应点击跳转。booleanfalse
href跳转的目标,以 # 开头时按元素 id 查找,其余按 CSS 选择器查找。string"#"
ref链接项(role="listitem")最外层 div 的引用。TypeReact.Ref<HTMLDivElement>-
style链接项的样式,落在最外层的 div 上。React.CSSProperties-
title链接的文字内容,可以是节点;未开启 showTooltip 且为非空字符串时同时作为原生 title。React.ReactNode""

id、data-* 等其他原生属性落在链接最外层的 div(role="listitem")上。

文案规范

  • 按句子大小写书写
  • 保持简洁,避免换行

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$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. 为何我的 Link 没有高亮和滑动跟随?
    检查下点击锚点是否可以滚动到指定位置:
    • 不可以,说明 href 有问题,检查文档中是否存在该 id;
    • 可以,可能是滚动容器设置不正确,确保文档内容被包裹在滚动容器内。滚动容器默认为 window,如果你的容器是 .my-container 的 div,则应该将滚动容器设置为该 div。
import React from 'react';
import { Anchor } from '@fibrous/semi-ui-react';

function() {
    // 此容器不是 Anchor 组件的容器,是文档内容的容器,因为要根据文档容器去计算当前是哪个 id 在容器上方
    const getContainer = () => {
        return document.querySelector('.my-container');
    }
    return (
        <Anchor
            /* 其他属性 */
            getContainer={getContainer}
            >
            /* Links */
        </Anchor>
    )
}