con un clic
review-component-pr
// Comprehensive code review checklist for component pull requests ensuring quality, accessibility, and adherence to project conventions
// Comprehensive code review checklist for component pull requests ensuring quality, accessibility, and adherence to project conventions
Identify and select the right Ignite UI Web Components for your app UI, then navigate to official docs, usage examples, and API references
Implement application views from design images using Ignite UI Web Components. Uses MCP servers (igniteui-cli, igniteui-theming) to discover components, generate themes, and follow best practices. Triggers when the user provides a design image (screenshot, mockup, wireframe) and wants it built as a working view with Ignite UI Web Components. Also triggers when the user asks to "implement this design", "build this UI", "convert this mockup", or "create a page from this image" in an Ignite UI Web Components project.
Integrate Ignite UI Web Components packages into React, Angular, Vue, or vanilla JS applications with framework-specific configurations
Customize Ignite UI Web Components styling using CSS custom properties, optional Sass, and the igniteui-theming MCP server for AI-assisted theming
Optimize application bundle size by importing only necessary components and using tree-shaking effectively
Add a reactive property to an existing Lit web component with proper decorators, types, tests, and documentation
| name | review-component-pr |
| description | Comprehensive code review checklist for component pull requests ensuring quality, accessibility, and adherence to project conventions |
This skill provides a systematic checklist for reviewing pull requests that add or modify web components in the project.
src/components/[component-name]/[component-name].ts[component-name].spec.tsstories/[component-name].stories.tsthemes/ directory
[component-name].base.scssthemes.ts aggregatorsrc/index.ts in alphabetical orderany types - Use unknown or proper types.js extension (not .ts)_prefix or TypeScript private, not #_method(), _property@property, @query, etc.)Good:
@property({ reflect: true })
public variant: StyleVariant = 'primary';
private _internalState: string = '';
Bad:
@property()
public variant: any; // ❌ No any types
#privateField = ''; // ❌ No native private fields
LitElement or appropriate mixintagName static property defined: 'igc-[component-name]' with readonly modifierstyles static property includes base and shared stylesregister() static method present_internalMethod(), _privateStateaddThemingController(this, all)super() first if overriddenexport default classTemplate:
export default class IgcComponentComponent extends LitElement {
public static readonly tagName = 'igc-component';
public static override styles = [styles, shared];
public static register(): void {
registerComponent(IgcComponentComponent);
}
//#region Internal state
private _internalState = '';
//#endregion
//#region Public properties
@property({ reflect: true })
public variant = 'primary';
//#endregion
constructor() {
super();
addThemingController(this, all);
}
//#region Lit lifecycle
protected override render() {
return html`<div part="base"><slot></slot></div>`;
}
//#endregion
//#region Internal API
private _handleChange(): void {
// Internal helper
}
//#endregion
}
declare global {
interface HTMLElementTagNameMap {
'igc-component': IgcComponentComponent;
}
}
attribute: false{ type: Boolean, reflect: true }{ type: Number }@attr for reflected properties@default for default valuesGood:
/**
* The variant style of the component
* @attr variant
* @default 'primary'
*/
@property({ reflect: true })
public variant: StyleVariant = 'primary';
/**
* Complex configuration object
*/
@property({ attribute: false })
public config: Config = {};
Bad:
@property({ reflect: true }) // ❌ Trying to reflect complex type
public config: Config = {};
update() for side effects (DOM available)willUpdate() only for pre-render computationsuper.update() called when overriding update()changedProperties.has() checked to avoid unnecessary work@watch decorator used (prefer lifecycle hooks)requestUpdate() not called unnecessarilyGood:
protected override update(changedProperties: PropertyValues<this>): void {
if (changedProperties.has('disabled')) {
// Update ARIA or other side effects
this._internals.setARIA({ ariaDisabled: `${this.disabled}` });
}
super.update(changedProperties);
}
part attribute for external styling@csspart@cssproperty.css.js files.css.js edits (only edit SCSS):host styles include appropriate display valueGood:
/**
* @csspart base - The main container
* @csspart content - The content wrapper
* @cssproperty --padding - Internal padding
*/
protected override render() {
return html`<div part="base"><slot></slot></div>`;
}
await expect(el).to.be.accessible()role attribute appropriate for component typedelegatesFocus used if component should delegate focusaddInternalsController used for ARIA management if neededCheck:
// Should have accessibility test
it('passes the a11y audit', async () => {
const el = await fixture<IgcComponentComponent>(
html`<igc-component></igc-component>`
);
await expect(el).shadowDom.to.be.accessible();
await expect(el).to.be.accessible();
});
@event in JSDocon prefix)Good:
export interface IgcComponentEventMap {
igcChange: CustomEvent<string>;
}
/**
* @event igcChange - Emitted when value changes
*/
export default class IgcComponentComponent extends EventEmitterMixin<
IgcComponentEventMap,
Constructor<LitElement>
>(LitElement) {
// ...
this.emitEvent('igcChange', { detail: newValue });
}
defineComponents() called in before() hookelementUpdated() used after programmatic changes@open-wc/testing frameworkMinimum Required:
describe('Component', () => {
before(() => {
defineComponents(IgcComponentComponent);
});
it('passes the a11y audit', async () => {
// Required accessibility test
});
it('should initialize with default values', async () => {
// Test defaults
});
it('can change properties', async () => {
// Test reactivity
});
});
stories/[component-name].stories.ts@element tag with component tag name@slot tags for all slots (default and named)@csspart tags for all exposed parts@cssproperty tags for CSS custom properties@event tags for emitted eventsComplete Example:
/**
* A button component for user interactions.
*
* @element igc-button
*
* @slot - Default slot for button text
* @slot prefix - Content before the button text
*
* @csspart base - The button element
* @csspart content - The content wrapper
*
* @cssproperty --padding - Button padding
*
* @event igcClick - Emitted on click
*/
value property reactive and syncednpm run check-types.css.js filesnpm run testconsole.log, debugger)common/ where applicableProblem: Component doesn't respond to theme changes
Fix: Add addThemingController(this, all) in constructor
Problem: Using .ts instead of .js in imports
Fix: All TypeScript imports must use .js extension
Problem: Trying to reflect objects/arrays to HTML attributes
Fix: Use attribute: false for non-primitive types
Problem: No a11y test in spec file Fix: Always include accessibility audit test
Problem: Component not available when importing from package
Fix: Add export to src/index.ts in alphabetical order
Problem: Using deprecated pattern for property changes
Fix: Use update() or willUpdate() lifecycle hooks
Problem: Using #privateField syntax
Fix: Use _privateField or TypeScript private keyword
anyImmediate Reject if:
any types extensively#)Request Changes if:
Approve if: