toiljs 0.0.15 → 0.0.19

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.
Files changed (273) hide show
  1. package/.babelrc +13 -13
  2. package/.gitattributes +2 -2
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  4. package/.github/ISSUE_TEMPLATE/bug_report.yml +90 -90
  5. package/.github/ISSUE_TEMPLATE/config.yml +8 -8
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  7. package/.github/PULL_REQUEST_TEMPLATE.md +43 -43
  8. package/.github/changelog-config.json +45 -45
  9. package/.github/dependabot.yml +27 -27
  10. package/.github/workflows/ci.yml +191 -191
  11. package/.prettierrc.json +11 -11
  12. package/.vscode/settings.json +9 -9
  13. package/CHANGELOG.md +116 -5
  14. package/LICENSE +187 -187
  15. package/README.md +524 -315
  16. package/as-pect.asconfig.json +34 -34
  17. package/as-pect.config.js +65 -65
  18. package/assets/logo.svg +36 -36
  19. package/build/backend/.tsbuildinfo +1 -1
  20. package/build/backend/index.d.ts +1 -0
  21. package/build/backend/index.js +20 -1
  22. package/build/cli/.tsbuildinfo +1 -1
  23. package/build/cli/index.js +1320 -696
  24. package/build/client/.tsbuildinfo +1 -1
  25. package/build/client/dev/devtools.d.ts +6 -0
  26. package/build/client/dev/devtools.js +479 -0
  27. package/build/client/dev/error-overlay.d.ts +9 -0
  28. package/build/client/dev/error-overlay.js +19 -4
  29. package/build/client/errors.d.ts +1 -0
  30. package/build/client/errors.js +3 -0
  31. package/build/client/index.d.ts +2 -0
  32. package/build/client/index.js +2 -0
  33. package/build/client/navigation/prefetch.d.ts +1 -0
  34. package/build/client/navigation/prefetch.js +35 -0
  35. package/build/client/routing/Router.js +1 -1
  36. package/build/client/routing/hooks.js +6 -2
  37. package/build/client/routing/loader.d.ts +23 -0
  38. package/build/client/routing/loader.js +53 -7
  39. package/build/client/routing/mount.js +4 -3
  40. package/build/client/rpc.d.ts +1 -0
  41. package/build/client/rpc.js +37 -0
  42. package/build/compiler/.tsbuildinfo +1 -1
  43. package/build/compiler/config.d.ts +16 -0
  44. package/build/compiler/config.js +9 -0
  45. package/build/compiler/docs.js +78 -21
  46. package/build/compiler/generate.js +5 -4
  47. package/build/compiler/index.d.ts +3 -2
  48. package/build/compiler/index.js +2 -2
  49. package/build/compiler/plugin.js +228 -0
  50. package/build/compiler/prerender.d.ts +1 -0
  51. package/build/compiler/prerender.js +1 -1
  52. package/build/compiler/seo.d.ts +1 -1
  53. package/build/compiler/seo.js +20 -5
  54. package/build/compiler/ssg.js +39 -2
  55. package/build/compiler/vite.js +25 -0
  56. package/build/io/.tsbuildinfo +1 -1
  57. package/build/io/codec.d.ts +54 -0
  58. package/build/io/codec.js +143 -0
  59. package/build/io/index.d.ts +1 -2
  60. package/build/io/index.js +1 -2
  61. package/build/logger/.tsbuildinfo +1 -1
  62. package/build/shared/.tsbuildinfo +1 -1
  63. package/eslint.config.js +48 -48
  64. package/examples/basic/client/404.tsx +11 -11
  65. package/examples/basic/client/components/.gitkeep +1 -1
  66. package/examples/basic/client/global-error.tsx +13 -13
  67. package/examples/basic/client/layout.tsx +25 -25
  68. package/examples/basic/client/public/images/.gitkeep +1 -1
  69. package/examples/basic/client/public/images/logo.svg +36 -36
  70. package/examples/basic/client/public/robots.txt +2 -2
  71. package/examples/basic/client/routes/docs/[...slug].tsx +12 -12
  72. package/examples/basic/client/routes/features/error/error.tsx +16 -16
  73. package/examples/basic/client/routes/features/index.tsx +1 -1
  74. package/examples/basic/client/routes/features/template/b.tsx +14 -14
  75. package/examples/basic/client/routes/files/[[...slug]].tsx +21 -21
  76. package/examples/basic/client/routes/gallery/layout.tsx +13 -13
  77. package/examples/basic/client/routes/io.tsx +23 -24
  78. package/examples/basic/client/routes/loader-demo/loading.tsx +13 -13
  79. package/examples/basic/client/routes/rest.tsx +74 -0
  80. package/examples/basic/client/routes/rpc.tsx +43 -0
  81. package/examples/basic/client/routes/search.tsx +61 -61
  82. package/examples/basic/client/toil.tsx +5 -5
  83. package/package.json +167 -148
  84. package/presets/eslint.js +88 -88
  85. package/presets/no-uint8array-tostring.js +200 -200
  86. package/presets/prettier-plugin.js +51 -0
  87. package/presets/prettier.json +19 -18
  88. package/presets/tsconfig.json +37 -37
  89. package/server/runtime/README.md +97 -0
  90. package/server/runtime/abort/abort.ts +27 -0
  91. package/server/runtime/env/Server.ts +61 -0
  92. package/server/runtime/envelope.ts +191 -0
  93. package/server/runtime/exports/index.ts +52 -0
  94. package/server/runtime/handlers/ToilHandler.ts +34 -0
  95. package/server/runtime/index.ts +26 -0
  96. package/server/runtime/lang/Potential.ts +5 -0
  97. package/server/runtime/memory.ts +81 -0
  98. package/server/runtime/request.ts +55 -0
  99. package/server/runtime/response.ts +86 -0
  100. package/server/runtime/rest/Rest.ts +39 -0
  101. package/server/runtime/rest/RestHandler.ts +20 -0
  102. package/server/runtime/rest/RouteContext.ts +82 -0
  103. package/server/runtime/rest/match.ts +48 -0
  104. package/server/runtime/tsconfig.json +7 -0
  105. package/src/backend/index.ts +202 -160
  106. package/src/cli/create.ts +15 -5
  107. package/src/cli/diagnostics.ts +81 -0
  108. package/src/cli/doctor.ts +384 -7
  109. package/src/cli/index.ts +11 -2
  110. package/src/cli/proc.ts +50 -50
  111. package/src/cli/updates.ts +69 -69
  112. package/src/cli/validate.ts +31 -31
  113. package/src/client/channel/channel.ts +146 -146
  114. package/src/client/components/Form.tsx +65 -65
  115. package/src/client/components/Script.tsx +113 -113
  116. package/src/client/components/Slot.tsx +21 -21
  117. package/src/client/dev/devtools.tsx +1018 -0
  118. package/src/client/dev/error-overlay.tsx +30 -4
  119. package/src/client/errors.ts +11 -0
  120. package/src/client/head/head.ts +167 -167
  121. package/src/client/head/metadata.ts +112 -112
  122. package/src/client/index.ts +91 -89
  123. package/src/client/navigation/NavLink.tsx +86 -86
  124. package/src/client/navigation/navigation.ts +235 -235
  125. package/src/client/navigation/prefetch.ts +169 -130
  126. package/src/client/navigation/scroll.ts +53 -53
  127. package/src/client/routing/Router.tsx +8 -2
  128. package/src/client/routing/action.ts +122 -122
  129. package/src/client/routing/error-boundary.tsx +43 -43
  130. package/src/client/routing/hooks.ts +21 -6
  131. package/src/client/routing/loader.ts +325 -235
  132. package/src/client/routing/match.ts +47 -47
  133. package/src/client/routing/mount.tsx +54 -52
  134. package/src/client/routing/params-context.ts +10 -10
  135. package/src/client/routing/slot-context.ts +7 -7
  136. package/src/client/rpc.ts +64 -0
  137. package/src/client/search/search.ts +189 -189
  138. package/src/client/search/use-page-search.ts +73 -73
  139. package/src/client/types.ts +73 -73
  140. package/src/compiler/config.ts +221 -182
  141. package/src/compiler/docs.ts +285 -228
  142. package/src/compiler/generate.ts +395 -394
  143. package/src/compiler/index.ts +66 -57
  144. package/src/compiler/pages.ts +70 -70
  145. package/src/compiler/plugin.ts +258 -2
  146. package/src/compiler/prerender.ts +156 -156
  147. package/src/compiler/seo.ts +417 -390
  148. package/src/compiler/ssg.ts +171 -126
  149. package/src/compiler/vite.ts +34 -0
  150. package/src/io/FastMap.ts +151 -127
  151. package/src/io/FastSet.ts +15 -1
  152. package/src/io/codec.ts +217 -0
  153. package/src/io/index.ts +10 -11
  154. package/src/io/lengths.ts +14 -14
  155. package/src/io/types.ts +19 -18
  156. package/src/logger/index.ts +22 -22
  157. package/src/shared/index.ts +10 -10
  158. package/std/client/index.d.ts +15 -15
  159. package/std/client/package.json +3 -3
  160. package/test/assembly/example.spec.ts +17 -7
  161. package/test/channel.test.ts +21 -21
  162. package/test/doctor.test.ts +65 -0
  163. package/test/dom/Link.test.tsx +47 -47
  164. package/test/dom/NavLink.test.tsx +37 -37
  165. package/test/dom/error-overlay.test.tsx +44 -44
  166. package/test/dom/loader.test.tsx +121 -121
  167. package/test/dom/navigation.test.ts +59 -59
  168. package/test/dom/revalidate.test.tsx +38 -38
  169. package/test/dom/route-head.test.tsx +78 -78
  170. package/test/dom/router-loading.test.tsx +44 -44
  171. package/test/dom/scroll.test.ts +56 -56
  172. package/test/dom/use-metadata.test.tsx +58 -58
  173. package/test/errors.test.ts +21 -0
  174. package/test/io.test.ts +117 -93
  175. package/test/navlink.test.ts +28 -28
  176. package/test/placeholder.test.ts +9 -9
  177. package/test/prettier-plugin.test.ts +46 -0
  178. package/test/routes.test.ts +76 -76
  179. package/test/rpc.test.ts +50 -0
  180. package/test/seo.test.ts +175 -164
  181. package/test/slot-layouts.test.ts +69 -69
  182. package/test/ssg.test.ts +36 -36
  183. package/test/update.test.ts +44 -44
  184. package/test/validate.test.ts +42 -42
  185. package/tests/data-parity/generated-parity.ts +99 -0
  186. package/tests/data-parity/parity.ts +80 -0
  187. package/tests/data-parity/spec.ts +46 -0
  188. package/toil-routes.d.ts +7 -0
  189. package/tsconfig.backend.json +13 -13
  190. package/tsconfig.base.json +35 -35
  191. package/tsconfig.cli.json +13 -13
  192. package/tsconfig.client.json +14 -14
  193. package/tsconfig.compiler.json +13 -13
  194. package/tsconfig.io.json +12 -12
  195. package/tsconfig.json +22 -22
  196. package/tsconfig.logger.json +12 -12
  197. package/tsconfig.server.json +10 -10
  198. package/tsconfig.shared.json +12 -12
  199. package/vitest.config.ts +26 -26
  200. package/.idea/codeStyles/Project.xml +0 -54
  201. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  202. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  203. package/.idea/modules.xml +0 -8
  204. package/.idea/prettier.xml +0 -7
  205. package/.idea/toiljs.iml +0 -8
  206. package/.idea/vcs.xml +0 -6
  207. package/.toil/entry.tsx +0 -9
  208. package/.toil/index.html +0 -12
  209. package/.toil/routes.ts +0 -9
  210. package/build/cli/configure.d.ts +0 -16
  211. package/build/cli/configure.js +0 -272
  212. package/build/cli/create.d.ts +0 -16
  213. package/build/cli/create.js +0 -420
  214. package/build/cli/diagnostics.d.ts +0 -55
  215. package/build/cli/diagnostics.js +0 -333
  216. package/build/cli/doctor.d.ts +0 -6
  217. package/build/cli/doctor.js +0 -249
  218. package/build/cli/features.d.ts +0 -25
  219. package/build/cli/features.js +0 -107
  220. package/build/cli/index.d.ts +0 -2
  221. package/build/cli/proc.d.ts +0 -6
  222. package/build/cli/proc.js +0 -31
  223. package/build/cli/ui.d.ts +0 -9
  224. package/build/cli/ui.js +0 -75
  225. package/build/cli/update.d.ts +0 -7
  226. package/build/cli/update.js +0 -117
  227. package/build/cli/updates.d.ts +0 -10
  228. package/build/cli/updates.js +0 -45
  229. package/build/cli/validate.d.ts +0 -4
  230. package/build/cli/validate.js +0 -19
  231. package/build/client/Link.d.ts +0 -8
  232. package/build/client/Link.js +0 -44
  233. package/build/client/NavLink.d.ts +0 -14
  234. package/build/client/NavLink.js +0 -37
  235. package/build/client/Router.d.ts +0 -7
  236. package/build/client/Router.js +0 -55
  237. package/build/client/channel.d.ts +0 -23
  238. package/build/client/channel.js +0 -94
  239. package/build/client/error-boundary.d.ts +0 -16
  240. package/build/client/error-boundary.js +0 -19
  241. package/build/client/head.d.ts +0 -26
  242. package/build/client/head.js +0 -87
  243. package/build/client/hooks.d.ts +0 -17
  244. package/build/client/hooks.js +0 -48
  245. package/build/client/lazy.d.ts +0 -16
  246. package/build/client/lazy.js +0 -53
  247. package/build/client/match.d.ts +0 -2
  248. package/build/client/match.js +0 -32
  249. package/build/client/mount.d.ts +0 -2
  250. package/build/client/mount.js +0 -13
  251. package/build/client/navigation.d.ts +0 -13
  252. package/build/client/navigation.js +0 -97
  253. package/build/client/params-context.d.ts +0 -2
  254. package/build/client/params-context.js +0 -2
  255. package/build/client/prefetch.d.ts +0 -11
  256. package/build/client/prefetch.js +0 -100
  257. package/build/client/runtime.d.ts +0 -31
  258. package/build/client/runtime.js +0 -112
  259. package/build/client/scroll.d.ts +0 -8
  260. package/build/client/scroll.js +0 -36
  261. package/build/io/BinaryReader.d.ts +0 -44
  262. package/build/io/BinaryReader.js +0 -244
  263. package/build/io/BinaryWriter.d.ts +0 -44
  264. package/build/io/BinaryWriter.js +0 -297
  265. package/build/server/release.wasm +0 -0
  266. package/build/server/release.wat +0 -9
  267. package/src/io/BinaryReader.ts +0 -340
  268. package/src/io/BinaryWriter.ts +0 -385
  269. package/src/server/index.ts +0 -10
  270. package/src/server/main.ts +0 -13
  271. package/src/server/tsconfig.json +0 -4
  272. package/toil-env.d.ts +0 -16
  273. package/toilconfig.json +0 -30
