bklit-playground
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBklit Playground Skill
Bklit Playground Skill
Monorepo contributors only. Use this skill automatically whenever the user is building a new chart, editing an existing chart, tuning chart props, or debugging animation — before shipping via bklit-ship.
仅面向Monorepo贡献者使用。 当用户构建新图表、编辑现有图表、调整图表属性或调试动画时,自动使用此技能——在通过bklit-ship发布之前使用。
When to use (auto-trigger)
使用时机(自动触发)
Apply this skill when the user:
- Asks to build, prototype, or edit a chart
- Adds or changes chart props, settings, data, styling, or animation
- Mentions the playground, local chart preview, or
/playground - Is iterating on a chart before it lives in
packages/ui
Do not wait for the user to name this skill — scaffold or update the playground as part of the chart work.
当用户出现以下操作时应用此技能:
- 请求构建、制作原型或编辑图表
- 添加或修改图表属性、设置、数据、样式或动画
- 提及沙箱(playground)、本地图表预览或路径
/playground - 在将图表移入之前进行迭代开发
packages/ui
无需等待用户指定此技能——在处理图表相关工作时直接搭建或更新沙箱。
How agents discover this (route is gitignored)
代理如何发现此技能(路径已被git忽略)
The playground page is not in git — only the skill, template, and shared components are. Agents find the workflow via:
- (repo root) — chart work → read this skill, copy template →
AGENTS.mdpage.tsx - — same copy command and pointers (committed)
apps/web/app/playground/README.md - This skill — (committed; auto-trigger description)
.agents/skills/bklit-playground/SKILL.md - Template — (committed source of truth)
.agents/skills/bklit-playground/templates/page.tsx - Shared UI — ,
apps/web/components/editor/(committed)apps/web/components/playground/
If is missing, create it by copying the template. Do not invent a new layout.
apps/web/app/playground/page.tsx沙箱页面不在git仓库中——仅技能、模板和共享组件会被提交。代理可通过以下途径找到该工作流:
- (仓库根目录)——图表开发工作 → 阅读此技能,复制模板 →
AGENTS.mdpage.tsx - ——包含相同的复制命令和指引(已提交)
apps/web/app/playground/README.md - 此技能文档——(已提交;自动触发说明)
.agents/skills/bklit-playground/SKILL.md - 模板文件——(已提交的基准文件)
.agents/skills/bklit-playground/templates/page.tsx - 共享UI组件——、
apps/web/components/editor/(已提交)apps/web/components/playground/
如果不存在,通过复制模板创建。请勿自行设计新布局。
apps/web/app/playground/page.tsxDefault playground layout
默认沙箱布局
The playground is a full-height editor shell (not a docs page with a header):
| Region | Purpose |
|---|---|
| Left pane | Animation / motion controls only |
| Center | Dot-grid canvas, rulers, resizable chart frame, bottom menu bar |
| Right pane | Chart props, data, styling, and settings controls |
Mobile: side panes collapse to sheet triggers (top-left = motion, top-right = controls). Fixed viewport, 4:3 chart frame, pinch-to-zoom enabled.
沙箱是一个全屏高度的编辑器外壳(而非带页眉的文档页面):
| 区域 | 用途 |
|---|---|
| 左侧面板 | 仅用于动画/动效控制 |
| 中间区域 | 点阵网格画布、标尺、可调整大小的图表框架、底部菜单栏 |
| 右侧面板 | 图表属性、数据、样式和设置控制 |
移动端: 侧边面板会折叠为触发按钮(左上角=动效,右上角=控制)。固定视口,图表框架为4:3比例,支持捏合缩放。
Default empty state
默认空状态
When first scaffolded, the playground has:
- Empty left pane — placeholder until the chart uses motion
- Empty right pane — placeholder until controls are wired
- Empty chart frame — alert:
PlaygroundEmptyState
Use the playground skill to start building a new chart, or ask it to edit an existing chart. Your agent will automatically add the necessary controls.
Copy the template verbatim for new playgrounds:
.agents/skills/bklit-playground/templates/page.tsx
→ apps/web/app/playground/page.tsxVisit while is running.
http://localhost:3000/playgroundpnpm dev首次搭建时,沙箱包含:
- 空左侧面板——占位符,直到图表使用动效
- 空右侧面板——占位符,直到控件被关联
- 空图表框架——提示:
PlaygroundEmptyState
使用沙箱技能开始构建新图表,或请求编辑现有图表。你的代理会自动添加必要的控件。
新建沙箱时请完全复制模板内容:
.agents/skills/bklit-playground/templates/page.tsx
→ apps/web/app/playground/page.tsx在运行时访问。
pnpm devhttp://localhost:3000/playgroundControl wiring rules
控件关联规则
As you add chart functionality, automatically wire controls — do not leave panes empty once the chart uses those settings.
添加图表功能时,自动关联控件——一旦图表使用了相关设置,请勿让面板保持为空。
Right pane — chart props & settings
右侧面板——图表属性与设置
Pass to . Each group maps keys to sidebar controls.
controlGroupsEditorShellStudioUrlState- Prefer existing groups from :
apps/web/lib/studio/registry-control-groups.ts- ,
lineChartControlGroups,barChartControlGroups, etc.gaugeControlGroups
- Add new controls when introducing props:
- Extend the chart's group in , or
registry-control-groups.ts - Define inline groups with helpers from (
apps/web/lib/studio/sidebar-control-templates.ts,controlGroup,dataGroup,lineGroup, …)designGroup
- Extend the chart's group in
- Wire state with or chart-specific hooks built on top of it.
usePlaygroundState({ chart: "your-chart", … })
tsx
import { lineChartControlGroups } from "@/lib/studio/registry-control-groups";
<EditorShell
controlGroups={lineChartControlGroups}
showMotionControls={false} // see left pane rules
chartState={chartState}
…
/>Rule: every new tunable prop the user adds → add a matching control to the right pane (same as ).
keyStudioUrlState将传入。每个组将键映射到侧边栏控件。
controlGroupsEditorShellStudioUrlState- 优先使用现有组,来自:
apps/web/lib/studio/registry-control-groups.ts- 、
lineChartControlGroups、barChartControlGroups等gaugeControlGroups
- 添加新控件以适配新增属性:
- 在中扩展对应图表的组,或
registry-control-groups.ts - 使用中的辅助函数定义内联组(
apps/web/lib/studio/sidebar-control-templates.ts、controlGroup、dataGroup、lineGroup等)designGroup
- 在
- 关联状态使用或基于它构建的图表专属钩子。
usePlaygroundState({ chart: "your-chart", … })
tsx
import { lineChartControlGroups } from "@/lib/studio/registry-control-groups";
<EditorShell
controlGroups={lineChartControlGroups}
showMotionControls={false} // 参考左侧面板规则
chartState={chartState}
…
/>规则: 用户添加的每个可调整新属性 → 需在右侧面板添加匹配的控件(与使用相同的)。
StudioUrlStatekeyLeft pane — animation only
左侧面板——仅用于动画
Set when the chart uses enter/reveal/motion (CSS reveal, Motion, spring/ease).
showMotionControls={true}The left pane renders (duration, ease/spring, curve editor, presets). Do not put data or styling controls here.
MotionControltsx
<EditorShell
showMotionControls
controlGroups={lineChartControlGroups}
chartState={chartState}
…
/>Wire motion into the chart with helpers from and pass from to remount/replay.
apps/web/lib/studio/motion-config.tsreplayKeyuseReplayKey()Rule: animation-related settings → left pane only. Everything else → right pane.
当图表使用入场/展示/动效(CSS展示、Motion、弹簧/缓动)时,设置。
showMotionControls={true}左侧面板渲染(时长、缓动/弹簧、曲线编辑器、预设)。请勿在此放置数据或样式控件。
MotionControltsx
<EditorShell
showMotionControls
controlGroups={lineChartControlGroups}
chartState={chartState}
…
/>使用中的辅助函数将动效关联到图表,并传递返回的以重新挂载/重播动效。
apps/web/lib/studio/motion-config.tsuseReplayKey()replayKey规则: 动画相关设置 → 仅放在左侧面板。其他所有设置 → 放在右侧面板。
Scaffold checklist
搭建检查清单
When starting or resetting a playground:
- Copy template → (gitignored)
apps/web/app/playground/page.tsx - +
EditorShell+EditorChartFrame+usePlaygroundStateuseReplayKey - and
controlGroups={[]}until chart is wiredshowMotionControls={false} - inside the chart frame until a chart component renders
PlaygroundEmptyState
When wiring a chart:
- Replace with the chart component
PlaygroundEmptyState - Set to the matching registry groups (+ new groups for new props)
controlGroups - Set if the chart animates
showMotionControls={true} - Pass /
chartState.displayStateinto the chartchartState.state - Pass and wire
replayKeyfromonReplayuseReplayKey() - Colocate prototype components under until shipping
apps/web/components/playground/
启动或重置沙箱时:
- 复制模板 → (已被git忽略)
apps/web/app/playground/page.tsx - 包含+
EditorShell+EditorChartFrame+usePlaygroundStateuseReplayKey - 初始设置和
controlGroups={[]},直到图表完成关联showMotionControls={false} - 在图表框架内使用,直到渲染出图表组件
PlaygroundEmptyState
关联图表时:
- 用图表组件替换
PlaygroundEmptyState - 将设置为匹配的注册组(+为新属性添加新组)
controlGroups - 如果图表包含动画,设置
showMotionControls={true} - 将/
chartState.displayState传入图表组件chartState.state - 传递并关联
replayKey的useReplayKey()onReplay - 将原型组件放在下,直到发布
apps/web/components/playground/
Committed building blocks
已提交的构建模块
Do not rebuild these — import from committed paths:
| Export | Path | Purpose |
|---|---|---|
| | Full editor layout |
| | Resizable chart container |
| | Default empty chart message |
| | Local studio-like state |
| | |
| | Reference line chart wiring |
| | Example right-pane groups |
Legacy components (, , ) are superseded by the editor shell — do not use them in new playgrounds.
PlaygroundShellPlaygroundToolbarResizablePreview请勿重新构建这些模块——从已提交的路径导入:
| 导出内容 | 路径 | 用途 |
|---|---|---|
| | 完整编辑器布局 |
| | 可调整大小的图表容器 |
| | 默认空图表提示 |
| | 类本地工作室状态 |
| | |
| | 参考折线图关联示例 |
| | 右侧面板组示例 |
旧版组件(、、)已被编辑器外壳取代——请勿在新沙箱中使用。
PlaygroundShellPlaygroundToolbarResizablePreviewExample: line chart playground
示例:折线图沙箱
tsx
"use client";
import { useState } from "react";
import { EditorChartFrame } from "@/components/editor/editor-chart-frame";
import { EditorShell } from "@/components/editor/editor-shell";
import type { ViewportPreset } from "@/components/editor/viewport-presets";
import { resolveViewportSize } from "@/components/editor/viewport-presets";
import { PlaygroundLineChart } from "@/components/playground/playground-line-chart";
import { usePlaygroundLineChartState } from "@/components/playground/use-playground-line-chart-state";
import { useReplayKey } from "@/components/playground/use-replay-key";
import { lineChartControlGroups } from "@/lib/studio/registry-control-groups";
export default function PlaygroundPage() {
const chartState = usePlaygroundLineChartState();
const [replayKey, replay] = useReplayKey();
const [viewport, setViewport] = useState<ViewportPreset | null>("desktop");
const [size, setSize] = useState(() =>
resolveViewportSize("desktop", 960)
);
return (
<EditorShell
chartState={chartState}
controlGroups={lineChartControlGroups}
onReplay={replay}
onSizeChange={(width, height) => setSize({ width, height })}
onViewportChange={setViewport}
showMotionControls
size={size}
viewport={viewport}
>
{({ size: frameSize, boundsRef, onResize, mobileViewport }) => (
<EditorChartFrame
boundsRef={boundsRef}
height={frameSize.height}
onResize={onResize}
resizable={!mobileViewport}
width={frameSize.width}
>
<PlaygroundLineChart
committedState={chartState.state}
motionCurveDragging={chartState.motionCurveDragging}
replayKey={replayKey}
state={chartState.displayState}
/>
</EditorChartFrame>
)}
</EditorShell>
);
}tsx
"use client";
import { useState } from "react";
import { EditorChartFrame } from "@/components/editor/editor-chart-frame";
import { EditorShell } from "@/components/editor/editor-shell";
import type { ViewportPreset } from "@/components/editor/viewport-presets";
import { resolveViewportSize } from "@/components/editor/viewport-presets";
import { PlaygroundLineChart } from "@/components/playground/playground-line-chart";
import { usePlaygroundLineChartState } from "@/components/playground/use-playground-line-chart-state";
import { useReplayKey } from "@/components/playground/use-replay-key";
import { lineChartControlGroups } from "@/lib/studio/registry-control-groups";
export default function PlaygroundPage() {
const chartState = usePlaygroundLineChartState();
const [replayKey, replay] = useReplayKey();
const [viewport, setViewport] = useState<ViewportPreset | null>("desktop");
const [size, setSize] = useState(() =>
resolveViewportSize("desktop", 960)
);
return (
<EditorShell
chartState={chartState}
controlGroups={lineChartControlGroups}
onReplay={replay}
onSizeChange={(width, height) => setSize({ width, height })}
onViewportChange={setViewport}
showMotionControls
size={size}
viewport={viewport}
>
{({ size: frameSize, boundsRef, onResize, mobileViewport }) => (
<EditorChartFrame
boundsRef={boundsRef}
height={frameSize.height}
onResize={onResize}
resizable={!mobileViewport}
width={frameSize.width}
>
<PlaygroundLineChart
committedState={chartState.state}
motionCurveDragging={chartState.motionCurveDragging}
replayKey={replayKey}
state={chartState.displayState}
/>
</EditorChartFrame>
)}
</EditorShell>
);
}Adding a new prop (agent workflow)
添加新属性(代理工作流)
When the user adds a chart prop like or :
strokeWidthshowMarkers- Add the key to /
StudioUrlStateif missing (defaultStudioState)apps/web/lib/studio/studio-parsers.ts - Add a control to the chart's group in (right pane)
registry-control-groups.ts - Wire the prop from into the chart component
chartState.displayState - If the prop affects animation timing/easing/reveal → ensure is on and use motion helpers
showMotionControls
When the user adds animation behavior:
- Set on
showMotionControls={true}EditorShell - Wire /
getStudioCssRevealProps/studioMotionToTransitionas appropriatemotionSignature - Keep data/styling controls on the right pane
当用户添加或等图表属性时:
strokeWidthshowMarkers- 如果缺失,将键添加到/
StudioUrlState中(defaultStudioState)apps/web/lib/studio/studio-parsers.ts - 在中对应图表的组里添加控件(右侧面板)
registry-control-groups.ts - 将属性从关联到图表组件
chartState.displayState - 如果属性影响动画时长/缓动/展示 → 确保已开启,并使用动效辅助函数
showMotionControls
当用户添加动画行为时:
- 在上设置
EditorShellshowMotionControls={true} - 按需关联/
getStudioCssRevealProps/studioMotionToTransitionmotionSignature - 将数据/样式控件保留在右侧面板
Ship when ready
准备就绪后发布
When the API is stable, follow to move the chart into , add docs, gallery examples, and registry entries.
.agents/skills/bklit-ship/SKILL.mdpackages/ui当API稳定后,按照中的指引将图表移入,添加文档、画廊示例和注册条目。
.agents/skills/bklit-ship/SKILL.mdpackages/uiFile reference
文件参考
| Item | Path |
|---|---|
| Playground route (gitignored) | |
| Template | |
| Editor components | |
| Playground helpers | |
| Control group registry | |
| Control templates | |
| Ship checklist | |
| Gitignore entry | |
| 项目 | 路径 |
|---|---|
| 沙箱路由(已被git忽略) | |
| 模板 | |
| 编辑器组件 | |
| 沙箱辅助工具 | |
| 控件组注册 | |
| 控件模板 | |
| 发布检查清单 | |
| Git忽略条目 | |