Agent Skills › soybeanjs/soybean-ui › soybean-ui-develop

soybean-ui-develop

GitHub

SoybeanUI组件开发技能,规范Vue3+TS环境下无头与样式分离架构的组件创建、迁移、扩展及审计流程。

.agents/skills/soybean-ui-develop/SKILL.md soybeanjs/soybean-ui

Trigger Scenarios

新增或迁移SoybeanUI组件 组件标准化与代码审计 涉及packages/headless或packages/ui的代码修改

Install

npx skills add soybeanjs/soybean-ui --skill soybean-ui-develop -g -y
More Options

Non-standard path

npx skills add https://github.com/soybeanjs/soybean-ui/tree/main/.agents/skills/soybean-ui-develop -g -y

Use without installing

npx skills use soybeanjs/soybean-ui@soybean-ui-develop

指定 Agent (Claude Code)

npx skills add soybeanjs/soybean-ui --skill soybean-ui-develop -a claude-code -g -y

安装 repo 全部 skill

npx skills add soybeanjs/soybean-ui --all -g -y

预览 repo 内 skill

npx skills add soybeanjs/soybean-ui --list

SKILL.md

Frontmatter
{
    "name": "soybean-ui-develop",
    "description": "Builds, updates, and audits SoybeanUI components with headless\/UI split, delivery phases, and generation workflow. Invoke when adding, migrating, extending, standardizing, fixing, or auditing components, or when work touches packages\/headless\/src\/components, packages\/ui\/src\/components, apps\/docs\/src\/examples, apps\/docs\/src\/content, or packages\/ui\/test\/specs\/components."
}

SoybeanUI Component Development

This skill is the single, self-contained source of truth for SoybeanUI component work. It owns pattern classification, phase order, layer rules, delivery surfaces, generation workflow, and the finish-stage checklist. Load it for any task that creates, migrates, extends, standardizes, fixes, or audits a SoybeanUI component.

For detailed rules, see layers.md (headless admission, implementation layers), surfaces.md (delivery surfaces), e2e.md (browser e2e testing), process.md (finish checklist and commit convention), and audit.md (assessment methodology, seven check dimensions, and regression flows for already-shipped components). For request shapes that trigger this skill, see EXAMPLES.md. TypeScript functional style and Vue SFC structure are owned by the global typescript-functional-style and vue-sfc-structure skills — load them directly; this skill does not restate their content.

Repository context

  • Monorepo: pnpm workspaces (private root + 13 child workspaces: 10 packages + 2 apps + skills/)
  • Stack: Vue 3 + TypeScript (strict) + UnoCSS + @soybeanjs/cva
  • Architecture: headless / styled separation. Compile-time dependency is packages/ui -> packages/headless; headless never imports UI.
  • @soybeanjs/headless (packages/headless/): Logic, state, a11y, structure. Zero styles.
  • @soybeanjs/ui (packages/ui/): Styled wrappers. UnoCSS + cv() / scv(). S-prefixed components.
  • @soybeanjs/ui-docs (apps/docs/): ubean SSG (mode: 'ssg') with file routing, content collections, and built-in i18n (en + zh). NOT VitePress.

Quick start

  1. Classify the task before editing.
    • Headless admission: behavioral family, UI-only (refused), or compose an existing primitive. See layers.md -> Headless admission.
    • Component pattern: multi-slot base, compact aggregation, or single-class.
    • Scenario: new component, migration or normalization, standards alignment, or audit and evaluation.
    • Delivery scope: headless only, UI only, or full surface.
  2. Find concrete local references.
    • Inspect at least one neighboring same-pattern headless implementation and one UI implementation before editing.
    • For migration, preserve behavior, state, accessibility, slots, and public API before restructuring.
  3. Reuse existing building blocks first.
    • Prefer packages/headless/src/composables/, packages/headless/src/shared/, and packages/headless/src/types/.
    • Use @vueuse/core composables as-is; do not reimplement them in-repo. Date math goes through packages/headless/src/date/; positioning, virtualization, carousel, and schema-standard integrations use the existing runtime deps (@floating-ui/dom, @tanstack/vue-virtual, embla-carousel, @standard-schema/spec); drag/drop and motion are self-maintained in-repo (composables/use-sortable-list.ts, shared/collapse-motion.ts).
    • Only add a new composable, helper, type, or third-party dependency when shared/composables/types, existing runtime deps, and @vueuse/core are all insufficient — and state that reason in the result.

