diff --git a/code/frameworks/nextjs/README.md b/code/frameworks/nextjs/README.md index 5994ef7b5f0c..8541bf490df2 100644 --- a/code/frameworks/nextjs/README.md +++ b/code/frameworks/nextjs/README.md @@ -24,6 +24,7 @@ - [Set `nextjs.appDirectory` to `true`](#set-nextjsappdirectory-to-true) - [Overriding defaults](#overriding-defaults-1) - [Global Defaults](#global-defaults-1) + - [`useSelectedLayoutSegment` and `useSelectedLayoutSegments` hook](#useselectedlayoutsegment-and-useselectedlayoutsegments-hook) - [Default Navigation Context](#default-navigation-context) - [Actions Integration Caveats](#actions-integration-caveats-1) - [Sass/Scss](#sassscss) @@ -440,6 +441,40 @@ export const parameters = { }; ``` +#### `useSelectedLayoutSegment` and `useSelectedLayoutSegments` hook + +The `useSelectedLayoutSegment` and `useSelectedLayoutSegments` hooks are supported in Storybook. You have to set the `nextjs.navigation.segments` parameter to return the segments you want to use. + +```js +// SomeComponentThatUsesTheNavigation.stories.js +import SomeComponentThatUsesTheNavigation from './SomeComponentThatUsesTheNavigation'; + +export default { + component: SomeComponentThatUsesTheNavigation, + parameters: { + nextjs: { + appDirectory: true, + navigation: { + segments: ['dashboard', 'analytics'] + }, + }, + }, +}; + +export const Example = {}; + +// SomeComponentThatUsesTheNavigation.js +import { useSelectedLayoutSegment, useSelectedLayoutSegments } from 'next/navigation'; + +export default function SomeComponentThatUsesTheNavigation() { + const segment = useSelectedLayoutSegment(); // dashboard + const segments = useSelectedLayoutSegments(); // ["dashboard", "analytics"] + ... +} +``` + +The default value of `nextjs.navigation.segments` is `[]` if not set. + #### Default Navigation Context The default values on the stubbed navigation context are as follows: diff --git a/code/frameworks/nextjs/src/routing/app-router-provider.tsx b/code/frameworks/nextjs/src/routing/app-router-provider.tsx index ec1a1e023c48..ea761d9e1209 100644 --- a/code/frameworks/nextjs/src/routing/app-router-provider.tsx +++ b/code/frameworks/nextjs/src/routing/app-router-provider.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import { AppRouterContext } from 'next/dist/shared/lib/app-router-context'; +import { AppRouterContext, LayoutRouterContext } from 'next/dist/shared/lib/app-router-context'; import { PathnameContext, SearchParamsContext } from 'next/dist/shared/lib/hooks-client-context'; +import type { FlightRouterState } from 'next/dist/server/app-render'; import type { RouteParams } from './types'; type AppRouterProviderProps = { @@ -8,8 +9,19 @@ type AppRouterProviderProps = { routeParams: RouteParams; }; +const getParallelRoutes = (segmentsList: Array): FlightRouterState => { + const segment = segmentsList.shift(); + + if (segment) { + return [segment, { children: getParallelRoutes(segmentsList) }]; + } + + return [] as any; +}; + const AppRouterProvider: React.FC = ({ children, action, routeParams }) => { - const { pathname, query, ...restRouteParams } = routeParams; + const { pathname, query, segments = [], ...restRouteParams } = routeParams; + return ( = ({ children, action, }} > - {children} + + {children} + ); diff --git a/code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx b/code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx index 5335fa098ae6..f43167da2c14 100644 --- a/code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx +++ b/code/frameworks/nextjs/template/stories_default-js/Navigation.stories.jsx @@ -1,10 +1,18 @@ -import { useRouter, usePathname, useSearchParams } from 'next/navigation'; +import { + useRouter, + usePathname, + useSearchParams, + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation'; import React from 'react'; function Component() { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); + const segment = useSelectedLayoutSegment(); + const segments = useSelectedLayoutSegments(); const searchParamsList = Array.from(searchParams.entries()); @@ -38,6 +46,8 @@ function Component() { return (
pathname: {pathname}
+
segment: {segment}
+
segments: {segments.join(',')}
searchparams:{' '}
    @@ -75,3 +85,14 @@ export default { }; export const Default = {}; + +export const WithSegmentDefined = { + parameters: { + nextjs: { + appDirectory: true, + navigation: { + segments: ['dashboard', 'settings'], + }, + }, + }, +};