--- name: ha-frontend-gallery description: Home Assistant frontend gallery structure, pages, demos, content, and verification. Use when changing files under gallery/, including gallery markdown, TypeScript demos, sidebar entries, mock data, page generation, or gallery builds. --- # HA Frontend Gallery Use this skill for all work under `gallery/`. Follow the persistent repository guidance in `AGENTS.md` and load the matching specialist skills alongside this gallery-specific guidance. ## Quick Reference Run commands from the repository root unless noted otherwise: ```bash gallery/script/develop_gallery # Start the gallery development server gallery/script/build_gallery # Build the static gallery pnpm lint # ESLint, Prettier, TypeScript, and Lit checks pnpm lint:types # TypeScript compiler, without file arguments ``` Never run `pnpm lint:types` or `tsc` with file arguments. File arguments make `tsc` ignore `tsconfig.json` and can emit `.js` files into `src/`. ## Purpose The gallery is a developer and designer reference for Home Assistant frontend UI patterns. It documents component APIs, shows realistic Lovelace and more-info states, captures brand and copy guidance, and provides reproducible demos that are safe to inspect outside a running Home Assistant instance. - Prefer demonstrating real production components from `src/` instead of creating gallery-only replacements. - Keep fake state, sample data, and demo-only helpers inside `gallery/`. - Do not move gallery stubs or demo data into production code unless a production feature explicitly needs them. - Do not hand-edit generated output under `gallery/build/` or `gallery/dist/`. ## Structure - `gallery/sidebar.js`: Defines gallery sections, headers, and explicit page ordering. - `gallery/script/develop_gallery`: Wrapper for the `develop-gallery` gulp task. - `gallery/script/build_gallery`: Wrapper for the `build-gallery` gulp task. - `gallery/src/entrypoint.js`: Creates the `` shell. - `gallery/src/ha-gallery.ts`: Renders the drawer, page routing, markdown descriptions, demos, edit links, and RTL toggle. - `gallery/src/html/index.html.template`: HTML template used by the gallery build. - `gallery/src/pages//.markdown`: Optional page description and frontmatter. - `gallery/src/pages//.ts`: Optional live demo module for the same page ID. - `gallery/src/components/`: Gallery-only demo wrappers like `demo-card`, `demo-cards`, `demo-more-info`, and `page-description`. - `gallery/src/data/`: Fake `hass`, demo states, mock traces, and reusable sample data. - `gallery/public/`: Static assets copied into the gallery output. ## Page Model Gallery pages are generated by `gather-gallery-pages` in `build-scripts/gulp/gallery.js`. - A page ID is the path under `gallery/src/pages/` without the extension, like `components/ha-button`. - A `.markdown` file and a `.ts` file with the same page ID become one gallery page. - A page may have only markdown, only a TypeScript demo, or both. - Markdown can contain YAML frontmatter with `title` and optional `subtitle`. - Markdown that contains only frontmatter contributes metadata without rendering a description block. - TypeScript demo modules are dynamically imported for side effects when the page is opened. - A demo module must define a custom element named `demo-${category}-${page}` with slashes replaced by hyphens, like `demo-components-ha-button` for `components/ha-button`. - `gallery/src/ha-gallery.ts` renders that element with `dynamicElement()` based on the current page ID. ## Sidebar Use `gallery/sidebar.js` when a page needs a visible section, section header, or deterministic ordering. - `category` must match the first directory name under `gallery/src/pages/`. - `header` is the section label shown in the drawer. - `pages` is optional. When present, listed pages keep that exact order. - Pages in a category that are not listed are appended alphabetically after the listed pages. - New categories without a sidebar entry are appended by the generator with their category name as the header. - If a listed page does not exist, the generator logs an error during `gather-gallery-pages`. ### Subsections A section can group its pages under named subsections instead of one flat list. Use this for large categories where related pages should sit together. - `subsections` is an array of `{ header, pages }`. It is mutually exclusive with a flat `pages` array on the same group. - Each subsection `header` is a non-collapsible label rendered inside the section's expansion panel; the section stays the only collapsible level. - Listed pages keep their per-subsection order. - Any pages found in the category but not listed in a subsection are collected into a generated `Other` subsection, appended alphabetically. The `Other` subsection is omitted when there are no leftovers. - A listed page that does not exist still logs an error during `gather-gallery-pages`. - Use sentence case for subsection headers and follow the content standards below. ## Markdown Pages Use markdown pages for explanations, design guidance, API notes, and copy standards. - Start with frontmatter when the page needs a title or subtitle. - Use sentence case for titles, headings, labels, and UI copy. - Put the live example before the reference API when that makes the page easier to scan. - Use fenced code blocks with a language tag for copyable examples. - Keep examples short and focused on the behavior being documented. - Prefer real component names and attributes over prose-only descriptions. - Use Home Assistant terminology from `ha-frontend-user-facing-text`. - For remove/delete and add/create wording, follow `gallery/src/pages/misc/remove-delete-add-create.markdown`. Gallery markdown is documentation content and is not localized with `localize`. If demo code creates production UI strings, follow the localization and copy guidance in `ha-frontend-user-facing-text`. ## Demo Components Use TypeScript demo pages for interactive or stateful examples. - Import production components from `src/` using the correct relative path from the demo file. - Import reusable gallery helpers from `gallery/src/components/` when they already model the pattern. - Use `demo-card` and `demo-cards` for Lovelace card examples that render YAML card configs. - Use `demo-more-info` and `demo-more-infos` for more-info dialog examples. - Use shared mock data from `gallery/src/data/` instead of repeating large fake state objects inline. - Show meaningful states, such as loading, unavailable, empty, error, active, inactive, and disabled when relevant. - Check responsive behavior and the gallery RTL toggle when layout or direction-sensitive UI changes. - Keep unavoidable casts or loose demo parsing local to the demo helper or demo page. The gallery ESLint config allows `console` for gallery diagnostics. Do not copy that exception into production frontend code. ## Content Standards Follow the detailed copy standards in `ha-frontend-user-facing-text`: use American English, sentence case, active voice, inclusive language, direct user-focused wording, and consistent Home Assistant terminology. - Use `Home Assistant` in full, not `HA` or `HASS`. - Use `integration` instead of `component` for product concepts. - Use `Remove` for reversible disassociation and `Delete` for permanent deletion. - Use `Add` for existing items and `Create` for something made from scratch. - Avoid Latin abbreviations like `e.g.` and `i.e.` in prose. - Avoid stitching sentence fragments together in production UI examples. ## Verification - For markdown, sidebar, and page-generation changes, run `gallery/script/build_gallery`. - For TypeScript demo or gallery shell changes, run the smallest relevant check plus `pnpm lint` when practical. - For type checking, run `pnpm lint:types` without file arguments. - For visual changes, run `gallery/script/develop_gallery` and check the affected page on desktop, narrow viewport, and RTL when relevant. - If verification is skipped, state which command was skipped and why.