Example: "migrate a compound widget into SoybeanUI" usually means migration scenario + multi-slot or compact pattern + full delivery surface.

Example: "audit the dialog component against industry baselines" means audit scenario + follow audit.md for the assessment flow, seven check dimensions, and regression rules.

Component patterns

Multi-slot base component

  • Headless exposes multiple slot primitives.
  • Uses UiSlot and UiClass<UiSlot>.
  • UI injects classes through provide{Name}Ui(ui).
  • Examples: accordion, dialog.

Compact aggregation

  • Use when structure is stable and data-driven.
  • Headless owns iteration, default content, structure, and non-style orchestration via {Name}Compact.
  • UI wrappers stay thin: only variants, class injection, prop/listener forwarding, and slot forwarding.
  • Exposes {Name}CompactProps / {Name}CompactEmits / {Name}CompactSlots.
  • Current examples: accordion, card, date-field, dialog, editable, hover-card, layout, navigation-menu, pagination, popover, stepper, table flows.

Single-class component

  • No UiContext.
  • UI composes classes directly from variants and props.class via {name}Variants({...}, props.class).
  • Examples: button, link.

Workflows

New or migrated component

  1. Admit or refuse headless. Apply layers.md -> Headless admission. If refused, skip step 1 and implement UI-only or compose an existing family.
  2. Build headless first (admitted families only).
    • types.ts -> context.ts -> base slot SFCs -> optional {Name}Compact -> index.ts.
  3. Build UI second.
    • packages/ui/src/styles/{name}.ts -> types.ts -> wrapper .vue -> index.ts.
  4. Complete exports and generated surfaces.
    • Update packages/headless/src/index.ts and packages/ui/src/index.ts.
    • Run pnpm sui gen catalog.
    • Do not hand-edit generated files.
  5. Complete delivery surfaces unless the user explicitly narrows scope.
    • apps/docs/src/examples/ui/{component}/
    • apps/docs/src/content/en/ui/components/{component}.md
    • apps/docs/src/content/zh/ui/components/{component}.md
    • apps/docs/src/constants/menus.ts
    • packages/ui/test/specs/components/{component}.spec.ts
    • Run pnpm sui gen api when public API changes; for non-English locales run pnpm sui translate api.
    • Run pnpm sui gen changelog when changelog mapping or release-facing surfaces change; for non-English locales run pnpm sui translate changelog.

Existing component fix or extension

  1. Decide whether the change belongs to headless logic or UI wrapping.
  2. Preserve the boundary:
    • No styles in headless (not even hidden, sr-only).
    • No ARIA, role, tabindex, or keyboard semantics in UI.
    • No reverse dependency from packages/headless to packages/ui.
  3. Check whether playground, docs, tests, exports, or generated API data must move with the change.
  4. If a new composable, helper, or type is introduced, explain why existing repository utilities and @vueuse/core were insufficient.

Audit and evaluation of shipped components

  1. Load audit.md for the full assessment methodology, seven check dimensions (D1–D7, 106 items), severity levels, acceptance states, and regression rules.
  2. Run the eight-step assessment flow from audit.md -> Assessment flow. Grade every finding by severity; do not start the next component while a Blocker is open.
  3. For D2 industry benchmarking, follow audit.md -> Industry benchmarking (six libraries) and record concrete findings.
  4. Apply the audit.md -> Single-component acceptance checklist before marking the component passed.
  5. After each category, run the cross-component consistency regression from audit.md -> Cross-component consistency regression. After all components, run the full regression.

Phase order

Execute in this order. Do not skip ahead until the current phase is done.

Phase 0: Classify pattern, scenario, and scope

  • Determine component pattern, task scenario, and whether this is full delivery.
  • For a new family: apply layers.md -> Headless admission before types.ts. If the family is not admitted, implement UI-only or compose an existing family.
  • Do not write code first and reverse-engineer the pattern.

Phase 1: Find reference implementations

  • Inspect at least one same-pattern headless reference and one UI reference.
  • Migration (scenario B): catalog behavior, state, a11y, slots, and public API that must be preserved.
  • Standards alignment (scenario C): list the gap inventory.
  • Audit and evaluation (scenario D): the gap inventory is the assessment itself — follow audit.md instead of the implementation phases below.

