sl-design-system/components/implement-design-lit

Claude Code and agent skill by sl-design-system/components

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Lit/LitElement implementation conventions for the /implement-design pipeline. Loaded on demand by component-implementer (and component-author) when the chosen framework is Lit.

Install

npx vskill@latest install sl-design-system/components/implement-design-lit

SKILL.md

Implementing an SLDS component in Lit

This is the framework skill for Lit in the /implement-design pipeline. The full, detailed Lit conventions live in `../implement-design/component-conventions.md` (relative to this skill's folder; the orchestrator also passes its absolute path) — read that file; it is the authoritative Lit reference. This skill is a checklist of the Lit-specific essentials it covers.

Scaffolding

  • A published package (packages/components/<name>/) has package.json in the root and everything else under src/: index.ts (re-export), register.ts (customElements.define), <name>.ts, <name>.css, <name>.stories.ts. There is no per-package `tsconfig.json`/ESLint/stylelint config — the shared ones in packages/components/ cover every component. An example (folder under the chosen app/example path) is lighter — .ts + .css + .stories.ts co-located, sharing the example package's existing index.ts/tsconfig.json; no package.json/register.ts. Copy boilerplate from a neighbour; use .js import specifiers for .ts modules.
  • No monorepo registration needed — the root packages/components/* workspace glob and tsdown's workspace: '*' pick a new package up automatically. Run yarn install from the repo root after scaffolding.
  • exports / publishConfig.exports in package.json are generated by tsdown on build — copy them from the component you mirror (the @sl-design-system/source condition in exports → ./src/*.ts, default → ./dist/*.js, and publishConfig.exports → ./dist/*.js) and don't hand-tune them. Local development tools enable the source condition; consumers use default without relying on npm to apply publishConfig.exports. Entry points default to src/index.ts + src/register.ts; extra ones go in a tsdown: { entry: [...] } field listing all of them.

The element

  • extends LitElement; @property({ reflect: true }) for attributes that drive selectors; exported string-union types for enums; full JSDoc.
  • Scoped custom elements: a component that renders other custom elements in its shadow uses ScopedElementsMixin(LitElement) + static scopedElements; child components used only inside a parent do not customElements.define — only the root/public component registers globally.
  • Accessibility: formAssociated / FormControlMixin for value-holding controls; ForwardAriaMixin to forward aria-*. Never <main>/role="main".

Events

  • Emit with the `@event` decorator + `EventEmitter` from @sl-design-system/shared — never hand-roll new CustomEvent(...) + this.dispatchEvent(...). Export a CustomEvent type alias (export type SlSaveEvent = CustomEvent<{ value: T }>;, CustomEvent<void> when no detail), add it to GlobalEventHandlersEventMap in the file's declare global, declare the emitter (@event({ name: 'sl-save' }) saveEvent!: EventEmitter<SlSaveEvent>;), and fire it via this.saveEvent.emit(detail) (or .emit() for void). emit already defaults to bubbles: true, composed: true. Mirror packages/components/tabs, tree, or form.

Styles

  • Plain `.css` (not .scss), imported via an import attribute: import styles from './<name>.css' with { type: 'css' }; → static override styles = styles;. No build step, no `.scss.ts` — the @sl-design-system/rolldown-plugin-css-sheet plugin transforms the { type: 'css' } import into a CSSStyleSheet (typed by vite-env.d.ts) for Storybook/Vite, Vitest and the tsdown build alike, and .css edits hot-reload in the running dev server (no restart).
  • Design tokens only — no `var()` fallbacks, light-mode semantic tokens even for dark designs, logical properties. Prefer styling a component's ::part() over wrapper <div>s.
  • A --sl-text-new-* token is a font: shorthand that resets font-weight to normal — add an explicit font-weight: var(--sl-fontWeight-600|700) after it for any semibold/bold text (otherwise headings/badges render un-bold).

Icons

  • Every <sl-icon name="..."> needs Icon.register(faX) (import faX from @fortawesome/pro-*-svg-icons) at module load in the component that renders it.

Forms

  • A single <sl-form> wraps all controls and the action bar — and lives in the same component as the controls (don't wrap a child component in a parent-level form; that yields a separate/dummy form). Manage it with a `FormController<T>(this)` on that component — give each control a name, set the whole value from the component's value input (this.#form.value = this.value in updated()), and read this.#form.value / reportValidity() / reset() for the buttons. Never bind `.value` per field. The data-owner parent passes the initial value in and handles the form component's emitted save/cancel events.

i18n (when enabled)

  • Reference: Lit's own localization guide — <https://lit.dev/docs/localization/overview/> (covers @lit/localize, msg(), @localized(), runtime vs. transform mode, and lit-localize extraction). Consult it when unsure about the API.
  • import { localized, msg } from '@lit/localize';, @localized() on every component that shows text, every user-visible label as msg('<English>', { id: '<sl.namespaced.id>' }) in that component's own `render`.
  • Models carry data + stable keys, not translated strings. Localize in render keyed off the model value via a `switch` returning a literal `msg()` per case — msg() requires a LITERAL source string and literal id (lit-localize extracts statically); msg(map[key].en, { id: map[key].id }) silently fails to extract. Never accept a pre-translated label/title through a @property model. Per-record free text (names, titles from the data) is rendered directly. A non-English design renders its English source at runtime until the translated locale is loaded — expected.
  • Structural config (column sets, fixed tabs, option lists) is a local constant in the component, not a model input.

Stories (authored during implementation)

  • Write a basic Storybook story (@storybook/web-components-vite) as part of implementing the component — before visual validation, which needs it to render. Page components set parameters: { layout: 'fullscreen' }. Stage 5 adds variant stories.

Tests / Docs / Changeset (Stage 5) — only for published packages

  • For a packages/components/* package: Vitest browser tests via fixture, website docs under website/, and a changeset. For an example/app target, skip these — produce only the component + story (match the neighbouring examples).

Build / verify

  • No style build step, and no build needed while developing — Storybook and the tests consume the TypeScript sources directly. Type-check against the tsconfig that covers your target: npx tsc -p packages/components/tsconfig.json --noEmit for an SLDS package, npx tsc -p examples/lit/tsconfig.json --noEmit for a Lit example. Both cover every file in that tree, so only fix the errors in your files — pre-existing ones elsewhere aren't yours.
  • Tests run from the repo root: yarn vitest --project=unit --run <path> (drop --run for watch mode).
  • A full build is yarn build (tsdown); components only is yarn tsdown --config packages/components/tsdown.config.mjs, with --filter <package-name> for a single package.
  • Run the dev server with yarn start; .css and template edits hot-reload — do not restart Storybook to pick up changes.

See component-conventions.md for the full detail of every point above (data ownership, single <sl-form>, tab lazy-load with sl-tab-group+sl-tab only, reproduce-the-design content fidelity, naming).

Security

  • Security scanPassed, 91 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
67
Repository forks
8
7-day trend score
21

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/sl-design-system/components/implement-design-lit/badge)](https://verified-skill.com/skills/sl-design-system/components/implement-design-lit)

Something wrong with this skill or its page? Tell us.