Files
the-collective-hub/.github/instructions/components.instructions.md
T
KungRaseri b192cd53ba docs(copilot): add Copilot instructions for The Collective Hub
- Add comprehensive project overview and core philosophy
- Document file structure reference for the codebase
- Create key files reference table for task-specific guidance
- Include multi-tenant guidelines and site resolution flow
2026-06-05 23:46:15 -07:00

124 lines
4.2 KiB
Markdown

---
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
<script lang="ts">
let {
title,
description = undefined,
children
} = $props<{
title: string;
description?: string;
children: Snippet;
}>();
</script>
```
- 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
<!-- SectionCard: accepts children + optional headerAction -->
{#if headerAction}
{@render headerAction()}
{/if}
{@render children()}
```
Named snippets in the consumer:
```svelte
{#snippet headerAction()}
<button class="btn-ghost">Export</button>
{/snippet}
<SectionCard title="Movies" {headerAction}>
<!-- body -->
</SectionCard>
```
> **Note on dynamic components:** In Svelte 5, `<svelte:component>` is deprecated. Use `{@const ComponentVar = ...}` in the template and render it as `<ComponentVar />` 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
<div
class="rounded-lg p-4"
style="background-color: var(--bg); color: var(--text);"
>
<h2 style="color: var(--accent);">Section Title</h2>
...
</div>
```
- `rounded-lg` — standard border radius
- Use CSS custom properties for all colors (never hardcode)
- Use consistent spacing and alignment