Skip to main content

review-component-pr

Comprehensive code review checklist for component pull requests ensuring quality, accessibility, and adherence to project conventions

الانتقال إلى التثبيت

معلومات المصدر

المستودع
IgniteUI/igniteui-webcomponents
آخر نشاط في المصدر
١٨ أغسطس ٢٠٢٦ في ٠٧:٥٣
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٧٠
التفرعات
١١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
review-component-pr
description
Comprehensive code review checklist for component pull requests ensuring quality, accessibility, and adherence to project conventions
# Review Component PR A review checklist for pull requests that add or modify components. The rules behind it live in the [Coding Guidelines](../../CODING_GUIDELINES.md); this skill is the pass over a diff. ## When to Use - Reviewing a PR that adds or changes a component - Pre-merge quality gate, or a self-review before opening a PR ## Review Order 1. **Structure** — are all the required files there? 2. **Public API** — properties, events, docs; this is the part that cannot be changed later 3. **Accessibility** — mandatory, never skipped 4. **Behavior** — lifecycle, state, forms 5. **Styles and themes** 6. **Tests and generated artifacts** 7. **Build and hygiene** ## 1. Structure - [ ] Component at `src/components/[name]/[name].ts` with a single default export - [ ] Spec at `src/components/[name]/[name].spec.ts` - [ ] Story at `stories/[name].stories.ts` — filename matches the tag name - [ ] Theme scaffold complete: `[name].base.scss`, `shared/`, `light/`, `dark/`, `themes.ts` - [ ] Exported from `src/index.ts` in alphabetical order - [ ] Cross-cutting imports use `#internals/*`, `#theming/*`, `#animations/*`; component-to-component imports stay relative; every specifier ends in `.js` - [ ] Nothing new under `src/internals` is exported from the public entry point ## 2. Public API and Documentation - [ ] `tagName`, `styles` and `register()` static members present; `register()` also registers every dependency rendered in the template - [ ] `HTMLElementTagNameMap` declaration added - [ ] Only primitives are attributes; complex types use `attribute: false` and are never reflected - [ ] Booleans default to `false` - [ ] Attribute names are kebab-case, spelled out for multi-word properties - [ ] Events go through `EventEmitterMixin` with a typed event map; names are `igc`-prefixed camelCase, cancelable ones use the `-ing` suffix and their return value is checked - [ ] Events are emitted from user interaction, not from property assignment or method calls - [ ] JSDoc carries `@element`, `@slot`, `@csspart`, `@cssproperty`, `@attr`, `@default`, `@event` as applicable, with tags after the description - [ ] Deprecations follow `@deprecated since [SemVer]. Use the \`[new API]\` [type] instead.` - [ ] **No `igc-` tag names in description prose** — they ship verbatim into `custom-elements.json` and every framework wrapper's docs. Allowed only in `@element`, fenced `@example` blocks, literal `igc-`-containing event/attribute names, and `@internal`/`@hidden` members. - [ ] Descriptions don't restate the tag ("The label _attribute_ of…"), don't use `Gets/Sets`, and booleans start with "Whether" describing the `true` state accurately ```bash # Quick leak check — should return nothing outside @element/@example grep -rn "igc-" --include="*.ts" src/ \ | grep -E "^\S+:[0-9]+:\s*\*" \ | grep -vE "@element|@example|\.spec\.ts" ``` ## 3. Accessibility - [ ] The spec contains the mandatory a11y audit (`shadowDom` **and** light DOM) - [ ] Semantic elements used instead of `div`s with click handlers - [ ] ARIA set through `addInternalsController` (`initialARIA`, `setARIA()`) — never `this.role = '…'`; `reflectRole: true` when attribute-only tooling must see the role - [ ] Keyboard interaction implemented through `addKeybindings` (Tab, arrows, Enter/Space, Escape, Home/End as applicable) with visible focus indicators - [ ] Composite hosts wrapping an input-shaped component project their semantics with `addAriaProjector` / `addAriaTarget` instead of setting `role`/`aria-*` on the host or the wrapper - [ ] Cross-root relations use ARIA element reflection, never IDREFs - [ ] Theme selectors for composite anchors key off the mirrored `data-role`/`data-haspopup` attributes, not `role`/`aria-*` - [ ] No `public` members tagged `@hidden`/`@internal` added for cross-component access — use `internalsOf()` - [ ] Cross-root ARIA is covered by `runExternalLabelAssociationTests` / `runAriaProjectionTests`; reflected relations are asserted by identity readback, with `axeReflectedRelationsOptions` suppressing the known `aria-required-attr` false positive ## 4. Behavior - [ ] Region fences and member order follow the standard component structure - [ ] Internal API is `_`-prefixed; no native private fields (`#`); `readonly` on controllers and other non-reassigned fields - [ ] No `any`; explicit return types except where obviously noise - [ ] Derived state computed in `willUpdate()`, side effects in `update()` with `super.update()` called; guarded by `changedProperties.has()` - [ ] No new `@watch` usages - [ ] Existing controllers reused rather than reimplemented (slots, observers, root click, keybindings, gestures, i18n) - [ ] Dynamically added listeners on `window`/`document` are removed in `disconnectedCallback`; listeners in templates and on the host are not manually cleaned up - [ ] User-facing strings come from the i18n controller, not inlined in templates - [ ] Form controls: extend the right form-associated mixin, own their `_formValue` through `createFormValueState`, expose validators via `__validators` (reusing `#internals/validators.js`), update through `setValueAndFormState`, call `_validate()` from constraint-affecting setters, and wire `_handleBlur` / `_handleEnterKeydown` on the native editor - [ ] Form controls don't reimplement touched/pristine/invalid bookkeeping; overrides of `formResetCallback` call `super` ## 5. Styles and Themes - [ ] Only `.scss` edited — no generated `.css.ts` in the diff - [ ] Load-path specifiers (`@use 'styles/utilities' as *`), no relative global imports - [ ] Values read through `var-get()` and the theming functions; nothing hardcoded - [ ] Part selectors use `[part~='…']` - [ ] All four themes covered in light and dark; dark files emit only the `diff()` - [ ] `themes.ts` aggregates every theme file that was added - [ ] `:host` has an appropriate `display`; selector specificity kept low ## 6. Tests and Generated Artifacts - [ ] `defineComponents()` in the `before()` hook; `elementUpdated()` after programmatic changes - [ ] Coverage for defaults, property/attribute reflection, events, interaction and edge cases - [ ] Interaction driven by the shared simulators from `#internals/testing/simulate.spec.js`, not raw `click()` / hand-built events - [ ] Form controls tested through `createFormAssociatedTestBed` and the validity helpers - [ ] The story's `// region default … // endregion` block was regenerated (`npm run cem && npm run build:meta`), not hand-edited, and is committed - [ ] Hand-written stories cover the states a user cares about - [ ] CHANGELOG updated ## 7. Build and Hygiene - [ ] `npm run check` (aliases, dependency rules, types) passes - [ ] `npm run lint` passes — oxlint, lit-analyzer, oxfmt, stylelint - [ ] `npm run test` passes - [ ] No leftover `console.log`/`debugger`, no commented-out code, no unexplained magic numbers - [ ] No new heavy third-party dependency ## Frequent Findings | Finding | Why it matters | | ---------------------------------------------- | --------------------------------------------------------------------- | | Missing `addThemingController` | The component never reacts to theme changes | | Relative import into `internals`/`theming` | `npm run check` fails; alias is the contract | | Alias added to `package.json` only | Breaks only for consumers of the published package | | `igc-` tag name in a description | Ships verbatim into every framework wrapper's API docs | | Hand-edited story metadata | Reverts on the next `npm run build:meta` | | `.css.ts` file in the diff | Generated and gitignored — the `.scss` is the source | | `[part='base']` with `partMap` | Selector silently stops matching once a second part name is emitted | | ARIA on a `delegatesFocus` host | Assistive technology reads the native editor, not the host | | New `@hidden` public member | Leaks into the compiled public API — use `internalsOf()` | | Boolean property defaulting to `true` | Cannot be turned off from markup | | `@watch` in new code | Lifecycle hooks are the supported path | ## Verdict **Request changes** when: the a11y audit is missing or failing, ARIA is set on the wrong element, `any` types or native private fields appear, generated artifacts are hand-edited or missing, themes are incomplete, or the public API is undocumented. **Approve** when the checklist passes, `npm run check`, `npm run lint` and `npm run test` are green, and the public API reads the way it will be documented for users. Be specific in feedback: name the file, the line and the guideline it maps to.
عرض على GitHub