@steppy /播放器
点燃的 <steppy-guide> 呈现交互式指南清单的Web组件
(guide.json),加上共享的光标动画器和应用程序内的游览覆盖
<steppy-tour-host> ( ./tour 条目)。框架不可知,完全离线,
没有CDN。
npm install @steppy/player
向导玩家是游戏包的主要入口;巡回覆盖是
@steppy/player/tour.
开发
npm run build-四个包:引导玩家ESM包 (dist/steppy-player.js),遗留游标IIFE (dist/steppy-cursor-legacy.js),视频渲染器IIFE (dist/steppy-video.js),以及旅游覆盖(dist/steppy-tour.js与 声明中dist/types/),再加上JSON模式。重新出售前三个 成src/steppy/_player_bundle/后改变src/(CI检查它们的字节 For字节并在释放时执行);旅游覆盖从来没有出售。npm run size:tour-巡回覆盖的大小预算(min + gzip)。npm run check:pack- publish-readiness:每个文件package.json点 (main,types,exports,typesVersions)在什么地方?npm pack将船, 什么也没有src/或者test/是多少。prepack构建包。指南项的声明和./tour来自tsc -p tsconfig.types.json(npm run build:types)。npm test-测试(架构,动画,定位,组件,模板, Python↔TS桥,共享的src/ui/模块,巡回覆盖)。npm run typecheck- - - - - -tsc --noEmit.- 开发利用:
dist/建立,然后打开dev/index.html.
演示模板
引擎(步进状态,光标动画,目标高亮显示,i18n,
导航(键盘、区域设置/布局切换)是一回事;步骤是怎样的?
提出了 是另一回事。表示是可切换的 模板 -其中之一
overlay (默认:全流预览+浮动标注固定在
目标), sidebar (左轨与垂直台阶时间线+电流
步骤的描述),或者 inline (细细的底部标题栏)。所有三个渲染
相同的引擎状态;只有镀铬不同。
这个 template 属性+解析顺序
template 是一个运行时可切换的、持久化的查看器设置:
<steppy-guide src="./guide.json" template="sidebar"></steppy-guide>
解析有效模板(优先级最高):
- 显式
template属性/属性, - 中的持久化选择
localStorage['steppy:active-template'], - 清单的顶层
defaultTemplate(每个指南的默认值), 'overlay'.
切换模板(通过内置分段控件或通过设置 属性)保留当前步骤、区域设置、布局和突出显示—它是 纯粹的引擎状态的重新渲染,从来没有重置。选择是持久的;一个 显式属性或切换器持续存在,初始解析不会。
每个指南默认值(defaultTemplate)
在构建配置中编写,而不是在组件中硬编码:
// steppy.guide.config.ts
defineGuideConfig({
defaultTemplate: 'sidebar', // project-wide default
guides: [
{ slug: 'onboarding', /* … */ template: 'inline' }, // per-guide override
],
});
steppy build 解决了 entry.template || config.defaultTemplate || 'overlay'
并将其作为清单发出 defaultTemplate;它也被设置为首字母
template 属性在生成的主机的 <steppy-guide>.
引擎→模板API契约
模板是类中的纯函数 src/templates/{overlay,sidebar,inline}.ts,
每一个出口 render(ctx: TemplateContext): TemplateResult 和一个 styles
CSSResult。组件(steppy-guide.ts)拥有所有的州,并建立了一个州
不可变的 TemplateContext (src/templates/types.ts)每次渲染:
steps: StepView[]-完整的有序列表,每个带有index、本地化title/description/subLabel,status(completed|current|upcoming), 和reachable(goTo门);currentIndex,total,durationLabel,guideTitle,locale,ui;waitingForInput,completed;- 导航回调(
onNext/onPrev/onRestart/onGoTo) +预计算prevDisabled/nextDisabled所以模板永远不会重新实现门; - 切换器数据+处理程序(
locales/layouts/templates,onLocaleChange/onLayoutChange/onTemplateChange); renderStage()-一个坦克返回现场舞台子树(截图+ 光标/涟漪/kbd +热点+错过吐司),共享逐字,所以refs和 处理程序始终绑定到组件。
要添加模板:添加一个模块,注册它 src/templates/index.ts
(TEMPLATES + ALL_TEMPLATES),并扩展 TEMPLATE_MODES 在
manifest/schema.ts ( .strict() 模式拒绝未知id)。
阶段重挂载不变量: 切换模板会交换整个顶层
模板,所以Lit重新创建 .steppy-stage 元素。 updated() 检测到
新的元素标识和调用 _reattachStage -重新指向 CursorAnimator
(通过 animator.setStage)及 ResizeObserver,然后重新计算热点
-不触碰步进状态,所以飞行中的动画在切换后仍然存在。
添加铬线
UI铬字符串生活在 src/i18n/ui-strings.ts:把钥匙加到
UiStrings 接口和到的值 每一个 语言环境中 DEFAULT_UI_STRINGS
(en, fr, nl, de). 使用 format(ui.key, vars) 用于 {placeholder}
插值。主机可以通过 uiStrings 财产。一个
区域区域设置回落到其基础语言(fr-BE 读取 fr),然后到
英语。 next 和 progress 来自 CHROME_STRINGS 在 src/ui/strings.ts,
与旅游覆盖共享。
设计令牌
温暖的调色板(奶油色的表面,近黑色的文字,锈橙色的口音,绿色
完成)和serif/sans/mono字体比例是CSS自定义属性
:host 在 src/templates/base-styles.ts (只有系统字体堆栈-没有web
字体)。覆盖任何 --steppy-* 变量从主机重新主题。动画
尊重 prefers-reduced-motion.
这个 sidebar 模板添加四个 布局 令牌(在
src/templates/sidebar.ts,不上 :host,因为他们对对方毫无意义
模板)。轨道帽碰到的所有东西都是一个标记,因为影子DOM
没有 part= 属性-不能使用默认值的主机没有其他属性
进入,找到它需要释放:
| 令牌 | 默认的 | 它是做什么的 |
|---|---|---|
--steppy-rail-width | 340px | 左轨宽度;剩下的行是预览 |
--steppy-rail-max-height | calc(100vh - 32px) | 铁帽;时间轴在里面滚动 |
--steppy-sidebar-offset | 16px | top 对于粘轨 |
--steppy-rail-max-height-narrow | 60vh | 轨顶一次塌陷成一柱(≤640px) |
嵌入式主机应该覆盖 --steppy-rail-max-height. 这个 100vh
默认假设玩家拥有视口,这对于静态来说是正确的
目标的 interactive.html 如果是Angular目标,则为false,其中主机的
自己的标题和导航位于组件的上方 calc(100vh - <chrome>) 是
正确的值,只有主机知道。
应用内导览覆盖(./tour)
import '@steppy/player/tour' 寄存器 <steppy-tour-host> (一次,甚至
当bundle的两个副本加载并导出其类型时,契约值
(TOUR_EVENTS, TOUR_PARTS, ADVANCE_KINDS,…)和验证器。用户
文档-主机API,事件,主题,CSP -是 docs/tours.md 在
库根。
代码布局:
src/ui/与引导玩家共享:设计令牌(tokens.ts,这templates/base-styles.ts插值-指南的样式表散列是固定的 由test/ui/guide-styles-stable.test.ts), chrome字符串和区域设置查找 (strings.ts),内联Markdown渲染器及其链接策略 (markdown.ts),placeTooltip(placement.ts)及产品名称 (names.ts). 它从不注册元素,也从不导入元素。src/tour/engine.ts是纯减速器:reduce(state, event)返回下一个 状态和要运行的效果。host.ts通过DOM解释效果 适配器,loader,resolver,triggers,tracker,layer,storage- - - - - - 和dom.ts是接缝测试交换(SteppyTourHost.dom幸福没有幸福 布局,没有弹出窗口API和一个requestAnimationFrame外部假计时器,所以test/tour/helpers.ts提供了一个带有可设置rects和手册的存根DOM 调度器。src/tour/validate.ts安全边界是:每个舱单和旅行文件 手工完整地验证(对于大小,没有zod)。它运行相同的金色外壳 作为Python制作人(contracts/fixtures/tours/cases.json)。- 几何图形仅通过CSSOM自定义属性编写-不
style=绑定 也没有styleMap所以覆盖层在严格的CSP下运行test/tour/boundaries.test.ts强制执行它和导入边界。 - 真实的浏览器行为(顶层,命中测试,焦点,键盘,远程加载)
中可选的Python套件涵盖了CORS和SRI)
tests/integration/test_tour_*_it.py反对fixtures/tour-demo/.
每个镀铬字符串的覆盖显示存在 en, fr, nl 和 de
(src/tour/strings.ts); 给这四个添加一个键。添加一个 语言 意味着
添加到 CHROME_STRING_LOCALES 在 src/tour/contract.ts 和
src/steppy/tour_spec.py (编译器警告 chrome-strings-missing 用于
每一个其他旅游语言)和检查 npm run size:tour。这层承载着
旅游文件 lang 和 dir (textDir 在 strings.ts),所以泡沫是
内部布局仅使用逻辑属性- test/tour/small-modules.test.ts
拒绝体检 margin-left/right。跑步游重新加载时,主持人
locale (其他 <html lang>)变化;看到 _swapLocale 在 host.ts。不像
引导玩家,覆盖暴露 part= 属性 ::part() 样式。
它的 --steppy-tour-* 令牌是一张表, TOUR_THEME_KEYS 在 theme.ts:
样式表,主机的 theme 财产和文件都跟着,而且
appearance="light"/"auto" 交换默认值(TOUR_LIGHT 在 ui/tokens.ts,
aa检查过了,就像黑暗的人一样)。在那里添加一个记号,永远不要作为文字 styles.ts.