@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
115 lines • 4.65 kB
JSX
import * as Solid from 'solid-js';
import { replaceEqualDeep, rootRouteId } from '@tanstack/router-core';
import { isServer } from '@tanstack/router-core/isServer';
import { CatchBoundary, ErrorComponent } from './CatchBoundary';
import { useRouter } from './useRouter';
import { Rendered, Transitioner } from './Transitioner';
import { nearestMatchContext } from './matchContext';
import { SafeFragment } from './SafeFragment';
import { Match } from './Match';
import { renderInNonRouteComponentContext } from './nonRouteComponentContext';
export function Matches() {
const router = useRouter();
const ResolvedSuspense = (isServer ?? router.isServer) ||
(typeof document !== 'undefined' && router.ssr)
? SafeFragment
: Solid.Suspense;
const rootRoute = () => router.routesById[rootRouteId];
const PendingComponent = rootRoute().options.pendingComponent ??
router.options.defaultPendingComponent;
const OptionalWrapper = router.options.InnerWrap || SafeFragment;
return (<OptionalWrapper>
<ResolvedSuspense fallback={PendingComponent
? (() => {
if (process.env.NODE_ENV !== 'production') {
return renderInNonRouteComponentContext(() => <PendingComponent />, 'pendingComponent');
}
return <PendingComponent />;
})()
: null}>
<Transitioner />
<MatchesInner />
<Rendered />
</ResolvedSuspense>
</OptionalWrapper>);
}
function MatchesInner() {
const router = useRouter();
const routeId = () => router.stores.ids.get()[0];
const match = () => routeId() ? router.stores.byRoute.get(routeId())?.get() : undefined;
const nearestMatch = [routeId, match];
const matchComponent = () => {
return (<Solid.Show when={routeId()}>
<Match routeId={routeId()}/>
</Solid.Show>);
};
return (<nearestMatchContext.Provider value={nearestMatch}>
{router.options.disableGlobalCatchBoundary ? (matchComponent()) : (<CatchBoundary getResetKey={match} errorComponent={ErrorComponent} onCatch={process.env.NODE_ENV !== 'production'
? (error) => {
console.warn(`Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`);
console.warn(`Warning: ${error.message || error.toString()}`);
}
: undefined}>
{matchComponent()}
</CatchBoundary>)}
</nearestMatchContext.Provider>);
}
export function useMatchRoute() {
const router = useRouter();
return (opts) => {
return Solid.createMemo(() => {
const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts;
router.stores.location.get();
router.stores.resolvedLocation.get();
router.stores.status.get();
return router.matchRoute(rest, {
pending,
caseSensitive,
fuzzy,
includeSearch,
});
});
};
}
export function MatchRoute(props) {
const matchRoute = useMatchRoute();
const params = matchRoute(props);
const renderedChild = Solid.createMemo(() => {
const matchedParams = params();
const child = props.children;
if (typeof child === 'function') {
return child(matchedParams);
}
return matchedParams ? child : null;
});
return <>{renderedChild()}</>;
}
export function useMatches(opts) {
const router = useRouter();
return Solid.createMemo((prev) => {
const matches = router.stores.matches.get();
const res = opts?.select ? opts.select(matches) : matches;
if (prev === undefined)
return res;
return replaceEqualDeep(prev, res);
});
}
export function useParentMatches(opts) {
const contextRouteId = Solid.useContext(nearestMatchContext)[0 /* route id */];
return useMatches({
select: (matches) => {
matches = matches.slice(0, matches.findIndex((d) => d.routeId === contextRouteId()));
return opts?.select ? opts.select(matches) : matches;
},
});
}
export function useChildMatches(opts) {
const contextRouteId = Solid.useContext(nearestMatchContext)[0 /* route id */];
return useMatches({
select: (matches) => {
matches = matches.slice(matches.findIndex((d) => d.routeId === contextRouteId()) + 1);
return opts?.select ? opts.select(matches) : matches;
},
});
}
//# sourceMappingURL=Matches.jsx.map