Agent SkillsIgniteUI/igniteui-webcomponents › add-component-property

add-component-property

GitHub

为现有 Lit Web Component 添加响应式属性,包括装饰器、类型定义、测试及文档生成。适用于需修改组件 API 以支持新状态或配置的场景。

.github/skills/add-component-property/SKILL.md IgniteUI/igniteui-webcomponents

Trigger Scenarios

需要为组件添加新的响应式属性 要求自动生成属性的元数据和文档

Install

npx skills add IgniteUI/igniteui-webcomponents --skill add-component-property -g -y
More Options

Non-standard path

npx skills add https://github.com/IgniteUI/igniteui-webcomponents/tree/master/.github/skills/add-component-property -g -y

Use without installing

npx skills use IgniteUI/igniteui-webcomponents@add-component-property

指定 Agent (Claude Code)

npx skills add IgniteUI/igniteui-webcomponents --skill add-component-property -a claude-code -g -y

安装 repo 全部 skill

npx skills add IgniteUI/igniteui-webcomponents --all -g -y

预览 repo 内 skill

npx skills add IgniteUI/igniteui-webcomponents --list

SKILL.md

Frontmatter
{
    "name": "add-component-property",
    "description": "Add a reactive property to an existing Lit web component with proper decorators, types, tests, and documentation"
}

Add Component Property

Adds a reactive property to an existing component, with the documentation, tests and generated metadata that go with it.

When to Use

  • "Add an 'orientation' property to the divider component"
  • "Add a 'variant' property with multiple options"

Related Skills

Required Context

  • Component: which component to modify
  • Name and type: camelCase property, kebab-case attribute
  • Default value: booleans must default to false
  • Reflection: only for primitives that affect styling or accessibility
  • Purpose: the description that ships in the public API docs

Steps

1. Declare the property

Place it in the //#region Public attributes and properties section, in the shape that matches its type:

/**
 * The style variant of the component.
 * @attr variant
 * @default 'primary'
 */
@property({ reflect: true })
public variant: StyleVariant = 'primary';

/**
 * Whether user interaction with the component is disabled.
 * @attr
 * @default false
 */
@property({ type: Boolean, reflect: true })
public disabled = false;

/**
 * The number of items rendered per page.
 * @attr items-per-page
 * @default 10
 */
@property({ type: Number, attribute: 'items-per-page' })
public itemsPerPage = 10;

/** The items rendered by the component. */
@property({ attribute: false })
public items: Array<Item> = [];

Rules that are easy to get wrong:

  • Booleans must default to false. An attribute's presence equates to true, so a true default cannot be turned off from markup. Rename the property instead (enableddisabled).
  • Never reflect objects or arrays, and give them attribute: false so Lit doesn't try to serialize them.
  • Lit derives the attribute name automatically, but spell it out for multi-word properties and for HTML look-alikes (readOnlyreadonly, minLengthminlength).
  • A read-only value is a getter, not a readonly @property.

2. Write the description

The JSDoc is copied verbatim into custom-elements.json, the generated Storybook metadata and the Angular / React / Blazor wrapper docs.

  • No igc- tag names in prose — "the select component", not igc-select.
  • Don't restate that it is an attribute. @attr already says so.
  • No Gets/Sets. State what the value is; add a second sentence for side effects.
  • Booleans start with "Whether …" and must describe the true state accurately — verify against the implementation, since hide*/disable* names invert the sentence.
  • Present tense, not "will".
// ❌ Wrong
/**
 * The outlined attribute of the control.
 * @attr
 */

// ✅ Right
/**
 * Whether the control has an outlined appearance.
 * @attr
 */

Full reference: create-new-component → Documentation Conventions.

3. React to the change

If the property only affects the template, do nothing — just use it in render(). If it has side effects or feeds derived state, use the Lit lifecycle hooks, not @watch:

// Derived state, before rendering
protected override willUpdate(changedProperties: PropertyValues<this>): void {
  if (changedProperties.has('value')) {
    this._normalized = this.value.trim();
  }
}

