How to get all the children of a route, to set up a navigation? #1806
Replies: 3 comments 4 replies
-
Can you please provide a minimal complete example by forking one of the examples on stackblitz? |
Beta Was this translation helpful? Give feedback.
-
I came up with a small stackblitz example.
|
Beta Was this translation helpful? Give feedback.
-
If anyone elses wants to do something like this, this is my current solution for a similar problem (using shadcn/Radix-UI). It could probably be improved a lot, but it works: export const Route = createFileRoute("/_app/deliver-collect/$hubId")({
component: RouteComponent,
beforeLoad: async ({ location, params, context }) => {
return preloadQuery<routeHubIdDeliverCollectQuery>(context.relayEnvironment, query, {
hubId: params.hubId,
});
},
loader: async (ctx) => {
return ctx.context;
},
});
function RouteComponent() {
const { hub } = usePreloadedQuery<routeHubIdDeliverCollectQuery>(query, Route.useLoaderData());
const location = useLocation();
const router = useRouter();
const params = Route.useParams();
const match = Route.useMatch();
const tabs = useMemo(() => {
return [
linkOptions({ to: "/deliver-collect/$hubId", label: "Deliver", params }),
linkOptions({ to: "/deliver-collect/$hubId/collect", label: "Collect", params }),
];
}, [params]);
// Router location updates before the page navigates away so we need to store the last active tab
const lastActiveTab = useRef<string | null>(null);
const activeTab = tabs
.toSorted((a, b) => b.to.length - a.to.length)
.find((tab) => {
const tabLocation = router.buildLocation(tab);
return location.pathname.startsWith(tabLocation.pathname);
});
if (activeTab) {
lastActiveTab.current = activeTab.label;
}
const activeTabLabel = lastActiveTab.current;
if (!activeTabLabel) {
throw new Error("Should not happen");
}
const hubName = hub.meta?.name || hub.slug;
return (
<div>
<PageTitle title={`Hub ${hubName.toUpperCase()}`} />
<Tabs value={activeTabLabel}>
<TabsList>
{tabs.map(({ label, ...linkProps }) => (
<TabsTrigger value={label} key={label} asChild>
<Link {...linkProps} from={Route.fullPath} replace>
{label}
</Link>
</TabsTrigger>
))}
</TabsList>
<TabsContent value={activeTabLabel}>
<Outlet />
</TabsContent>
</Tabs>
</div>
);
} This is opt-in, so not 100% automatic but fine for me and the pages nested even further opt-out of the tabbed layout by prefixing with
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
How do I set up the following navigation properly.
For example:
/tables
The navigation should have two links to tableA and tableB as tabs.
This is my solution so far.
Looks pretty cumbersome. Help me improve it.
For now I have to define each NavigationItem manually.
How could I improve that?
Can I somehow read the children from tables route and then autogenerate them?
I am using MUI. To match a tab I have to use the current location as the value.
Getting it from useChildMatches is the way I could figure. But getting it from the array seems to be wrong.
Why is it an array, and can it happen that the current path won't be on index 0?
Beta Was this translation helpful? Give feedback.
All reactions