Skip to content

Commit

Permalink
fix(create-pages): layouts missing with more nesting (#1077)
Browse files Browse the repository at this point in the history
Adds tests for layouts with nesting and slugs

fixes #1055

---------

Co-authored-by: Tyler <[email protected]>
  • Loading branch information
tylersayshi and tylersayshi authored Dec 18, 2024
1 parent 10c3f65 commit fae4d15
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 11 deletions.
6 changes: 6 additions & 0 deletions e2e/21_create-pages_standalone.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ async function testRouterExample(page: Page, port: number) {
await page.goto(`http://localhost:${port}/foo`);
await expect(page.getByRole('heading', { name: 'Foo' })).toBeVisible();

// /nested/foo is defined as a staticPath of /nested/[id] which matches this layout
await page.goto(`http://localhost:${port}/nested/foo`);
await expect(
page.getByRole('heading', { name: 'Deeply Nested Layout' }),
).toBeVisible();

await page.goto(`http://localhost:${port}/nested/baz`);
await expect(
page.getByRole('heading', { name: 'Nested Layout' }),
Expand Down
12 changes: 12 additions & 0 deletions examples/21_create-pages/src/components/DeeplyNestedLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const DeeplyNestedLayout = ({
children,
}: {
children: React.ReactNode;
}) => {
return (
<div>
<h3>Deeply Nested Layout</h3>
{children}
</div>
);
};
7 changes: 7 additions & 0 deletions examples/21_create-pages/src/entries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import NestedBazPage from './components/NestedBazPage';
import NestedQuxPage from './components/NestedQuxPage';
import Root from './components/Root';
import NestedLayout from './components/NestedLayout';
import { DeeplyNestedLayout } from './components/DeeplyNestedLayout';

const pages = createPages(async ({ createPage, createLayout, createRoot }) => [
createRoot({
Expand Down Expand Up @@ -77,6 +78,12 @@ const pages = createPages(async ({ createPage, createLayout, createRoot }) => [
),
}),

createLayout({
render: 'static',
path: '/nested/[id]',
component: DeeplyNestedLayout,
}),

createPage({
render: 'dynamic',
path: '/nested/[id]',
Expand Down
18 changes: 18 additions & 0 deletions packages/waku/src/lib/utils/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ export const path2regexp = (path: PathSpec) => {
return `^/${parts.join('/')}$`;
};

/** Convert a path spec to a string for the path */
export const pathSpecAsString = (path: PathSpec) => {
return (
'/' +
path
.map(({ type, name }) => {
if (type === 'literal') {
return name;
} else if (type === 'group') {
return `[${name}]`;
} else {
return `[...${name}]`;
}
})
.join('/')
);
};

/**
* Helper function to get the path mapping from the path spec and the pathname.
*
Expand Down
27 changes: 17 additions & 10 deletions packages/waku/src/router/create-pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
parsePathWithSlug,
getPathMapping,
path2regexp,
pathSpecAsString,
} from '../lib/utils/path.js';
import type { PathSpec } from '../lib/utils/path.js';
import type {
Expand Down Expand Up @@ -135,14 +136,14 @@ export type CreateLayout = <Path extends string>(
layout:
| {
render: 'dynamic';
path: PathWithoutSlug<Path>;
path: Path;
component: FunctionComponent<
Pick<RouteProps, 'path'> & { children: ReactNode }
>;
}
| {
render: 'static';
path: PathWithoutSlug<Path>;
path: Path;
component: FunctionComponent<{ children: ReactNode }>;
},
) => void;
Expand Down Expand Up @@ -231,6 +232,14 @@ export const createPages = <
}
};

/** helper to get original static slug path */
const getOriginalStaticPathSpec = (path: string) => {
const staticPathSpec = staticPathMap.get(path);
if (staticPathSpec) {
return staticPathSpec.originalSpec ?? staticPathSpec.literalSpec;
}
};

const registerStaticComponent = (
id: string,
component: FunctionComponent<any>,
Expand Down Expand Up @@ -371,12 +380,8 @@ export const createPages = <

const getLayouts = (spec: PathSpec): string[] => {
const pathSegments = spec.reduce<string[]>(
(acc, segment, index) => {
if (index === 0) {
acc.push('/' + segment.name);
} else {
acc.push(acc[index - 1] + '/' + segment.name);
}
(acc, _segment, index) => {
acc.push(pathSpecAsString(spec.slice(0, index + 1)));
return acc;
},
['/'],
Expand Down Expand Up @@ -408,7 +413,7 @@ export const createPages = <
? path2regexp(originalSpec)
: path2regexp(literalSpec);

const layoutPaths = getLayouts(literalSpec);
const layoutPaths = getLayouts(originalSpec ?? literalSpec);

const elements = {
...layoutPaths.reduce<Record<string, { isStatic: boolean }>>(
Expand Down Expand Up @@ -513,7 +518,9 @@ export const createPages = <
),
};

const layoutPaths = getLayouts(pathSpec);
const layoutPaths = getLayouts(
getOriginalStaticPathSpec(path) ?? pathSpec,
);

for (const segment of layoutPaths) {
const layout =
Expand Down
7 changes: 6 additions & 1 deletion packages/waku/tests/create-pages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ describe('createPages', () => {
elements: {
root: { isStatic: true },
'page:/test/nested': { isStatic: true },
'layout:/test/nested': { isStatic: true },
},
routeElement: { isStatic: true },
noSsr: false,
Expand All @@ -668,7 +669,11 @@ describe('createPages', () => {
});
expect(route).toBeDefined();
expect(route.routeElement).toBeDefined();
expect(Object.keys(route.elements)).toEqual(['root', 'page:/test/nested']);
expect(Object.keys(route.elements)).toEqual([
'root',
'page:/test/nested',
'layout:/test/nested',
]);
});

it('creates a nested dynamic page', async () => {
Expand Down

0 comments on commit fae4d15

Please sign in to comment.