vela 0.1.0 → 0.9.1
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.
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/bin.js +6245 -0
- package/dist/bin.js.map +7 -0
- package/package.json +85 -17
- package/templates/minimal/.ignore +3 -0
- package/templates/minimal/.prettierignore +9 -0
- package/templates/minimal/.prettierrc +15 -0
- package/templates/minimal/.vscode/extensions.json +3 -0
- package/templates/minimal/.vscode/settings.json +5 -0
- package/templates/minimal/_gitignore +30 -0
- package/templates/minimal/_npmrc +1 -0
- package/templates/minimal/components.json +16 -0
- package/templates/minimal/data/fixtures/README.md +1 -0
- package/templates/minimal/data/hooks/README.md +3 -0
- package/templates/minimal/data/seeds/README.md +1 -0
- package/templates/minimal/package.template.json +54 -0
- package/templates/minimal/src/app.css +121 -0
- package/templates/minimal/src/app.d.ts +19 -0
- package/templates/minimal/src/app.html +13 -0
- package/templates/minimal/src/hooks.server.ts +8 -0
- package/templates/minimal/src/lib/assets/favicon.svg +8 -0
- package/templates/minimal/src/lib/components/ui/button/button.svelte +80 -0
- package/templates/minimal/src/lib/components/ui/button/index.ts +17 -0
- package/templates/minimal/src/lib/components/ui/navbar/index.ts +11 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-brand.svelte +8 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-brandname.svelte +8 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-item.svelte +6 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-link.svelte +13 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-list.svelte +22 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-logo.svelte +10 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-mobile-toggle.svelte +20 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-mode.svelte +12 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar-store.ts +5 -0
- package/templates/minimal/src/lib/components/ui/navbar/navbar.svelte +20 -0
- package/templates/minimal/src/lib/components/ui/sonner/index.ts +1 -0
- package/templates/minimal/src/lib/components/ui/sonner/sonner.svelte +13 -0
- package/templates/minimal/src/lib/index.ts +1 -0
- package/templates/minimal/src/lib/utils.ts +13 -0
- package/templates/minimal/src/routes/(public)/+layout.svelte +9 -0
- package/templates/minimal/src/routes/(public)/+page.svelte +65 -0
- package/templates/minimal/src/routes/(public)/root-layout.svelte +55 -0
- package/templates/minimal/src/routes/(public)/server.test.ts +10 -0
- package/templates/minimal/src/routes/+error.svelte +29 -0
- package/templates/minimal/src/routes/+layout.server.ts +30 -0
- package/templates/minimal/src/routes/+layout.svelte +38 -0
- package/templates/minimal/src/routes/api/README.md +26 -0
- package/templates/minimal/static/og.jpg +0 -0
- package/templates/minimal/static/robots.txt +3 -0
- package/templates/minimal/template.json +4 -0
- package/templates/minimal/test/setup.ts +46 -0
- package/templates/minimal/tsconfig.json +15 -0
- package/templates/minimal/vite.config.ts +17 -0
- package/templates/minimal/vitest.config.ts +15 -0
- package/templates/static/.ignore +3 -0
- package/templates/static/.prettierignore +9 -0
- package/templates/static/.prettierrc +15 -0
- package/templates/static/.vscode/extensions.json +3 -0
- package/templates/static/.vscode/settings.json +5 -0
- package/templates/static/_gitignore +23 -0
- package/templates/static/_npmrc +1 -0
- package/templates/static/components.json +16 -0
- package/templates/static/package.template.json +44 -0
- package/templates/static/src/app.css +121 -0
- package/templates/static/src/app.d.ts +13 -0
- package/templates/static/src/app.html +13 -0
- package/templates/static/src/hooks.server.ts +26 -0
- package/templates/static/src/lib/assets/favicon.svg +8 -0
- package/templates/static/src/lib/components/ui/button/button.svelte +80 -0
- package/templates/static/src/lib/components/ui/button/index.ts +17 -0
- package/templates/static/src/lib/components/ui/navbar/index.ts +11 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-brand.svelte +8 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-brandname.svelte +8 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-item.svelte +6 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-link.svelte +13 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-list.svelte +22 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-logo.svelte +10 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-mobile-toggle.svelte +20 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-mode.svelte +12 -0
- package/templates/static/src/lib/components/ui/navbar/navbar-store.ts +5 -0
- package/templates/static/src/lib/components/ui/navbar/navbar.svelte +20 -0
- package/templates/static/src/lib/components/ui/sonner/index.ts +1 -0
- package/templates/static/src/lib/components/ui/sonner/sonner.svelte +13 -0
- package/templates/static/src/lib/index.ts +1 -0
- package/templates/static/src/lib/site.template.ts +11 -0
- package/templates/static/src/lib/utils.ts +13 -0
- package/templates/static/src/routes/(public)/+layout.svelte +9 -0
- package/templates/static/src/routes/(public)/+page.svelte +65 -0
- package/templates/static/src/routes/(public)/root-layout.svelte +55 -0
- package/templates/static/src/routes/+error.svelte +29 -0
- package/templates/static/src/routes/+layout.svelte +25 -0
- package/templates/static/src/routes/+layout.ts +35 -0
- package/templates/static/static/og.jpg +0 -0
- package/templates/static/static/robots.txt +3 -0
- package/templates/static/template.json +4 -0
- package/templates/static/tsconfig.json +15 -0
- package/templates/static/vite.config.ts +31 -0
- package/templates/ui/css/gray.css +68 -0
- package/templates/ui/css/neutral.css +68 -0
- package/templates/ui/css/slate.css +68 -0
- package/templates/ui/css/stone.css +68 -0
- package/templates/ui/css/zinc.css +68 -0
- package/src/Component.js +0 -10
- package/src/index.js +0 -14
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
@import 'tw-animate-css';
|
|
3
|
+
@plugin '@tailwindcss/typography';
|
|
4
|
+
|
|
5
|
+
@custom-variant dark (&:is(.dark *));
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
--radius: 0.625rem;
|
|
9
|
+
--background: oklch(1 0 0);
|
|
10
|
+
--foreground: oklch(0.129 0.042 264.695);
|
|
11
|
+
--card: oklch(1 0 0);
|
|
12
|
+
--card-foreground: oklch(0.129 0.042 264.695);
|
|
13
|
+
--popover: oklch(1 0 0);
|
|
14
|
+
--popover-foreground: oklch(0.129 0.042 264.695);
|
|
15
|
+
--primary: oklch(0.208 0.042 265.755);
|
|
16
|
+
--primary-foreground: oklch(0.984 0.003 247.858);
|
|
17
|
+
--secondary: oklch(0.968 0.007 247.896);
|
|
18
|
+
--secondary-foreground: oklch(0.208 0.042 265.755);
|
|
19
|
+
--muted: oklch(0.968 0.007 247.896);
|
|
20
|
+
--muted-foreground: oklch(0.554 0.046 257.417);
|
|
21
|
+
--accent: oklch(0.968 0.007 247.896);
|
|
22
|
+
--accent-foreground: oklch(0.208 0.042 265.755);
|
|
23
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
24
|
+
--border: oklch(0.929 0.013 255.508);
|
|
25
|
+
--input: oklch(0.929 0.013 255.508);
|
|
26
|
+
--ring: oklch(0.704 0.04 256.788);
|
|
27
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
28
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
29
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
30
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
31
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
32
|
+
--sidebar: oklch(0.984 0.003 247.858);
|
|
33
|
+
--sidebar-foreground: oklch(0.129 0.042 264.695);
|
|
34
|
+
--sidebar-primary: oklch(0.208 0.042 265.755);
|
|
35
|
+
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
|
36
|
+
--sidebar-accent: oklch(0.968 0.007 247.896);
|
|
37
|
+
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
|
|
38
|
+
--sidebar-border: oklch(0.929 0.013 255.508);
|
|
39
|
+
--sidebar-ring: oklch(0.704 0.04 256.788);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.dark {
|
|
43
|
+
--background: oklch(0.129 0.042 264.695);
|
|
44
|
+
--foreground: oklch(0.984 0.003 247.858);
|
|
45
|
+
--card: oklch(0.208 0.042 265.755);
|
|
46
|
+
--card-foreground: oklch(0.984 0.003 247.858);
|
|
47
|
+
--popover: oklch(0.208 0.042 265.755);
|
|
48
|
+
--popover-foreground: oklch(0.984 0.003 247.858);
|
|
49
|
+
--primary: oklch(0.929 0.013 255.508);
|
|
50
|
+
--primary-foreground: oklch(0.208 0.042 265.755);
|
|
51
|
+
--secondary: oklch(0.279 0.041 260.031);
|
|
52
|
+
--secondary-foreground: oklch(0.984 0.003 247.858);
|
|
53
|
+
--muted: oklch(0.279 0.041 260.031);
|
|
54
|
+
--muted-foreground: oklch(0.704 0.04 256.788);
|
|
55
|
+
--accent: oklch(0.279 0.041 260.031);
|
|
56
|
+
--accent-foreground: oklch(0.984 0.003 247.858);
|
|
57
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
58
|
+
--border: oklch(1 0 0 / 10%);
|
|
59
|
+
--input: oklch(1 0 0 / 15%);
|
|
60
|
+
--ring: oklch(0.551 0.027 264.364);
|
|
61
|
+
--chart-1: oklch(0.488 0.243 264.376);
|
|
62
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
63
|
+
--chart-3: oklch(0.769 0.188 70.08);
|
|
64
|
+
--chart-4: oklch(0.627 0.265 303.9);
|
|
65
|
+
--chart-5: oklch(0.645 0.246 16.439);
|
|
66
|
+
--sidebar: oklch(0.208 0.042 265.755);
|
|
67
|
+
--sidebar-foreground: oklch(0.984 0.003 247.858);
|
|
68
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
69
|
+
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
|
70
|
+
--sidebar-accent: oklch(0.279 0.041 260.031);
|
|
71
|
+
--sidebar-accent-foreground: oklch(0.984 0.003 247.858);
|
|
72
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
73
|
+
--sidebar-ring: oklch(0.551 0.027 264.364);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@theme inline {
|
|
77
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
78
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
79
|
+
--radius-lg: var(--radius);
|
|
80
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
81
|
+
--color-background: var(--background);
|
|
82
|
+
--color-foreground: var(--foreground);
|
|
83
|
+
--color-card: var(--card);
|
|
84
|
+
--color-card-foreground: var(--card-foreground);
|
|
85
|
+
--color-popover: var(--popover);
|
|
86
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
87
|
+
--color-primary: var(--primary);
|
|
88
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
89
|
+
--color-secondary: var(--secondary);
|
|
90
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
91
|
+
--color-muted: var(--muted);
|
|
92
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
93
|
+
--color-accent: var(--accent);
|
|
94
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
95
|
+
--color-destructive: var(--destructive);
|
|
96
|
+
--color-border: var(--border);
|
|
97
|
+
--color-input: var(--input);
|
|
98
|
+
--color-ring: var(--ring);
|
|
99
|
+
--color-chart-1: var(--chart-1);
|
|
100
|
+
--color-chart-2: var(--chart-2);
|
|
101
|
+
--color-chart-3: var(--chart-3);
|
|
102
|
+
--color-chart-4: var(--chart-4);
|
|
103
|
+
--color-chart-5: var(--chart-5);
|
|
104
|
+
--color-sidebar: var(--sidebar);
|
|
105
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
106
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
107
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
108
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
109
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
110
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
111
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@layer base {
|
|
115
|
+
* {
|
|
116
|
+
@apply border-border outline-ring/50;
|
|
117
|
+
}
|
|
118
|
+
body {
|
|
119
|
+
@apply bg-background text-foreground;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -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,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
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
|
+
%sveltekit.head%
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body class="min-h-dvh" data-sveltekit-preload-data="hover">
|
|
11
|
+
<div style="display: contents">%sveltekit.body%</div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { dev } from '$app/environment';
|
|
2
|
+
import { error, type Handle } from '@sveltejs/kit';
|
|
3
|
+
|
|
4
|
+
/** Pages a `vela` command generates, and the command that generates them. */
|
|
5
|
+
const GENERATED_PAGES: Record<string, string> = {
|
|
6
|
+
'/privacy': 'vela legal privacy',
|
|
7
|
+
'/terms': 'vela legal terms'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The footer links to these before they exist. In dev, say which command creates
|
|
12
|
+
* the page instead of showing a bare 404.
|
|
13
|
+
*
|
|
14
|
+
* Server hooks run in dev and at prerender time; a static build has no server, so
|
|
15
|
+
* the `dev` guard also keeps this out of the prerendered output.
|
|
16
|
+
*/
|
|
17
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
18
|
+
const response = await resolve(event);
|
|
19
|
+
|
|
20
|
+
if (dev && response.status === 404) {
|
|
21
|
+
const command = GENERATED_PAGES[event.url.pathname];
|
|
22
|
+
if (command) error(404, `Run \`${command}\` to create this page.`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return response;
|
|
26
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="15.87 6.75 78.15 98.88">
|
|
2
|
+
<style>
|
|
3
|
+
path {
|
|
4
|
+
fill: #00B2FF;
|
|
5
|
+
}
|
|
6
|
+
</style>
|
|
7
|
+
<path d="M42.18 99.49c-4.02.83-8.35 1.51-9.62 1.51-2.31 0-2.31 0-.98-6.25 5.2-24.38 1.05-54.7-10.67-78.03L15.9 6.75l3.96 3.14C36.8 23.31 50.44 47.8 53.48 70.25c.35 2.61 1.03 4.75 1.51 4.75 1.49 0 15.24-15.72 20.72-23.68C82.96 40.79 85.76 35.2 90.14 22.5c4.36-12.65 4.79-11.3 2.41 7.54-4.23 33.45-16.49 54.96-37.05 65-3.3 1.61-9.29 3.61-13.32 4.45Zm40.32 3.55c-5.66 1.8-9.87 2.28-22 2.54-14.05.29-23.95-.66-25.8-2.49-.44-.44 2.26-1.08 6-1.43 10.68-1 21.43-5.62 30.97-13.3L75.84 85l2.12 3.43c2.52 4.09 8.06 9.12 11.07 10.08 3.01.96 1.58 1.95-6.53 4.53Z"/>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { cn, type WithElementRef } from '$lib/utils';
|
|
3
|
+
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
4
|
+
import { type VariantProps, tv } from 'tailwind-variants';
|
|
5
|
+
|
|
6
|
+
export const buttonVariants = tv({
|
|
7
|
+
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
|
11
|
+
destructive:
|
|
12
|
+
'bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white',
|
|
13
|
+
outline:
|
|
14
|
+
'bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border',
|
|
15
|
+
secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
|
|
16
|
+
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
|
17
|
+
link: 'text-primary underline-offset-4 hover:underline'
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
21
|
+
sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
|
|
22
|
+
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
|
23
|
+
icon: 'size-9'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: 'default',
|
|
28
|
+
size: 'default'
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
|
33
|
+
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
|
34
|
+
|
|
35
|
+
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
|
36
|
+
WithElementRef<HTMLAnchorAttributes> & {
|
|
37
|
+
variant?: ButtonVariant;
|
|
38
|
+
size?: ButtonSize;
|
|
39
|
+
};
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<script lang="ts">
|
|
43
|
+
let {
|
|
44
|
+
class: className,
|
|
45
|
+
variant = 'default',
|
|
46
|
+
size = 'default',
|
|
47
|
+
ref = $bindable(null),
|
|
48
|
+
href = undefined,
|
|
49
|
+
type = 'button',
|
|
50
|
+
disabled,
|
|
51
|
+
children,
|
|
52
|
+
...restProps
|
|
53
|
+
}: ButtonProps = $props();
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
{#if href}
|
|
57
|
+
<a
|
|
58
|
+
bind:this={ref}
|
|
59
|
+
data-slot="button"
|
|
60
|
+
class={cn(buttonVariants({ variant, size }), className)}
|
|
61
|
+
href={disabled ? undefined : href}
|
|
62
|
+
aria-disabled={disabled}
|
|
63
|
+
role={disabled ? 'link' : undefined}
|
|
64
|
+
tabindex={disabled ? -1 : undefined}
|
|
65
|
+
{...restProps}
|
|
66
|
+
>
|
|
67
|
+
{@render children?.()}
|
|
68
|
+
</a>
|
|
69
|
+
{:else}
|
|
70
|
+
<button
|
|
71
|
+
bind:this={ref}
|
|
72
|
+
data-slot="button"
|
|
73
|
+
class={cn(buttonVariants({ variant, size }), className)}
|
|
74
|
+
{type}
|
|
75
|
+
{disabled}
|
|
76
|
+
{...restProps}
|
|
77
|
+
>
|
|
78
|
+
{@render children?.()}
|
|
79
|
+
</button>
|
|
80
|
+
{/if}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Root, {
|
|
2
|
+
type ButtonProps,
|
|
3
|
+
type ButtonSize,
|
|
4
|
+
type ButtonVariant,
|
|
5
|
+
buttonVariants
|
|
6
|
+
} from './button.svelte';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
Root,
|
|
10
|
+
type ButtonProps as Props,
|
|
11
|
+
//
|
|
12
|
+
Root as Button,
|
|
13
|
+
buttonVariants,
|
|
14
|
+
type ButtonProps,
|
|
15
|
+
type ButtonSize,
|
|
16
|
+
type ButtonVariant
|
|
17
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Root from './navbar.svelte';
|
|
2
|
+
import Logo from './navbar-logo.svelte';
|
|
3
|
+
import List from './navbar-list.svelte';
|
|
4
|
+
import MobileToggle from './navbar-mobile-toggle.svelte';
|
|
5
|
+
import Item from './navbar-item.svelte';
|
|
6
|
+
import Mode from './navbar-mode.svelte';
|
|
7
|
+
import Link from './navbar-link.svelte';
|
|
8
|
+
import Brand from './navbar-brand.svelte';
|
|
9
|
+
import BrandName from './navbar-brandname.svelte';
|
|
10
|
+
|
|
11
|
+
export { Root, Root as Navbar, Logo, List, MobileToggle, Item, Mode, Link, Brand, BrandName };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from '$lib/utils.js';
|
|
3
|
+
let { href, children, class: className = '' } = $props();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<a
|
|
7
|
+
{href}
|
|
8
|
+
class={cn(
|
|
9
|
+
'block py-2 px-3 text-white bg-blue-700 rounded-sm md:bg-transparent md:text-blue-700 md:p-0 dark:text-white md:dark:text-blue-500',
|
|
10
|
+
className
|
|
11
|
+
)}
|
|
12
|
+
aria-current="page">{@render children?.()}</a
|
|
13
|
+
>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from '$lib/utils.js';
|
|
3
|
+
import { getContext } from 'svelte';
|
|
4
|
+
import { MOBILE_MENU_CONTEXT_KEY, type MobileMenuContext } from './navbar-store';
|
|
5
|
+
|
|
6
|
+
let { children, class: className = '' } = $props();
|
|
7
|
+
|
|
8
|
+
const { menuOpen } = getContext<MobileMenuContext>(MOBILE_MENU_CONTEXT_KEY);
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div
|
|
12
|
+
class={cn('hidden w-full md:block md:w-auto', className, menuOpen.isOpen && 'block')}
|
|
13
|
+
id="navbar-default"
|
|
14
|
+
>
|
|
15
|
+
<ul
|
|
16
|
+
class={cn(
|
|
17
|
+
'font-medium flex flex-col p-2 md:p-0 mt-4 border rounded-lg bg-card md:flex-row md:space-x-4 rtl:space-x-reverse md:mt-0 md:border-0 md:bg-transparent'
|
|
18
|
+
)}
|
|
19
|
+
>
|
|
20
|
+
{@render children?.()}
|
|
21
|
+
</ul>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from '$lib/utils.js';
|
|
3
|
+
let {
|
|
4
|
+
src = 'https://upload.wikimedia.org/wikipedia/commons/1/1b/Svelte_Logo.svg',
|
|
5
|
+
alt = 'Logo',
|
|
6
|
+
class: className = ''
|
|
7
|
+
} = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<img {src} class={cn('h-8', className)} {alt} />
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
import { Button } from '$lib/components/ui/button';
|
|
4
|
+
import MenuIcon from '@lucide/svelte/icons/menu';
|
|
5
|
+
import { MOBILE_MENU_CONTEXT_KEY, type MobileMenuContext } from './navbar-store';
|
|
6
|
+
|
|
7
|
+
const { toggleMenu } = getContext<MobileMenuContext>(MOBILE_MENU_CONTEXT_KEY);
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Button
|
|
11
|
+
type="button"
|
|
12
|
+
aria-controls="navbar-default"
|
|
13
|
+
aria-expanded="false"
|
|
14
|
+
variant="ghost"
|
|
15
|
+
class="md:hidden"
|
|
16
|
+
onclick={toggleMenu}
|
|
17
|
+
>
|
|
18
|
+
<span class="sr-only">Open main menu</span>
|
|
19
|
+
<MenuIcon class="size-6" />
|
|
20
|
+
</Button>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import SunIcon from '@lucide/svelte/icons/sun';
|
|
3
|
+
import MoonIcon from '@lucide/svelte/icons/moon';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<SunIcon
|
|
7
|
+
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 !transition-all dark:-rotate-90 dark:scale-0"
|
|
8
|
+
/>
|
|
9
|
+
<MoonIcon
|
|
10
|
+
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 !transition-all dark:rotate-0 dark:scale-100"
|
|
11
|
+
/>
|
|
12
|
+
<span class="sr-only">Toggle theme</span>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext } from 'svelte';
|
|
3
|
+
import { cn } from '$lib/utils.js';
|
|
4
|
+
let { children, class: className = '' } = $props();
|
|
5
|
+
|
|
6
|
+
import { MOBILE_MENU_CONTEXT_KEY } from './navbar-store';
|
|
7
|
+
|
|
8
|
+
let menuOpen = $state({ isOpen: false });
|
|
9
|
+
|
|
10
|
+
setContext(MOBILE_MENU_CONTEXT_KEY, {
|
|
11
|
+
menuOpen,
|
|
12
|
+
toggleMenu: () => (menuOpen.isOpen = !menuOpen.isOpen)
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<nav class={cn(className)}>
|
|
17
|
+
<div class="max-w-7xl flex flex-wrap items-center justify-between mx-auto p-4">
|
|
18
|
+
{@render children?.()}
|
|
19
|
+
</div>
|
|
20
|
+
</nav>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Toaster } from './sonner.svelte';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Toaster as Sonner, type ToasterProps as SonnerProps } from 'svelte-sonner';
|
|
3
|
+
import { mode } from 'mode-watcher';
|
|
4
|
+
|
|
5
|
+
let { ...restProps }: SonnerProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<Sonner
|
|
9
|
+
theme={mode.current}
|
|
10
|
+
class="toaster group"
|
|
11
|
+
style="--normal-bg: var(--color-popover); --normal-text: var(--color-popover-foreground); --normal-border: var(--color-border);"
|
|
12
|
+
{...restProps}
|
|
13
|
+
/>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// place files you want to import through the `$lib` alias in this folder.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site-wide metadata.
|
|
3
|
+
*
|
|
4
|
+
* A static build has no backend to read this from, so this file is the source of
|
|
5
|
+
* truth. Set `url` to where the site is actually deployed — canonical links and
|
|
6
|
+
* Open Graph image URLs are built from it at prerender time.
|
|
7
|
+
*/
|
|
8
|
+
export const site = {
|
|
9
|
+
name: '~APP_NAME~',
|
|
10
|
+
url: 'http://localhost:5173'
|
|
11
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
export function cn(...inputs: ClassValue[]) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
|
|
12
|
+
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
|
13
|
+
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import favicon from '$lib/assets/favicon.svg';
|
|
3
|
+
|
|
4
|
+
let { data } = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<main class="flex-1">
|
|
8
|
+
<section class="px-6 py-16 md:py-24">
|
|
9
|
+
<div class="mx-auto max-w-4xl text-center">
|
|
10
|
+
<a href="/" class="inline-flex items-center gap-2 font-medium">
|
|
11
|
+
<span
|
|
12
|
+
class="bg-primary text-primary-foreground inline-flex size-6 items-center justify-center rounded-md"
|
|
13
|
+
>
|
|
14
|
+
<img src={favicon} alt="logo" class="size-4" />
|
|
15
|
+
</span>
|
|
16
|
+
{data.meta.appName}
|
|
17
|
+
</a>
|
|
18
|
+
|
|
19
|
+
<h1 class="mt-6 text-4xl font-semibold tracking-tight sm:text-5xl">
|
|
20
|
+
A modern way to get things done
|
|
21
|
+
</h1>
|
|
22
|
+
<p class="text-muted-foreground mt-4 text-lg">
|
|
23
|
+
Everything you need to launch faster, collaborate better, and stay focused.
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<div class="mt-8 flex items-center justify-center gap-3">
|
|
27
|
+
<a
|
|
28
|
+
href="#features"
|
|
29
|
+
class="bg-primary text-primary-foreground inline-flex items-center rounded-md px-5 py-2.5"
|
|
30
|
+
>
|
|
31
|
+
Get started
|
|
32
|
+
</a>
|
|
33
|
+
<a
|
|
34
|
+
href="https://svelte.dev/docs/kit"
|
|
35
|
+
class="border border-border text-foreground inline-flex items-center rounded-md px-5 py-2.5"
|
|
36
|
+
>
|
|
37
|
+
Read the docs
|
|
38
|
+
</a>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
42
|
+
|
|
43
|
+
<section id="features" class="px-6 pb-16 md:pb-24">
|
|
44
|
+
<div class="mx-auto grid max-w-5xl gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
45
|
+
<div class="bg-card text-card-foreground rounded-lg border p-6">
|
|
46
|
+
<h3 class="font-medium">Fast</h3>
|
|
47
|
+
<p class="text-muted-foreground mt-2">
|
|
48
|
+
Simple workflows that help you move from idea to done.
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="bg-card text-card-foreground rounded-lg border p-6">
|
|
52
|
+
<h3 class="font-medium">Flexible</h3>
|
|
53
|
+
<p class="text-muted-foreground mt-2">
|
|
54
|
+
Works for teams of any size and adapts to your process.
|
|
55
|
+
</p>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="bg-card text-card-foreground rounded-lg border p-6">
|
|
58
|
+
<h3 class="font-medium">Secure</h3>
|
|
59
|
+
<p class="text-muted-foreground mt-2">
|
|
60
|
+
Built with best practices and modern standards in mind.
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</section>
|
|
65
|
+
</main>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import favicon from '$lib/assets/favicon.svg';
|
|
3
|
+
|
|
4
|
+
import { toggleMode } from 'mode-watcher';
|
|
5
|
+
import * as Navbar from '$lib/components/ui/navbar';
|
|
6
|
+
import { Button } from '$lib/components/ui/button';
|
|
7
|
+
|
|
8
|
+
let { children, data } = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class="min-h-dvh grid grid-rows-[max-content_1fr_max-content] root-layout">
|
|
12
|
+
<Navbar.Root>
|
|
13
|
+
<Navbar.Brand href="/">
|
|
14
|
+
<Navbar.Logo src={favicon} alt="Logo" />
|
|
15
|
+
</Navbar.Brand>
|
|
16
|
+
|
|
17
|
+
<Navbar.MobileToggle />
|
|
18
|
+
|
|
19
|
+
<Navbar.List>
|
|
20
|
+
<Navbar.Item>
|
|
21
|
+
<Button class="w-full justify-start md:justify-center md:w-auto" href="/" variant="ghost">
|
|
22
|
+
Home
|
|
23
|
+
</Button>
|
|
24
|
+
</Navbar.Item>
|
|
25
|
+
</Navbar.List>
|
|
26
|
+
</Navbar.Root>
|
|
27
|
+
|
|
28
|
+
{@render children?.()}
|
|
29
|
+
|
|
30
|
+
<footer class="border-t border-border py-4">
|
|
31
|
+
<div
|
|
32
|
+
class="mx-auto flex max-w-7xl px-4 flex-col items-center justify-between gap-3 sm:flex-row"
|
|
33
|
+
>
|
|
34
|
+
<p class="text-muted-foreground text-sm">
|
|
35
|
+
© {new Date().getFullYear()}
|
|
36
|
+
{data.meta.appName}. All rights reserved.
|
|
37
|
+
</p>
|
|
38
|
+
<nav class="flex items-center gap-4 text-sm">
|
|
39
|
+
<Button onclick={toggleMode} variant="ghost" size="icon">
|
|
40
|
+
<Navbar.Mode />
|
|
41
|
+
</Button>
|
|
42
|
+
<a href="/privacy" class="underline-offset-4 hover:underline">Privacy</a>
|
|
43
|
+
<a href="/terms" class="underline-offset-4 hover:underline">Terms</a>
|
|
44
|
+
</nav>
|
|
45
|
+
</div>
|
|
46
|
+
</footer>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<style lang="postcss">
|
|
50
|
+
@reference "tailwindcss";
|
|
51
|
+
|
|
52
|
+
.root-layout :global(section[data-role='content']) {
|
|
53
|
+
@apply container mx-auto max-w-7xl px-4 py-8 w-full;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { page } from '$app/state';
|
|
3
|
+
import { Button } from '$lib/components/ui/button';
|
|
4
|
+
import RootLayout from './(public)/root-layout.svelte';
|
|
5
|
+
|
|
6
|
+
let { data } = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<RootLayout {data}>
|
|
10
|
+
<main class="mx-auto max-w-7xl px-4 w-full flex items-center justify-center">
|
|
11
|
+
<div class="text-center space-y-4">
|
|
12
|
+
<div class="text-9xl font-bold text-primary">
|
|
13
|
+
{page.status}
|
|
14
|
+
</div>
|
|
15
|
+
<div class="relative">
|
|
16
|
+
<h1 class="text-4xl font-bold relative inline-block bg-background">
|
|
17
|
+
Oops! Something went wrong
|
|
18
|
+
</h1>
|
|
19
|
+
</div>
|
|
20
|
+
<p class="text-xl text-muted-foreground max-w-lg mx-auto">
|
|
21
|
+
{page.error?.message ||
|
|
22
|
+
"We couldn't find what you were looking for. Let's get you back on track!"}
|
|
23
|
+
</p>
|
|
24
|
+
<div>
|
|
25
|
+
<Button href="/" variant="default" size="lg">Take me home</Button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</main>
|
|
29
|
+
</RootLayout>
|