Phase 2: Implement headless

  • Skip this phase when admission refused the family (UI-only or compose existing).
  • Default order: types.ts -> context.ts -> base slot SFCs -> optional {Name}Compact -> index.ts.
  • See layers.md -> Headless for layer rules.

Phase 3: Implement UI

  • Default order: packages/ui/src/styles/{name}.ts -> types.ts -> wrapper .vue -> index.ts.
  • See layers.md -> UI layer for layer rules.

Phase 4: Wire exports and generated files

  • Update packages/headless/src/index.ts and packages/ui/src/index.ts.
  • Run pnpm sui gen catalog.
  • Do not hand-edit generated files.

Phase 5: Complete delivery surfaces

  • Playground (examples): see surfaces.md -> Playground (examples).
  • Docs: see surfaces.md -> Docs.
  • Tests: see surfaces.md -> Testing. For interactive components, also add a browser e2e spec — see e2e.md.
  • If public API changed, run pnpm sui gen api; for non-English locales run pnpm sui translate api.
  • If changelog mapping or release surfaces changed, run pnpm sui gen changelog; for non-English locales run pnpm sui translate changelog.

Phase 6: Validate and finish

  • Run pnpm typecheck, pnpm lint, pnpm fmt, and the narrowest relevant test: pnpm vitest packages/ui/test/specs/components/{component}.spec.ts.
  • If a command cannot run, state the blocker explicitly.
  • Apply process.md -> Finish checklist only now.

Boundary rules

  • Compile-time dependency must remain packages/ui -> packages/headless. Never import @soybeanjs/ui from packages/headless.
  • Headless owns logic, state, accessibility, structure aggregation, and default semantics. Structure aggregation does not by itself admit a new family — see layers.md -> Headless admission.
  • UI owns variants, UnoCSS classes, ui injection, and wrapper composition.
  • Do not add visual token styles or utility classes in headless (not even hidden, sr-only). Geometric layout-contract inline styles are allowed (admission R8).
  • Do not put ARIA, role, tabindex, keyboard interaction, or state semantics in packages/ui/src/components.
  • Do not hand-edit generated files; update source exports and rerun scripts.
  • Avoid adding new helpers before checking existing repository utilities and @vueuse/core.

Guardrails

  • Use UiClass<UiSlot> (from packages/headless/src/types), not Record<UiSlot, ClassValue>.
  • Props always extends /** @vue-ignore */ HTMLAttributes to suppress IDE noise; if based on Primitive, extends PrimitiveWithBaseProps.
  • Context values must be reactive: ComputedRef or ShallowRef. Use toContext(props, keys) (from headless shared/vue) for prop-derived fields; fromContext(context, keys) snapshots back to plain values when needed.
  • use{Name}Ui('root') -> ComputedRef<ClassValue> (single slot); use{Name}Ui() -> full map.
  • For multi-slot wrappers, pass props.ui and { root: props.class } directly into the scv() recipe call.
  • Multi-slot: only export provide{Name}Ui from headless barrel; never export use{Name}Ui.
  • packages/ui/src/styles/{name}.ts first line must be // @unocss-include. Shared class tokens live in _*.ts files (_field.ts, _overlay.ts); recipes compose those tokens or inherit a sibling recipe via extend / alias / extendBase.
  • Headless families built on another family alias inner slots that have no domain semantics, and wrap inner primitives in a domain SFC when the slot has a11y, context, UI, or data-soybean-{family-slot} of its own. See layers.md -> Composing an existing family. Compact only assembles; it does not define the contract of a publicly exported primitive.
  • slots keys in style recipe must match headless {Name}UiSlot exactly.
  • useOmitProps must include class to avoid double-binding.
  • UI component names use S prefix (SButton, SDialog); headless names do not (Button, Dialog).
  • Never use as any / @ts-ignore / @ts-expect-error.
  • Never modify typed-router.d.ts (auto-generated).

Full delivery surface

