@svgrid/create 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,153 @@
1
+ /* ---------------------------------------------------------------------------
2
+ * Your stylesheet. All of it.
3
+ *
4
+ * Nothing here comes from @svgrid/grid - there is no preset import, no --sg-*
5
+ * token, no theme to pick. The headless entry point ships an engine and no CSS,
6
+ * so the table below is styled the same way any other table in your app would
7
+ * be. Rename the variables, drop them for Tailwind classes, delete this file
8
+ * and start over: none of it affects sorting or filtering.
9
+ *
10
+ * If you'd rather inherit a themed grid than write one, the other starters use
11
+ * the <SvGrid> renderer and its 20 presets:
12
+ * npm create @svgrid@latest my-app -- --template minimal
13
+ * ------------------------------------------------------------------------- */
14
+
15
+ :root {
16
+ --app-bg: #ffffff;
17
+ --app-surface: #fafaf9;
18
+ --app-fg: #1c1917;
19
+ --app-muted: #78716c;
20
+ --app-border: #e7e5e4;
21
+ --app-accent: #c2410c;
22
+ --app-hover: #f5f5f4;
23
+ color-scheme: light;
24
+ }
25
+
26
+ /* Dark mode follows the OS. Swap this for a data-theme attribute and a toggle
27
+ if you want the choice to be the user's. */
28
+ @media (prefers-color-scheme: dark) {
29
+ :root {
30
+ --app-bg: #1c1917;
31
+ --app-surface: #292524;
32
+ --app-fg: #fafaf9;
33
+ --app-muted: #a8a29e;
34
+ --app-border: #44403c;
35
+ --app-accent: #fb923c;
36
+ --app-hover: #292524;
37
+ color-scheme: dark;
38
+ }
39
+ }
40
+
41
+ body {
42
+ margin: 0;
43
+ min-height: 100vh;
44
+ background: var(--app-bg);
45
+ color: var(--app-fg);
46
+ font-family: system-ui, -apple-system, Segoe UI, sans-serif;
47
+ }
48
+
49
+ main {
50
+ max-width: 720px;
51
+ margin: 3rem auto;
52
+ padding: 0 1rem;
53
+ }
54
+
55
+ h1 {
56
+ margin: 0 0 0.5rem;
57
+ font-size: 1.4rem;
58
+ }
59
+
60
+ header p {
61
+ margin: 0 0 1.5rem;
62
+ color: var(--app-muted);
63
+ line-height: 1.6;
64
+ }
65
+
66
+ code {
67
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
68
+ font-size: 0.9em;
69
+ }
70
+
71
+ .search {
72
+ width: 260px;
73
+ margin-bottom: 1rem;
74
+ padding: 0.45rem 0.7rem;
75
+ border: 1px solid var(--app-border);
76
+ border-radius: 6px;
77
+ background: var(--app-bg);
78
+ color: var(--app-fg);
79
+ font: inherit;
80
+ font-size: 0.9rem;
81
+ }
82
+
83
+ .search:focus-visible {
84
+ outline: 2px solid var(--app-accent);
85
+ outline-offset: 1px;
86
+ }
87
+
88
+ table {
89
+ width: 100%;
90
+ border-collapse: collapse;
91
+ font-size: 0.9rem;
92
+ }
93
+
94
+ th {
95
+ padding: 0;
96
+ background: var(--app-surface);
97
+ border-bottom: 2px solid var(--app-border);
98
+ text-align: left;
99
+ }
100
+
101
+ /* The header is a button so keyboard users can sort too - the engine does not
102
+ care what element calls toggleSort. */
103
+ th button {
104
+ width: 100%;
105
+ padding: 0.6rem 0.75rem;
106
+ border: 0;
107
+ background: none;
108
+ color: inherit;
109
+ font: inherit;
110
+ font-weight: 600;
111
+ text-align: inherit;
112
+ cursor: pointer;
113
+ }
114
+
115
+ th button:hover {
116
+ color: var(--app-accent);
117
+ }
118
+
119
+ th button:focus-visible {
120
+ outline: 2px solid var(--app-accent);
121
+ outline-offset: -2px;
122
+ }
123
+
124
+ .indicator {
125
+ color: var(--app-accent);
126
+ font-size: 0.7em;
127
+ }
128
+
129
+ td {
130
+ padding: 0.6rem 0.75rem;
131
+ border-bottom: 1px solid var(--app-border);
132
+ }
133
+
134
+ tbody tr:hover td {
135
+ background: var(--app-hover);
136
+ }
137
+
138
+ .numeric {
139
+ text-align: right;
140
+ font-variant-numeric: tabular-nums;
141
+ }
142
+
143
+ .empty {
144
+ padding: 1.5rem;
145
+ color: var(--app-muted);
146
+ text-align: center;
147
+ }
148
+
149
+ .count {
150
+ margin-top: 0.75rem;
151
+ color: var(--app-muted);
152
+ font-size: 0.8rem;
153
+ }
@@ -0,0 +1,7 @@
1
+ import { mount } from 'svelte'
2
+ import './app.css'
3
+ import App from './App.svelte'
4
+
5
+ const app = mount(App, { target: document.getElementById('app')! })
6
+
7
+ export default app
@@ -0,0 +1,2 @@
1
+ /// <reference types="svelte" />
2
+ /// <reference types="vite/client" />
@@ -0,0 +1,5 @@
1
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
2
+
3
+ export default {
4
+ preprocess: vitePreprocess(),
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
7
+ "resolveJsonModule": true,
8
+ "isolatedModules": true,
9
+ "skipLibCheck": true,
10
+ "strict": true,
11
+ "noEmit": true
12
+ },
13
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.svelte"]
14
+ }
@@ -0,0 +1,6 @@
1
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
2
+ import { defineConfig } from 'vite'
3
+
4
+ export default defineConfig({
5
+ plugins: [svelte()],
6
+ })
@@ -13,7 +13,7 @@
13
13
  * Token reference: https://svgrid.com/docs/getting-started/5-theme-and-density
