agentleFS
shika-worksshika-works/pixelium-design/.claude/skills/write-component-docs/SKILL.md

write-component-docs

Skill255 starsChanged 43 days agoMITView on GitHub

Write bilingual (zh + en) documentation for any Vue component in the pixelium-design monorepo, following the project's VitePress doc template system. Use when asked to write or update docs for a component (e.g. "为 xxx 写文档", "write docs for xxx", "参照其他组件写文档"), or to add an example preview / API block / sidebar entry for a component.

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. digital-go-jp/design-system-example-components-react★ 685same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 4 are distinctive, and 15 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 15

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read <component>/type.ts — the exported type names are what matter:

    line 21
  2. Very specific:

    Read every prop/event/slot's JSDoc to write accurate descriptions.

    line 23
  3. Very specific:

    Read <component>/index.vue to understand behavior and caveats (e.g.

    line 24
  4. Very specific:

    Check sibling sub-components (e.g.

    line 25
  5. Very specific:

    Place one preview after each usage section.

    line 60
  6. Very specific:

    Add ## API (NOT wrapped in language blocks) then:

    line 64
  7. Very specific:

    Every .md file in packages/document/slice/ is a reusable fragment (currently: percent, rest-attrs, emit-event, option, option-list, …

    line 97
  8. Distinctive:

    EVERY type that shows up in the rendered tables must be presented in full on the same page - a name alone is not enough.

    line 117
  9. Very specific:

    Use the canonical Chinese component name from share.ts additionMapZh (e.g.

    line 125
  10. Distinctive:

    Use accurate component terminology for the concept (e.g.

    line 129
  11. Very specific:

    When describing component-exposed methods/props in prose, simply say the component "暴露 X 方法 / exposes X methods" — do NOT mention ref (e.g.

    line 130
  12. Very specific:

    Create one *.vue per usage section, referenced by <preview path="./xxx.vue"></preview>.

    line 134
  13. Distinctive:

    Icons: import from the icon package, do NOT hand-write glyphs:

    line 140
  14. Very specific:

    Fixed colors: use fixed hex colors, not CSS variables like var(--px-color-warning) (those don't exist).

    line 148
  15. Very specific:

    When possible reuse sibling layouts — px-space wraps multiple items.

    line 152
  16. Very specific:

    Add the component's kebab name to newItems to show the NEW!

    line 158
  17. Very specific:

    Add <component>: '<中文名>' to additionMapZh (e.g.

    line 159
  18. Very specific:

    Run npm run build inside packages/document/ (runs gen-doc.mts) to regenerate zh//en/ and confirm the md/API/slice blocks resolve without …

    line 166
  19. Distinctive:

    If the user previously declined a build, don't rerun it — just report that the generated folders hold stale content until a build runs.

    line 167

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Write Pixelium Component Docs

This skill explains how to write documentation for any Vue component in the pixelium-design monorepo. It is distilled from the completed timeline doc work plus the patterns found across all existing component docs (button, tab, input, table, card, menu, dialog, drawer, etc.). Follow it to avoid the corrections the user repeatedly made during review.

1. System architecture (understand before editing)

  • Component source: packages/web-vue/lib/<component>/ — each component folder has type.ts (JSDoc-annotated prop/event/slot types), index.vue, index.less, and test/.
  • Doc template source (EDIT THESE): packages/document/template/ — *.md files plus example *.vue preview files, grouped in category folders: common/, data-input/, data-display/, layout/, navigation/, feedback/, base/, config/, fabulous-idea/, guide/.
  • Reusable doc fragments: packages/document/slice/ — every .md file in this folder is a reusable fragment referenced by [[[slice ...]]] blocks (e.g. percent.md, rest-attrs.md, emit-event.md, option.md, date-format.md, value-with-device-width.md).
  • Generated output (DO NOT hand-edit): packages/document/zh/ and packages/document/en/ — regenerated by the build script.
  • Build script: packages/document/script/gen-doc.mts; API resolver: packages/document/script/resolve-api.mts.
  • Sidebar: auto-generated at runtime by packages/document/.vitepress/dfs-4-md.ts. To register a NEW! badge or Chinese/English nav titles, edit packages/document/.vitepress/share.ts. Do NOT hand-edit sidebar files.

2. Step 1 — Read the component source

  1. Read <component>/type.ts — the exported type names are what matter:
    • ${CompName}Props, ${CompName}Events, ${CompName}Slots are auto-grouped by the resolver into 属性/类型/可选/默认值/描述/版本, 事件/参数/描述/版本, and 插槽/参数/描述/版本 tables.
    • Read every prop/event/slot's JSDoc to write accurate descriptions.
  2. Read <component>/index.vue to understand behavior and caveats (e.g. for timeline, the last item renders no connector line — never demonstrate line-variant on the last item).
  3. Check sibling sub-components (e.g. timeline-item, tab-panel, collapse-item, grid-item) — each needs its own [[[api <name> ...]]] block.
  4. Determine the category folder by comparing with existing components (button→common, tab→navigation, timeline→data-display, input→data-input, dialog→feedback, ...).
  5. Confirm the registered component names from the lib entry (px- kebab-case in templates, e.g. px-timeline, px-timeline-item; PascalCase Timeline in prose).

3. Step 2 — Write the .md file

Create packages/document/template/<category>/<component>.md.

Language blocks

Wrap every prose section in language blocks:

[[[zh

## 标题

中文说明
]]]
[[[en

## English Heading

English explanation
]]]

The doc starts with an H1 in each language block (# Timeline), then a one-line description.

Preview blocks

<preview path="./xxx.vue"></preview>

Place one preview after each usage section. The referenced .vue file lives in the same template folder.

API blocks

Add ## API (NOT wrapped in language blocks) then:

## API

[[[api zh
propName: Description.
events.eventName: Description.
slots.slotName: Description.
exposeName.method: Description.]]]
[[[api en
propName: Description.
events.eventName: Description.
slots.slotName: Description.
exposeName.method: Description.]]]
  • [[[api <lang>]] with no component name resolves from the file basename (kebab-case) to ../web-vue/lib/<basename>/type.ts.
  • [[[api <sub-component> <lang>]] (e.g. [[[api timeline-item zh]]) resolves ../web-vue/lib/timeline-item/type.ts. The sub-component name is kebab-case.
  • Description keys (how the resolver matches them to table rows):
    • Props: the plain prop name (direction), or optionally CompName.prop. Unmatched props render with an empty description cell.
    • Events: events.<event> (e.g. events.update:modelValue).
    • Slots: slots.<slot> (e.g. slots.default, slots.icon).
    • Expose methods: plain key like inputExpose.focus (no events./slots. prefix).
  • List events/slots on their own lines; blank lines inside a block are fine (they're skipped).
  • The build merges these descriptions with the JSDoc types/defaults from type.ts into the final tables. You do NOT write types/defaults yourself.

Slice blocks

[[[slice <name>]]]

Every .md file in packages/document/slice/ is a reusable fragment (currently: percent, rest-attrs, emit-event, option, option-list, group-option, date-format, quick-access-option, value-with-device-width). The script reads ./slice/<name>.md. Prefer these over rewriting common explanations; if a shared concept is missing, add a new .md file there instead of inlining it.

Prose rules (user-mandated)

  • Describe the COMPONENT only. Do NOT describe the examples themselves - no commentary about the sample data or how a demo is built (e.g. "the files below carry an url only, without a file"). The code panel already shows it, and it does not change how the component is used.
  • Example .vue files carry no explanatory text either: no hint / caption / status paragraphs, and no scoped styles that exist only to style them. The prose block above the <preview> is the place for explanation.

API description rules (user-mandated)

  • Descriptions describe ONLY the meaning of the property/event/slot — NO types, NO default values, NO code-related details.
  • Refer to the component with its own PascalCase name (Timeline, TimelineItem) when the word means the component — never lowercase, never the Chinese name — in BOTH zh and en blocks.
  • zh example: direction: Timeline 的排列方向。
  • en example: direction: The arrangement direction of Timeline.
  • Slot wording example: slots.icon: TimelineItem 节点处的图标。 / slots.icon: The icon at the node of TimelineItem.
  • Optional parameters that change the scope of a call MUST be spelled out: when omitting a parameter makes the call act on every matching item (e.g. submit(fileId?), retry(fileId?), abort(id?), and the same methods in the file-list slot scope), the description must say so - e.g. "handling every pending file when none is given". The signature alone does not explain what the call acts on.
  • The same applies to optional parameters of events, props and slot scope methods.

Type definition rules (user-mandated)

  • EVERY type that shows up in the rendered tables must be presented in full on the same page - a name alone is not enough.
  • Shared types that already have a slice: include the slice ([[[slice emit-event]]] for EmitEvent, [[[slice rest-attrs]]] for RestAttrs). When a shared type appears and no slice exists, add one under packages/document/slice/.
  • Types owned by the component (e.g. UploadData, UploadHeaders, UploadPatch, UploadCustomRequestOptions, CustomRequest, CustomDownload, CreateThumbnailUrl, FileInfo): add a ### <TypeName> section holding a ts block copied verbatim from <component>/type.ts, ordered as the types are first referenced.
  • A type owned by ANOTHER component (e.g. ButtonProps, ButtonEvents) is only referenced - its definition belongs to that component's page.
  • Inline function/object shapes that a table already spells out need no extra section.

Terminology rules (user-mandated)

  • Use the canonical Chinese component name from share.ts additionMapZh (e.g. "时间线", NOT "时间轴"). Verify, don't assume.
  • In Chinese prose, refer to components by PascalCase component names (Timeline, TimelineItem), not Chinese translations like 时间线/时间线项.
  • In English prose, also use PascalCase (Timeline, TimelineItem) where the word refers to the component.
  • Prop names in prose: backticked camelCase (theme, lineVariant, contentPlacement); in Vue templates use kebab-case (line-variant, content-placement, default-active).
  • Use accurate component terminology for the concept (e.g. "自定义节点" not "自定义圆点").
  • When describing component-exposed methods/props in prose, simply say the component "暴露 X 方法 / exposes X methods" — do NOT mention ref (e.g. do NOT write "通过 ref 暴露", "exposes ... via ref"). The docs describe the component's API, not how it is accessed in a template.

4. Step 3 — Write example preview .vue files

Create one *.vue per usage section, referenced by <preview path="./xxx.vue"></preview>.

Required conventions (each is a user-mandated fix)

  1. No Chinese in code — all strings, comments, and values in .vue files must be English.
  2. Use px- prefix and kebab-case props in templates: <px-button>, <px-tab :default-active="'1'">, <px-timeline-item line-variant="dashed">.
  3. Icons: import from the icon package, do NOT hand-write glyphs:
    <script setup lang="ts">
    import { IconHome, IconCog, IconEnvelope } from '@pixelium/web-vue/icon-hn/es'
    </script>
    <!-- <IconHome></IconHome> inside the relevant #icon slot -->
    (See tab-icon.vue for the reference pattern.)
  4. Fixed colors: use fixed hex colors, not CSS variables like var(--px-color-warning) (those don't exist). Examples seen in the codebase: #409EFF, #FAE13C, #E956AE, #909399, #0960bd, #00b42a, #d97706, #ff7875, #86909c.
  5. Vary theme across items when the component has a theme prop — don't leave everything default (primary, success, warning, info, danger, notice, sakura).
  6. Visual-caveat props (like line-variant on a last item that renders no line): never put them on the last item; demonstrate on a middle item followed by a solid one.
  7. Make the section's feature obvious (e.g. #icon slot shows <IconX>; #mark slot shows styled content).
  8. When possible reuse sibling layouts — px-space wraps multiple items; for grouped sections keep consistent visual density.

5. Step 4 — Register in share.ts

In packages/document/.vitepress/share.ts:

  • Add the component's kebab name to newItems to show the NEW! badge (same format as existing entries, e.g. 'timeline'). Every newly added component MUST be put in the newItems list — this is a required step, not optional.
  • Add <component>: '<中文名>' to additionMapZh (e.g. timeline: '时间线'). Add an English title to additionMapEn/titleMapEn only if the auto-derived title is wrong.
  • order controls the display order of top-level categories (folder names, e.g. common, data-input, data-display, ...) and guideOrder controls the order of the guide sub-pages — only touch them when adding a brand-new category/guide page. Adding a component does NOT require editing them: within a category, component pages are simply ordered by the filesystem listing (alphabetical).

The sidebar itself is auto-generated — do NOT hand-edit it.

6. Step 5 — Verify the build

  • Run npm run build inside packages/document/ (runs gen-doc.mts) to regenerate zh//en/ and confirm the md/API/slice blocks resolve without errors.
  • If the user previously declined a build, don't rerun it — just report that the generated folders hold stale content until a build runs.
  • Note: the full VitePress build may fail on a PRE-EXISTING unrelated dependency issue (parsnip-kit missing wait export). Don't chase it; it's not caused by doc edits.

7. Final self-check before presenting

  • File is in the correct category folder under template/.
  • Prose wrapped in [[[zh ...]]] / [[[en ...]]]; ## API is NOT wrapped.
  • Every component reference is PascalCase in BOTH zh and en prose and API descriptions.
  • API descriptions contain no types/defaults/code.
  • Prose describes the component only; no commentary about an example's own data or implementation, and no hint/caption text inside the example .vue files.
  • All props/events/slots from type.ts have matching descriptions; sub-components each have their own [[[api ...]]] block.
  • Shared concepts use [[[slice ...]]] where applicable.
  • Every type name that appears in the tables is presented in full - a slice or a ### <TypeName> section with the verbatim ts definition; no bare type name is left undefined.
  • Optional parameters that change the scope of a call (e.g. "handling every pending file when none is given") are explained in the descriptions.
  • Example .vue files: English only, px- prefix, kebab-case props, Icon imports, fixed hex colors, varied themes, mark + footer present, no last-item line-variant.
  • share.ts updated (badge + zh title); canonical Chinese name used (e.g. 时间线).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.