|
48 | 48 | routingSnippet?: RouterViewProps['routing']; |
49 | 49 | } = $props(); |
50 | 50 |
|
51 | | - type ComponentOrSnippet = Component | Snippet<[unknown]>; |
| 51 | + type ComponentOrSnippet = Component | Snippet<[any]>; |
52 | 52 |
|
53 | | - // Resolve route, loading or error component to be rendered |
54 | | - let ResolvedComponent = $state<ComponentOrSnippet>(); |
| 53 | + // If we should force a remount on route change |
| 54 | + const force = $derived<boolean>(!!(transition?.updateOnRouteChange || router?.routing?.options?.force)); |
55 | 55 |
|
56 | 56 | // Generate a unique identifier for each loading state, to prevent cancelled navigations from updating the view |
57 | 57 | const change: ViewChangeEvent = $derived(new ViewChangeEvent({ view: { id: view.id, name: view.name }, route })); |
|
69 | 69 | // Delay properties update until component is resolved |
70 | 70 | let _properties: ComponentProps | undefined = $state(); |
71 | 71 |
|
72 | | - // If we should force a remount on route change |
73 | | - const force = $derived<boolean>(!!(transition?.updateOnRouteChange || router?.routing?.options?.force)); |
| 72 | + // Resolved route component when async loading & error handling is complete |
| 73 | + let resolvedComponent = $state<ComponentOrSnippet>(); |
| 74 | +
|
| 75 | + // Routed component to be rendered (loading, error, or resolved component) |
| 76 | + const routedComponent = $derived.by<ComponentOrSnippet | undefined>(() => { |
| 77 | + if (view.loading && loading) return loading; |
| 78 | + else if (view.loading && loadingSnippet) return loadingSnippet; |
| 79 | + else if (view.error && error) return error; |
| 80 | + else if (view.error && errorSnippet) return errorSnippet; |
| 81 | + else if (resolvedComponent) return resolvedComponent; |
| 82 | + }); |
| 83 | +
|
| 84 | + // Trigger transition on route change or component update |
| 85 | + const transitionKey = $derived.by(() => { |
| 86 | + const _keys: any[] = [routedComponent]; |
| 87 | +
|
| 88 | + if (transition?.updateOnPropsChange) _keys.push(_properties); |
| 89 | + if (routingSnippet) _keys.push(routing); |
| 90 | +
|
| 91 | + console.info('Transition key changed:', _keys); |
| 92 | + return _keys; |
| 93 | + }); |
74 | 94 | // Final unique identifier for the current route change |
75 | 95 | let resolvedID = $state(); |
76 | 96 |
|
|
87 | 107 | }, |
88 | 108 | onLoaded: (_component?: AnyComponent | AnySnippet) => { |
89 | 109 | if (change.uuid !== _uuid) return; |
90 | | - ResolvedComponent = _component; |
| 110 | + resolvedComponent = _component; |
91 | 111 | _properties = properties; |
92 | 112 | if (force) resolvedID = _uuid; |
93 | 113 | return untrack(() => view.complete()); |
|
104 | 124 | $effect(() => { |
105 | 125 | resolveComponent(component, listeners); |
106 | 126 | }); |
107 | | -
|
108 | | - const routedComponent = $derived.by(() => { |
109 | | - if (view.loading && loading) return loading; |
110 | | - else if (view.loading && loadingSnippet) return loadingSnippet; |
111 | | - else if (view.error && error) return error; |
112 | | - else if (view.error && errorSnippet) return errorSnippet; |
113 | | - else if (ResolvedComponent) return ResolvedComponent; |
114 | | - }); |
115 | | -
|
116 | | - // Trigger transition on route change or component update |
117 | | - const transitionKey = $derived.by(() => { |
118 | | - const _keys: any[] = [routedComponent]; |
119 | | -
|
120 | | - if (transition?.updateOnPropsChange) _keys.push(_properties); |
121 | | - if (routingSnippet) _keys.push(routing); |
122 | | -
|
123 | | - console.info('Transition key changed:', _keys); |
124 | | - return _keys; |
125 | | - }); |
126 | 127 | </script> |
127 | 128 |
|
128 | 129 | {#snippet resolved(ComponentOrSnippet: ComponentOrSnippet)} |
|
138 | 139 | {#snippet result()} |
139 | 140 | {#if routing && routingSnippet} |
140 | 141 | {@render routingSnippet(router.routing)} |
141 | | - {:else} |
| 142 | + {:else if routedComponent} |
142 | 143 | {@render resolved(routedComponent)} |
143 | 144 | {/if} |
144 | 145 | {/snippet} |
|
0 commit comments