toiljs 0.0.10 → 0.0.12
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/README.md +315 -1
- package/assets/logo.svg +37 -0
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/configure.js +10 -4
- package/build/cli/create.js +60 -32
- package/build/cli/diagnostics.d.ts +55 -0
- package/build/cli/diagnostics.js +333 -0
- package/build/cli/doctor.d.ts +6 -0
- package/build/cli/doctor.js +249 -0
- package/build/cli/index.js +26 -0
- package/build/cli/proc.d.ts +5 -0
- package/build/cli/proc.js +20 -0
- package/build/cli/ui.d.ts +1 -0
- package/build/cli/ui.js +1 -0
- package/build/cli/update.d.ts +7 -0
- package/build/cli/update.js +117 -0
- package/build/cli/updates.d.ts +10 -0
- package/build/cli/updates.js +45 -0
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/dev/error-overlay.js +1 -1
- package/build/client/head/metadata.js +3 -1
- package/build/client/index.d.ts +5 -1
- package/build/client/index.js +2 -0
- package/build/client/navigation/navigation.js +1 -1
- package/build/client/routing/Router.js +2 -2
- package/build/client/search/search.d.ts +26 -0
- package/build/client/search/search.js +101 -0
- package/build/client/search/use-page-search.d.ts +8 -0
- package/build/client/search/use-page-search.js +21 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/generate.js +35 -26
- package/build/compiler/index.d.ts +2 -0
- package/build/compiler/index.js +1 -0
- package/build/compiler/pages.d.ts +8 -0
- package/build/compiler/pages.js +37 -0
- package/build/compiler/plugin.js +3 -1
- package/build/compiler/prerender.d.ts +1 -0
- package/build/compiler/prerender.js +11 -5
- package/build/compiler/seo.js +10 -3
- package/build/compiler/vite.js +7 -0
- package/build/io/.tsbuildinfo +1 -1
- package/examples/basic/client/components/Header.tsx +43 -38
- package/examples/basic/client/components/HoneycombBackground.tsx +223 -230
- package/examples/basic/client/layout.tsx +4 -1
- package/examples/basic/client/public/index.html +18 -16
- package/examples/basic/client/routes/(legal)/privacy.tsx +18 -0
- package/examples/basic/client/routes/(legal)/terms.tsx +15 -0
- package/examples/basic/client/routes/about.tsx +21 -19
- package/examples/basic/client/routes/blog/[id].tsx +26 -12
- package/examples/basic/client/routes/features/actions.tsx +67 -0
- package/examples/basic/client/routes/features/error/error.tsx +16 -0
- package/examples/basic/client/routes/features/error/index.tsx +27 -0
- package/examples/basic/client/routes/features/head.tsx +38 -0
- package/examples/basic/client/routes/features/index.tsx +83 -0
- package/examples/basic/client/routes/features/realtime.tsx +34 -0
- package/examples/basic/client/routes/features/script.tsx +31 -0
- package/examples/basic/client/routes/features/seo.tsx +39 -0
- package/examples/basic/client/routes/features/template/b.tsx +14 -0
- package/examples/basic/client/routes/features/template/index.tsx +20 -0
- package/examples/basic/client/routes/features/template/template.tsx +16 -0
- package/examples/basic/client/routes/files/[[...slug]].tsx +21 -0
- package/examples/basic/client/routes/gallery/@modal/(.)photo/[id].tsx +23 -0
- package/examples/basic/client/routes/gallery/index.tsx +42 -0
- package/examples/basic/client/routes/gallery/layout.tsx +13 -0
- package/examples/basic/client/routes/gallery/photo/[id].tsx +18 -0
- package/examples/basic/client/routes/get-started.tsx +157 -84
- package/examples/basic/client/routes/index.tsx +137 -87
- package/examples/basic/client/routes/loader-demo/index.tsx +59 -50
- package/examples/basic/client/routes/search.tsx +61 -0
- package/examples/basic/client/routes/test.tsx +7 -8
- package/examples/basic/client/styles/main.css +624 -552
- package/examples/basic/client/toil.tsx +2 -4
- package/package.json +3 -2
- package/presets/eslint.js +10 -3
- package/src/cli/configure.ts +363 -353
- package/src/cli/create.ts +563 -530
- package/src/cli/diagnostics.ts +421 -0
- package/src/cli/doctor.ts +318 -0
- package/src/cli/features.ts +166 -160
- package/src/cli/index.ts +242 -211
- package/src/cli/proc.ts +30 -0
- package/src/cli/ui.ts +111 -103
- package/src/cli/update.ts +150 -0
- package/src/cli/updates.ts +69 -0
- package/src/client/components/Image.tsx +91 -89
- package/src/client/dev/error-overlay.tsx +193 -197
- package/src/client/head/metadata.ts +94 -92
- package/src/client/index.ts +79 -64
- package/src/client/navigation/Link.tsx +94 -100
- package/src/client/navigation/navigation.ts +215 -218
- package/src/client/routing/Router.tsx +210 -193
- package/src/client/routing/hooks.ts +110 -114
- package/src/client/routing/lazy.ts +77 -81
- package/src/client/search/search.ts +189 -0
- package/src/client/search/use-page-search.ts +73 -0
- package/src/compiler/config.ts +173 -171
- package/src/compiler/fonts.ts +89 -87
- package/src/compiler/generate.ts +378 -364
- package/src/compiler/image-report.ts +88 -85
- package/src/compiler/index.ts +2 -0
- package/src/compiler/pages.ts +70 -0
- package/src/compiler/plugin.ts +51 -47
- package/src/compiler/prerender.ts +152 -130
- package/src/compiler/routes.ts +132 -131
- package/src/compiler/seo.ts +381 -356
- package/src/compiler/vite.ts +155 -130
- package/src/io/FastSet.ts +99 -96
- package/test/configure.test.ts +94 -90
- package/test/doctor.test.ts +140 -0
- package/test/dom/Image.test.tsx +73 -46
- package/test/dom/Script.test.tsx +48 -45
- package/test/dom/action.test.tsx +146 -129
- package/test/dom/error-overlay.test.tsx +44 -44
- package/test/dom/loader.test.tsx +2 -2
- package/test/dom/revalidate.test.tsx +1 -1
- package/test/dom/route-head.test.tsx +35 -2
- package/test/dom/slot.test.tsx +131 -109
- package/test/dom/view-transitions.test.tsx +53 -51
- package/test/features.test.ts +149 -142
- package/test/fonts.test.ts +28 -26
- package/test/head.test.ts +45 -35
- package/test/metadata.test.ts +42 -41
- package/test/pages.test.ts +105 -0
- package/test/prerender.test.ts +54 -46
- package/test/search.test.ts +114 -0
- package/test/seo.test.ts +164 -142
- package/test/slot-layouts.test.ts +69 -0
- package/test/update.test.ts +44 -0
|
@@ -1,84 +1,157 @@
|
|
|
1
|
-
export default function GetStarted() {
|
|
2
|
-
return (
|
|
3
|
-
<div className="gs-page">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
→
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
export default function GetStarted() {
|
|
2
|
+
return (
|
|
3
|
+
<div className="gs-page">
|
|
4
|
+
{/* Hero */}
|
|
5
|
+
<div className="gs-hero">
|
|
6
|
+
<h1 className="gs-title">Get Started</h1>
|
|
7
|
+
<p className="gs-desc">Everything you need to build your first ToilJS app.</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
{/* Info grid */}
|
|
11
|
+
<section className="gs-section">
|
|
12
|
+
<h2 className="gs-section-title">Project Structure</h2>
|
|
13
|
+
<div className="gs-grid">
|
|
14
|
+
<div className="gs-card gs-card--accent1">
|
|
15
|
+
<div className="gs-card-icon">
|
|
16
|
+
<svg
|
|
17
|
+
width="22"
|
|
18
|
+
height="22"
|
|
19
|
+
viewBox="0 0 24 24"
|
|
20
|
+
fill="none"
|
|
21
|
+
stroke="currentColor"
|
|
22
|
+
strokeWidth="2"
|
|
23
|
+
strokeLinecap="round"
|
|
24
|
+
strokeLinejoin="round">
|
|
25
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
|
|
26
|
+
</svg>
|
|
27
|
+
</div>
|
|
28
|
+
<h3>File-based Routing</h3>
|
|
29
|
+
<p>
|
|
30
|
+
Every <code>.tsx</code> file in <code>client/routes/</code> becomes a route. No config
|
|
31
|
+
required.
|
|
32
|
+
</p>
|
|
33
|
+
<pre>
|
|
34
|
+
<code>{`index.tsx → /
|
|
35
|
+
about.tsx → /about
|
|
36
|
+
[id].tsx → /:id
|
|
37
|
+
[...slug].tsx → /*`}</code>
|
|
38
|
+
</pre>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div className="gs-card gs-card--accent2">
|
|
42
|
+
<div className="gs-card-icon">
|
|
43
|
+
<svg
|
|
44
|
+
width="22"
|
|
45
|
+
height="22"
|
|
46
|
+
viewBox="0 0 24 24"
|
|
47
|
+
fill="none"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
strokeWidth="2"
|
|
50
|
+
strokeLinecap="round"
|
|
51
|
+
strokeLinejoin="round">
|
|
52
|
+
<rect x="2" y="3" width="20" height="14" rx="2" />
|
|
53
|
+
<path d="M8 21h8M12 17v4" />
|
|
54
|
+
</svg>
|
|
55
|
+
</div>
|
|
56
|
+
<h3>Public Folder</h3>
|
|
57
|
+
<p>
|
|
58
|
+
Files in <code>public/</code> are copied as-is to the build root. Reference them with an
|
|
59
|
+
absolute path.
|
|
60
|
+
</p>
|
|
61
|
+
<pre>
|
|
62
|
+
<code>{`public/images/logo.svg
|
|
63
|
+
→ /images/logo.svg`}</code>
|
|
64
|
+
</pre>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div className="gs-card gs-card--accent3">
|
|
68
|
+
<div className="gs-card-icon">
|
|
69
|
+
<svg
|
|
70
|
+
width="22"
|
|
71
|
+
height="22"
|
|
72
|
+
viewBox="0 0 24 24"
|
|
73
|
+
fill="none"
|
|
74
|
+
stroke="currentColor"
|
|
75
|
+
strokeWidth="2"
|
|
76
|
+
strokeLinecap="round"
|
|
77
|
+
strokeLinejoin="round">
|
|
78
|
+
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
79
|
+
<path d="M3 9h18M9 21V9" />
|
|
80
|
+
</svg>
|
|
81
|
+
</div>
|
|
82
|
+
<h3>Layout</h3>
|
|
83
|
+
<p>
|
|
84
|
+
<code>client/layout.tsx</code> wraps every page. Use it for your nav, footer, providers, and
|
|
85
|
+
global styles.
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div className="gs-card gs-card--accent4">
|
|
90
|
+
<div className="gs-card-icon">
|
|
91
|
+
<svg
|
|
92
|
+
width="22"
|
|
93
|
+
height="22"
|
|
94
|
+
viewBox="0 0 24 24"
|
|
95
|
+
fill="none"
|
|
96
|
+
stroke="currentColor"
|
|
97
|
+
strokeWidth="2"
|
|
98
|
+
strokeLinecap="round"
|
|
99
|
+
strokeLinejoin="round">
|
|
100
|
+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
|
101
|
+
</svg>
|
|
102
|
+
</div>
|
|
103
|
+
<h3>Entry Point</h3>
|
|
104
|
+
<p>
|
|
105
|
+
<code>client/toil.tsx</code> is the app entry. Import global CSS and call{' '}
|
|
106
|
+
<code>Toil.mount()</code>, runs once on startup.
|
|
107
|
+
</p>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</section>
|
|
111
|
+
|
|
112
|
+
{/* Navigation section */}
|
|
113
|
+
<section className="gs-section">
|
|
114
|
+
<h2 className="gs-section-title">Navigation</h2>
|
|
115
|
+
<div className="gs-card gs-card--flat">
|
|
116
|
+
<div className="gs-card-icon">
|
|
117
|
+
<svg
|
|
118
|
+
width="22"
|
|
119
|
+
height="22"
|
|
120
|
+
viewBox="0 0 24 24"
|
|
121
|
+
fill="none"
|
|
122
|
+
stroke="currentColor"
|
|
123
|
+
strokeWidth="2"
|
|
124
|
+
strokeLinecap="round"
|
|
125
|
+
strokeLinejoin="round">
|
|
126
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
|
127
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
|
128
|
+
</svg>
|
|
129
|
+
</div>
|
|
130
|
+
<h3>
|
|
131
|
+
Use <code>{'<Toil.Link>'}</code> for client-side navigation
|
|
132
|
+
</h3>
|
|
133
|
+
<p>
|
|
134
|
+
Avoids full page reloads and keeps transitions instant. Use a regular <code>{'<a>'}</code> only
|
|
135
|
+
for external links.
|
|
136
|
+
</p>
|
|
137
|
+
<pre>
|
|
138
|
+
<code>{`// ✅ Internal navigation
|
|
139
|
+
<Toil.Link href="/about">About</Toil.Link>
|
|
140
|
+
|
|
141
|
+
// ✅ External link
|
|
142
|
+
<a href="https://toil.org" target="_blank">Docs</a>`}</code>
|
|
143
|
+
</pre>
|
|
144
|
+
</div>
|
|
145
|
+
</section>
|
|
146
|
+
|
|
147
|
+
<div className="gs-actions">
|
|
148
|
+
<Toil.Link href="/" className="btn btn-secondary">
|
|
149
|
+
← Back home
|
|
150
|
+
</Toil.Link>
|
|
151
|
+
<a href="https://toil.org/docs" target="_blank" rel="noopener noreferrer" className="btn btn-primary">
|
|
152
|
+
Read the Docs
|
|
153
|
+
</a>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
@@ -1,87 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
1
|
+
// The home page sets its own title with an absolute template (`%s`), so the tab reads exactly this
|
|
2
|
+
// rather than being suffixed by the layout's "%s | ToilJS".
|
|
3
|
+
export const metadata: Toil.Metadata = {
|
|
4
|
+
title: 'ToilJS, the modern React framework',
|
|
5
|
+
titleTemplate: '%s',
|
|
6
|
+
description: 'File-based routing, instant HMR, build-time SEO, and a WebAssembly backend. Zero config.',
|
|
7
|
+
openGraph: { title: 'ToilJS', type: 'website' }
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const GitHubIcon = () => (
|
|
11
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
12
|
+
<path d="M12 2C6.477 2 2 6.477 2 12c0 4.418 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.009-.868-.013-1.703-2.782.604-3.369-1.341-3.369-1.341-.454-1.154-1.11-1.462-1.11-1.462-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836a9.59 9.59 0 0 1 2.504.337c1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.202 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.579.688.481C19.138 20.163 22 16.418 22 12c0-5.523-4.477-10-10-10z" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const icons = {
|
|
17
|
+
hmr: (
|
|
18
|
+
<svg
|
|
19
|
+
width="16"
|
|
20
|
+
height="16"
|
|
21
|
+
viewBox="0 0 24 24"
|
|
22
|
+
fill="none"
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
strokeWidth="2"
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round">
|
|
27
|
+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
|
28
|
+
</svg>
|
|
29
|
+
),
|
|
30
|
+
routing: (
|
|
31
|
+
<svg
|
|
32
|
+
width="16"
|
|
33
|
+
height="16"
|
|
34
|
+
viewBox="0 0 24 24"
|
|
35
|
+
fill="none"
|
|
36
|
+
stroke="currentColor"
|
|
37
|
+
strokeWidth="2"
|
|
38
|
+
strokeLinecap="round"
|
|
39
|
+
strokeLinejoin="round">
|
|
40
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
|
|
41
|
+
</svg>
|
|
42
|
+
),
|
|
43
|
+
typescript: (
|
|
44
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
|
45
|
+
<rect x="2" y="2" width="20" height="20" rx="3" fill="currentColor" />
|
|
46
|
+
<path d="M13.5 12H15.5V18H17V12H19V10.5H13.5V12Z" fill="var(--bg)" />
|
|
47
|
+
<path
|
|
48
|
+
d="M11 10.5C9.07 10.5 7.5 12.07 7.5 14C7.5 15.45 8.38 16.69 9.65 17.23L7.5 18H11C12.93 18 14.5 16.43 14.5 14.5C14.5 13.26 13.86 12.17 12.9 11.55C12.42 11.22 11.73 10.5 11 10.5ZM11 12C12.1 12 13 12.9 13 14C13 15.1 12.1 16 11 16H9.72C9.28 15.57 9 14.81 9 14C9 12.9 9.9 12 11 12Z"
|
|
49
|
+
fill="var(--bg)"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
),
|
|
53
|
+
builds: (
|
|
54
|
+
<svg
|
|
55
|
+
width="16"
|
|
56
|
+
height="16"
|
|
57
|
+
viewBox="0 0 24 24"
|
|
58
|
+
fill="none"
|
|
59
|
+
stroke="currentColor"
|
|
60
|
+
strokeWidth="2"
|
|
61
|
+
strokeLinecap="round"
|
|
62
|
+
strokeLinejoin="round">
|
|
63
|
+
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
|
64
|
+
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
|
65
|
+
<line x1="12" y1="22.08" x2="12" y2="12" />
|
|
66
|
+
</svg>
|
|
67
|
+
)
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const features = [
|
|
71
|
+
{ icon: icons.hmr, label: 'Instant HMR' },
|
|
72
|
+
{ icon: icons.routing, label: 'File Routing' },
|
|
73
|
+
{ icon: icons.typescript, label: 'TypeScript' },
|
|
74
|
+
{ icon: icons.builds, label: 'Optimized Builds' }
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
export default function Home() {
|
|
78
|
+
return (
|
|
79
|
+
<section className="hero">
|
|
80
|
+
<div className="hero-logo">
|
|
81
|
+
<img
|
|
82
|
+
src="/images/logo.svg"
|
|
83
|
+
className="hero-logo-glow"
|
|
84
|
+
alt=""
|
|
85
|
+
aria-hidden="true"
|
|
86
|
+
width={96}
|
|
87
|
+
height={96}
|
|
88
|
+
/>
|
|
89
|
+
<Toil.Image
|
|
90
|
+
src="/images/logo.svg"
|
|
91
|
+
className="hero-logo-img"
|
|
92
|
+
alt="ToilJS"
|
|
93
|
+
width={96}
|
|
94
|
+
height={96}
|
|
95
|
+
priority
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<h1 className="hero-title">ToilJS</h1>
|
|
100
|
+
|
|
101
|
+
<p className="hero-tagline">
|
|
102
|
+
Next-gen React.
|
|
103
|
+
<br />
|
|
104
|
+
<span>Zero config.</span>
|
|
105
|
+
</p>
|
|
106
|
+
|
|
107
|
+
<p className="hero-desc">
|
|
108
|
+
File-based routing, blazing-fast HMR, and full TypeScript.
|
|
109
|
+
<br />
|
|
110
|
+
All powered by Vite.
|
|
111
|
+
</p>
|
|
112
|
+
|
|
113
|
+
<ul className="features">
|
|
114
|
+
{features.map((f) => (
|
|
115
|
+
<li key={f.label} className="feature-badge">
|
|
116
|
+
{f.icon}
|
|
117
|
+
{f.label}
|
|
118
|
+
</li>
|
|
119
|
+
))}
|
|
120
|
+
</ul>
|
|
121
|
+
|
|
122
|
+
<div className="hero-cta">
|
|
123
|
+
<Toil.Link href="/get-started" className="btn btn-primary">
|
|
124
|
+
Get Started
|
|
125
|
+
</Toil.Link>
|
|
126
|
+
<a
|
|
127
|
+
className="btn btn-secondary"
|
|
128
|
+
href="https://github.com/btc-vision/toiljs"
|
|
129
|
+
target="_blank"
|
|
130
|
+
rel="noopener noreferrer">
|
|
131
|
+
<GitHubIcon />
|
|
132
|
+
GitHub
|
|
133
|
+
</a>
|
|
134
|
+
</div>
|
|
135
|
+
</section>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
@@ -1,50 +1,59 @@
|
|
|
1
|
-
async function wait(ms: number): Promise<void> {
|
|
2
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const loader = async ({ searchParams }: Toil.LoaderArgs) => {
|
|
6
|
-
await wait(2000);
|
|
7
|
-
return { loadedAt: new Date().toISOString(), q: searchParams.get('q') };
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// Cache this route's data for 10s: revisiting within 10s is instant (no 2s wait); after that it
|
|
11
|
-
// refetches on navigation. Use `false` to cache forever, or omit for the default (refetch every nav).
|
|
12
|
-
export const revalidate: Toil.Revalidate = 10;
|
|
13
|
-
|
|
14
|
-
// Dynamic metadata derived from the loader's data (vs the static `metadata` export on /about).
|
|
15
|
-
export const generateMetadata: Toil.GenerateMetadata<Awaited<ReturnType<typeof loader>>> = ({
|
|
16
|
-
data
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
export default function LoaderDemo() {
|
|
20
|
-
// Pass the loader to infer the data type from its return, no generics, no restating the shape.
|
|
21
|
-
const data = Toil.useLoaderData(loader);
|
|
22
|
-
const router = Toil.useRouter();
|
|
23
|
-
return (
|
|
24
|
-
<main>
|
|
25
|
-
<h1>Loader demo</h1>
|
|
26
|
-
<p>
|
|
27
|
-
Data loaded before render (no <code>useEffect</code>): <code>{data.loadedAt}</code>
|
|
28
|
-
{data.q !== null ?
|
|
29
|
-
</p>
|
|
30
|
-
<p>
|
|
31
|
-
<button
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
1
|
+
async function wait(ms: number): Promise<void> {
|
|
2
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export const loader = async ({ searchParams }: Toil.LoaderArgs) => {
|
|
6
|
+
await wait(2000);
|
|
7
|
+
return { loadedAt: new Date().toISOString(), q: searchParams.get('q') };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// Cache this route's data for 10s: revisiting within 10s is instant (no 2s wait); after that it
|
|
11
|
+
// refetches on navigation. Use `false` to cache forever, or omit for the default (refetch every nav).
|
|
12
|
+
export const revalidate: Toil.Revalidate = 10;
|
|
13
|
+
|
|
14
|
+
// Dynamic metadata derived from the loader's data (vs the static `metadata` export on /about).
|
|
15
|
+
export const generateMetadata: Toil.GenerateMetadata<Awaited<ReturnType<typeof loader>>> = ({ data }) => ({
|
|
16
|
+
title: `Loader demo, loaded ${data.loadedAt}`
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default function LoaderDemo() {
|
|
20
|
+
// Pass the loader to infer the data type from its return, no generics, no restating the shape.
|
|
21
|
+
const data = Toil.useLoaderData(loader);
|
|
22
|
+
const router = Toil.useRouter();
|
|
23
|
+
return (
|
|
24
|
+
<main>
|
|
25
|
+
<h1>Loader demo</h1>
|
|
26
|
+
<p>
|
|
27
|
+
Data loaded before render (no <code>useEffect</code>): <code>{data.loadedAt}</code>
|
|
28
|
+
{data.q !== null ? `, q=${data.q}` : ''}
|
|
29
|
+
</p>
|
|
30
|
+
<p>
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
onClick={() => {
|
|
34
|
+
router.revalidate();
|
|
35
|
+
}}>
|
|
36
|
+
Revalidate (refetch)
|
|
37
|
+
</button>
|
|
38
|
+
</p>
|
|
39
|
+
{/* The write half: an action runs on submit, then revalidates this route's loader so
|
|
40
|
+
`loadedAt` above updates, read, write, revalidate, no manual refetch. */}
|
|
41
|
+
<Toil.Form
|
|
42
|
+
action={async (form) => {
|
|
43
|
+
await wait(500);
|
|
44
|
+
console.log('saved', form.get('note'));
|
|
45
|
+
}}
|
|
46
|
+
revalidate>
|
|
47
|
+
{({ pending }) => (
|
|
48
|
+
<>
|
|
49
|
+
<input name="note" placeholder="Leave a note" disabled={pending} />
|
|
50
|
+
<button type="submit" disabled={pending}>
|
|
51
|
+
{pending ? 'Saving' : 'Save & revalidate'}
|
|
52
|
+
</button>
|
|
53
|
+
</>
|
|
54
|
+
)}
|
|
55
|
+
</Toil.Form>
|
|
56
|
+
<Toil.Link href="/">Back home</Toil.Link>
|
|
57
|
+
</main>
|
|
58
|
+
);
|
|
59
|
+
}
|