New components check every entry that applies; existing component changes sync affected entries. Headless paths apply only when the family passed Headless admission; UI-only components skip the headless directory and barrel.

  • packages/headless/src/components/{component}/ (admitted families)
  • packages/ui/src/components/{component}/
  • packages/headless/src/index.ts (admitted families)
  • packages/ui/src/index.ts
  • apps/docs/src/examples/ui/{component}/
  • apps/docs/src/content/en/ui/components/{component}.md
  • apps/docs/src/content/zh/ui/components/{component}.md
  • apps/docs/src/constants/menus.ts
  • packages/ui/test/specs/components/{component}.spec.ts

Generated surfaces

Run these after the corresponding source changes. Never hand-edit generated outputs.

  • pnpm sui gen catalog — regenerates the component catalogs: packages/headless/src/constants/components.ts, packages/headless/src/namespaced/index.ts (from packages/headless/src/index.ts), and packages/ui/src/constants/components.ts (from packages/ui/src/index.ts). Pass headless or ui to regenerate only one.
  • pnpm sui gen api — regenerates apps/docs/src/generated/api/*.json and apps/docs/src/generated/api-locales/*.json base data.
  • pnpm sui gen changelog — regenerates apps/docs/src/generated/changelog/*.json and apps/docs/src/generated/changelog-locales/*.json base data.
  • pnpm sui gen schema / pnpm sui gen skills — regenerates the sbean JSON Schemas / the skills distribution.
  • pnpm sui gen all — regenerates every surface above.
  • pnpm sui translate <api|changelog|locale|all> — refreshes the surface it translates and then fills pending entries through DeepL (--locale, --dry-run, --limit, --overwrite). This is the only command that needs DEEPL_API_KEY.
  • pnpm sui check generated — regenerates every surface and diffs it against git; CI runs it, so committed generated data cannot drift unnoticed.
  • pnpm sui check deps — dependency gate: banned imports plus the headless/ui runtime dependency whitelists.

Generation is content-aware: a document whose payload did not change keeps its committed generatedAt and is not rewritten, so a no-op run leaves git status clean. On top of that, gen api skips the TypeDoc extraction entirely (~40s → ~0.15s) when a fingerprint of its inputs and its on-disk output still matches the last run; the fingerprint lives in node_modules/.cache/sui/. --force bypasses it.

Build and validation commands

pnpm dev:docs         # Documentation site (ubean dev)
pnpm build            # libs (theme, ui-uno) -> headless -> ui -> sbean via Vite Plus pack
pnpm build:libs       # theme -> ui-uno
pnpm lint             # vp lint --fix && package Vue lint
pnpm fmt              # vp fmt
pnpm test             # recursive workspace tests (pnpm -r run test)
pnpm test:e2e         # Vitest Browser Mode + Playwright Chromium
pnpm typecheck        # recursive workspace type checks
pnpm release          # Publish packages (soy release)
pnpm stub             # switch headless exports to src (`--reset` restores dist)
  • Pre-commit hook (Vite Plus, .vite-hooks/pre-commit): vp staged.
  • CI: PR/push typecheck, lint, unit tests, and browser e2e; tag-triggered build/release.
  • Formatter: Vite Plus vp fmt.

Result reporting

In the final handoff, make the following explicit when relevant:

  • Component pattern, scenario, and scope.
  • Which delivery surfaces were changed or intentionally left unchanged.
  • Which generation and validation commands were run.
  • Any blocker that prevented validation or full delivery.
  • Why a new composable, shared helper, or type was introduced instead of reusing repository utilities or @vueuse/core.

Version History

  • 294c46a Current 2026-09-27 22:09

    移除v0.50文档及重构指南,将无头组件准入规则整合至layers.md并刷新审计维度。

  • c080112 2026-09-22 10:21

Same Skill Collection

.agents/skills/soybean-ui-component-development/SKILL.md
.agents/skills/vean-ui-develop/SKILL.md
skills/skills-source/soybean-headless/SKILL.md
skills/skills-source/soybean-ui/SKILL.md
skills/skills-source/vean-aria/SKILL.md
skills/skills-source/vean-ui/SKILL.md
skills/skills/soybean-headless/SKILL.md
skills/skills/soybean-ui/SKILL.md
skills/skills/vean-aria/SKILL.md
skills/skills/vean-ui/SKILL.md

Metadata

Files
0
Version
294c46a
Hash
8ff57f55
Indexed
2026-09-22 10:21

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-11-01 22:47
浙ICP备14020137号-1