@@ -1,113 +1,113 @@
1
- import { useEffect, type ReactNode } from 'react';
2
-
3
- /**
4
- * When a {@link Script} is injected, relative to the app becoming interactive:
5
- * - `afterInteractive` (default), on mount, once the app is running. Good for analytics, widgets.
6
- * - `lazyOnload`, deferred until the browser is idle (after `window.load`). For low-priority scripts.
7
- * - `beforeInteractive`, as early as possible. In a client-only SPA there is no SSR, so this still
8
- * runs after hydration, but synchronously on first mount with high fetch priority.
9
- */
10
- export type ScriptStrategy = 'beforeInteractive' | 'afterInteractive' | 'lazyOnload';
11
-
12
- /** Props for {@link Script}. Provide either `src` (external) or inline `children` (script body). */
13
- export interface ScriptProps {
14
- /** URL of an external script. Omit when providing an inline script body via `children`. */
15
- src?: string;
16
- /** When to load the script. Default `'afterInteractive'`. */
17
- strategy?: ScriptStrategy;
18
- /** Stable identity for dedup (required for inline scripts; defaults to `src` for external ones). */
19
- id?: string;
20
- /** `type` attribute (e.g. `'module'`, `'application/json'`). */
21
- type?: string;
22
- /** Fired once the script has loaded (external) or been inserted (inline). */
23
- onLoad?: () => void;
24
- /** Fired after load, and on every later mount once the script is already loaded. */
25
- onReady?: () => void;
26
- /** Fired if an external script fails to load. */
27
- onError?: (error: unknown) => void;
28
- /** Inline script body. Mutually exclusive with `src`. */
29
- children?: string;
30
- }
31
-
32
- type LoadState = 'loading' | 'ready';
33
- /** Module-level registry so a given script is injected/executed at most once across the app. */
34
- const registry = new Map<string, LoadState>();
35
-
36
- function inject(props: ScriptProps, key: string): void {
37
- const { src, type, onLoad, onReady, onError, children } = props;
38
- const el = document.createElement('script');
39
- el.dataset.toilScript = key;
40
- if (type !== undefined) el.type = type;
41
-
42
- if (src !== undefined) {
43
- el.src = src;
44
- el.async = true;
45
- el.addEventListener('load', () => {
46
- registry.set(key, 'ready');
47
- onLoad?.();
48
- onReady?.();
49
- });
50
- el.addEventListener('error', (event) => {
51
- registry.delete(key); // allow a later remount to retry
52
- onError?.(event);
53
- });
54
- document.head.appendChild(el);
55
- } else {
56
- el.textContent = children ?? '';
57
- document.head.appendChild(el);
58
- registry.set(key, 'ready');
59
- onLoad?.();
60
- onReady?.();
61
- }
62
- }
63
-
64
- /**
65
- * Loads an external or inline `<script>` with a load `strategy`, deduplicated across the app so the
66
- * same script never executes twice. Renders nothing. Mirrors the ergonomics of Next.js `next/script`
67
- * for a client-only SPA.
68
- */
69
- export function Script(props: ScriptProps): ReactNode {
70
- const { src, id, strategy = 'afterInteractive', onReady } = props;
71
- const key = id ?? src;
72
-
73
- useEffect(() => {
74
- if (key === undefined) {
75
- // No id and no src: nothing to dedup or load (an inline script needs at least an id).
76
- return;
77
- }
78
-
79
- const state = registry.get(key);
80
- if (state === 'ready') {
81
- onReady?.();
82
- return;
83
- }
84
- if (state === 'loading') {
85
- return; // another instance is already injecting it
86
- }
87
-
88
- registry.set(key, 'loading');
89
- const run = (): void => {
90
- inject(props, key);
91
- };
92
-
93
- if (strategy === 'lazyOnload') {
94
- if (document.readyState === 'complete') {
95
- const idle = window.requestIdleCallback?.bind(window);
96
- if (idle) idle(run);
97
- else setTimeout(run, 0);
98
- } else {
99
- window.addEventListener('load', run, { once: true });
100
- }
101
- return () => {
102
- window.removeEventListener('load', run);
103
- };
104
- }
105
-
106
- // beforeInteractive + afterInteractive: inject now (on mount).
107
- run();
108
- // Intentionally keyed on identity only: inject once per script key; later prop changes
109
- // (handlers, body) are read at inject time and must not re-run/re-inject the script.
110
- }, [key, strategy]);
111
-
112
- return null;
113
- }
1
+ import { useEffect, type ReactNode } from 'react';
2
+
3
+ /**
4
+ * When a {@link Script} is injected, relative to the app becoming interactive:
5
+ * - `afterInteractive` (default), on mount, once the app is running. Good for analytics, widgets.
6
+ * - `lazyOnload`, deferred until the browser is idle (after `window.load`). For low-priority scripts.
7
+ * - `beforeInteractive`, as early as possible. In a client-only SPA there is no SSR, so this still
8
+ * runs after hydration, but synchronously on first mount with high fetch priority.
9
+ */
10
+ export type ScriptStrategy = 'beforeInteractive' | 'afterInteractive' | 'lazyOnload';
11
+
12
+ /** Props for {@link Script}. Provide either `src` (external) or inline `children` (script body). */
13
+ export interface ScriptProps {
14
+ /** URL of an external script. Omit when providing an inline script body via `children`. */
15
+ src?: string;
16
+ /** When to load the script. Default `'afterInteractive'`. */
17
+ strategy?: ScriptStrategy;
18
+ /** Stable identity for dedup (required for inline scripts; defaults to `src` for external ones). */
19
+ id?: string;
20
+ /** `type` attribute (e.g. `'module'`, `'application/json'`). */
21
+ type?: string;
22
+ /** Fired once the script has loaded (external) or been inserted (inline). */
23
+ onLoad?: () => void;
24
+ /** Fired after load, and on every later mount once the script is already loaded. */
25
+ onReady?: () => void;
26
+ /** Fired if an external script fails to load. */
27
+ onError?: (error: unknown) => void;
28
+ /** Inline script body. Mutually exclusive with `src`. */
29
+ children?: string;
30
+ }
31
+
32
+ type LoadState = 'loading' | 'ready';
33
+ /** Module-level registry so a given script is injected/executed at most once across the app. */
34
+ const registry = new Map<string, LoadState>();
35
+
36
+ function inject(props: ScriptProps, key: string): void {
37
+ const { src, type, onLoad, onReady, onError, children } = props;
38
+ const el = document.createElement('script');
39
+ el.dataset.toilScript = key;
40
+ if (type !== undefined) el.type = type;
41
+
42
+ if (src !== undefined) {
43
+ el.src = src;
44
+ el.async = true;
45
+ el.addEventListener('load', () => {
46
+ registry.set(key, 'ready');
47
+ onLoad?.();
48
+ onReady?.();
49
+ });
50
+ el.addEventListener('error', (event) => {
51
+ registry.delete(key); // allow a later remount to retry
52
+ onError?.(event);
53
+ });
54
+ document.head.appendChild(el);
55
+ } else {
56
+ el.textContent = children ?? '';
57
+ document.head.appendChild(el);
58
+ registry.set(key, 'ready');
59
+ onLoad?.();
60
+ onReady?.();
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Loads an external or inline `<script>` with a load `strategy`, deduplicated across the app so the
66
+ * same script never executes twice. Renders nothing. Mirrors the ergonomics of Next.js `next/script`
67
+ * for a client-only SPA.
68
+ */
69
+ export function Script(props: ScriptProps): ReactNode {
70
+ const { src, id, strategy = 'afterInteractive', onReady } = props;
71
+ const key = id ?? src;
72
+
73
+ useEffect(() => {
74
+ if (key === undefined) {
75
+ // No id and no src: nothing to dedup or load (an inline script needs at least an id).
76
+ return;
77
+ }
78
+
79
+ const state = registry.get(key);
80
+ if (state === 'ready') {
81
+ onReady?.();
82
+ return;
83
+ }
84
+ if (state === 'loading') {
85
+ return; // another instance is already injecting it
86
+ }
87
+
88
+ registry.set(key, 'loading');
89
+ const run = (): void => {
90
+ inject(props, key);
91
+ };
92
+
93
+ if (strategy === 'lazyOnload') {
94
+ if (document.readyState === 'complete') {
95
+ const idle = window.requestIdleCallback?.bind(window);
96
+ if (idle) idle(run);
97
+ else setTimeout(run, 0);
98
+ } else {
99
+ window.addEventListener('load', run, { once: true });
100
+ }
101
+ return () => {
102
+ window.removeEventListener('load', run);
103
+ };
104
+ }
105
+
106
+ // beforeInteractive + afterInteractive: inject now (on mount).
107
+ run();
108
+ // Intentionally keyed on identity only: inject once per script key; later prop changes
109
+ // (handlers, body) are read at inject time and must not re-run/re-inject the script.
110
+ }, [key, strategy]);
111
+
112
+ return null;
113
+ }
@@ -1,21 +1,21 @@
1
- import { useContext, type ReactNode } from 'react';
2
-
3
- import { SlotContext } from '../routing/slot-context.js';
4
-
5
- /** Props for {@link Slot}. */
6
- export interface SlotProps {
7
- /** The parallel-slot name, the `@name` directory under `routes/` (without the `@`). */
8
- name: string;
9
- /** Rendered when the slot has no match for the current URL. Default `null`. */
10
- fallback?: ReactNode;
11
- }
12
-
13
- /**
14
- * Renders the parallel-route slot named `name` for the current URL. Place it in a layout or page to
15
- * show an `@name` route tree alongside the main content (e.g. a persistent sidebar, or a modal that
16
- * an intercepting route fills). Renders `fallback` (default nothing) when no slot route matches.
17
- */
18
- export function Slot({ name, fallback = null }: SlotProps): ReactNode {
19
- const slots = useContext(SlotContext);
20
- return slots[name] ?? fallback;
21
- }
1
+ import { useContext, type ReactNode } from 'react';
2
+
3
+ import { SlotContext } from '../routing/slot-context.js';
4
+
5
+ /** Props for {@link Slot}. */
6
+ export interface SlotProps {
7
+ /** The parallel-slot name, the `@name` directory under `routes/` (without the `@`). */
8
+ name: string;
9
+ /** Rendered when the slot has no match for the current URL. Default `null`. */
10
+ fallback?: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * Renders the parallel-route slot named `name` for the current URL. Place it in a layout or page to
15
+ * show an `@name` route tree alongside the main content (e.g. a persistent sidebar, or a modal that
16
+ * an intercepting route fills). Renders `fallback` (default nothing) when no slot route matches.
17
+ */
18
+ export function Slot({ name, fallback = null }: SlotProps): ReactNode {
19
+ const slots = useContext(SlotContext);
20
+ return slots[name] ?? fallback;
21
+ }