--- name: Svelte Components description: | Svelte 5 component patterns for the Exceptionless SPA. Runes, reactivity, props, events, snippets, component organization, and shadcn-svelte integration. Keywords: Svelte 5, $state, $derived, $effect, $props, runes, onclick, snippets, {@render}, reactive, component composition, shadcn-svelte --- # Svelte Components > **Documentation:** [svelte.dev](https://svelte.dev/docs) | Use `context7` for API reference ## Visual Validation with Chrome MCP **Always verify UI changes visually** using the Chrome MCP: 1. After making component changes, use Chrome MCP to take a snapshot or screenshot 2. Verify the component renders correctly and matches expected design 3. Test interactive states (hover, focus, disabled) when applicable 4. Check responsive behavior at different viewport sizes 5. Default to the `/next` site path for verification This visual validation loop catches styling issues, layout problems, and accessibility regressions that automated tests may miss. ## File Organization ### Naming Conventions - **kebab-case** for all component files: `stack-status-badge.svelte`, `user-profile-card.svelte` - Co-locate with feature slice, aligned with API controllers ### Directory Structure ```text src/lib/features/ ├── organizations/ # Matches OrganizationController │ ├── components/ │ │ ├── organization-card.svelte │ │ └── organization-switcher.svelte │ ├── api.svelte.ts │ ├── models.ts │ └── schemas.ts ├── stacks/ # Matches StackController │ └── components/ │ └── stack-status-badge.svelte └── shared/ # Shared across features └── components/ ├── data-table/ ├── navigation/ └── typography/ ``` ## Always Use shadcn-svelte Components **Never use native HTML** for buttons, inputs, or form elements: ```svelte Settings ``` ## Runes ### $state - Reactive State ```svelte ``` ### $derived - Computed Values ```svelte ``` ### $effect - Side Effects ```svelte ``` ## Props ```svelte ``` ## Event Handling Use `onclick` instead of `on:click`: ```svelte (value = e.currentTarget.value)} /> ``` ## Snippets (Content Projection) Replace `` with snippets. From [login/+page.svelte](src/Exceptionless.Web/ClientApp/src/routes/(auth)/login/+page.svelte): ```svelte state.errors}> {#snippet children(errors)} {/snippet} {#snippet children(field)} Email field.handleChange(e.currentTarget.value)} /> {/snippet} ``` ## Class Merging Use array syntax for conditional classes: ```svelte
Content
``` ## Keyboard Accessibility All interactive components must be keyboard accessible: - Use `Button` component (provides focus handling automatically) - Ensure custom interactions have `tabindex` and keyboard handlers - Test with keyboard-only navigation See [accessibility](accessibility/SKILL.md) for WCAG guidelines. ## Imports ```svelte ``` ## References - [shadcn-svelte](shadcn-svelte/SKILL.md) — UI component patterns and trigger snippets - [accessibility](accessibility/SKILL.md) — WCAG guidelines and keyboard navigation