• 简体中文
  • 末尾标记

    suffix 在当前可见内容的末尾追加一个小标记。可以选择终端风格的方块光标,或柔和呼吸的圆点。标记跟随文字,适用于段落、列表、行内格式、表格和代码块。

    跟随当前内容的末尾

    播放完成后保留标记,便于查看位置。实际应用中,将 streaming 设为 false 即可移除。

    切换内容类型,可以查看不同结尾的表现;暂停或重播,可以观察标记的位置;选择自定义类型,可以体验 renderer 的扩展方式。演示播放完成后仍保留标记,方便检查间距。

    使用方式

    选择对应框架查看代码。Core 示例中的 mappers 传入 Core 输入,并显式启用 mapper;组件通过 streaming.effect 启用相同效果,并内置视觉渲染器。

    import type { MapperPluggable } from '@fluxdown/core';
    import { Smooth } from '@fluxdown/core-plugins/plugins/mapper/smooth';
    import { Suffix } from '@fluxdown/core-plugins/plugins/mapper/suffix';
    
    const mappers: MapperPluggable[] = [
      [Smooth, { enabled: true }],
      [Suffix, { enabled: true, type: 'cursor' }],
    ];

    将 type 设为 'dot' 即可使用圆点。effect: 'suffix' 默认使用方块光标。两种形状都继承当前文字颜色,随文字缩放,呼吸动画遵循系统的 prefers-reduced-motion 设置。

    只要 effect 启用,标记就会保持显示。响应完成后,将 streaming 设为 false;如果需要继续保留其他流式行为,也可以只把 suffix 的 enabled 设为 false:

    import type { MapperPluggable } from '@fluxdown/core';
    import { Smooth } from '@fluxdown/core-plugins/plugins/mapper/smooth';
    import { Suffix } from '@fluxdown/core-plugins/plugins/mapper/suffix';
    import { MutableState, toClosure } from 'stative';
    
    const isStreaming = MutableState.of(true);
    const active = toClosure(isStreaming);
    
    const mappers: MapperPluggable[] = [
      [Smooth, { enabled: true }],
      [Suffix, { enabled: active, type: 'dot' }],
    ];

    将标记和入场效果一起使用:

    import type { MapperPluggable } from '@fluxdown/core';
    import { Smooth } from '@fluxdown/core-plugins/plugins/mapper/smooth';
    import { Scale } from '@fluxdown/core-plugins/plugins/mapper/scale';
    import { Suffix } from '@fluxdown/core-plugins/plugins/mapper/suffix';
    
    const mappers: MapperPluggable[] = [
      [Smooth, { enabled: true }],
      [Scale, { enabled: true }],
      [Suffix, { enabled: true, type: 'dot' }],
    ];

    渲染自定义类型

    type 的类型是 'cursor' | 'dot' | (string & {})。所有值都会生成相同结构的 HAST 节点:一个 span,其 dataFluxdownSuffix 属性保存类型。默认 renderer 只识别 cursor 和 dot,遇到其他值直接返回 null。未知类型是提供给 renderer 的信息,不会作为文字显示。

    通过各框架的渲染插件显示一个笑脸。SuffixRenderer 复用内置标记的布局与呼吸动画;Vue 使用 h,Svelte 使用 createElement,Lynx 将 JSX 渲染函数放在插件类外:

    import type {
      ReactRenderMatchParams,
      ReactRenderParams,
    } from '@fluxdown/react-plugins/base';
    
    import {
      isSuffixNode,
      SUFFIX_DATA_ATTR,
    } from '@fluxdown/core-plugins/plugins/mapper/suffix';
    import { BaseReactRenderPlugin } from '@fluxdown/react-plugins/base';
    import { SuffixRenderer } from '@fluxdown/react-plugins/plugins/effect-suffix';
    import { Fluxdown } from 'fluxdown';
    
    class SmileRenderPlugin extends BaseReactRenderPlugin {
      static readonly key = 'render-smile';
    
      match({ node }: ReactRenderMatchParams) {
        return isSuffixNode(node) && node.properties[SUFFIX_DATA_ATTR] === 'smile';
      }
    
      render({ node }: ReactRenderParams) {
        if (!isSuffixNode(node) || node.properties[SUFFIX_DATA_ATTR] !== 'smile') {
          return null;
        }
    
        return <SuffixRenderer type="smile">🙂</SuffixRenderer>;
      }
    }
    
    type MessageProps = {
      text: string;
    };
    
    export function Message({ text }: MessageProps) {
      return (
        <Fluxdown
          plugins={{ renders: [SmileRenderPlugin] }}
          streaming={{ effect: ['suffix', { type: 'smile' }] }}
          text={text}
        />
      );
    }

    相同优先级下,传入的 renderer 先于预设处理 smile,其他类型仍由预设处理。上面的演示使用了相同的插件与动画。

    Core 示例用 MutableState 保存接收状态;完成时调用 isStreaming.next(false),销毁 Core 后再调用 active.destroy() 和 isStreaming.destroy() 清理外部状态。

    代码块与 Core

    代码块中的标记跟在可见代码之后,与最后一个字符保持在同一行。代码末尾如果包含显式空行,标记会出现在该空行上。标记独立于代码内容,复制代码时不会被带入。自定义代码 slot 需要在高亮后的代码内容之后渲染 suffix 属性,才能保留这个行为。

    Core 的 Suffix mapper 将标记插入当前可见 HAST 的末尾,不增加文本长度,具体外观由 renderer 决定。

    Suffix mapper、SuffixConfig、SuffixType、SUFFIX_DATA_ATTR 和 isSuffixNode 从 @fluxdown/core-plugins/plugins/mapper/suffix 导出。

    配置

    以下字段属于 ['suffix', config] 中的 suffix 配置对象。

    enabled 可选

    类型: boolean

    默认值: true

    在当前可见内容的末尾显示标记。生成完成后可以单独禁用,也可以将 streaming 设为 false 关闭所有流式行为。

    type 可选

    类型: 'cursor' | 'dot' | (string & {})

    默认值: 'cursor'

    选择方块光标或圆点。所有类型都保存在相同的 HAST 标记节点上;默认 renderer 对未知类型返回 null。