Adding a New Component
Adding a component to the native bloodline takes five steps, in order.
1. Write the component contract specs/<name>.json
Section titled “1. Write the component contract specs/<name>.json”Declare props / enums / defaults / events / slots / behaviors / consumed tokens.
{ "$schema": "./schema.json", "name": "stepper", "component": "LhStepper", "since": "0.1.0", "description": "Stepper: increments or decrements a value by a fixed step within a given range.", "props": [ { "name": "value", "type": "number", "default": 0, "description": "Current value (controlled)" }, { "name": "step", "type": "number", "default": 1, "description": "Step size" }, { "name": "disabled", "type": "boolean", "default": false, "description": "Whether disabled" } ], "events": [ { "name": "onChange", "payload": [{ "name": "value", "type": "number", "description": "The value after the change" }], "description": "Fires when the value changes" } ], "behaviors": [ "When disabled is true: the increment/decrement buttons do not respond and onChange is not fired" ], "tokenRefs": ["stepper.height", "stepper.buttonSize"]}For field constraints see Contract Format.
2. Write the golden cases cases/<name>.json
Section titled “2. Write the golden cases cases/<name>.json”Write one given/when/then assertion per behavior that needs a cross-platform guarantee:
{ "$schema": "./schema.json", "component": "stepper", "cases": [ { "id": "disabled-blocks-change", "name": "The disabled state does not fire onChange", "given": { "props": { "disabled": true } }, "when": { "action": "click", "target": "increment button" }, "then": { "events": [{ "name": "onChange", "assertion": "notEmitted" }], "enabled": false } } ]}For the format see Case Format.
3. Run verification
Section titled “3. Run verification”pnpm verify:specsThis checks case/spec consistency: whether the keys of a case’s given.props are all among the spec’s props, whether every then.events[].name is among the spec’s events, and so on.
4. Add component-level tokens (if needed)
Section titled “4. Add component-level tokens (if needed)”If the component introduces new component-level tokens (e.g. stepper.height), add the keys under the component’s namespace in tokens/components.json:
"stepper": { "height": { "value": "32px", "description": "Stepper height", "nativeOnly": true }, "buttonSize": { "value": "24px", "description": "Increment/decrement button size" }}Then:
pnpm codegen # regenerate dist/pnpm verify:tokenspnpm test -- -u # update snapshotsIf the new tokens are brand-level (global values such as the color palette or spacing scale rather than component dimensions), edit the corresponding tokens/<category>.json and register the change in the “变更登记” (change log) section of the family docs/设计语言基线.md.
5. Release
Section titled “5. Release”pnpm changeset # write a changesetpnpm changeset:versioncore is released first, then each native target bumps its token dependency version and translates the cases from cases/stepper.json by hand into local tests (JUnit / XCTest / ohpm test / C unit tests).
Checklist
Section titled “Checklist”-
specs/<name>.jsonexists andpnpm verify:specspasses -
cases/<name>.jsonexists and is consistent with the spec - New tokens were added to
tokens/andpnpm verify:tokenspasses -
pnpm codegensucceeds andpnpm testsnapshots are updated - A changeset was written
- (Brand-level tokens) The family baseline document is updated
Copyright © 2024-2026 FengMo WenXue