0.0.18 • Published 6 days ago

@alanlyc/svelte5-tailwind-scaffolding v0.0.18

Weekly downloads
-
License
MIT
Repository
github
Last release
6 days ago

svelte5-tailwind-scaffolding

This is just a simple package to bootstrap my personal projects with Svelte 5 and TailwindCSS. Nothing special.

It provides functions for displaying modals and it displays error automatically. There are also utilities for buttons, input, and autocompleted input. It also automatically apply bg-neutral-900 and text-white to body in dark mode.

Browser Requirements

  1. modal, modal.builder, block, and BaseModal requires HTMLDialogElement (Baseline 2022) and the CSS *-inline-start, *-inline-end family of properties (Baseline 2020)
  2. Autocomplete.autoselect requires the CSS :has() selector
  3. Table requires the CSS *-inline-start, *-inline-end family of properties

Setup

1. Install Everything

npm create svelte@latest   # select Svelte 5
npm i
npm install -D tailwindcss postcss autoprefixer && npx tailwindcss init -p
npm i @alanlyc/svelte5-tailwind-scaffolding

2. tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
    content: ['./src/**/*.{html,js,svelte,ts}'],
    theme: {
        extend: {},
    },
    plugins: [],
    darkMode: "class",  // <-- this is required
}

3. src/app.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <link rel="icon" href="%sveltekit.assets%/favicon.png" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        %sveltekit.head%
        <script>
            if (
                window.matchMedia('prefers-color-scheme: dark') ||
                localStorage.getItem('theme') === 'dark'
            )
                document.documentElement.classList.add('dark');
            if (localStorage.getItem('theme') === 'light')
                document.documentElement.classList.remove('dark');
        </script>
    </head>
    <body data-sveltekit-preload-data="hover">
        <div style="display: contents">%sveltekit.body%</div>
    </body>
</html>

4. src/app.css

@tailwind base;
@tailwind components;
@tailwind utilities;

5. src/routes/+layout.svelte

<script lang="ts">
    import { Scaffolding } from "@alanlyc/svelte5-tailwind-scaffolding"
	import '../app.css'
</script>

<Scaffolding />

<slot />

6. src/routes/+page.svelte

<script lang="ts">
    import { modal, Button } from "@alanlyc/svelte5-tailwind-scaffolding"
</script>

<Button class="block" onclick={async () => {
    // most part of the modal was designed by Tailwind UI
    // but dark mode was added by me
    await modal({
        type: "ok",
        title: "Congratulations!",
        md: "You have completed setting up the scaffolding!",
        actions: ["OK"],
		defaultReturn: undefined,
    })
}}>
    OK Modal
</Button>

7. npm run dev

When you click the button, you may encounter a Vite optimization and see a hydration error. It should be fine to just wait for it to reload.

Bonus: cloudflare

Since setting up Cloudflare + SvelteKit for development is a hassle, I will just add a section here on how to setup Cloudflare development environment (only partially tested as of right now).

1. Install Everything

npm i -D @cloudflare/workers-types @sveltejs/adapter-cloudflare miniflare

2. src/hooks.server.ts

import { dev } from "$app/environment";
import type { Miniflare } from "miniflare";

let mf: Miniflare;

export async function handle({ event, resolve }) {
    if (dev) {
        if (!mf) {
            const { Miniflare, Log, LogLevel } = await import("miniflare");
            mf = new Miniflare({
                log: new Log(LogLevel.INFO),
                kvPersist: ".wrangler/state/v3/kv",
                kvNamespaces: ["KV"],
                r2Persist: ".wrangler/state/v3/r2",
                r2Buckets: ["RV"],
                // ... and whatever bindings you have
                script: "",
                modules: true,
            });
        }
        event.platform = { env: await mf.getBindings() };
    }
    return resolve(event);
}

3. src/app.d.ts

import type { KVNamespace, R2Bucket } from "@cloudflare/workers-types";

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
    namespace App {
        // interface Error {}
        // interface Locals {}
        // interface PageData {}
        // interface PageState {}
        interface Platform {
            env: {
                KV: KVNamespace,
                R2: R2Bucket,
            }
        }
    }
}

export {};

4. wrangler.toml

You don't actually have to put any config here for development.

name = "<insert_app_name>"
compatibility_date = "<insert_today_YYYY-MM-DD>"

5. npm run dev

If vite is trying to optimize miniflare, configure vite.config.ts as follow:

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';

export default defineConfig({
    plugins: [sveltekit()],
    test: {
        include: ['src/**/*.{test,spec}.{js,ts}']
    },
    optimizeDeps: {
        exclude: ['miniflare']
    }
});

6. Interact with bindings with Wrangler

Interact with KV:

# notice that we use --namespace-id, not --bindings (which is used if we actually use wrangler.toml)
npx wrangler kv:key put abcxyz "https://google.com" --namespace-id KV --local
0.0.18

6 days ago

0.0.14

7 days ago

0.0.15

7 days ago

0.0.16

7 days ago

0.0.13

11 days ago

0.0.11

17 days ago

0.0.12

17 days ago

0.0.10

18 days ago

0.0.9

20 days ago

0.0.8

20 days ago

0.0.5

22 days ago

0.0.7

21 days ago

0.0.6

22 days ago

0.0.4

22 days ago

0.0.3

22 days ago

0.0.2

22 days ago

0.0.1

22 days ago