.github/skills/component-authoring/SKILL.md
End-to-end workflow for composing or extending an SGDS web component. Use this skill whenever the user says "create a new component", "build a new sgds-* element", "add a feature to an existing component", "I want to contribute a component", or asks how to structure, scaffold, test, or write a Lit component for the design system. Also apply when the user asks about TDD workflow, code conventions, or ADRs in the context of component development.
npx skillsauth add govtechsg/sgds-web-component component-authoringInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A guided workflow for building or extending SGDS web components correctly.
Before writing any code, ask the author:
Is this a new component, or a feature/fix on an existing component?
Plop generates the boilerplate source, test, and story files. Because plop is an interactive CLI, the author must run this command themselves in their terminal:
pnpm run write:component
Tell the author to run the command and follow the prompts (component name, etc.). Once plop finishes, it will have generated:
src/components/<ComponentName>/
sgds-<component-name>.ts # LitElement source
<component-name>.css # Component styles
test/
<component-name>.test.ts # Unit test file
stories/templates/<ComponentName>/
basic.js # Base Storybook template
additional.stories.js # Additional story variants
additional.mdx # Story documentation
Do not hand-create these files — always use plop to stay consistent with the project structure.
Follow a strict test-first workflow. Never write implementation before a failing test.
Open the generated test file and write a test for the behaviour you are about to implement. The author runs the test suite and confirms it fails:
pnpm test
The test must be red before any implementation code is written.
Read CODE_CONVENTIONS.md → ## Testing before writing any test. Key rules:
@state() fields prefixed with _._ prefix, no private/protected modifier = public API = valid to assert.// Bad — internal state
expect(item._selected).to.be.true;
// Good — DOM outcome
expect(item.shadowRoot?.querySelector(".sidebar-item")).to.have.class("active");
// Good — public API
expect(group.showMenu).to.be.true;
Write the minimum implementation to make the test pass. Re-run:
pnpm test
Confirm the test is now green before moving on to the next behaviour.
Read CODE_CONVENTIONS.md while writing component code. Key rules to check:
@state() fields must be prefixed with _private/protected/public on all methods; @watch-decorated methods have no access modifier (TypeScript constraint)@property decorators: must have a jsdoc block above each onesgds- prefix (e.g. sgds-change)querySelectorAll("sgds-*") tag namesAlso read the Architecture Decision Records in contributing/architecture-decision-record/ before making structural decisions. These encode resolved tradeoffs for the project:
| ADR | When to read |
|-----|-------------|
| slotchange-vs-firstupdated-for-slot-attribute-setting.md | Whenever you need to react to slotted children |
| ssr-prop-slot-detection.md | If the component detects slot content to toggle behaviour |
| force-slotchange-event-ssr.md | SSR / hydration slot edge cases |
| reduce-host-styling.md | When styling the host element |
| custom-validation.md | Form components with validation |
| automated-icon-conversion.md | Adding or modifying icons |
While developing, create a playground HTML file to get a live visual check outside of Storybook. Playground files are flat HTML files at the root of playground/ — one per component:
playground/<ComponentName>.html
Plop does not generate this file — create it manually. Look at an existing file (e.g. playground/Badge.html) as a reference for the import and markup pattern. Iterate between implementation, tests, and playground until the component behaves correctly.
When development is complete, build the library to update the compiled output in lib/:
pnpm build
Confirm the build passes before proceeding.
When the author signals development is complete, ask:
Do you want to write Storybook stories for this component?
If yes, use the storybook-stories skill — it covers the basic.js / additional.stories.js / additional.mdx pattern and the file-concatenation behaviour that makes Template available without imports.
tools
Complete reference for all SGDS web components including installation and framework integration. Use when users ask about any <sgds-*> component — accordion, alert, badge, breadcrumb, button, card, checkbox, close-button, combo-box, datepicker, description-list, divider, drawer, dropdown, file-upload, footer, icon, icon-button, icon-card, icon-list, image-card, input, link, mainnav, masthead, modal, overflow-menu, pagination, progress-bar, quantity-toggle, radio, select, sidebar, sidenav, skeleton, spinner, stepper, subnav, switch, system-banner, tab, table, table-of-contents, textarea, thumbnail-card, toast, or tooltip. Also covers React 19+, React ≤18, Vue, Angular, and Next.js integration.
testing
Use this skill when users ask about form validation in SGDS, hasFeedback prop, constraint validation, custom validation, noValidate, setInvalid, form submission, or reading FormData from SGDS form components.
tools
Complete catalog of page layout patterns for SGDS applications. Use this skill whenever a user asks about page layouts, content arrangement, aside panels, split views, sidebar layouts, breadcrumb layouts, or viewport-height layouts — even if they just say 'how should I lay out my page' or 'I need a two-column layout'. Covers Full Width layouts (public-facing pages with sgds-container) and With Sidebar layouts (dashboards/internal tools with sgds-container-sidebar). Trigger on: layout, aside, split view, sidebar layout, two-column, three-column, content arrangement, page structure with aside.
tools
Complete ready-to-use page templates built with SGDS components and utilities. Use this skill whenever a user asks to build a page, dashboard, login page, form page, settings page, list page, or any full-page UI — even if they don't say 'template'. Apply when starting a new app, building internal tools, dashboards, admin portals, authentication flows, or data table views.