14
14
  * ------------------------------------------------------------------------- */
15
15
  /* svgrid-theme:start */
16
- @import '@svgrid/grid/themes/shadcn.css';
16
+ @import '@svgrid/grid/themes/ember.css';
17
17
  /* svgrid-theme:end */
18
18
 
19
19
  /* Which way the page leans, so scrollbars, form controls and the canvas behind
@@ -0,0 +1,44 @@
1
+ # SvGrid + SvelteKit sample
2
+
3
+ A grid whose rows are loaded on the server, sorted from the URL, and edited
4
+ through a form action - the three things that are different about running a grid
5
+ in SvelteKit rather than a plain Vite SPA.
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev # http://localhost:5173/people
10
+ ```
11
+
12
+ ## What to try
13
+
14
+ 1. **Click the `Year` header.** The URL becomes `?sort=year&dir=asc`. Copy that
15
+ link into a new tab - it opens already sorted, because the server did it.
16
+ 2. **Double-click a name, change it, press Enter, then reload.** The edit went
17
+ through the form action in `+page.server.ts` and survived.
18
+ 3. **Switch the theme** with the picker in the header. All 20 built-in presets,
19
+ light and dark, applied live.
20
+ 4. **`curl localhost:5173/people`.** The rows are in the HTML, not injected by
21
+ JS afterwards. That is what a crawler sees.
22
+
23
+ ## Where things are
24
+
25
+ | File | Does |
26
+ | --- | --- |
27
+ | `src/lib/people.ts` | Stands in for your database. Swap for real queries. |
28
+ | `src/routes/people/+page.server.ts` | `load` sorts from the query string; the `rename` action takes the edit. |
29
+ | `src/routes/people/+page.svelte` | The grid. `externalSort` because the server owns the ordering. |
30
+ | `src/lib/theme.svelte.ts` | Runtime theme switching via `resolveThemeTokens`. |
31
+ | `src/app.css` | Imports one preset so the first paint is themed before JS runs. |
32
+
33
+ ## Themes
34
+
35
+ Pick a starting theme when you scaffold:
36
+
37
+ ```bash
38
+ npm create @svgrid@latest my-app -- --template sveltekit --theme dracula --dark
39
+ ```
40
+
41
+ Or change it at runtime with the header picker. The picker writes the preset's
42
+ `--sg-*` custom properties onto `<html>`; nothing rebuilds.
43
+
44
+ Full guide: https://svgrid.com/docs/getting-started/sveltekit/
@@ -0,0 +1,23 @@
1
+ node_modules
2
+
3
+ # Output
4
+ .output
5
+ .vercel
6
+ .netlify
7
+ .wrangler
8
+ /.svelte-kit
9
+ /build
10
+
11
+ # OS
12
+ .DS_Store
13
+ Thumbs.db
14
+
15
+ # Env
16
+ .env
17
+ .env.*
18
+ !.env.example
19
+ !.env.test
20
+
21
+ # Vite
22
+ vite.config.js.timestamp-*
23
+ vite.config.ts.timestamp-*
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "svgrid-sveltekit-sample",
3
+ "private": true,
4
+ "version": "0.0.1",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview",
10
+ "prepare": "svelte-kit sync || echo ''",
11
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
13
+ },
14
+ "devDependencies": {
15
+ "@sveltejs/adapter-auto": "^7.0.1",
16
+ "@sveltejs/kit": "^2.63.0",
17
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
18
+ "svelte": "^5.56.1",
19
+ "svelte-check": "^4.6.0",
20
+ "typescript": "^6.0.3",
21
+ "vite": "^8.0.16"
22
+ },
23
+ "dependencies": {
24
+ "@svgrid/grid": "^2.6.8"
25
+ }
26
+ }
@@ -0,0 +1,15 @@
1
+ /* SvGrid theme. One of the 20 presets @svgrid/grid ships.
2
+ *
3
+ * Importing it as a stylesheet means the FIRST paint - and the server-rendered
4
+ * HTML - is already themed, before any JavaScript runs. The theme picker in the
5
+ * layout overrides these values at runtime by setting the same --sg-* custom
6
+ * properties on <html>.
7
+ *
8
+ * `npm create @svgrid@latest -- --theme <id>` rewrites the line between the
9
+ * markers, so pick a starting theme at scaffold time if you prefer. */
10
+ /* svgrid-theme:start */
11
+ @import '@svgrid/grid/themes/ember.css';
12
+ /* svgrid-theme:end */
13
+
14
+ * { box-sizing: border-box; }
15
+ body { margin: 0; }
@@ -0,0 +1,13 @@
1
+ // See https://svelte.dev/docs/kit/types#app.d.ts
2
+ // for information about these interfaces
3
+ declare global {
4
+ namespace App {
5
+ // interface Error {}
6
+ // interface Locals {}
7
+ // interface PageData {}
8
+ // interface PageState {}
9
+ // interface Platform {}
10
+ }
11
+ }
12
+
13
+ export {};
@@ -0,0 +1,22 @@
1
+ <!doctype html>
2
+ <html lang="en" data-theme="light">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="text-scale" content="scale" />
7
+ <script>
8
+ // Settle the theme before the first paint. Without this the server-rendered
9
+ // HTML shows one palette and the picker in +layout.svelte swaps it a frame
10
+ // later. With nothing saved yet we follow the OS.
11
+ try {
12
+ var saved = JSON.parse(localStorage.getItem('svgrid-theme') || 'null')
13
+ var fallback = matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
14
+ document.documentElement.dataset.theme = (saved && saved.mode) || fallback
15
+ } catch (e) {}
16
+ </script>
17
+ %sveltekit.head%
18
+ </head>
19
+ <body data-sveltekit-preload-data="hover">
20
+ <div style="display: contents">%sveltekit.body%</div>
21
+ </body>
22
+ </html>
@@ -0,0 +1,22 @@
1
+ export type Person = { id: number; name: string; role: string; year: number }
2
+
3
+ // Stands in for your database. Mutating a module-level array is fine for a
4
+ // tutorial; swap it for real queries and the rest of the page is unchanged.
5
+ const people: Person[] = [
6
+ { id: 1, name: 'Ada Lovelace', role: 'Mathematician', year: 1843 },
7
+ { id: 2, name: 'Grace Hopper', role: 'Rear Admiral', year: 1952 },
8
+ { id: 3, name: 'Karen Sparck Jones', role: 'Computer Scientist', year: 1972 },
9
+ { id: 4, name: 'Barbara Liskov', role: 'Computer Scientist', year: 1968 },
10
+ { id: 5, name: 'Margaret Hamilton', role: 'Software Engineer', year: 1969 },
11
+ ]
12
+
13
+ export function listPeople(sortBy: keyof Person = 'name', desc = false): Person[] {
14
+ const rows = [...people]
15
+ rows.sort((a, b) => (a[sortBy] > b[sortBy] ? 1 : a[sortBy] < b[sortBy] ? -1 : 0))
16
+ return desc ? rows.reverse() : rows
17
+ }
18
+
19
+ export function renamePerson(id: number, name: string): void {
20
+ const row = people.find((p) => p.id === id)
21
+ if (row) row.name = name
22
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Runtime theme switching.
3
+ *
4
+ * `@svgrid/grid/themes` ships 20 presets and a `resolveThemeTokens(preset, mode)`
5
+ * helper that returns the `--sg-*` custom properties for a given preset and
6
+ * light/dark mode. Writing those onto `<html>` re-themes the grid live - there
7
+ * is nothing to rebuild and no stylesheet to swap.
8
+ *
9
+ * `app.css` imports one preset as a stylesheet so the very first paint (and the
10
+ * server-rendered HTML) already has a theme before any JS runs. The values set
11
+ * here override it once the user picks something.
12
+ */
13
+ import {
14
+ getThemePreset,
15
+ resolveThemeTokens,
16
+ themePresets,
17
+ type ThemeMode,
18
+ } from '@svgrid/grid/themes'
19
+
20
+ /** Every preset, for the picker. */
21
+ export const presets = themePresets.map((p) => ({ id: p.id, name: p.name }))
22
+
23
+ const STORAGE_KEY = 'svgrid-theme'
24
+
25
+ // `npm create @svgrid@latest -- --theme <id> [--dark|--light]` patches the two
26
+ // values between these markers so the scaffolded app starts on the theme you
27
+ // asked for. INITIAL_MODE is only the fallback: a saved choice wins over it, and
28
+ // so does the OS preference when nobody has pinned a mode. The inline script in
29
+ // `app.html` settles the same question before the first paint.
30
+ /* svgrid-initial-theme:start */
31
+ export const INITIAL_THEME = 'ember'
32
+ export const INITIAL_MODE: ThemeMode = 'light'
33
+ /* svgrid-initial-theme:end */
34
+
35
+ type Saved = { id: string; mode: ThemeMode }
36
+
37
+ function restore(): Saved {
38
+ const fallback: Saved = { id: INITIAL_THEME, mode: INITIAL_MODE }
39
+ if (typeof document === 'undefined') return fallback
40
+ // Trust whatever app.html's inline script settled on, so the picker agrees
41
+ // with what is already on screen.
42
+ const painted = document.documentElement.dataset.theme
43
+ if (painted === 'dark' || painted === 'light') fallback.mode = painted
44
+ try {
45
+ const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) ?? 'null') as Saved | null
46
+ if (!saved || typeof saved.id !== 'string') return fallback
47
+ if (!getThemePreset(saved.id)) return fallback
48
+ return { id: saved.id, mode: saved.mode === 'dark' ? 'dark' : 'light' }
49
+ } catch {
50
+ return fallback
51
+ }
52
+ }
53
+
54
+ class ThemeState {
55
+ #initial = restore()
56
+ id = $state(this.#initial.id)
57
+ mode = $state<ThemeMode>(this.#initial.mode)
58
+
59
+ /** Push the current selection onto <html> as CSS custom properties. */
60
+ apply() {
61
+ if (typeof document === 'undefined') return
62
+ const tokens = resolveThemeTokens(getThemePreset(this.id) ?? getThemePreset(INITIAL_THEME)!, this.mode)
63
+ const root = document.documentElement
64
+ for (const [key, value] of Object.entries(tokens)) root.style.setProperty(key, value)
65
+ // Lets the browser theme form controls and scrollbars to match, and keeps
66
+ // any `[data-theme='dark']` rules in your own CSS in step.
67
+ root.style.colorScheme = this.mode
68
+ root.dataset.theme = this.mode
69
+ try {
70
+ localStorage.setItem(STORAGE_KEY, JSON.stringify({ id: this.id, mode: this.mode }))
71
+ } catch {
72
+ // Private mode, quota, a blocked origin - not worth breaking the page over.
73
+ }
74
+ }
75
+
76
+ set(id: string, mode: ThemeMode = this.mode) {
77
+ this.id = id
78
+ this.mode = mode
79
+ this.apply()
80
+ }
81
+
82
+ toggleMode() {
83
+ this.set(this.id, this.mode === 'dark' ? 'light' : 'dark')
84
+ }
85
+ }
86
+
87
+ export const theme = new ThemeState()
@@ -0,0 +1,78 @@
1
+ <script lang="ts">
2
+ import '../app.css'
3
+ import { theme, presets } from '$lib/theme.svelte'
4
+
5
+ let { children } = $props()
6
+
7
+ // Apply on mount so the picker's starting value wins over the stylesheet, and
8
+ // on every later change. Runs client-side only - the server-rendered HTML is
9
+ // already themed by the stylesheet import in app.css.
10
+ $effect(() => {
11
+ theme.apply()
12
+ })
13
+ </script>
14
+
15
+ <header class="bar">
16
+ <strong>SvGrid + SvelteKit</strong>
17
+
18
+ <label>
19
+ Theme
20
+ <select
21
+ value={theme.id}
22
+ onchange={(e) => theme.set(e.currentTarget.value)}
23
+ aria-label="Grid theme"
24
+ >
25
+ {#each presets as p (p.id)}
26
+ <option value={p.id}>{p.name}</option>
27
+ {/each}
28
+ </select>
29
+ </label>
30
+
31
+ <button type="button" onclick={() => theme.toggleMode()} aria-pressed={theme.mode === 'dark'}>
32
+ {theme.mode === 'dark' ? 'Dark' : 'Light'}
33
+ </button>
34
+ </header>
35
+
36
+ <main>
37
+ {@render children?.()}
38
+ </main>
39
+
40
+ <style>
41
+ .bar {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 1rem;
45
+ flex-wrap: wrap;
46
+ padding: 0.75rem 1.25rem;
47
+ border-bottom: 1px solid var(--sg-border);
48
+ background: var(--sg-header-bg);
49
+ color: var(--sg-header-fg);
50
+ font-family: system-ui, sans-serif;
51
+ }
52
+ .bar label {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 0.4rem;
56
+ font-size: 0.875rem;
57
+ }
58
+ .bar select,
59
+ .bar button {
60
+ font: inherit;
61
+ padding: 0.3rem 0.5rem;
62
+ border-radius: 6px;
63
+ border: 1px solid var(--sg-border);
64
+ background: var(--sg-bg);
65
+ color: var(--sg-fg);
66
+ }
67
+ .bar button {
68
+ cursor: pointer;
69
+ min-width: 4.5rem;
70
+ }
71
+ main {
72
+ padding: 1.25rem;
73
+ font-family: system-ui, sans-serif;
74
+ color: var(--sg-fg);
75
+ background: var(--sg-bg);
76
+ min-height: 100vh;
77
+ }
78
+ </style>
@@ -0,0 +1,7 @@
1
+ <h1>SvGrid + SvelteKit</h1>
2
+ <p>
3
+ The sample lives at <a href="/people">/people</a> - a grid whose rows are
4
+ loaded in <code>+page.server.ts</code>, sorted from the URL, and edited through
5
+ a form action.
6
+ </p>
7
+ <p>Use the picker in the header to switch the grid theme while it runs.</p>
@@ -0,0 +1,16 @@
1
+ import type { Actions, PageServerLoad } from './$types'
2
+ import { listPeople, renamePerson, type Person } from '$lib/people'
3
+
4
+ export const load: PageServerLoad = ({ url }) => {
5
+ const sortBy = (url.searchParams.get('sort') ?? 'name') as keyof Person
6
+ const desc = url.searchParams.get('dir') === 'desc'
7
+ return { rows: listPeople(sortBy, desc), sortBy, desc }
8
+ }
9
+
10
+ export const actions: Actions = {
11
+ rename: async ({ request }) => {
12
+ const data = await request.formData()
13
+ renamePerson(Number(data.get('id')), String(data.get('name')))
14
+ return { success: true }
15
+ },
16
+ }
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import { goto } from '$app/navigation'
3
+ import { page } from '$app/state'
4
+ import { SvGrid, type GridColumns } from '@svgrid/grid'
5
+ import type { Person } from '$lib/people'
6
+
7
+ let { data } = $props()
8
+
9
+ const columns: GridColumns<Person> = [
10
+ { field: 'name', header: 'Name', editable: true },
11
+ { field: 'role', header: 'Role' },
12
+ { field: 'year', header: 'Year' },
13
+ ]
14
+
15
+ // Header click -> URL -> server sorts -> load returns ordered rows.
16
+ function onSortingChange(sorting: Array<{ id: string; desc: boolean }>) {
17
+ const next = new URL(page.url)
18
+ if (sorting.length === 0) {
19
+ next.searchParams.delete('sort')
20
+ next.searchParams.delete('dir')
21
+ } else {
22
+ next.searchParams.set('sort', sorting[0]!.id)
23
+ next.searchParams.set('dir', sorting[0]!.desc ? 'desc' : 'asc')
24
+ }
25
+ goto(next, { keepFocus: true, noScroll: true })
26
+ }
27
+
28
+ // Committed edit -> form action -> database.
29
+ async function onCellValueChange(e: { row: Person; columnId: string; newValue: unknown }) {
30
+ if (e.columnId !== 'name') return
31
+ const body = new FormData()
32
+ body.set('id', String(e.row.id))
33
+ body.set('name', String(e.newValue))
34
+ await fetch('?/rename', { method: 'POST', body })
35
+ }
36
+ </script>
37
+
38
+ <h1>People</h1>
39
+ <p>Click a header to sort - the order lives in the URL. Double-click a name to edit it.</p>
40
+
41
+ <SvGrid
42
+ data={data.rows}
43
+ {columns}
44
+ sortable
45
+ editable
46
+ externalSort
47
+ initialSorting={[{ id: data.sortBy, desc: data.desc }]}
48
+ {onSortingChange}
49
+ {onCellValueChange}
50
+ containerHeight={320}
51
+ />
@@ -0,0 +1,20 @@
1
+ {
2
+ "extends": "./.svelte-kit/tsconfig.json",
3
+ "compilerOptions": {
4
+ "rewriteRelativeImportExtensions": true,
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "esModuleInterop": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "resolveJsonModule": true,
10
+ "skipLibCheck": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "moduleResolution": "bundler"
14
+ }
15
+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
16
+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
17
+ //
18
+ // To make changes to top-level options such as include and exclude, we recommend extending
19
+ // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
20
+ }
@@ -0,0 +1,20 @@
1
+ import adapter from '@sveltejs/adapter-auto';
2
+ import { sveltekit } from '@sveltejs/kit/vite';
3
+ import { defineConfig } from 'vite';
4
+
5
+ export default defineConfig({
6
+ plugins: [
7
+ sveltekit({
8
+ compilerOptions: {
9
+ // Force runes mode for the project, except for libraries. Can be removed in svelte 6.
10
+ runes: ({ filename }) =>
11
+ filename.split(/[/\\]/).includes('node_modules') ? undefined : true
12
+ },
13
+
14
+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
15
+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
16
+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
17
+ adapter: adapter()
18
+ })
19
+ ]
20
+ });