--- name: patchies-frontend description: Use when editing Patchies Svelte components, UI state, styling, buttons, persistence, or frontend implementation patterns. --- # Patchies Frontend ## Code Patterns - Use TypeScript for all code. - Use Svelte 5 runes: `$state`, `$props`, `$effect`, `$derived`. - Use event attributes such as `onclick`, not `on:click`. - Separate UI from business logic with manager/system objects when behavior is non-trivial. - Prefer shared named functions when the same logic appears in multiple places, such as a message handler and context menu item. - Prefer existing files and local patterns over new abstractions. - Use `if` branches with early returns for multi-way decisions. Keep ternaries to simple two-way expressions; avoid nested ternaries. In Svelte derived state, use `$derived.by(() => { ... })` with `if`/return branches for these decisions, including icon, label, and class selection. ## Component Size and Svelte Composables - Aim for at most 500 lines per `.svelte` component. Check the full file's line count before extending it. - When a component already exceeds 500 lines, aggressively extract state, derived values, effects, and event-handling logic into focused `use*.svelte.ts` composables. Put new behavior in composables and keep component changes to minimal wiring; do not grow the component further. Extract existing logic as needed so the component's final line count does not increase. - If a change would push a component above 500 lines, extract logic as part of that change instead of crossing the threshold. - Keep each composable focused on one responsibility, colocated with its owning object or feature. Accept reactive getters and callbacks, expose a small interface, and preserve lifecycle cleanup. Keep pure decision logic in ordinary TypeScript helpers when it needs no Svelte reactivity. - Extract cohesive markup into child components when markup drives the file size. Keep the parent focused on rendering and composing behavior; preserve readable formatting rather than compressing lines to meet the limit. ## `ts-pattern` Use `ts-pattern` when it improves clarity: - Exhaustive branching on discriminated unions, enums, or mode/state values. - Matching data shapes where destructuring in branches is useful. - Replacing switch statements that duplicate fallthrough/default logic. Avoid `ts-pattern` when direct control flow is clearer: - Simple null checks. - Early returns in effects, event handlers, setup, or cleanup. - Hot paths such as render loops, audio processing, worker messages, pointer handlers, or animation handlers. - Sequential guards with side effects. ## Persistence Never put localStorage keys or persistence logic directly in components. Create a dedicated store in `src/stores/`; use `preset-library.store.ts` or `help-view.store.ts` as patterns. ## Styling - Prefer Tailwind utilities for DOM the component owns directly. - Use small scoped `