# Adding a feature Walk-through for building a new side-panel feature. We'll use a hypothetical "NOTAMs" panel (no-fly-zone overlays) as the example. ## 1. Pick a feature folder ``` src/lib/features/notams/ ├── index.ts ├── store.ts ├── types.ts ├── NotamsPanel.svelte └── NotamRenderer.svelte # if you draw on the map ``` Re-export the public surface from `index.ts`. ## 2. Define the domain If the feature introduces a durable type (something saved to a server or localStorage), put the type in `src/lib/domain/notam.ts` and re-export from `src/lib/domain/index.ts`. Ephemeral state types can live in the feature's `types.ts`. ```ts // src/lib/domain/notam.ts export interface Notam { id: string; code: string; polygon: LatLngTuple[]; validFrom: string; validTo: string; } ``` ## 3. Add state Feature-scoped stores go in the feature folder. Use `persisted()` if the user should not lose the state on reload, plain `writable()` otherwise. ```ts // src/lib/features/notams/store.ts import { persisted } from '$state'; import type { Notam } from '$domain'; export const notamsStore = persisted('notams', []); ``` ## 4. Add API (if needed) ```ts // src/lib/api/notams.ts import { api } from './client'; import type { Notam } from '$domain'; export const notamsApi = { list: () => api.get('/notams/') }; ``` And export from `src/lib/api/index.ts`. ## 5. Build the panel Re-use UI primitives. Wrap everything in `CollapsibleCard` so it lands in the side panel. ```svelte {#each $notamsStore as notam (notam.id)}
{notam.code}
{/each}
``` ## 6. Add i18n keys Append to `src/lib/i18n/locales/ru.json` and `en.json`. The lookup is dot-separated: ```json { "notams": { "title": "NOTAMs", "empty": "Нет активных NOTAMs" } } ``` ## 7. Draw on the map (optional) Every on-map drawing goes through a Scene. One scene per feature, or per sub- entity if the feature manages many independent overlays (like workspaces). ```svelte ``` Add `` as a child of `` in the predict route. ## 8. Wire into the route ```svelte {#if rightTab === 'notams'} {/if} ``` ## 9. Add a settings entry (optional) If the feature should be toggleable, extend `src/lib/features/settings/store.ts` and `schema.ts`. Keep the field declarative (kind + labelKey + path) — the SettingsPanel renders it automatically. ## 10. Checklist before you open a PR - [ ] `npm run check` passes - [ ] `npm run build` passes - [ ] All user-visible strings routed through `$t` - [ ] Feature only depends on shared modules (`$domain`, `$state`, `$api`, `$ui`, `$map`) — not on other features' internals - [ ] `index.ts` exports only what the outside world needs - [ ] Panel matches existing visual language (CollapsibleCard, Bootstrap sm form controls, same spacing)