Skip to content

Commit

Permalink
feat(packages/tuono-(router|fs-router-vite-plugin)): replace `__route…
Browse files Browse the repository at this point in the history
… ` with `__layout` (#283)
  • Loading branch information
marcalexiei authored Jan 3, 2025
1 parent cf56b3a commit 0ef1252
Show file tree
Hide file tree
Showing 24 changed files with 82 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ then it will be accessible at `posts/1`, `posts/2`, etc.
## The Root route (Layout components)

Tuono allows you to have a layout component to wrap all the routes included within the same folder.
To define such component you will have to create a `__root.tsx` file (is allowed only a single `__root` file per folder).
To define such component you will have to create a `__layout.tsx` file (is allowed only a single `__layout` file per folder).

This file won't generate any route.

Expand All @@ -63,7 +63,7 @@ This file won't generate any route.
A file created in this location will wrap all project route.

```tsx
// src/routes/__root.tsx
// src/routes/__layout.tsx
export default function RootLayout({ children }) {
return <main>{children}</main>
}
Expand All @@ -74,8 +74,8 @@ export default function RootLayout({ children }) {
A file created in this location will wrap only the routes defined within the `src/routes/posts` folder.

```tsx
// src/routes/posts/__root.tsx
export default function PostRootLayout({ children }) {
// src/routes/posts/__layout.tsx
export default function PostLayout({ children }) {
return <article>{children}</article>
}
```
Expand All @@ -86,9 +86,9 @@ Referring to the two examples above consider that:

```tsx
<RootLayout>
<PostRootLayout>
<PostLayout>
<ExamplePost />
</PostRootLayout>
</PostLayout>
</RootLayout>
```

Expand Down
4 changes: 2 additions & 2 deletions apps/documentation/src/routes/sitemap.xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use time::OffsetDateTime;
use tuono_lib::axum::http::{header, HeaderMap, StatusCode};
use tuono_lib::{Request, Response};

const FILE_TO_EXCLUDE: [&str; 2] = ["sitemap.xml", "__root"];
const FILES_TO_EXCLUDE: [&str; 2] = ["sitemap.xml", "__layout"];

const SITEMAP: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
Expand All @@ -20,7 +20,7 @@ fn load_routes() -> Vec<String> {
if !entry.is_dir() {
let path = clean_path(format!("/{}", entry.to_string_lossy()));

if !FILE_TO_EXCLUDE
if !FILES_TO_EXCLUDE
.iter()
.any(|exclude| path.ends_with(exclude))
{
Expand Down
6 changes: 3 additions & 3 deletions crates/tuono/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::process::Stdio;
use crate::route::Route;

const IGNORE_EXTENSIONS: [&str; 3] = ["css", "scss", "sass"];
const IGNORE_FILES: [&str; 1] = ["__root"];
const IGNORE_FILES: [&str; 1] = ["__layout"];

#[cfg(target_os = "windows")]
const ROUTES_FOLDER_PATH: &str = "\\src\\routes";
Expand Down Expand Up @@ -333,8 +333,8 @@ mod tests {
app.base_path = "/home/user/Documents/tuono".into();

let routes = [
"/home/user/Documents/tuono/src/routes/__root.tsx",
"/home/user/Documents/tuono/src/routes/posts/__root.tsx",
"/home/user/Documents/tuono/src/routes/__layout.tsx",
"/home/user/Documents/tuono/src/routes/posts/__layout.tsx",
];

routes.into_iter().for_each(|route| {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ReactNode, JSX } from 'react'

interface RootRouteProps {
interface RootLayoutProps {
children: ReactNode
}

export default function RootRoute({ children }: RootRouteProps): JSX.Element {
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
return (
<html>
<body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ReactNode, JSX } from 'react'

interface RootRouteProps {
interface RootLayoutProps {
children: ReactNode
}

export default function RootRoute({ children }: RootRouteProps): JSX.Element {
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
return (
<html>
<body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { ReactNode, JSX } from 'react'
import { MDXProvider } from '@mdx-js/react'

interface RootRouteProps {
interface RootLayoutProps {
children: ReactNode
}

export default function RootRoute({ children }: RootRouteProps): JSX.Element {
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
return (
<html>
<body>
Expand Down
24 changes: 12 additions & 12 deletions packages/tuono-fs-router-vite-plugin/src/build-route-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ const routes = [
routePath: '/posts/my-post',
variableName: 'PostsMyPost',
parent: {
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
path: '/posts/__root',
path: '/posts/__layout',
cleanedPath: '/posts',
children: undefined,
},
Expand All @@ -29,12 +29,12 @@ const routes = [
routePath: '/posts/',
variableName: 'PostsIndex',
parent: {
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/home/valerio/Documents/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/home/valerio/Documents/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
path: '/posts/__root',
path: '/posts/__layout',
cleanedPath: '/posts',
children: undefined,
},
Expand All @@ -48,12 +48,12 @@ const routes = [
routePath: '/posts/',
variableName: 'PostspostIndex',
parent: {
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
path: '/posts/__root',
path: '/posts/__layout',
cleanedPath: '/posts',
children: undefined,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/tuono-fs-router-vite-plugin/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const ROUTES_FOLDER = './src/routes/'
export const ROOT_PATH_ID = '__root'
export const LAYOUT_PATH_ID = '__layout'
export const GENERATED_ROUTE_TREE = './.tuono/routeTree.gen.ts'
18 changes: 11 additions & 7 deletions packages/tuono-fs-router-vite-plugin/src/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import {
} from './utils'

import type { Config, RouteNode } from './types'
import { ROUTES_FOLDER, ROOT_PATH_ID, GENERATED_ROUTE_TREE } from './constants'
import {
ROUTES_FOLDER,
LAYOUT_PATH_ID,
GENERATED_ROUTE_TREE,
} from './constants'

import { sortRouteNodes } from './sort-route-nodes'
import isDefaultExported from './utils/is-default-exported'
Expand Down Expand Up @@ -154,7 +158,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
const routeConfigChildrenText = buildRouteConfig(routeNodes)

const sortedRouteNodes = multiSortBy(routeNodes, [
(d): number => (d.routePath.includes(`/${ROOT_PATH_ID}`) ? -1 : 1),
(d): number => (d.routePath.includes(`/${LAYOUT_PATH_ID}`) ? -1 : 1),
(d): number => d.routePath.split('/').length,
(d): number => (d.routePath.endsWith("index'") ? -1 : 1),
(d): RouteNode => d,
Expand All @@ -179,7 +183,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {

const createRoutes = [
...sortedRouteNodes.map((node) => {
const isRoot = node.routePath.endsWith(ROOT_PATH_ID)
const isRoot = node.routePath.endsWith(LAYOUT_PATH_ID)
const rootDeclaration = isRoot ? ', isRoot: true' : ''
const variableName = node.variableName as string

Expand All @@ -195,7 +199,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
return [
`const ${variableName}Route = ${variableName}.update({
${[
!node.path?.endsWith(ROOT_PATH_ID) && `path: '${cleanedPath}'`,
!node.path?.endsWith(LAYOUT_PATH_ID) && `path: '${cleanedPath}'`,
`getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,
rustHandlersNodes.includes(node.path || '')
? 'hasHandler: true'
Expand All @@ -213,15 +217,15 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
'// This file is auto-generated by Tuono',
"import { createRoute, dynamic } from 'tuono'",
[
`import RootImport from './${replaceBackslash(
`import RootLayoutImport from './${replaceBackslash(
path.relative(
path.dirname(config.generatedRouteTree),
path.resolve(config.folderName, ROOT_PATH_ID),
path.resolve(config.folderName, LAYOUT_PATH_ID),
),
)}'`,
].join('\n'),
imports,
'const rootRoute = createRoute({ isRoot: true, component: RootImport });',
'const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport });',
createRoutes,
'// Create/Update Routes',
createRouteUpdates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ const routes = [
cleanedPath: '/posts/[post]',
},
{
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
path: '/posts/__root',
path: '/posts/__layout',
cleanedPath: '/posts',
},
{
Expand All @@ -42,12 +42,12 @@ const routes = [
]

const parent = {
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
path: '/posts/__root',
path: '/posts/__layout',
cleanedPath: '/posts',
}

Expand Down
8 changes: 4 additions & 4 deletions packages/tuono-fs-router-vite-plugin/src/has-parent-route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ROOT_PATH_ID } from './constants'
import { LAYOUT_PATH_ID } from './constants'
import { multiSortBy } from './utils'
import type { RouteNode } from './types'

Expand All @@ -19,15 +19,15 @@ export function hasParentRoute(
(d): number => d.routePath.length * -1,
(d): string | undefined => d.variableName,
])
// Exclude base __root file
.filter((d) => d.routePath !== `/${ROOT_PATH_ID}`)
// Exclude base __layout file
.filter((d) => d.routePath !== `/${LAYOUT_PATH_ID}`)

for (const route of sortedNodes) {
if (route.routePath === '/') continue

if (
route.routePath.startsWith(parentRoutePath) &&
route.routePath.endsWith(ROOT_PATH_ID)
route.routePath.endsWith(LAYOUT_PATH_ID)
) {
return route
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const routes = [
cleanedPath: '/about',
},
{
filePath: '__root.tsx',
filePath: '__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/__root.tsx',
routePath: '/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/__layout.tsx',
routePath: '/__layout',
variableName: 'root',
},
{
Expand All @@ -50,10 +50,10 @@ const routes = [
variableName: 'PostsIndex',
},
{
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
},
]
Expand All @@ -78,10 +78,10 @@ const expectedSorting = [
cleanedPath: '/about',
},
{
filePath: 'posts/__root.tsx',
filePath: 'posts/__layout.tsx',
fullPath:
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
routePath: '/posts/__root',
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
routePath: '/posts/__layout',
variableName: 'Postsroot',
},
{
Expand Down
4 changes: 2 additions & 2 deletions packages/tuono-fs-router-vite-plugin/src/sort-route-nodes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { RouteNode } from './types'
import { multiSortBy } from './utils'
import { ROOT_PATH_ID } from './constants'
import { LAYOUT_PATH_ID } from './constants'

// Routes need to be sorted in order to iterate over the handleNode fn
// with first the items that might be parent routes
Expand All @@ -14,4 +14,4 @@ export const sortRouteNodes = (routes: Array<RouteNode>): Array<RouteNode> =>
(d): number => (d.filePath.match(/[./]route[.]/) ? -1 : 1),
(d): number => (d.routePath.endsWith('/') ? -1 : 1),
(d): string => d.routePath,
]).filter((d) => ![`/${ROOT_PATH_ID}`].includes(d.routePath || ''))
]).filter((d) => ![`/${LAYOUT_PATH_ID}`].includes(d.routePath || ''))
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import { createRoute, dynamic } from 'tuono'

import RootImport from './routes/__root'
import RootLayoutImport from './routes/__layout'

const IndexImport = dynamic(() => import('./routes/index'))
const PostscatchallImport = dynamic(
() => import('./routes/posts/[...catch_all]'),
)

const rootRoute = createRoute({ isRoot: true, component: RootImport })
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })

const Index = createRoute({ component: IndexImport })
const Postscatchall = createRoute({ component: PostscatchallImport })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import { createRoute, dynamic } from 'tuono'

import RootImport from './routes/__root'
import RootLayoutImport from './routes/__layout'

const AboutImport = dynamic(() => import('./routes/about.mdx'))
const IndexImport = dynamic(() => import('./routes/index'))

const rootRoute = createRoute({ isRoot: true, component: RootImport })
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })

const About = createRoute({ component: AboutImport })
const Index = createRoute({ component: IndexImport })
Expand Down
Loading

0 comments on commit 0ef1252

Please sign in to comment.