// Side effects that need DOM access
protected override update(changedProperties: PropertyValues<this>): void {
  if (changedProperties.has('disabled')) {
    this._internals.setARIA({ ariaDisabled: `${this.disabled}` });
  }
  super.update(changedProperties);
}

Always guard with changedProperties.has() and call super.update() when overriding update.

For a form-associated control, a property that participates in constraint validation (min, pattern, maxLength, …) must call this._validate() from its setter.

4. Add tests

it('is initialized with the proper default value', async () => {
  const el = await fixture<IgcComponentComponent>(
    html`<igc-component></igc-component>`
  );

  expect(el.propertyName).to.equal(defaultValue);
});

it('updates on property change', async () => {
  const el = await fixture<IgcComponentComponent>(
    html`<igc-component></igc-component>`
  );

  el.propertyName = newValue;
  await elementUpdated(el);

  expect(el.propertyName).to.equal(newValue);
});

it('reflects to an attribute', async () => {
  const el = await fixture<IgcComponentComponent>(
    html`<igc-component property-name=${value}></igc-component>`
  );

  expect(el.propertyName).to.equal(value);
  expect(el.getAttribute('property-name')).to.equal(value);
});

If the property changes the rendered semantics, extend the a11y audit rather than adding a separate one.

5. Regenerate the story metadata

The argTypes, args and the args interface live inside a generated // region default … // endregion block in stories/[component-name].stories.ts. Never edit it by hand:

npm run cem        # custom-elements.json from the source JSDoc
npm run build:meta # the `// region default` block of each story

If the generated description reads badly, fix the JSDoc and regenerate. If the property doesn't appear at all, the story was skipped: the filename must match the tag name (igc-date-pickerdate-picker.stories.ts) and the region fence must be present — a missing fence is a silent no-op.

Then wire the property into the story templates, which are hand-written:

export const Basic: Story = {
  render: (args) => html`
    <igc-component .propertyName=${args.propertyName}>Content</igc-component>
  `,
};

6. Verify

npm run check
npm run test

Validation Checklist

  • Property declared in the public properties region with the right decorator options
  • Booleans default to false; complex types use attribute: false
  • @attr and @default tags present; description follows the description rules
  • Lifecycle hook used for side effects, super.update() called
  • _validate() called from setters affecting constraint validation
  • Tests cover default, change and reflection
  • npm run cem && npm run build:meta run; generated story region committed
  • Story template uses the new property
  • npm run check and npm run test pass
  • CHANGELOG updated if the property is part of a feature or fix

Common Pitfalls

Symptom Cause / Fix
Attribute can't be turned off from markup Boolean defaults to true — rename so the default is false
[object Object] in the DOM Complex type without attribute: false
String 'false' behaves as true Missing { type: Boolean } in the decorator
Attribute name is propertyname Multi-word property without an explicit attribute: 'property-name'
Story control missing after adding a property npm run build:meta not run, or the story is being skipped silently
Story description reverts The generated region was hand-edited — fix the JSDoc instead

Reference Examples

  • src/components/badge/badge.ts — reflected string, boolean and union-typed properties
  • src/components/input/input.ts — validation-affecting setters calling _validate()
  • src/components/combo/combo.ts — complex, non-attribute properties

Version History

  • 7.2.4 Current 2026-08-20 11:42

Same Skill Collection

.github/skills/create-new-component/SKILL.md
.github/skills/review-component-pr/SKILL.md
.github/skills/update-component-styles/SKILL.md
skills/igniteui-wc-choose-components/SKILL.md
skills/igniteui-wc-customize-component-theme/SKILL.md
skills/igniteui-wc-integrate-with-framework/SKILL.md
skills/igniteui-wc-migrate-grid-lite-to-premium/SKILL.md
skills/igniteui-wc-optimize-bundle-size/SKILL.md
skills/igniteui-wc-generate-from-image-design/SKILL.md

Metadata

Files
0
Version
7.2.4
Hash
cc1451d6
Indexed
2026-08-20 11:42

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-24 20:44
浙ICP备14020137号-1 $방문자$