---
description: 'Use when creating, editing, or organizing Svelte components for The Collective Hub. Enforces folder structure, naming, prop typing, and composition conventions for src/lib/components/.'
applyTo: 'src/lib/components/**/*.svelte'
---
# Component Conventions
## Folder Structure
```
src/lib/components/
ui/ ← Generic, reusable UI primitives (no business logic)
layout/ ← Structural shell components (Header, Footer, Navigation)
```
Place new components in the most specific folder:
- If it's a general-purpose display or form element → `ui/`
- If it's a page-level structural shell → `layout/`
- Do **not** create new folders without a clear category need
## Naming
- Files: **PascalCase** — `SectionCard.svelte`, `StatusBadge.svelte`
- One component per file
- Name reflects what it **is**, not what it **does**: `StatCard` not `DisplayStat`
## Imports
Always import from the full `$lib/components/...` path — do not use relative paths from within `src/`:
```ts
// ✅
import SectionCard from '$lib/components/ui/SectionCard.svelte';
// ❌
import SectionCard from '../components/ui/SectionCard.svelte';
```
## Props
Type props inline using `$props<{...}>()` — do not use a separate `interface` or `type` alias unless it's shared across multiple components:
```svelte
```
- Optional props must have a default value (`= undefined` or a real default)
- Use `Snippet` from `'svelte'` for composable markup slots
- Use `Snippet<[T]>` for typed render props (e.g., row renderers in `DataTable`)
## Composition: Snippets over Slots
Accept content via `Snippet` props. Common pattern:
```svelte
{#if headerAction}
{@render headerAction()}
{/if}
{@render children()}
```
Named snippets in the consumer:
```svelte
{#snippet headerAction()}
{/snippet}
```
> **Note on dynamic components:** In Svelte 5, `` is deprecated. Use `{@const ComponentVar = ...}` in the template and render it as `` instead. See [`svelte5.instructions.md`](svelte5.instructions.md#deprecated-apis) for details.
### No `svelte-ignore` Suppression
`svelte-ignore` comments must NOT be used to suppress svelte-check errors or warnings. All accessibility and type issues must be fixed properly — never hidden behind a suppression comment.
## Admin Components
Admin-specific components live alongside their route pages in `src/routes/admin/` rather than in `src/lib/components/`. Shared admin UI patterns (form fields, buttons, layouts) should be placed in `src/lib/components/admin/` if reused across multiple admin pages.
## Current Component Inventory
| Component | Path | Description |
|-----------|------|-------------|
| Public site sections | [route-level](src/routes/) | Hero, About, Events, Social Links — defined in the route or as page-specific components |
| Layout components | [`$lib/components/layout/`](src/lib/components/layout/) | Header, Footer, Navigation |
| UI primitives | [`$lib/components/ui/`](src/lib/components/ui/) | Container, SectionHeading, buttons, cards |
> The component inventory evolves as the platform grows. When adding a new component, place it in the most specific folder: `ui/` for generic UI, `layout/` for structural shells, or a route directory for page-specific components.
## Visual Style
All components follow The Collective Hub theme system — see [`public-site-theming.instructions.md`](public-site-theming.instructions.md) for CSS custom property conventions and [`tailwindcss.instructions.md`](tailwindcss.instructions.md) for token and color usage.
Use CSS custom properties for theme-aware colors:
```svelte
Section Title
...
```
- `rounded-lg` — standard border radius
- Use CSS custom properties for all colors (never hardcode)
- Use consistent spacing and alignment