Skip to content

Commit

Permalink
useSelectedLayoutSegment at the current level (#42299)
Browse files Browse the repository at this point in the history
When `useSelectedLayoutSegment` is used on the current level or in a
page it should return null.

fixes #41879
fixes #41878

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
Hannes Bornö committed Nov 2, 2022
1 parent 9de871e commit 8350f7e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
4 changes: 2 additions & 2 deletions packages/next/client/components/navigation.ts
Expand Up @@ -174,10 +174,10 @@ export function useSelectedLayoutSegments(
*/
export function useSelectedLayoutSegment(
parallelRouteKey: string = 'children'
): string {
): string | null {
const selectedLayoutSegments = useSelectedLayoutSegments(parallelRouteKey)
if (selectedLayoutSegments.length === 0) {
throw new Error('No selected layout segment below the current level')
return null
}

return selectedLayoutSegments[0]
Expand Down
@@ -1,11 +1,18 @@
'use client'

import { useSelectedLayoutSegments } from 'next/navigation'
import {
useSelectedLayoutSegments,
useSelectedLayoutSegment,
} from 'next/navigation'

export default function Page() {
const selectedLayoutSegment = useSelectedLayoutSegments()
const selectedLayoutSegments = useSelectedLayoutSegments()
const selectedLayoutSegment = useSelectedLayoutSegment()

return (
<p id="page-layout-segments">{JSON.stringify(selectedLayoutSegment)}</p>
<>
<p id="page-layout-segments">{JSON.stringify(selectedLayoutSegments)}</p>
<p id="page-layout-segment">{JSON.stringify(selectedLayoutSegment)}</p>
</>
)
}
@@ -1,13 +1,18 @@
'use client'

import { useSelectedLayoutSegments } from 'next/navigation'
import {
useSelectedLayoutSegments,
useSelectedLayoutSegment,
} from 'next/navigation'

export default function Layout({ children }) {
const selectedLayoutSegment = useSelectedLayoutSegments()
const selectedLayoutSegments = useSelectedLayoutSegments()
const selectedLayoutSegment = useSelectedLayoutSegment()

return (
<>
<p id="inner-layout">{JSON.stringify(selectedLayoutSegment)}</p>
<p id="inner-layout">{JSON.stringify(selectedLayoutSegments)}</p>
<p id="inner-layout-segment">{JSON.stringify(selectedLayoutSegment)}</p>
{children}
</>
)
Expand Down
@@ -1,13 +1,18 @@
'use client'

import { useSelectedLayoutSegments } from 'next/navigation'
import {
useSelectedLayoutSegments,
useSelectedLayoutSegment,
} from 'next/navigation'

export default function Layout({ children }) {
const selectedLayoutSegment = useSelectedLayoutSegments()
const selectedLayoutSegments = useSelectedLayoutSegments()
const selectedLayoutSegment = useSelectedLayoutSegment()

return (
<>
<p id="outer-layout">{JSON.stringify(selectedLayoutSegment)}</p>
<p id="outer-layout">{JSON.stringify(selectedLayoutSegments)}</p>
<p id="outer-layout-segment">{JSON.stringify(selectedLayoutSegment)}</p>
{children}
</>
)
Expand Down
34 changes: 33 additions & 1 deletion test/e2e/app-dir/index.test.ts
Expand Up @@ -1273,7 +1273,7 @@ describe('app dir', () => {
}
})

describe('useSelectedLayoutSegment', () => {
describe('useSelectedLayoutSegments', () => {
it.each`
path | outerLayout | innerLayout
${'/hooks/use-selected-layout-segment/first'} | ${['first']} | ${[]}
Expand Down Expand Up @@ -1303,6 +1303,38 @@ describe('app dir', () => {
expect(JSON.parse($('#page-layout-segments').text())).toEqual([])
})
})

describe('useSelectedLayoutSegment', () => {
it.each`
path | outerLayout | innerLayout
${'/hooks/use-selected-layout-segment/first'} | ${'first'} | ${null}
${'/hooks/use-selected-layout-segment/first/slug1'} | ${'first'} | ${'slug1'}
${'/hooks/use-selected-layout-segment/first/slug2/second/a/b'} | ${'first'} | ${'slug2'}
`(
'should have the correct layout segment at $path',
async ({ path, outerLayout, innerLayout }) => {
const html = await renderViaHTTP(next.url, path)
const $ = cheerio.load(html)

expect(JSON.parse($('#outer-layout-segment').text())).toEqual(
outerLayout
)
expect(JSON.parse($('#inner-layout-segment').text())).toEqual(
innerLayout
)
}
)

it('should return null in pages', async () => {
const html = await renderViaHTTP(
next.url,
'/hooks/use-selected-layout-segment/first/slug2/second/a/b'
)
const $ = cheerio.load(html)

expect(JSON.parse($('#page-layout-segment').text())).toEqual(null)
})
})
})

if (isDev) {
Expand Down

0 comments on commit 8350f7e

Please sign in to comment.