- name
- webstatus-frontend
- description
- Use when modifying the frontend SPA, working with TypeScript, Lit web components, Shoelace components, or frontend tests.
# webstatus-frontend
This skill provides architectural guidance and conventions for the `frontend/` directory in `webstatus.dev`.
## Architecture & Technology
- **Framework**: Built with **TypeScript**, **Lit**, and **Web Components**.
- **UI Library**: Utilizes **Shoelace** component library.
- **State Management**: Uses **Lit Context** for dependency injection and state management via a service container pattern (`<webstatus-services-container>`).
- **API Interaction**: Communicates with the Go backend using TypeScript types generated from the OpenAPI specification (`make node-openapi`).
## Architecture
For a technical breakdown of the Lit component hierarchy, frontend identity flows, and theming patterns, see [references/architecture.md](references/architecture.md).
## Guidelines (Do's and Don'ts)
- **DO** cross-reference all TypeScript and CSS against the official Google TypeScript/HTML/CSS Style Guides. If you are unsure about a specific style rule, DO NOT assume; you MUST ask the user for clarification.
- **DO** create new UI elements as custom elements extending Lit's `LitElement`.
- **DO** leverage Shoelace components for common UI patterns.
- **DON'T** introduce other UI frameworks like React or Vue.
- **DO** use Lit Context to access shared services.
- **DON'T** create new global state management solutions.
- **DON'T** render the full page layout (header, sidebar, etc.) inside a page component. Page components should focus on route-specific content; `webstatus-app` provides the shell.
- **DON'T** add generic class names to `shared-css.ts`. **DO** leverage Shadow DOM encapsulation and use composition with slots for reusable layout patterns.
- **DO** write unit tests for all component logic.
- **DO** place application-wide service providers within `WebstatusServicesContainer` to ensure a stable context hierarchy.
- **DO** use specialized child components (the "Context Bridge" pattern) to consume global context if high-level components (like `WebstatusHeader`) don't reliably subscribe to context changes due to slotting or complex rendering lifecycles.
- **DO** use Shoelace semantic CSS variables (e.g., `--sl-color-neutral-0`) for themeable properties to ensure cross-browser inheritance (Firefox/WebKit) without relying on unsupported selectors like `:host-context`.
- **DON'T** directly use Shoelace variables (starting with `--sl-`) in component stylesheets. **DO** use custom variables defined in `_theme-css.ts` (e.g., `--color-background`, `--table-padding`) that act as a project-specific abstraction layer.
- **DO** type `routerContext` cleanly as `createContext<Router | undefined>('router')` without referencing `AnyObject` (`Router<AnyObject, AnyObject>`), as `@vaadin/router` v2.0+ removed `AnyObject`.
- **DON'T** use `// @ts-ignore` to silence TypeScript warnings around decorated Lit properties (`@provide({context: routerContext})`). Properly type the property/context so it passes `tsc --noEmit` without `@typescript-eslint/ban-ts-comment` warnings.
- **DON'T** add redundant `as Type[]` assertions (`@typescript-eslint/no-unnecessary-type-assertion`) when assigning API data from `openapi-fetch` client helpers that already infer the paginated return type.
## Testing & Linting
- **Test Execution**: `npm run test -w frontend`.
- **Linting**: Run `make node-lint` to run ESLint and Prettier for the frontend code, or `make lint-fix` to attempt auto-fixing. `make style-lint` is also available for CSS.
- **ES Module Testing**: When testing components that use ES module exports directly (e.g. Firebase Auth), use a helper property (e.g. `credentialGetter`) that can be overridden with a Sinon stub.
- **Typing**: Use generic arguments for `querySelector` in tests (e.g. `querySelector<HTMLSlotElement>(...)`) for type safety.
## Theming & Inheritance
- **Global Classes**: The `WebstatusThemeService` toggles the `.sl-theme-dark` class on the `document.documentElement`.
- **Inheritance**: Shoelace variables (e.g., `--sl-color-neutral-0`) automatically switch values based on the root class. Our custom theme variables in `_theme-css.ts` should derive from these semantic Shoelace variables to inherit fixed values across Shadow DOM boundaries consistently.
- **Abstraction Layer**: Components should exclusively use custom variables from `_theme-css.ts`. Mapping these to Shoelace variables should only happen in the central theme file. This ensures that a library or color palette change can be managed in one place.
- **Avoid Unsupported Selectors**: Do not use `:host-context` for theme overrides as it lacks support in Firefox and WebKit. Use root-inherited variables instead.
## Debugging Frontend Tests
If a frontend unit test is timing out or failing mysteriously, Web Test Runner's console output is often unhelpful.
- **Watch Mode**: Instruct the user to run `npm run test:watch -w frontend` in their own terminal.
- **Visual Debugging**: Ask the user to open the provided localhost URL (e.g., `http://localhost:8000/`) in their web browser and inspect the developer console/DOM to see where the test is getting stuck.
- **DON'T** arbitrarily increase the timeout in `web-test-runner.config.mjs` to fix timeout issues. Address the root cause of the hang instead.
## Documentation Updates
When making significant architectural changes to the frontend or introducing new state management patterns:
- Trigger the "Updating the Knowledge Base" prompt in `GEMINI.md`.
- Update `docs/ARCHITECTURE.md` if the system boundaries change.
- Update these very skills files if you introduce new established patterns.
View on GitHub