diff --git a/.cursor/README.md b/.ai/README.md similarity index 74% rename from .cursor/README.md rename to .ai/README.md index 55e5dde33c1..be0cb95cc39 100644 --- a/.cursor/README.md +++ b/.ai/README.md @@ -1,6 +1,16 @@ -# Cursor documentation +# AI and agent documentation -This directory contains rules and skills that Cursor uses to enforce consistent formatting and structure in our codebase. +Coding agents should start with [`AGENTS.md`](../AGENTS.md) at the repository root. It summarizes how to use this directory as the canonical source for rules and skills. + +This directory contains rules, skills, and accumulated memory that coding agents use to enforce consistent formatting and structure in our codebase. + +## Why `.ai/` + +All rules and skills now live in **`.ai/`** — a tool-agnostic, plain-markdown directory that any agent or tool can read. IDE-specific directories (`.cursor/`, `.claude/`) become thin adapters that point back to `.ai/` via symlinks: + +- Edit once in `.ai/` → all tools see the update automatically +- No sync step, no duplication, no drift between tools +- New contributors or tools start from `AGENTS.md` at the repo root, which bootstraps everything ## Rules @@ -21,7 +31,7 @@ Rules defined in the `config.json` follow this structure: } ``` -Additional, more specific rules can be found in the `rules` directory in either a `json` or `mdc` format. +Additional, more specific rules can be found in the `rules` directory in either a `json` or `md` format. ### Available rules @@ -39,7 +49,7 @@ Additional, more specific rules can be found in the `rules` directory in either - **required_sections**: Ensures required sections are present - **templates**: Enforces template structure for different ticket types - **labels**: Validates that only allowed labels are used -- **issue_types**: Ensures correct issue type selectionc +- **issue_types**: Ensures correct issue type selection #### Styles @@ -55,7 +65,7 @@ Additional, more specific rules can be found in the `rules` directory in either - **branch_format**: Recommends `username/type-description[-swc-XXX]` format - Uses conventional commit types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert` - - Commit type list and validation pattern: `.cursor/config.json` (`git.types`, `validationPattern`). When adding or removing a type, update both `types` and `validationPattern` together. + - Commit type list and validation pattern: `.ai/config.json` (`git.types`, `validationPattern`). When adding or removing a type, update both `types` and `validationPattern` together. - Lowercase letters and numbers only, words separated by dashes - Severity: Warning (recommended, not required) @@ -104,14 +114,14 @@ These two rules share the same glob (`2nd-gen/**/stories/**`) and work as a pair #### Deep understanding - **apply_intelligently**: Use for non-trivial work (multiple files, new area, complex behavior); do not use for simple, self-contained requests (e.g. creating a regex, one-line fix, single known file) to avoid wasting tokens and overloading context. Before writing non-trivial code, do deep research on the relevant part of the codebase first. -- **action** (when the rule applies): Scope → deep read → write persistent report (e.g. research.md at repo root) → pause for user review → proceed only after validation. Full workflow in `.cursor/skills/deep-understanding/SKILL.md` +- **action** (when the rule applies): Scope → deep read → write persistent report (e.g. research.md at repo root) → pause for user review → proceed only after validation. Full workflow in `.ai/skills/deep-understanding/SKILL.md` - **rationale**: The written report is the review surface; wrong research leads to wrong plan and wrong code (garbage in, garbage out) ### When rules are activated **Always-applied rules:** Rules use `alwaysApply: true` to activate automatically, or `globs` to activate when matching files are edited. **On-demand rules:** Rules with `alwaysApply: false` and no globs are on-demand only (activated by `@` mentioning them in chat). -**Config-based rules:** The `config.json` also defines structured validation for Cursor (or other tooling) to verify branch names, Jira ticket drafts, text-formatting, etc.: +**Config-based rules:** The `config.json` also defines structured validation for editors and other tooling to verify branch names, Jira ticket drafts, text-formatting, etc.: - **text_formatting.headings**: Sentence case enforcement with technical term exceptions - **text_formatting.patterns**: File patterns for text formatting (`**/*.md`, `**/*.txt`, `**/*.mdx`) @@ -152,7 +162,7 @@ These two rules share the same glob (`2nd-gen/**/stories/**`) and work as a pair ### Usage -1. Cursor will automatically enforce these rules while editing relevant files; however, if you wish to enable a rule that is not triggered by default, you can do so by `@` mentioning it in the chat. +1. Rules are automatically enforced by your coding agent while editing relevant files; however, if you wish to enable a rule that is not triggered by default, you can do so by mentioning it in the chat (e.g. `@` in Cursor, or by name in Claude Code). 2. Rules can be toggled using the `enabled` flag 3. Custom error messages will be shown when rules are violated 4. Exceptions are handled through the `exceptions` field in relevant rules @@ -173,6 +183,14 @@ Skills are used on-demand. When a task matches a skill’s purpose, the agent re ### Available skills +#### Accessibility migration analysis + +- **purpose**: Create accessibility migration analysis docs for the "analyze accessibility" step of 2nd-gen component migration +- **How to invoke**: Say "create accessibility analysis for [component]", "analyze accessibility for [component]", or "accessibility migration for [component]". Also invoked when you refer to the "analyze accessibility" step in the 2nd-gen component migration workstream. +- Use when: On the analyze-accessibility step for one or more components; creating one markdown file per component at `CONTRIBUTOR-DOCS/03_project-planning/03_components/[component-name]/accessibility-migration-analysis.md` +- Applies to: `CONTRIBUTOR-DOCS/**/accessibility-migration-analysis.md` +- Provides: Required section order, ARIA recommendations structure, Shadow DOM guidance, keyboard and focus conventions, testing table format, reference examples + #### Accessibility compliance - **purpose**: Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support @@ -192,7 +210,7 @@ Skills are used on-demand. When a task matches a skill’s purpose, the agent re - **purpose**: Run the CONTRIBUTOR-DOCS nav script to update breadcrumbs and TOCs, and handle link verification - **How to invoke**: Say “update contributor docs nav”, “regenerate TOC”, “fix broken links in CONTRIBUTOR-DOCS”, or “run the nav script”. Also invoked when you add, remove, rename, or move files under `CONTRIBUTOR-DOCS/` or change H1/H2/H3 headings (the contributor-doc-update rule may trigger; the skill holds the full workflow). - Use when: Updating contributor docs structure, regenerating navigation, or fixing reported broken links -- Provides: Operator workflow (run script, verify, fix links), Maintainer workflow (when to update script). Full instructions in `.cursor/skills/contributor-docs-nav/references/ai-agent-instructions.md` +- Provides: Operator workflow (run script, verify, fix links), Maintainer workflow (when to update script). Full instructions in `.ai/skills/contributor-docs-nav/references/ai-agent-instructions.md` #### Component migration (rendering and styling) @@ -201,6 +219,13 @@ Skills are used on-demand. When a task matches a skill’s purpose, the agent re - Use when: On the analyze-rendering-and-styling step for one or more components; creating one markdown file per component at `CONTRIBUTOR-DOCS/03_project-planning/03_components/[component-name]/rendering-and-styling-migration-analysis.md` - Provides: Workflow summary (specs from CSS + SWC, three-way DOM comparison, CSS⇒SWC mapping table, summary). Full instructions in `CONTRIBUTOR-DOCS/03_project-planning/02_workstreams/02_2nd-gen-component-migration/02_step-by-step/01_analyze-rendering-and-styling/cursor_prompt.md` +#### Consumer migration guide + +- **purpose**: Create per-component migration guides for application developers upgrading from 1st-gen Spectrum Web Components to 2nd-gen components +- **How to invoke**: Say “create a consumer migration guide for [component]”, “write an upgrade guide for [component]”, or “document how consumers migrate [component] from 1st-gen to 2nd-gen”. +- Use when: Writing one markdown file per component at `CONTRIBUTOR-DOCS/03_project-planning/03_components/[component-name]/consumer-migration-guide.md` with code updates, styling guidance, accessibility notes, testing changes, and rollout advice +- Provides: Workflow summary (verified source inputs, required section order, before/after examples, migration checklist, rollout guidance). Full instructions in `.ai/skills/consumer-migration-guide/references/consumer-migration-guide-prompt.md` + #### Washing machine migration workflow - **purpose**: End-to-end 1st-gen → 2nd-gen migration sequence (phases, checklists, links to step docs and style guides) @@ -249,20 +274,59 @@ Skills are used on-demand. When a task matches a skill’s purpose, the agent re - Use when: Implementing any feature or bugfix, before writing implementation code - Provides: TDD cycle, verification checklist, good/bad test examples, anti-patterns to avoid -## Using rules and skills in other IDEs +## Using rules and skills across tools and IDEs + +Canonical content lives in **`.ai/`** (this directory). Tool-specific directories (`.cursor/`, `.claude/`) are thin adapters that point back here via symlinks — edit files in `.ai/`, never in the adapter directories. + +### Current symlink structure + +```text +.ai/rules/ +└── *.md ← canonical, tool-agnostic source of truth + +.ai/skills/ +└── /SKILL.md ← canonical, tool-agnostic source of truth + +.cursor/rules/ +└── *.mdc → ../../.ai/rules/*.md (per-file symlinks; Cursor expects .mdc) +.cursor/skills/ → ../.ai/skills/ (directory symlink) + +.claude/rules/ → ../.ai/rules/ (directory symlink; Claude Code reads .md) +.claude/skills/ → ../.ai/skills/ (directory symlink) +``` + +Editing any `.ai/rules/*.md` file immediately updates what both Cursor and Claude Code see — no sync step required. + +### Adding a new rule + +1. Create `rule-name.md` in `.ai/rules/` with YAML frontmatter (`globs`, `alwaysApply`). +2. Add one per-file symlink for Cursor (required — Cursor needs `.mdc` extension): + + ```sh + ln -s “../../.ai/rules/rule-name.md” “.cursor/rules/rule-name.mdc” + ``` + + `.claude/rules/` is a directory symlink pointing at `.ai/rules/`, so it picks up the new file automatically — no extra step needed. + +3. Register it in the tables in this README (rules catalog) and in [`AGENTS.md`](../AGENTS.md). + +### Adding a new skill -The rules and skills in this directory are set up for **Cursor** and are applied automatically when you use Cursor in this repo. If you use a different AI-enabled IDE (e.g. Windsurf, Zed, or another editor with built-in AI), that tool will not automatically read `.cursor/` — each IDE has its own config locations and formats. +1. Create `.ai/skills//SKILL.md`. +2. Register it in the skills catalog below and in [`AGENTS.md`](../AGENTS.md). +3. Both `.cursor/skills/` and `.claude/skills/` pick it up automatically via directory symlinks. -You can still get the same guidance in another IDE: +### Using rules and skills in other environments -- **Copy or adapt the contents** of `rules/` and `skills/` into your IDE’s equivalent config (e.g. your IDE’s project rules, instructions, or “AI context” directory). The content is markdown and JSON, so it’s portable; you may need to adjust paths or format to match your IDE’s schema. -- **Reference the files when prompting** — e.g. “Follow the rules in `.cursor/README.md` and the rules in `.cursor/rules/` when relevant” or “Use the workflow in `.cursor/skills/contributor-docs-nav/SKILL.md` for this task.” +If you use a tool that does not read `.cursor/` or `.claude/`, point it at `.ai/` directly: -Keeping rules and skills in this repo means everyone can use the same standards; Cursor users get them automatically, and non-Cursor users can copy or point their IDE at the same content. +- **Start from [`AGENTS.md`](../AGENTS.md)** at the repository root. +- **Reference files when prompting** — for example: “Follow the rules in `.ai/rules/` and load `.ai/skills/deep-understanding/SKILL.md` for this task.” +- **Copy or adapt** the markdown and JSON content into your tool’s own config format as needed. ## MCPs -When developing for the SWC project, there may be instances where Cursor needs context from external sources. Contributors and maintainers can configure [MCP (Model Context Protocol) servers](https://modelcontextprotocol.io/docs/getting-started/intro) via [Easy MCP](https://wiki.corp.adobe.com/display/assetscollab/Cursor+integration+with+Easy+MCP). Some recommended MCP servers might include: +When developing for the SWC project, there may be instances where your coding agent needs context from external sources. Contributors and maintainers can configure [MCP (Model Context Protocol) servers](https://modelcontextprotocol.io/docs/getting-started/intro) via [Easy MCP](https://wiki.corp.adobe.com/display/assetscollab/Cursor+integration+with+Easy+MCP). Some recommended MCP servers might include: - Figma - Corp Jira diff --git a/.cursor/config.json b/.ai/config.json similarity index 100% rename from .cursor/config.json rename to .ai/config.json diff --git a/.ai/rules/branch-naming.md b/.ai/rules/branch-naming.md new file mode 100644 index 00000000000..dd4f7e87d7a --- /dev/null +++ b/.ai/rules/branch-naming.md @@ -0,0 +1,63 @@ +--- +description: Suggests the preferred branch naming format for Spectrum Web Components contributions — lowercase, dash-separated, with a conventional commit type and optional issue number. +globs: +alwaysApply: true +--- + +# Branch naming format + +Suggests the ideal branch naming format for Spectrum Web Components contributions. + +## Pattern + +``` +^[a-z0-9]+\/(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)-[a-z0-9-]+(-swc-[0-9]+)?$ +``` + +The canonical list of types and the validation pattern are defined in `.ai/config.json` under `git.types` and `validationPattern`. + +## Message + +Consider following the preferred branch naming format: `/-[-swc-]` + +Username will be automatically pulled from your git config settings. + +### Guidelines + +- Use lowercase letters and numbers only +- Separate words with dashes (not camelCase) +- Use conventional commit types from `.ai/config.json` (`git.types`). Descriptions below are for quick reference: + • **feat**: New feature + • **fix**: Bug fix + • **docs**: Documentation only + • **style**: Code style/formatting + • **refactor**: Code change that neither fixes a bug nor adds a feature + • **perf**: Code change that improves performance + • **test**: Adding missing tests or correcting existing tests + • **build**: Changes that affect the build system or external dependencies + • **ci**: Changes to CI configuration files and scripts + • **chore**: Other changes that don't modify src or test files, dependency updates + • **revert**: Reverts a previous commit +- Optional issue number format: `-swc-XXX` + +### Good examples + +- `johndoe/feat-add-new-button-swc-123` +- `janedoe/fix-dropdown-alignment` +- `alice/refactor-component-structure` +- `bob/perf-optimize-rendering` + +### Avoid + +- `johnDoe/feat-addNewButton` (no camelCase) +- `jane/fix-Dropdown-Bug` (no uppercase) + +This is a recommended format to maintain consistency, but not required. + +## Severity + +warning + +## Scope + +git_branch diff --git a/.ai/rules/component-readme.md b/.ai/rules/component-readme.md new file mode 100644 index 00000000000..32446c5a334 --- /dev/null +++ b/.ai/rules/component-readme.md @@ -0,0 +1,213 @@ +--- +description: Guidelines for component README documentation structure and accessibility compliance +globs: 1st-gen/packages/*/README.md +alwaysApply: false +--- + +# Component README documentation guidelines + +Use this rule when editing or creating component README files in `1st-gen/packages/*/README.md`. + +## When to apply + +Apply when the user requests any of the following: + +- Reorganize or restructure a component README +- Update component documentation +- Add accessibility documentation to a component +- Create documentation for a new component +- Review README structure for a11y compliance +- Standardize README format + +## Required document structure + +Component READMEs must follow this heading hierarchy. All sections are required unless the component genuinely has no content for that section. + +```md +## Overview + +A brief description of what the component does and when to use it. + +### Usage + +NPM badges, yarn install command, and import statements. + +### Anatomy + +The parts of the component (labels, icons, slots, etc.) with examples. + +### Options + +Configurable options like sizes, variants, and visual treatments. + +### States + +Interactive states like disabled, pending, invalid, loading. + +### Behaviors + +Events, methods, values, and user interactions. + +### Accessibility + +Tips on accessible usage and notes on a11y considerations in development. +``` + +## Heading rules + +- Start with `## Overview` (not `# Component Name`) +- Use `###` for subsections within main sections +- Use `####` for sub-subsections when needed +- Maintain logical hierarchy (never skip levels) +- See W3C WAI [Headings tutorial](https://www.w3.org/WAI/tutorials/page-structure/headings/) + +## Usage section format + +Include in this order: + +1. NPM badges (see it on NPM, bundle size, try on Stackblitz) +2. Yarn install command +3. Side-effectful import statement +4. Base class import for extension + +Example: + +````md +[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/COMPONENT?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/COMPONENT) +[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/COMPONENT?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/COMPONENT) + +```bash +yarn add @spectrum-web-components/COMPONENT +``` + +Import the side effectful registration of `` via: + +```ts +import '@spectrum-web-components/COMPONENT/sp-COMPONENT.js'; +``` + +When looking to leverage the `ComponentName` base class as a type and/or for extension purposes, do so via: + +```ts +import { ComponentName } from '@spectrum-web-components/COMPONENT'; +``` +```` + +## Using sp-tabs for examples + +Use `` to organize related examples (sizes, variants, states). Always include: + +- `selected` attribute for the default tab +- `auto` attribute for automatic tab selection +- `label` attribute for accessibility + +Pattern: + +````html + + Small + + ```html demo + + ``` + + Medium + + ```html demo + + ``` + + +```` + +## Code example requirements + +All code examples must be accessible: + +1. **Labels required**: Every interactive component needs a visible label or `label` attribute +2. **Field labels**: Use `` paired with the component's `id` +3. **Icon-only buttons**: Must have `label` attribute on the button or icon +4. **SVG icons**: Include `aria-hidden="true" role="img"` or provide `label` +5. **Unique IDs**: Use unique `id` values (e.g., `picker-m`, `picker-l` for size variants) + +Good example: + +```html +Selection type: + + Option 1 + +``` + +Bad example: + +```html + + + Option 1 + +``` + +## Accessibility section requirements + +The accessibility section must include: + +1. **Usage guidance**: How to use the component accessibly +2. **Label requirements**: What labeling is required +3. **Keyboard considerations**: If applicable +4. **Screen reader notes**: Any AT-specific behavior +5. **Development notes**: Cross-root ARIA issues or other implementation details + +Use `` for keyboard actions when documenting keyboard interactions. +Use `` tags for keyboard keys (e.g., `Tab`, `Enter`). + +Link to related component accessibility sections: + +```md +Review the accessibility guidelines for [menu-item](../menu-item#accessibility). +``` + +## Cross-component references + +Link to related components using relative paths: + +- `[sp-menu-item](../menu-item)` - link to component +- `[accessibility section](../menu-item#accessibility)` - link to specific section + +## Prompt template for reorganizing READMEs + +When asked to reorganize a README, follow this process: + +1. **Do not remove any content** - Only reorganize and restructure +2. **Map existing content** to the required structure sections +3. **Use similar components as style references**: `menu`, `help-text`, `button`, `picker` +4. **Check the component's TypeScript file** for API details to document +5. **Follow the adding-component documentation standards** + +## Reference documents + +- [Documentation standards](https://opensource.adobe.com/spectrum-web-components/guides/adding-component/#documentation-standards) +- [Documentation structure](https://opensource.adobe.com/spectrum-web-components/guides/adding-component/#documentation-structure) +- [Spectrum Design System](https://spectrum.adobe.com/) for consistent language + +## Example component READMEs + +Reference these well-structured READMEs: + +- `packages/menu/README.md` - Good sp-tabs usage, accessibility cross-references +- `packages/help-text/README.md` - Good contextual examples, cross-root ARIA notes +- `packages/button/README.md` - Comprehensive options and accessibility guidance +- `packages/picker/README.md` - Complex anatomy, help text integration + +## Validation checklist + +Before completing a README update, verify: + +- [ ] Starts with `## Overview` (not h1) +- [ ] All six main sections present (Overview, Usage, Anatomy, Options, States, Behaviors, Accessibility) +- [ ] Heading hierarchy is correct (no skipped levels) +- [ ] All code examples have accessible labels +- [ ] `` have `auto` and `label` attributes +- [ ] Links to related components use relative paths +- [ ] Accessibility section has substantive guidance +- [ ] Language matches Spectrum Design System terminology diff --git a/.ai/rules/contributor-doc-update.md b/.ai/rules/contributor-doc-update.md new file mode 100644 index 00000000000..dc83ef1e952 --- /dev/null +++ b/.ai/rules/contributor-doc-update.md @@ -0,0 +1,50 @@ +--- +description: Useful for updating auto-generated navigation and validating links in the contributor docs +globs: CONTRIBUTOR-DOCS/** +alwaysApply: false +--- + +# Contributor docs navigation and link validation + +## When to run the nav script + +**1. When the user asks** for any of the following: + +- Update contributor docs navigation / nav / TOC / breadcrumbs +- Regenerate contributor docs +- Validate or verify links in contributor docs +- Fix broken links in contributor docs +- CONTRIBUTOR-DOCS or contributor docs with "update", "nav", "links", or "verify" + +**2. When you change CONTRIBUTOR-DOCS structure or content:** + +- Add, remove, rename, or move files or folders under `CONTRIBUTOR-DOCS/` +- Change document H1, H2, or H3 headings + +## What to do + +1. **Run the nav script** from the contributor docs script folder (from project root): + ```bash + cd CONTRIBUTOR-DOCS/01_contributor-guides/07_authoring-contributor-docs + node update-nav.js + ``` +2. **Confirm** the script completes without errors. +3. **Fix any link verification errors** reported by the script (fix straightforward cases; consult the user for ambiguous ones). +4. **Report results** to the user (files updated, link counts, any remaining issues). + +**Skill:** For full Operator and Maintainer workflows, use the contributor-docs-nav skill (`.ai/skills/contributor-docs-nav/SKILL.md`); it points to the full instructions below. + +Full instructions: `.ai/skills/contributor-docs-nav/references/ai-agent-instructions.md` (Role 1: Operator). + +## If the instructions file is missing + +If the file above is not found: + +1. Search for `**/ai-agent-instructions.md` and find the one under `.ai/skills/contributor-docs-nav/references/`. +2. Read it to confirm it contains the nav update instructions. +3. Update this rule with the correct path, inform the user, then run the nav process. + +## Quick reference + +- Script updates breadcrumbs, TOC, and validates all links (~20–200ms for the tree). +- Fix broken links automatically when the fix is clear; ask the user when the target is gone or intent is unclear. diff --git a/.ai/rules/deep-understanding.md b/.ai/rules/deep-understanding.md new file mode 100644 index 00000000000..3484f99eee4 --- /dev/null +++ b/.ai/rules/deep-understanding.md @@ -0,0 +1,20 @@ +--- +description: Apply intelligently. For non-trivial work, do deep research and write findings to a persistent file (e.g. research.md at repo root) before code. Do not apply for simple, self-contained requests (e.g. creating a regex, one-line fix, single known file). +alwaysApply: false +--- + +# Deep understanding + +**Apply intelligently.** Use this rule when the task is non-trivial (multiple files, new or unfamiliar area, complex behavior, or would benefit from a shared understanding document). Do not apply for simple, self-contained requests — e.g. creating a regex pattern, a one-line fix, a single known file, or a quick question — to avoid wasting tokens and overloading context. + +When the rule applies, do deep research before writing any code: + +1. **Scope** the relevant folder, flow, or system from the user’s request. +2. **Deep read** that area — understand how it works in depth, not at signature level only. Do not skip to planning or code. +3. **Write** your findings to a persistent markdown file (e.g. `research.md` at repo root). No verbal-only summary; the file is the artifact. +4. **Pause for review** — present the report to the user and do not proceed to planning or implementation until they have reviewed (or explicitly approve). +5. **Proceed only after validation** — if the user corrects the report, update it; only then move on to code. + +**Trivial tasks:** For very small, single-file edits (e.g. typo, one-line fix), a short in-chat confirmation of understanding in the form of a question is acceptable instead of a full research report. Confirm in chat before editing code. + +Follow the full workflow and rationale in `.ai/skills/deep-understanding/SKILL.md`. The written report is the review surface; wrong research leads to incorrect planning and wasted implementation time. diff --git a/.ai/rules/github-description.md b/.ai/rules/github-description.md new file mode 100644 index 00000000000..219b003ff0c --- /dev/null +++ b/.ai/rules/github-description.md @@ -0,0 +1,246 @@ +--- +description: Generates GitHub pull request and issue descriptions — title, labels, and body — following Spectrum Web Components conventions. Prompts for a linked ticket if none is provided. +globs: +alwaysApply: false +--- + +# GitHub description guidelines + +If a ticket (GitHub issue or Jira ticket) is not provided by the prompt, prompt the user to supply one before generating the description or pull request content. + +When prompted to create a GitHub description, output the following: + +- Title +- Labels +- Description + +Output results in the chat window in a way that can be copied and pasted into GitHub. + +## GitHub markdown formatting rules + +Use these syntax rules when writing GitHub descriptions: + +- `##` through `######` - Headings (use `##` for main, `###` for secondary, etc.) +- `**text**` - Bold text +- `` `code` `` - Inline code +- `` `language` `` - Language-specific code blocks +- `[text](url)` - Links +- `-` - Bullet points +- `1.` - Numbered list items +- `>` - Blockquotes for important notes +- `~~text~~` - Strikethrough for deprecated content + +## Title format + +- Use the format: `[Component] Brief description of change or issue` +- Keep titles concise but descriptive (under 80 characters) +- Use present tense for the description (e.g., "Add" not "Added") +- For PRs, include the component name in brackets if applicable + +## Description structure + +- Present title, labels, and type before description content +- Description format and structure should follow the pull request template in the Templates section below +- Accessibility testing checklist is required. Populate keyboard and screen reader with component-specific numbered + steps (Storybook paths, expected focus behavior, what should be announced). For non-interactive components (e.g. static + elements, dividers), state that clearly under Keyboard (e.g. no focusable parts; confirm no regressions in surrounding + examples) and still document Screen reader checks (roles, structure, labels). +- Include links to related issues, RFCs, or documentation when applicable +- All descriptions must include clear acceptance criteria or expected outcomes +- Provide enough context so anyone can understand the objective +- Use prefixes in titles: [Bug], [Fix], [Docs], [Refactor], [Research], [S2], [Test] + +Examples: + +- [bug]: +- [Bug(component)]: +- [fix]: +- [Fix(component)]: +- [docs]: +- [Docs(component)]: + +## Severity classification + +- SEV1: Critical - System down, data loss, security breach +- SEV2: High - Major feature broken, significant user impact +- SEV3: Medium - Feature partially broken, moderate impact +- SEV4: Low - Minor issues, minimal user impact +- SEV5: Trivial - Cosmetic issues, no functional impact + +## Best practices + +- Link to relevant issues using the format: `#issue-number` +- Include component name in brackets if applicable: `[sp-button]` +- Add relevant labels for easier filtering +- Attach screenshots or videos for visual changes +- Reference design specs or documentation when available +- Use descriptive commit messages when linking to PRs +- Include reproduction steps for bugs +- Add environment information when relevant + +## Acceptance criteria + +- Write criteria in "Given/When/Then" format +- Make criteria specific and testable +- Include edge cases and error scenarios +- Consider accessibility requirements +- Include performance considerations when relevant + +## Labels + +Use the following labels to categorize pull requests. Only use labels that exist in the repository. GitHub labels are separate from Jira labels; for Jira tickets use the jira-ticket rule and `config.json`. + +### Priority and release labels + +- `1.0.0`: Issues that should be addressed for a 1.0 release +- `2.0.0`: Issues for 2.0 release +- `Breaking`: Breaking changes + +### Platform and browser labels + +- `Android`: Android-specific issues +- `Browser: Chrome`: Chrome browser issues +- `Browser: Edge (Legacy)`: Issue with pre-chromium Edge +- `Browser: FireFox`: Firefox browser issues +- `Browser: Safari`: Safari browser issues +- `iOS`: iOS-specific issues and bugs + +### Development and process labels + +- `a11y`: Issues related to accessibility +- `API`: Changes to component APIs or interfaces + +### Additional labels (partial list) + +Note: The repository has 160 labels total. For a complete list, visit [https://github.com/adobe/spectrum-web-components/labels](https://github.com/adobe/spectrum-web-components/labels) + +Common additional labels include: + +- `chore`: Routine tasks, maintenance, or non-feature changes +- `dependencies`: Updates or changes to project dependencies +- `Documentation`: Documentation updates or improvements +- `feature`: New feature implementations or improvements to existing features +- `i18n`: Internationalization and localization work +- `mobile`: Mobile platform issues and responsive design +- `performance`: Performance-related improvements or regressions +- `refactor`: Code restructuring and refactoring work +- `regression`: Previously working functionality that is now broken +- `release`: Release process or versioning changes +- `research`: Tasks requiring investigation or research +- `RFC`: Request for Comments or design discussions +- `testing`: Test implementation or testing infrastructure work + +## Pull request guidelines + +- Include the Accessibility testing checklist section in every drafted PR body (see Description structure and the template below). +- Use conventional commit messages +- Keep PRs focused and small when possible +- Include tests for new features +- Update documentation when APIs change +- Add screenshots for visual changes +- Link to related issues using keywords like "Fixes #123" or "Closes #456" +- Request reviews from appropriate team members +- Use draft PRs for work in progress + +## Templates + +### Pull request template + +**Note:** All pull requests should include the `ready-for-review` label. + +**When returning the template, check off the author requirements in the Author's checklist section. Do not check off the Manual review test cases or Device review sections as these are for reviewers to complete. Fill in the **Accessibility testing checklist** with concrete steps; leave its checkboxes unchecked unless the user confirms testing is done.** + +```markdown + + +## Description + + + +## Motivation and context + + + +## Related issue(s) + + + +- fixes [Issue Number] + +## Screenshots (if appropriate) + +## Author's checklist + + + +- [ ] I have read the **[CONTRIBUTING](<(https://github.com/adobe/spectrum-web-components/blob/main/CONTRIBUTING.md)>)** and **[PULL_REQUESTS](<(https://github.com/adobe/spectrum-web-components/blob/main/PULL_REQUESTS.md)>)** documents. +- [ ] I have reviewed at the Accessibility Practices for this feature, see: [Aria Practices](https://www.w3.org/TR/wai-aria-practices/) +- [ ] I have added automated tests to cover my changes. +- [ ] I have included a well-written changeset if my change needs to be published. +- [ ] I have included updated documentation if my change required it. + +## Reviewer's checklist + +- [ ] Includes a Github Issue with appropriate flag or Jira ticket number without a link +- [ ] Includes thoughtfully written changeset if changes suggested include `patch`, `minor`, or `major` features +- [ ] Automated tests cover all use cases and follow best practices for writing +- [ ] Validated on all supported browsers +- [ ] All VRTs are approved before the author can update Golden Hash + +### Manual review test cases + + + +- [ ] _Descriptive Test Statement_ + 1. Go [here](url) + 2. Do this action + 3. Expect this result + +- [ ] _Descriptive Test Statement_ + 1. Go [here](url) + 2. Do this action + 3. Expect this result + +### Device review + + + +- [ ] Did it pass in Desktop? +- [ ] Did it pass in (emulated) Mobile? +- [ ] Did it pass in (emulated) iPad? + +## Accessibility testing checklist + + + +**Required:** Complete each applicable item and document your testing steps (replace the placeholders with your component-specific instructions). + +- [ ] **Keyboard** (required — document steps below) + + 1. Go [here](url) + 2. Do this action + 3. Expect this result + +- [ ] **Screen reader** (required — document steps below) + + 1. Go [here](url) + 2. Do this action + 3. Expect this result +``` diff --git a/.ai/rules/jira-ticket.md b/.ai/rules/jira-ticket.md new file mode 100644 index 00000000000..d00fbb5ce7d --- /dev/null +++ b/.ai/rules/jira-ticket.md @@ -0,0 +1,465 @@ +--- +description: Guidelines for drafting and formatting Jira tickets +alwaysApply: false +--- + +# Jira ticket guidelines + +When prompted to create a Jira ticket, output the following: + +- Title +- Labels +- Severity +- Description + +Output results in the chat window in a way that can be copied and pasted into Jira. + +## Jira syntax formatting rules + +Use these syntax rules when writing Jira tickets: + +- `h2.` through `h6.` - Headings (use `h2.` for main, `h3.` for secondary, etc. - avoid `h1.` in descriptions) +- `*text*` - Bold text +- `{{code}}` - Inline code +- `{code:language}{code}` - Language-specific code blocks, as in `{code:js}{code}` for JavaScript and Typescript code blocks (JIRA doesn't support `{code:typescript}`) +- `[text|url]` - Links +- `-` - Bullet points +- `#` - Numbered list items + +## Title format + +- Use the format: `[Component] Brief description of change or issue` +- Keep titles concise but descriptive (under 80 characters) +- Use present tense for the description (e.g., "Add" not "Added") + +## Description structure + +- Present title, labels, and severity before description content +- Include links to GitHub pull requests or RFCs when applicable (prompt if not provided) +- All tickets must include acceptance criteria +- Provide enough context so anyone can understand the objective +- Use prefixes in titles: [Bug], [Fix], [Docs], [Refactor], [Research], [S2], [Test] + +Examples: + +- [Bug(component)]: +- [bug]: +- [Fix(component)]: +- [fix]: +- [Docs(component)]: +- [docs]: +- [Documentation]: +- [Refactor(component)]: +- [Research(component)]: +- [discovery]: +- [RFC(component)]: +- [S2 Foundations]: +- [S2]: +- [Test(component)]: + +## More specific templates + +### General Jira ticket template + +``` +h2. Acceptance criteria +(how we ensure that the work is complete) + +h2. Overview +(plain language explaining the ticket) + +h2. Technical notes/resources +(any technical notes/links/etc) + +h2. QA +(steps someone will use to be sure that the work fulfills the ticket's request and that everything's working properly) + +h2. Design specs +(are there any design specs/files/mock-ups we can include here? Any other design notes?) +``` + +### Bug reporting template + +``` +{*}Link to original issue:{*} (Add a link to the original issue in GitHub if applicable) + +h2. Expected behavior +(Description of what the user would expect to happen) + +h2. Actual behavior +(The actual behavior observed by the user) + +h2. Screenshots +(Screenshots of the problem if applicable) + +h2. How can we reproduce the issue? + +# Go to '...' +# Click on '....' +# Scroll to '....' +# Check console +# See error + +h2. Sample code or abstract reproduction which illustrates the problem +(are there any design specs/files/mock-ups we can include here? Any other design notes?) + +h2. Severity +(The severity of the issue according to the [documentation|https://github.com/adobe/spectrum-web-components/blob/main/CONTRIBUTING.md#issue-severity-classification]) +``` + +### RFC or feature ticket template + +This ticket template is for tracking work for RFCs, new features, new components, or research tickets. This template is not a substitute for the deliverable itself; rather, it's setting expectations for what the deliverable might look like and gives a high-level overview of the problem being tackled so that others can understand what is being worked on. + +Items with an asterisk are optional depending on the context. + +**Note:** For RFC tickets, generate three related tickets that must be completed sequentially: + +1. RFC authoring and initial review +2. Internal discussion shepherding +3. External community discussion shepherding + +#### First ticket: RFC authoring + +``` +h2. Link to original issue +(Add a link to the original issue in GitHub if applicable) + +h2. Overview +(The problem you're looking to explore solutions for or do research on) + +h2. Acceptance criteria +(What is the desired outcome of this RFC or research process? What would make this ticket "done"? What follow-up work would be required? Refer to the RFC guide for examples.) + +Additional acceptance criteria for RFC tickets: + - RFC has been added to the [Decisions and RFCs wiki|https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + - RFC link has been added to this ticket + - Announcement posted in {{spectrum-web-reviews}} Slack channel with internal comment deadline (minimum 1 week) + - Announcement posted in {{spectrum-web-engineering}} Slack channel with internal comment deadline (minimum 1 week) + - Internal discussion scheduled for SWC team sync after comment period + +h2. Estimated internal impact +(If implemented, what impact would this work have on other APIs, other components, the project structure, or team initiatives? Refer to the impact diagram for details.) + +h2. Estimated external impact +(If implemented, what impact would this work have on consumers or downstream/upstream dependencies?) + +h2. Anticipated reviewing audience +(Who would you like to provide feedback on your RFC/research? Your immediate team, your partners, or a wider consumer audience? What are their roles?) + +h2. Proposed solutions +(Pseudocode or short description that outlines what the solution might look like. You may not have any solutions yet.) + +h2. Supplementary documentation +(Has this feature or component been implemented in existing design specs or in another project? Share those here to paint a bigger picture of the end result. For architectural changes, have you seen this done in other libraries? Are there any tools you're looking at trying out to solve your problem?) + +h2. Additional context +(Add any other context, drafts, etc. if you have them) +``` + +#### Second ticket: Internal discussion shepherding + +Title format: `Research: Shepherd [RFC name] RFC through SWC Team Sync discussion` + +**Note:** This ticket must be completed after the first RFC authoring ticket. + +``` +h2. Link to RFC + + * RFC authoring Jira Ticket: [ticket URL] + + * Decisions and RFCs wiki: [https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + +h2. Overview + +This ticket tracks the work required to shepherd the *[RFC name] RFC* through the internal discussion process and prepare it for external community review. This includes facilitating internal review, updating the RFC based on feedback, scheduling community comment periods, and ensuring proper communication across all relevant channels. + +h2. Acceptance criteria + + - SWC team comments on the RFC have been reviewed and addressed + + - RFC discussion has been facilitated during SWC team sync meeting + + - RFC has been updated based on team discussion feedback + + - RFC is prepared and formatted for external discussion + + - Community comment period of at least two weeks has been scheduled + + - Office hours (or other open discussion) session has been scheduled following the comment period + + - If RFC discussion has been scheduled for office hours, it has been added to the office hours agenda + + - Scheduled comment period and discussion dates have been added to the RFC wiki + + - Announcement has been posted in the {{spectrum-web-components}} Slack channel + + - Announcement has been posted in the {{swc-announcements}} Slack channel + + - Individual consumers who may be impacted have been identified and contacted + +h2. Tasks + + # Review and respond to all SWC team comments on the RFC + + # Facilitate RFC discussion during scheduled SWC team sync + + # Update RFC document based on internal feedback and discussion + + # Prepare RFC for external discussion (formatting, clarity, completeness) + + # Schedule community comment period (minimum 2 weeks) + + # Schedule SWC office hours (or open discussion) session after comment period concludes + + # If discussion is during office hours, add RFC discussion to SWC office hours agenda + + # Update RFC wiki with scheduled dates: + + ** Comment period start and end dates + + ** Office hours (or other open discussion) date + + # Post announcement in {{spectrum-web-components}} Slack channel + + # Post announcement in {{swc-announcements}} Slack channel + + # Identify consumers potentially impacted by the RFC + + # Reach out to impacted consumers individually + +h2. Communication checklist + +h3. SWC Team channels: + + - Slack: {{spectrum-web-reviews}} + + - Slack: {{spectrum-web-engineering}} + + - SWC Team sync discussion (scheduled) + + - SWC Team RFC comment responses + +h3. External channels: + + - Slack: {{spectrum-web-components}} + + - Slack: {{swc-announcements}} + + - Individual consumer outreach + +h3. Documentation: + + - RFC wiki updated with timeline + + - If discussion is scheduled for office hours, office hours agenda updated + +h2. Timeline considerations + + - Minimum 2-week community comment period required + + - SWC Office hours (or other open discussion) must be scheduled for a date after comment period ends + + - Allow time for SWC team updates before opening for community comments + + - Build in buffer time for individual consumer outreach + +h2. Resources + + - [link to RFC] + + - [Decisions and RFCs wiki|https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + + - [SWC Office hours agenda|https://adobe.enterprise.slack.com/lists/T024FSURM/F089J8QEZ0V] + + - [SWC Team sync canvas|https://adobe.enterprise.slack.com/docs/T024FSURM/F089Y29EFFH] +``` + +#### Third ticket: External community discussion shepherding + +Title format: `Research: Shepherd [RFC name] RFC through Open discussion` + +**Note:** This ticket must be completed after the second internal discussion shepherding ticket. + +``` +h2. Link to RFC + + * RFC authoring Jira Ticket: [link to RFC ticket] + + * Decisions and RFCs wiki: [https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + +h2. Overview + +This ticket tracks the work required to shepherd the *[RFC name] RFC* through the community discussion process and to finalize the decision. This includes monitoring and responding to community feedback during the comment period, facilitating discussion during office hours, documenting the final decision, and creating follow-up implementation tickets. + +h2. Acceptance criteria + + * All community comments on the RFC have been reviewed and responded to + + * RFC discussion has been facilitated during SWC office hours, or other open discussion + + * RFC has been updated based on community discussion feedback and final decisions + + * RFC is prepared and formatted for community discussion + + * RFC status and decision have been updated on the [Decisions and RFCs wiki|https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + + * Follow-up implementation tickets have been created for the agreed-upon course of action + + * Implementation tickets are linked to this RFC ticket + +h2. Tasks + + # Review and respond to all community comments on the RFC + + # Facilitate RFC discussion during scheduled open discussion + + # Update RFC document based from scheduled open discussion: + +## Key discussion points, concerns, and consensus + + ## Final decisions from discussion + + ## Implementation approach + + ## Timeline considerations + + # Create follow-up tickets for implementation work + + # Link implementation tickets to the RFC + + # Update Decisions and RFCs wiki with: + + ## RFC status (Accepted/Rejected/Modified) + + ## Final decision and rationale + + ## Implementation plan + + ## Link to follow-up tickets + +h2. Discussion facilitation notes + +h3. Before open discussion: + + * Review all community comments + + * Identify key questions or concerns to address + + * Prepare any examples or demonstrations needed + + * Coordinate with relevant team members + +h3. During open discussion: + + * Present RFC overview and context + + * Address questions and concerns from attendees + + * Guide discussion toward consensus + + * Document decisions and action items + + * Clarify next steps + +h3. After open discussion: + + * Create follow-up tickets for implementation work + + * Update RFC with final decisions + + * Update Decisions and RFCs wiki page + +h2. Documentation updates + +h3. RFC document: + + * Status: (Accepted/Rejected/Pending) + + * community feedback summary + + * Final decision rationale + + * Implementation timeline + +h3. Wiki page: + + * Decision status and date + + * Link to implementation tickets + +h3. Implementation tickets: + + * Reference to the RFC + + * Specific acceptance criteria from RFC decisions + + * Priority and timeline alignment + + * Dependencies between implementation tasks + +h2. Resources + + * [link to RFC] + + * [Decisions and RFCs wiki|https://wiki.corp.adobe.com/display/AdobeDesign/Decisions+and+RFCs] + + * [SWC Office hours agenda|https://adobe.enterprise.slack.com/lists/T024FSURM/F089J8QEZ0V] +``` + +## Severity classification + +- SEV1: Critical - System down, data loss, security breach +- SEV2: High - Major feature broken, significant user impact +- SEV3: Medium - Feature partially broken, moderate impact +- SEV4: Low - Minor issues, minimal user impact +- SEV5: Trivial - Cosmetic issues, no functional impact + +## Best practices + +- Link to relevant GitHub issues or pull requests using the format: `GH-{number}` +- Include component name in brackets if applicable: `[sp-button]` +- Add relevant labels for easier filtering +- Attach screenshots or videos for visual changes +- Reference design specs or documentation when available + +## Acceptance criteria + +- Write criteria in "Given/When/Then" format +- Make criteria specific and testable +- Include edge cases and error scenarios +- Consider accessibility requirements + +## Labels + +Use the following labels to categorize tickets appropriately. Jira labels are separate from GitHub labels; for PR/issue descriptions use the github-description rule. Use the labels defined in `config.json` (jira_tickets.labels) or the list below. + +- `a11y`: Accessibility-related issues and improvements +- `API`: Changes to component APIs or interfaces +- `docs`: Documentation updates or docs site changes +- `engineering-processes`: Engineering workflow and process improvements +- `feature`: New feature implementations +- `hold`: Tickets temporarily suspended or blocked +- `i18n`: Internationalization and localization work +- `iOS`: iOS-specific issues and bugs +- `mobile`: Mobile platform issues and responsive design +- `necromancy`: Backlog tickets older than 2 years requiring revival +- `product-processes`: Process improvements for product team collaboration +- `refactor`: Code restructuring and refactoring work +- `research`: Tasks requiring investigation or research +- `RFC`: Request for Comments documentation +- `s2foundations`: Spectrum 2 Foundations related work +- `spectrum2`: Spectrum 2 platform specific tasks +- `team-processes`: Internal team workflow improvements +- `test`: Test implementation or testing infrastructure work +- `triage`: New tickets requiring team assessment and prioritization +- `VoiceOver`: VoiceOver screen reader specific issues + +## Issue type + +Jira includes the following issue types: + +- Bug: For something in the code that needs to be fixed. +- Epic: For tickets that are larger than 8 story points and need to be broken up into multiple issues. +- Story: For tickets that tie to code deliverables. Whether that's research, an RFC, or a pull request, it counts! If you don't know what your issue type should be, this is a safe bet. +- Task: For work that doesn't relate to a code deliverable. diff --git a/.ai/rules/stories-documentation.md b/.ai/rules/stories-documentation.md new file mode 100644 index 00000000000..d466b9580df --- /dev/null +++ b/.ai/rules/stories-documentation.md @@ -0,0 +1,838 @@ +--- +description: Comprehensive guide for what to document in 2nd-gen Storybook stories — overview, anatomy, options, states, behaviors, and accessibility sections — with patterns for JSDoc, args, accessible examples, and 1st-gen comparison notes. +globs: 2nd-gen/packages/swc/components/*/stories/** +alwaysApply: false +--- + +# Component stories documentation standards + +Comprehensive guide for creating consistent, accurate, and accessible component documentation in Storybook stories. + +This guide integrates Shoelace's documentation patterns with Spectrum Web Components' structure, providing both visual and technical breakdowns while using TOC anchor linking. + +## Scope + +Apply to all component stories in: + +- `2nd-gen/packages/swc/components/*/stories/*.stories.ts` + +## Documentation structure + +Organize documentation into these sections (skip sections that don't apply): + +1. **Overview** - Introduction and primary use case +2. **Anatomy** - Both visual and technical structure +3. **Options** - Configuration, variants, sizes, styles +4. **States** - Different component states +5. **Behaviors** - Methods, events, automatic behaviors +6. **Accessibility** - Features and best practices + +**Note**: Installation instructions and standard documentation sections (Anatomy, Options, States, Behaviors, Accessibility) are programmatically generated by `DocumentTemplate.mdx` and should not be manually added. + +## Helpers section + +**Purpose**: Organize shared code, label mappings, and utilities used across multiple stories. + +**Location**: Between `export default meta` and first story (Playground/Autodocs). + +**When to use:** + +- Component has multiple variants, sizes, or options that need consistent labels +- Stories require reusable label mappings or data structures +- Complex rendering logic needs to be shared across stories + +**Pattern**: + +```typescript +// ──────────────────── +// HELPERS +// ──────────────────── + +// Label mappings for sizes +const sizeLabels = { + s: 'Small', + m: 'Medium', + l: 'Large', + xl: 'Extra-large', +} as const satisfies Record; + +// Label mappings for semantic variants +const semanticLabels = { + positive: 'Approved', + negative: 'Rejected', + informative: 'Active', + neutral: 'Archived', + notice: 'Pending', +} as const satisfies Record; + +// Combined label objects for convenience +const allLabels = { ...semanticLabels, ...colorLabels }; +``` + +**Key principles:** + +- Use TypeScript `as const satisfies` for type-safe label mappings +- Group related helpers together (size labels, variant labels, etc.) +- Use clear, descriptive constant names (`sizeLabels`, not `labels`) +- Provide realistic, meaningful labels (not "Label 1", "Label 2") + +**When NOT to use:** + +- Component has only 1-2 options (no need for label mappings) +- Labels are self-explanatory (e.g., true/false) +- Stories don't share any common code + +## Section patterns + +### Overview + +**Purpose**: Quick introduction showing the component in its most common use case. + +**Documentation**: The Overview story content comes from two sources: + +1. **JSDoc description above meta**: Provides the main description of what the component does and when to use it. This description: + - Is displayed as the primary documentation for the Overview story + - Can include markdown formatting and links to other components + - Should reference other components using Storybook paths: `[Badge](../?path=/docs/badge--readme)` + - Should provide fuller context than the subtitle + +2. **`parameters.docs.subtitle`**: Provides a brief summary displayed as the subtitle. This subtitle: + - Cannot include links (plain text only) + - Should be concise and to-the-point + - Should not repeat the JSDoc description verbatim + - Complements the JSDoc description + +**Pattern**: + +```typescript +/** + * A badge is a non-interactive visual label that displays a status, category, or attribute. + * Badges can be used to highlight important information or to categorize items. For interactive + * labels, see [Button](../?path=/docs/button--readme). + */ +const meta: Meta = { + title: 'Badge', + component: 'swc-badge', + args, + argTypes, + render: (args) => template(args), + parameters: { + docs: { subtitle: `Visual label for status, category, or attribute` }, + // ... other parameters + }, + tags: ['migrated'], +}; + +export default meta; + +// ... HELPERS section if needed ... + +export const Overview: Story = { + tags: ['overview'], + args: { + // Most common/representative configuration + }, +}; +``` + +**Note**: No JSDoc comment needed on the Overview story itself - the meta JSDoc and subtitle provide the documentation. + +### Anatomy + +**Purpose**: Document both visual structure (what users see) and technical structure (slots, parts, properties). + +**Required content:** + +- **All slots** with descriptions +- **Content-rendering properties** (label, icon, src, value, etc.) +- Visual examples showing structure + +**Consolidation rule**: Combine all slotted content combinations into a **single Anatomy story**. + +**Pattern**: + +```typescript +/** + * ### Visual structure + * + * A component-name consists of: + * + * 1. **Primary element** - Main visual component + * 2. **Secondary element** - Additional visual content + * 3. **Optional indicator** - Shown conditionally + * + * ### Technical structure + * + * #### Slots + * + * - **Default slot**: Primary content (text or HTML) + * - **icon slot**: Optional icon element + * - **description slot**: Additional descriptive content + * + * #### Properties + * + * Properties that render visual content: + * + * - **label**: Text label displayed by the component + * - **icon**: Icon identifier to display + * - **src**: Image source URL + * - **value**: Displayed value content + * + * All variations shown below for comparison. + */ +export const Anatomy: Story = { + render: (args) => html` + ${template({ ...args /* minimal */ })} + ${template({ ...args /* with icon */ })} + ${template({ ...args /* with additional content */ })} + `, + tags: ['anatomy'], + parameters: { + flexLayout: true, + }, +}; +``` + +**Key principles:** + +- Start with visual structure (designer-focused) +- Follow with technical structure (developer-focused) +- Document all slots with clear descriptions +- List content-rendering properties (label, icon, src, value, etc.) +- Show all meaningful combinations in one story + +### Options + +**Purpose**: Document every attribute or property not covered in Anatomy, States, or Behaviors. + +**Order**: Sizes → Semantic variants → Non-semantic variants → Quiet/Subtle/Emphasized → Outline → Static color → Positioning → Other options + +**Consolidation rules**: + +- All sizes → single `Sizes` story +- All semantic variants → single `SemanticVariants` story +- All non-semantic variants → single `NonSemanticVariants` story + +**Layout requirement**: Use `flexLayout: true` for stories displaying multiple variations. + +**Pattern for sizes**: + +```typescript +/** + * Component-names come in [X] sizes to fit various contexts: + * + * - **Small (s)**: Used for inline indicators or space-constrained areas + * - **Medium (m)**: Default size, used for typical use cases + * - **Large (l)**: Used for prominent displays or primary content areas + * - **Extra-large (xl)**: Maximum visibility (if applicable) + * + * All sizes shown below for comparison. + */ +export const Sizes: Story = { + render: (args) => html` + ${template({ ...args, size: 's', label: 'Small' })} + ${template({ ...args, size: 'm', label: 'Medium' })} + ${template({ ...args, size: 'l', label: 'Large' })} + `, + tags: ['options'], + parameters: { + flexLayout: true, + 'section-order': 1, + }, +}; +``` + +**Pattern for semantic variants**: + +```typescript +/** + * Semantic variants provide meaning through color: + * + * - **accent**: New, beta, prototype, draft + * - **informative**: Active, in use, live, published + * - **neutral**: Archived, deleted, paused, draft, not started, ended + * - **positive**: Approved, complete, success, new, purchased, licensed + * - **notice**: Needs approval, pending, scheduled + * - **negative**: Error, alert, rejected, failed + * + * All semantic variants shown below for comparison. + */ +export const SemanticVariants: Story = { + render: (args) => html` + ${template({ ...args, variant: 'positive', label: 'Positive' })} + ${template({ ...args, variant: 'informative', label: 'Informative' })} + ${template({ ...args, variant: 'negative', label: 'Negative' })} + ${template({ ...args, variant: 'neutral', label: 'Neutral' })} + ${template({ ...args, variant: 'notice', label: 'Notice' })} + `, + tags: ['options'], + parameters: { + flexLayout: true, + 'section-order': 2, + }, +}; +``` + +**Pattern for static color**: + +```typescript +/** + * Use the `static-color` attribute when displaying over images or colored backgrounds: + * + * - **white**: Use on dark or colored backgrounds for better contrast + * - **black**: Use on light backgrounds for better contrast + * + * Both variants shown below with appropriate backgrounds. + */ +export const StaticColors: Story = { + render: (args) => html` + ${['white', 'black'].map( + (color) => html` + ${template({ ...args, 'static-color': color })} + ` + )} + `, + args: { + label: 'Loading', + }, + tags: ['options', '!test'], + parameters: { + flexLayout: false, + staticColorsDemo: true, + 'section-order': 5, + }, +}; +``` + +### States + +**Purpose**: Document all possible states the component can be in. + +**Order**: Default → Selected → Active → Disabled → Readonly → Error → Loading/Pending/Indeterminate → Other states + +**Consolidation rule**: Combine all states into a **single States story** when possible (or minimal stories when states are complex). + +**Pattern**: + +```typescript +/** + * Components can exist in various states: + * + * - **Default**: Normal, interactive state + * - **Selected**: Item has been chosen or activated + * - **Disabled**: Functionality exists but is not available + * - **Error**: Validation failure or error condition + * + * All states shown below for comparison. + */ +export const States: Story = { + render: (args) => html` + ${template({ ...args, label: 'Default' })} + ${template({ ...args, selected: true, label: 'Selected' })} + ${template({ ...args, disabled: true, label: 'Disabled' })} + ${template({ ...args, invalid: true, label: 'Error' })} + `, + tags: ['states'], + parameters: { + flexLayout: true, + }, +}; +``` + +**Pattern for complex states** (when animation or interaction is critical): + +```typescript +/** + * The indeterminate state shows an animated loading indicator when progress is unknown or cannot be determined. + * The animation automatically loops until the state changes. + */ +export const Indeterminate: Story = { + tags: ['states'], + args: { + indeterminate: true, + label: 'Loading...', + }, +}; +``` + +**Disabled state template**: + +```typescript +/** + * A component in a disabled state shows that [functionality] exists, but is not available in that circumstance. + * This can be used to maintain layout continuity and communicate that [functionality] may become available later. + * + * **ARIA support**: When disabled, the component automatically sets `aria-disabled="true"`. + */ +``` + +### Behaviors + +**Purpose**: Document methods, events, and automatic behaviors. + +**Pattern for automatic behaviors**: + +```typescript +/** + * ### Text handling + * + * Long text content automatically wraps to multiple lines to fit the available space. + * When space is constrained, text truncates with an ellipsis (...). + * + * ### Focus management + * + * When opened, focus is automatically trapped within the component. + * When closed, focus returns to the triggering element. + */ +export const TextWrapping: Story = { + render: (args) => html` + ${template({ 'default-slot': 'Short text' })} + ${template({ + 'default-slot': + 'This is a much longer text that will wrap to multiple lines when the container becomes too narrow to fit it all on one line', + })} + `, + tags: ['behaviors'], + parameters: { + flexLayout: true, + }, +}; +``` + +**Pattern for methods**: + +````typescript +/** + * ### Methods + * + * The component exposes the following public methods: + * + * - **open()**: Opens the component programmatically + * - **close()**: Closes the component programmatically + * - **toggle()**: Toggles between open and closed states + * - **reset()**: Resets the component to its initial state + * + * Example usage: + * + * ```javascript + * const component = document.querySelector('swc-component-name'); + * component.open(); + * ``` + */ +export const Methods: Story = { + tags: ['behaviors'], + // ... implementation +}; +```` + +**Pattern for events**: + +````typescript +/** + * ### Events + * + * The component dispatches the following custom events: + * + * - **change**: Fired when the value changes (bubbles: true, composed: true) + * - **input**: Fired during user input (bubbles: true, composed: true) + * - **swc-opened**: Fired when the component opens (bubbles: true, composed: true) + * - **swc-closed**: Fired when the component closes (bubbles: true, composed: true) + * + * Example event listener: + * + * ```javascript + * component.addEventListener('change', (event) => { + * console.log('Value changed:', event.target.value); + * }); + * ``` + */ +export const Events: Story = { + tags: ['behaviors'], + // ... implementation +}; +```` + +### Accessibility + +**Purpose**: Document built-in accessibility features and provide best practices guidance. + +**Required structure**: Two subsections - Features and Best practices. + +**Pattern**: + +```typescript +/** + * ### Features + * + * The `` element implements several accessibility features: + * + * #### Keyboard navigation + * + * - Tab: Moves focus to/from the component + * - Space or Enter: Activates the component + * - Arrow keys: Navigate between items + * - Escape: Closes the component (if applicable) + * + * #### ARIA implementation + * + * 1. **ARIA role**: Automatically sets `role="progressbar"` (or appropriate role) + * 2. **Labeling**: Uses the `label` attribute as `aria-label` + * 3. **States**: + * - Sets `aria-valuenow` with current progress value + * - Sets `aria-disabled="true"` when disabled + * 4. **Status communication**: Screen readers announce value changes + * + * #### Visual accessibility + * + * - Progress is shown visually through multiple cues, not relying solely on color + * - High contrast mode is supported with appropriate color overrides + * - Static color variants ensure sufficient contrast on different backgrounds + * + * ### Best practices + * + * - Always provide a descriptive `label` that explains what the component represents + * - Use meaningful, specific labels (e.g., "Uploading document" instead of "Loading") + * - Ensure sufficient color contrast between the component and its background + * - Use semantic variants when status has specific meaning + * - Test with screen readers to verify announcements are clear + */ +export const Accessibility: Story = { + tags: ['a11y'], + args: { + // ... accessible example + }, +}; +``` + +**Common accessibility features to document:** + +- **Keyboard navigation**: Document all keyboard interactions +- **ARIA role**: Document automatic role assignment +- **ARIA labels**: Document labeling mechanism (aria-label, aria-labelledby) +- **ARIA states**: Document state attributes (aria-disabled, aria-valuenow, etc.) +- **Color meaning**: For components using color to convey information +- **High contrast mode**: If supported via forced-colors media query + +**Accessibility requirements for all stories:** + +All stories must demonstrate accessible usage: + +- Include required labels (`label`, `aria-label`, or slot content) +- Use meaningful, realistic content (no placeholder text) +- Show proper ARIA usage when applicable +- Never demonstrate inaccessible patterns + +## 1st-gen to 2nd-gen comparison + +When creating 2nd-gen documentation, check 1st-gen (`1st-gen/packages/*/README.md`) for content to preserve or differences to highlight. + +### Where to document differences + +Document 1st-gen vs 2nd-gen differences directly in the relevant story's JSDoc comment where that difference is apparent. + +**Pattern for documenting differences**: + +```typescript +/** + * Component-names come in [X] sizes... + * + * **Note**: The `xl` size is new in 2nd-gen and not available in 1st-gen. + * + * All sizes shown below for comparison. + */ +export const Sizes: Story = { + // ... +}; +``` + +Or for removed features: + +```typescript +/** + * ### Methods + * + * The component exposes the following public methods... + * + * **Migration note**: The `validate()` method from 1st-gen has been removed in 2nd-gen. + * Use the `invalid` property instead for validation state. + */ +export const Methods: Story = { + // ... +}; +``` + +### Content to check from 1st-gen + +Compare 2nd-gen against 1st-gen for: + +1. **Size options**: Verify all sizes (especially `xl`) are documented +2. **Variant lists**: Ensure all variants are listed (check for `accent`, etc.) +3. **States**: Check for disabled, loading, or other states +4. **Behavioral details**: Text wrapping, truncation, tooltip integration +5. **Keyboard interactions**: If documented in 1st-gen +6. **Methods and events**: Check for API changes +7. **Advanced examples**: Tooltips, containers, complex layouts +8. **Specific guidance**: Color contrast guidance for static-color variants + +### Common differences to highlight + +**New in 2nd-gen:** + +- Additional sizes (e.g., `xl`) +- Additional variants (e.g., `accent`) +- New properties (e.g., `subtle`, `outline`) +- Improved ARIA implementation +- Better high contrast support + +**Changed in 2nd-gen:** + +- Property names (e.g., `emphasized` → `outline`) +- Slot names or structure +- Event names or payloads +- Default values + +**Removed from 2nd-gen:** + +- Deprecated properties +- Removed methods +- Unsupported variants + +### Using CEM for comparison + +Use the Custom Elements Manifest (CEM) to verify differences: + +1. **Check 1st-gen CEM**: `1st-gen/packages/component-name/custom-elements.json` +2. **Check 2nd-gen types**: `2nd-gen/packages/core/components/component-name/*.types.ts` +3. **Compare**: + - Properties and their types + - Slots and their descriptions + - Methods and their signatures + - Events and their details + +**Example verification**: + +```bash +# Check 1st-gen properties +grep -A 5 '"name": "size"' 1st-gen/packages/badge/custom-elements.json + +# Check 2nd-gen types +grep "VALID_SIZES" 2nd-gen/packages/core/components/badge/Badge.types.ts +``` + +### Common gaps to check + +- [ ] Missing installation instructions +- [ ] Missing size options (xl is common) +- [ ] Missing semantic variants (accent is common) +- [ ] Undocumented disabled state +- [ ] Missing readonly state documentation +- [ ] Missing ARIA disabled documentation +- [ ] Lack of tooltip integration examples +- [ ] Missing icon-only accessibility guidance +- [ ] No keyboard navigation documentation +- [ ] Missing static-color contrast guidance +- [ ] No text truncation/wrapping behavior explanation +- [ ] Missing methods documentation +- [ ] Missing events documentation + +## Verification and accuracy + +**Critical**: Always verify documentation against the actual component implementation to prevent hallucinations and inaccuracies. + +### Verification process + +After creating or updating documentation: + +1. **Read the component source files:** + - Base class implementation (`2nd-gen/packages/core/components/*/Component.base.ts`) + - Component-specific implementation (`2nd-gen/packages/swc/components/*/Component.ts`) + - TypeScript type definitions (`2nd-gen/packages/core/components/*/Component.types.ts`) + - CSS stylesheets (`2nd-gen/packages/swc/components/*/component.css`) + +2. **Verify slots:** + - Check JSDoc comments in component class (`@slot` decorators) + - Verify slot names in the render method + - Confirm which slots are required vs. optional + +3. **Verify properties:** + - Check `@property` decorators in component and base classes + - Verify property types, defaults, and reflect values + - Confirm valid values (enums, arrays defined in types file) + - Check if properties exist in both base and subclass + +4. **Verify ARIA implementation:** + - Search for `aria-*` attributes in component code + - Check for `role` assignments + - Verify attribute behavior (when added/removed) + - **Don't claim attributes that aren't implemented** + +5. **Verify behavior:** + - Check for methods in component class (public methods only) + - Look for event dispatching (`dispatchEvent`, custom events) + - Verify automatic behaviors in lifecycle methods + +6. **Verify constraints:** + - Look for validation logic (e.g., outline only with semantic variants) + - Check for console warnings about invalid combinations + - Verify size/variant/option restrictions + +### Common hallucination patterns to avoid + +❌ **Claiming attributes that don't exist:** + +```typescript +// WRONG: Claiming a `label` attribute when component only has a slot +- Provide label via the `label` attribute +``` + +✅ **Verify what actually exists:** + +```typescript +// CORRECT: Check component source for actual API +- Provide label via the default slot or `aria-label` attribute +``` + +❌ **Assuming ARIA attributes are set:** + +```typescript +// WRONG: Claiming aria-valuemin/aria-valuemax without checking +- Includes `aria-valuemin="0"` and `aria-valuemax="100"` +``` + +✅ **Verify ARIA implementation in code:** + +```typescript +// CORRECT: Only document what the component actually sets +- Sets `aria-valuenow` with the current progress value +``` + +❌ **Claiming methods that don't exist:** + +```typescript +// WRONG: Assuming common methods exist +- **reset()**: Resets the component to initial state +``` + +✅ **Check component class for public methods:** + +```typescript +// CORRECT: Only document methods defined in the class +// (If no public methods exist, state this clearly) +``` + +### Verification tools + +Use these commands to verify claims: + +```bash +# Search for properties +grep -n "@property" 2nd-gen/packages/swc/components/component-name/Component.ts + +# Search for slots +grep -n "@slot" 2nd-gen/packages/core/components/component-name/Component.base.ts + +# Search for ARIA attributes +grep -n "aria-" 2nd-gen/packages/swc/components/component-name/Component.ts + +# Search for events +grep -n "dispatchEvent\|new CustomEvent" 2nd-gen/packages/swc/components/component-name/Component.ts + +# Compare with 1st-gen +diff <(grep "@property" 1st-gen/packages/component-name/*.ts) \ + <(grep "@property" 2nd-gen/packages/swc/components/component-name/*.ts) +``` + +### Documentation after verification + +After verifying accuracy: + +1. Document what was checked in commit message or PR +2. Note any inaccuracies found and fixed +3. Include code references for major claims (in JSDoc comments if helpful) +4. Consider creating a verification checklist for complex components + +## General guidelines + +### Documentation style + +- **Use sentence case** for all headings and descriptions +- **Be specific** - Instead of "Loading", use "Uploading document" or "Processing request" +- **Show, don't just tell** - Include visual examples for every concept +- **Consolidate variations** - Combine related options into single stories for easier comparison +- **Think multi-audience** - Balance designer needs (visual) with developer needs (technical) + +### Component linking + +When referencing other components in the JSDoc description above meta: + +- **Use Storybook paths**: Link to the component's overview story using relative paths +- **Format**: `[ComponentName](../?path=/docs/component-name--readme)` +- **Component name format**: Use kebab-case in the path (e.g., `action-button`, `progress-circle`) +- **Always link to readme**: Use `--readme` as the story anchor + +**Examples**: + +```typescript +/** + * A `` is a non-interactive visual label. For interactive labels, + * see [Action Button](../?path=/docs/action-button--readme). + */ + +/** + * Progress circles are commonly used with [Button](../?path=/docs/button--readme) + * and [Card](../?path=/docs/card--readme) components to show loading states. + */ +``` + +### Code examples + +- **Use realistic content** - Avoid placeholder text, use meaningful labels +- **Always be accessible** - Include required labels, ARIA attributes +- **Show complete patterns** - Don't abbreviate important details +- **Use consistent formatting** - Follow project style guidelines + +### Story organization + +- **Use flexLayout** for multi-item comparisons +- **Set section-order** to control display order within sections +- **Tag appropriately** - Use correct tags for each section +- **Add JSDoc comments** - Explain what each story demonstrates (except Playground and Overview) + +### JSDoc heading levels + +All headings in JSDoc comments must start at level 3 (`###`) or deeper: + +- **Level 3 (`###`)**: Top-level sections within a story (e.g., "Visual structure", "Features", "Methods") +- **Level 4 (`####`)**: Sub-sections within those sections (e.g., "Slots", "ARIA implementation", "Keyboard navigation") + +This ensures proper hierarchy since JSDoc content is rendered within the story context, subordinate to the main section headings in the DocumentTemplate (which use `##`). + +## Checklist + +When creating or updating documentation: + +- [ ] Overview story with common use case +- [ ] JSDoc description above meta (explains component purpose, links to related components) +- [ ] `parameters.docs.subtitle` is concise and non-repetitive (plain text, no links) +- [ ] Helpers section for shared label mappings and utilities (if applicable) +- [ ] Anatomy with both visual and technical structure +- [ ] All slots documented with descriptions +- [ ] All content-rendering properties listed +- [ ] All configuration options documented +- [ ] All states documented +- [ ] Methods documented (if applicable) +- [ ] Events documented (if applicable) +- [ ] Automatic behaviors explained +- [ ] Comprehensive accessibility section with features and best practices +- [ ] All examples use accessible, meaningful content +- [ ] Consistent flexLayout usage for comparisons +- [ ] Proper story tags for all sections +- [ ] JSDoc comments for all stories (except Playground and Overview) +- [ ] JSDoc headings start at level 3 (`###`) or deeper +- [ ] **Checked 1st-gen README.md for missing content or differences** +- [ ] **Documented 1st-gen differences where apparent (new/changed/removed features)** +- [ ] **Verified against component implementation** (no hallucinations) +- [ ] All slots verified in component source +- [ ] All properties verified with `@property` decorators +- [ ] ARIA attributes verified in component code +- [ ] Methods and events verified in implementation diff --git a/.ai/rules/stories-format.md b/.ai/rules/stories-format.md new file mode 100644 index 00000000000..08a900aabca --- /dev/null +++ b/.ai/rules/stories-format.md @@ -0,0 +1,674 @@ +--- +description: Enforces consistent file structure, section separators, meta configuration, story tags, layout parameters, and JSDoc conventions for 2nd-gen Storybook stories files. +globs: 2nd-gen/packages/swc/components/*/stories/** +alwaysApply: false +--- + +# Storybook stories format standards + +Enforce consistent formatting and technical structure for Storybook stories files in 2nd-gen components. + +**See also**: `.ai/rules/stories-documentation.md` for comprehensive guidance on WHAT to document (content, patterns, examples). + +## Scope + +Apply to all `.stories.ts` files in `2nd-gen/packages/swc/components/*/stories/`. + +**Note**: Component-specific `.usage.mdx` files are no longer needed. The `DocumentTemplate.mdx` automatically renders all documentation sections based on story tags. + +## File structure + +### Stories file (`.stories.ts`) + +Required structure with visual separators between sections: + +1. **Copyright header** (lines 1-11) +2. **Imports** +3. **METADATA** - Meta object with component configuration +4. **HELPERS** - Shared label mappings and utilities (if needed) +5. **AUTODOCS STORY** - Playground story +6. **ANATOMY STORIES** - Component structure (if applicable) +7. **OPTIONS STORIES** - Variants, sizes, styles +8. **STATES STORIES** - Component states (if applicable) +9. **BEHAVIORS STORIES** - Built-in functionality (if applicable) +10. **ACCESSIBILITY STORIES** - A11y demonstration + +#### Visual separators + +```typescript +// ──────────────── +// METADATA +// ──────────────── + +// ──────────────────── +// HELPERS +// ──────────────────── + +// ──────────────────── +// AUTODOCS STORY +// ──────────────────── + +// ────────────────────────── +// ANATOMY STORIES +// ────────────────────────── + +// ────────────────────────── +// OPTIONS STORIES +// ────────────────────────── + +// ────────────────────────── +// STATES STORIES +// ────────────────────────── + +// ────────────────────────────── +// BEHAVIORS STORIES +// ────────────────────────────── + +// ──────────────────────────────── +// ACCESSIBILITY STORIES +// ──────────────────────────────── +``` + +## Key Principles + +### Always Pass Args Through + +When using custom `render` functions, **always** spread `...args` into template calls: + +```typescript +// ✅ Good - args are passed through +export const MyStory: Story = { + render: (args) => html` + ${template({ ...args, size: 's' })} + `, +}; + +// ❌ Bad - args are lost +export const MyStory: Story = { + render: (args) => html` + ${template({ size: 's' })} + `, +}; +``` + +This ensures: + +- Storybook controls work correctly +- Args from the Playground/global level are respected +- Component defaults can be overridden + +### When to Use render vs args + +- **Use `args` directly**: When the default render is sufficient (single component, no wrapper) +- **Use `render: (args) =>`**: When you need multiple instances, custom HTML structure, or conditional rendering + +```typescript +// ✅ Good - simple case uses args +export const Overview: Story = { + args: { size: 'm', label: 'Example' }, + tags: ['overview'], +}; + +// ✅ Good - complex case uses render with args +export const Sizes: Story = { + render: (args) => html` + ${template({ ...args, size: 's' })} ${template({ ...args, size: 'm' })} + ${template({ ...args, size: 'l' })} + `, + tags: ['options'], +}; +``` + +### Documentation sections (auto-generated) + +**Component-specific `.usage.mdx` files are no longer needed.** The `DocumentTemplate.mdx` automatically renders all standard documentation sections based on story tags: + +- **Anatomy** (tag: `anatomy`) - Rendered with `hideTitle` +- **Options** (tag: `options`) +- **States** (tag: `states`) +- **Behaviors** (tag: `behaviors`) +- **Accessibility** (tag: `a11y`) - Rendered with `hideTitle` + +Each section only renders if stories with the corresponding tag exist. The template handles: + +- Installation instructions (auto-generated) +- Section headers and ordering +- Conditional rendering based on story availability + +**What you need to do**: Just tag your stories appropriately. The documentation structure is handled automatically. + +## Meta configuration + +### Required fields + +```typescript +/** + * Component description explaining its purpose and key features. + * + * This description is displayed in the Overview story. It should provide context about + * what the component does and when to use it. If referencing other components, link to + * their Storybook paths using relative URLs (e.g., `` becomes + * `[Badge](../?path=/docs/badge--overview)`). + */ +const meta: Meta = { + title: 'Component name', + component: 'swc-component-name', + args, + argTypes, + render: (args) => template(args), + parameters: { + actions: { handles: events }, // If events exist + docs: { + subtitle: `Component description`, // Required - displayed in Overview, cannot include links + }, + design: { type: 'figma', url: 'https://www.figma.com/...' }, // Recommended + stackblitz: { url: 'https://stackblitz.com/...' }, // Recommended + }, + tags: ['migrated'], +}; +``` + +**Important notes:** + +- **JSDoc description above meta**: Displayed in the Overview story. Can include markdown links to other components. +- **`parameters.docs.subtitle`**: Displayed as the subtitle in the Overview story. Cannot include links (plain text only). +- **Avoid repetition**: The subtitle and JSDoc description should complement each other, not duplicate content. The subtitle is a brief summary; the JSDoc provides fuller context. +- **Component links**: When referencing other components in the JSDoc description, use relative Storybook paths: `[ComponentName](../?path=/docs/component-name--overview)` + +## Layout and decorators + +Use `flexLayout: true` for stories displaying multiple items (sizes, variants, states). This applies flex layout with consistent spacing. + +```typescript +export const Sizes: Story = { + render: () => html` + Small + Medium + Large + Extra-large + `, + parameters: { flexLayout: true }, + tags: ['options'], +}; +``` + +### Customizing layout + +Extend with `parameters.styles` or use styles alone for custom layouts: + +```typescript +export const Sizes: Story = { + parameters: { + flexLayout: true, + styles: { + 'flex-wrap': 'wrap', + 'max-inline-size': '80ch', + }, + }, +}; + +// Or fully custom (no flex defaults): +export const GridLayout: Story = { + parameters: { + styles: { + display: 'grid', + 'grid-template-columns': 'repeat(3, 1fr)', + }, + }, +}; +``` + +### Static color decorator + +For static color stories, use `staticColorsDemo: true` with `flexLayout: true`: + +```typescript +export const StaticColors: Story = { + render: (args) => html` + ${['white', 'black'].map((color) => template({ 'static-color': color }), + parameters: { + flexLayout: true, + staticColorsDemo: true + }, + tags: ['options', '!test'], +}; +``` + +The decorator displays two background zones—dark gradient for `static-color="white"` content, light gradient for `static-color="black"` content. + +## Story ordering + +Control display order within sections using `section-order`. Stories sort by lowest value first, then alphabetically for ties or missing values. + +```typescript +export const Sizes: Story = { + tags: ['options'], + parameters: { 'section-order': 1 }, +}; + +export const StaticColors: Story = { + tags: ['options'], + parameters: { 'section-order': 10 }, +}; +``` + +## Tags + +### Required tags + +| Tag | Usage | +| --------------------- | --------------------------------------------- | +| `'autodocs'`, `'dev'` | Playground story only | +| `'overview'` | Overview story | +| `'anatomy'` | Anatomy stories | +| `'options'` | Variant, size, and style stories | +| `'states'` | State demonstration stories | +| `'behaviors'` | Method, event, and automatic behavior stories | +| `'a11y'` | Accessibility story | +| `'migrated'` | On meta object | + +### Exclusion tags + +- `'!test'` - Exclude from test runs +- `'!dev'` - Exclude from dev Storybook + +## Story types + +### Playground + +First story after meta. No JSDoc comment. Set args to the most common use case—this appears as the docs page preview. + +```typescript +export const Playground: Story = { + args: { + /* most common use case */ + }, + tags: ['autodocs', 'dev'], +}; +``` + +**Note**: Use `args` directly (not `render`) when the default render is sufficient. Only use `render: (args) => html` when you need custom rendering. + +Include comprehensive JSDoc comment above the meta object explaining what the component does. + +Every story export must have a JSDoc comment explaining: + +- What it demonstrates +- Any important context or usage notes +- Best practices if relevant + +**Exceptions**: Do NOT add JSDoc comments above the Playground or Overview stories. + +Use markdown formatting within JSDoc: + +- `**Bold**` for emphasis +- Bullet lists for multiple points +- Code formatting with backticks + +```typescript +/** + * A `` is a UI element that displays a **status** or **message**. + */ +export const Playground: Story = { + args: { + /* most common use case */ + }, + tags: ['autodocs', 'dev'], +}; +``` + +### Overview + +Quick introduction showing the component in its most common use case. No JSDoc comment needed. + +```typescript +export const Overview: Story = { + args: { + // Most common/representative configuration + }, + tags: ['overview'], +}; +``` + +**Note**: Use `args` directly when possible. Only use `render: (args) =>` if you need custom HTML structure around the component. + +### Anatomy + +Document all slots and content-rendering properties (e.g., `label`, `icon`, `src`). Combine variations into one story. + +**Important**: When using `render: (args) =>`, **always** spread `...args` into template calls to ensure Storybook controls work correctly. + +```typescript +/** + * A component-name consists of: + * + * - **Default slot**: Primary content + * - **icon slot**: Optional icon element + * - **label**: Text label rendered by the component + */ +export const Anatomy: Story = { + render: (args) => html` + ${template({ ...args /* text only */ })} + ${template({ ...args /* icon only */ })} + ${template({ ...args /* text + icon */ })} + `, + tags: ['anatomy'], + parameters: { flexLayout: true }, +}; +``` + +### Options + +Document every attribute/property not covered in Anatomy, States, or Behaviors. Consolidate related options into single stories. Use this order for story section-order: + +| Story | Content | +| ------------------------- | ------------------------------------------------- | +| `Sizes` | All size variants | +| `SemanticVariants` | Positive, informative, negative, notice, neutral | +| `NonSemanticVariants` | Color-coded categories (seafoam, indigo, etc.) | +| `StaticColors` | Static color pattern (see below) | +| `Quiet/Subtle/Emphasized` | Quiet, subtle, emphasized variants | +| `Outline` | Outline variants | +| `Positioning` | Positioning modifiers (fixed, absolute, relative) | + +```typescript +/** + * Components come in multiple sizes to fit various contexts. + */ +export const Sizes: Story = { + render: (args) => html` + ${template({ ...args, size: 's', label: 'Small' })} + ${template({ ...args, size: 'm', label: 'Medium' })} + ${template({ ...args, size: 'l', label: 'Large' })} + `, + tags: ['options'], + parameters: { flexLayout: true }, +}; + +/** + * Semantic variants provide meaning through color. + * + * Use these variants for the following statuses: + * + * - **Informative**: active, in use, live, published + * - **Neutral**: archived, deleted, paused, draft, not started, ended + * - **Positive**: approved, complete, success, new, purchased, licensed + * - **Notice**: needs approval, pending, scheduled, syncing, indexing, processing + * - **Negative**: error, alert, rejected, failed + * + */ +export const SemanticVariants: Story = { + render: (args) => html` + ${template({ ...args, variant: 'positive' })} + ${template({ ...args, variant: 'informative' })} + ${template({ ...args, variant: 'negative' })} + ${template({ ...args, variant: 'notice' })} + ${template({ ...args, variant: 'neutral' })} + `, + tags: ['options'], +}; + +/** + * Non-semantic variants use color-coded categories. + */ +export const NonSemanticVariants: Story = { + render: (args) => html` + ${template({ ...args, variant: 'seafoam' })} + ${template({ ...args, variant: 'indigo' })} ${/* ... other colors */ ''} + `, + tags: ['options'], +}; +``` + +#### Static color pattern + +For components with `static-color` attribute, implement three stories: + +1. **`StaticBlack`** - `static-color="black"` on light background +2. **`StaticWhite`** - `static-color="white"` on dark background +3. **`StaticColors`** - Both variants side-by-side + +```typescript +/** + * Use `static-color` for display over images or colored backgrounds. + */ +export const StaticBlack: Story = { + args: { 'static-color': 'black' }, + parameters: { flexLayout: false, styles: { color: 'black' } }, + tags: ['options'], +}; + +export const StaticWhite: Story = { + args: { 'static-color': 'white' }, + parameters: { flexLayout: false, styles: { color: 'white' } }, + tags: ['options'], +}; + +export const StaticColors: Story = { + render: (args) => html` + ${['white', 'black'].map( + (color) => html` + ${template({ ...args, 'static-color': color })} + ` + )} + `, + parameters: { flexLayout: false, staticColorsDemo: true }, + tags: ['options', '!test'], +}; +``` + +### States + +Combine all states into one story when possible. + +```typescript +/** + * Components can exist in various states. + */ +export const States: Story = { + render: (args) => html` + ${template({ ...args })} ${template({ ...args, selected: true })} + ${template({ ...args, disabled: true })} + `, + tags: ['states'], + parameters: { flexLayout: true }, +}; +``` + +Complex states (e.g., animated indeterminate) may warrant separate stories. + +```typescript +/** + * Indeterminate state shows unknown progress. + */ +export const Indeterminate: Story = { + tags: ['states'], + args: { + indeterminate: true, + }, +}; +``` + +### Behaviors + +Document automatic (built-in) behaviors, like text-wrapping, as well as, all methods, and all events. + +```typescript +/** + * Long text automatically wraps to multiple lines. + */ +export const TextWrapping: Story = { + render: (args) => html` + ${template({ 'default-slot': 'Long text that wraps to multiple lines' })} + `, + tags: ['behaviors'], +}; +``` + +### Accessibility + +Required for every component. Document features and best practices. + +```typescript +/** + * ### Features + * The `` element implements several accessibility features: + * + * 1. **Feature name**: Description (e.g., keyboard navigation, ARIA states, roles, properties) + * 2. **Feature name**: Description + * + * ### Best practices + * + * - Best practice, such as, "Always provide a descriptive label" + * - Best practice, such as, "Ensure sufficient color contrast" + */ +export const Accessibility: Story = { + tags: ['a11y'], +}; +``` + +## JSDoc requirements + +Every story export requires a JSDoc comment explaining what it demonstrates, **except Playground**. + +Use markdown formatting: + +- `**Bold**` for emphasis +- Bullet lists for multiple points +- Backticks for code + +```typescript +/** + * Semantic variants provide meaning through color: + * - **Positive**: approved, complete, success + * - **Negative**: error, alert, rejected + */ +export const SemanticVariants: Story = { + /* ... */ +}; +``` + +## Accessibility requirements + +All stories must demonstrate accessible usage: + +1. **Include required labels** - `label`, `aria-label`, or slot content as needed +2. **Use meaningful content** - No "Lorem ipsum" placeholder text +3. **Show proper ARIA usage** - Correct attributes when applicable +4. **Never show inaccessible patterns** + +| Component type | Required | +| ------------------- | ---------------------------- | +| Progress indicators | `label` attribute | +| Buttons/actions | Visible text or `aria-label` | +| Form fields | `