86 lines
2.5 KiB
Markdown
86 lines
2.5 KiB
Markdown
GitHub Copilot Instructions for This Repository
|
||
Use Svelte 5 runes exclusively
|
||
|
||
Declare reactive state with $state(); derive values with $derived(); run side-effect logic with $effect() etc.
|
||
svelte.dev
|
||
svelte.dev
|
||
|
||
Do not fall back to the legacy $: label syntax or Svelte 3/4 stores! This is important!
|
||
|
||
Enforce a clean component structure
|
||
|
||
<script> comes first, followed by markup and then an optional <style> (rarely needed—prefer Tailwind).
|
||
|
||
Export component props with export let … (still valid in Svelte 5).
|
||
|
||
Keep each component focused on one visual/behavioural concern; split larger UIs into children.
|
||
|
||
Tailwind-only styling conventions
|
||
|
||
Base container: rounded-lg border border-gray-300 (or rounded-md on small items).
|
||
|
||
Absolutely no shadow-* classes.
|
||
|
||
Use p-4 or p-6 for internal padding, and gap-* utilities (not margin hacks) for spacing between children.
|
||
|
||
Prefer neutral greys (gray-50‒gray-800) and a single accent palette defined in tailwind.config.js.
|
||
|
||
HTML & accessibility
|
||
|
||
Generate semantic elements (<button>, <nav>, <main>, <section>, <label>, etc.).
|
||
|
||
Every interactive element must have an accessible name (aria-label, visible text, or title).
|
||
|
||
Do not generate tabindex gymnastics; rely on natural DOM order.
|
||
|
||
Type safety & tooling
|
||
|
||
Default to <script lang="ts"> unless the file is explicitly plain JS.
|
||
|
||
Always import types from @types/svelte or svelte where needed.
|
||
|
||
File / folder conventions
|
||
|
||
Component names are PascalCase.svelte.
|
||
|
||
Collocate tests as ComponentName.test.ts beside the component.
|
||
|
||
Put shared util functions in src/lib.
|
||
|
||
Example pattern (reference only)
|
||
|
||
svelte
|
||
Copy
|
||
Edit
|
||
<!-- copilot: follow the repo instructions above -->
|
||
<script lang="ts">
|
||
let count = $state(0);
|
||
let doubled = $derived(count * 2);
|
||
$effect(() => console.log(`count is ${count}`));
|
||
</script>
|
||
|
||
<div class="rounded-lg border border-gray-300 p-4 flex flex-col gap-4">
|
||
<button
|
||
class="rounded-md px-4 py-2 bg-blue-600 text-white"
|
||
on:click={() => count++}
|
||
aria-label="Increment counter"
|
||
>
|
||
{count}
|
||
</button>
|
||
|
||
<p>{doubled}</p>
|
||
</div>
|
||
What not to do
|
||
|
||
No inline style="" attributes.
|
||
|
||
No external CSS files unless Tailwind cannot express the rule.
|
||
|
||
No class names that imply design debt (.box, .wrapper, .container-1, etc.).
|
||
|
||
Avoid non-reactive variables; if a value affects the UI, use a rune.
|
||
|
||
NEVER $: label syntax; use $state(), $derived(), and $effect().
|
||
|
||
If you want to use supabse client in the browser, it is stored in the data
|
||
variable obtained from let { data } = $props(); |