Skip to content

Commit

Permalink
feat: Adding a resolveRouteSegments function (#148)
Browse files Browse the repository at this point in the history
* Adding a resolveRouteSegments function

* Added changeset files

* Fix CI

* Fix CI

* Update Github action to actions/checkout@v3
  • Loading branch information
patricklafrance committed Feb 9, 2024
1 parent 905c71c commit a448347
Show file tree
Hide file tree
Showing 54 changed files with 3,089 additions and 3,447 deletions.
5 changes: 5 additions & 0 deletions .changeset/healthy-games-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@squide/react-router": minor
---

Added a `resolveRouteSegments` function.
5 changes: 5 additions & 0 deletions .changeset/lazy-gifts-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@squide/firefly": patch
---

Internal changes.
5 changes: 5 additions & 0 deletions .changeset/neat-worms-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@squide/webpack-configs": patch
---

Removed `@squide/webpack-module-federation` dependency.
5 changes: 5 additions & 0 deletions .changeset/real-waves-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@squide/firefly-configs": patch
---

Internal changes.
2 changes: 1 addition & 1 deletion .github/workflows/retype-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
contents: write

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: retypeapp/action-build@latest
with:
Expand Down
15 changes: 15 additions & 0 deletions docs/getting-started/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ To enable support for direct page hits, add the following redirect rule to your
/* /index.html 200
```

For Netlify, it can either be with a `netlify.toml` file at the root of project:

```netlify.toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
```

Or by adding a `_redirects` file into the Netlify publish directory:

```_redirects
/* /index.html 200
```

## Set the remote URL

Configure the remote modules production URL:
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ toc:
- [useRenderedNavigationItems](./routing/useRenderedNavigationItems.md)
- [useRouteMatch](./routing/useRouteMatch.md)
- [useIsRouteProtected](./routing/useIsRouteProtected.md)
- [resolveRouteSegments](./routing/resolveRouteSegments.md)
- [isNavigationLink](./routing/isNavigationLink.md)

### Logging

Expand Down
1 change: 1 addition & 0 deletions docs/reference/routing/ManagedRoutes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
order: 90
toc:
depth: 2-3
---
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/routing/appRouter.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
priority: 100
order: 100
toc:
depth: 2-3
---
Expand Down
33 changes: 33 additions & 0 deletions docs/reference/routing/isNavigationLink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
order: -200
toc:
depth: 2-3
---

# isNavigationLink

Indicate whether or not a navigation item should be rendered as a link. This utility is particularly handy when rendering a menu [with nested items](../runtime/runtime-class.md#register-nested-navigation-items).

## Reference

```ts
const isLink = isNavigationLink(item)
```

### Parameters

- `item`: A navigation item rendering props.

### Returns

A boolean value indicating whether or not the navigation item should be rendered as a link.

## Usage

```ts
import { isNavigationLink, type RenderItemFunction } from "@squide/firefly";

const renderItem: RenderItemFunction = item => {
return isNavigationLink(item) ? renderLinkItem(item) : renderSectionItem(item);
};
```
40 changes: 40 additions & 0 deletions docs/reference/routing/resolveRouteSegments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
order: 60
toc:
depth: 2-3
---

# resolveRouteSegments

Replace a route segments (paths starting with `:`) with the provided values. For a value to be applied to a segment, the value `key` must match the segment minus the `:`.

## Reference

```ts
const resolvedRoute = resolveRouteSegments("/page/:arg1", { arg1: "value-1" })
```

### Parameters

- `to`: A route with segments.
- `values`: An object literal of segment values.

### Returns

The resolved route.

## Usage

```ts
import { resolveRouteSegments, type NavigationLinkRenderProps } from "@squide/firefly";

function renderLinkItem({ label, linkProps: { to, ...linkProps } }: NavigationLinkRenderProps, index: number, level: number) {
return (
<li key={`${level}-${index}`}>
<Link to={resolveRouteSegments(to as string, { arg1: "value-1" })} {...linkProps}>
{label}
</Link>
</li>
);
}
```
94 changes: 93 additions & 1 deletion docs/reference/routing/useRenderedNavigationItems.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
order: 80
toc:
depth: 2-3
---
Expand All @@ -9,7 +10,7 @@ Recursively parse a navigation items structure to transform the items into React

> The `useNavigationItems` hook returns the navigation items tree structure as is, meaning the consumer has to recursively parse the structure to transform the items into actual React Elements.
>
> As it's a non-trivial process, the shell provides this utility hook to help with that.
> As it's a non-trivial process, Squide provides this utility hook.
## Reference

Expand All @@ -29,6 +30,8 @@ An array of `ReactElement`.

## Usage

### Render nested items

```tsx !#38-40,42-48,52 host/src/RootLayout.tsx
import type { ReactNode } from "react";
import { Link, Outlet } from "react-router-dom";
Expand Down Expand Up @@ -91,3 +94,92 @@ export function RootLayout() {
);
}
```

### Render dynamic segments

The `to` property of a navigation item can include dynamic segments (`/user-profile/:userId`), enabling the rendering of dynamic routes based on contextual values. To resolve a route dynamic segments, use the [resolveRouteSegments](resolveRouteSegments.md) function.

```tsx !#14,18,21,39-45,56,59 host/src/UserProfileLayout.tsx
import type { ReactNode } from "react";
import { Link, Outlet } from "react-router-dom";
import {
useNavigationItems,
useRenderedNavigationItems,
isNavigationLink,
resolveRouteSegments
type RenderItemFunction,
type RenderSectionFunction,
type NavigationLinkRenderProps,
type NavigationSectionRenderProps
} from "@squide/react-router";

type RenderLinkItemFunction = (item: NavigationLinkRenderProps, index: number, level: number, userId: string) => ReactNode;

type RenderSectionItemFunction = (item: NavigationSectionRenderProps, index: number, level: number) => ReactNode;

const renderLinkItem: RenderLinkItemFunction = ({ label, { to, ...linkProps}, additionalProps }, index, level, userId) => {
return (
<li key={`${level}-${index}`}>
<Link to={resolveRouteSegments(to as string, { userId })} {...linkProps} {...additionalProps}>
{label}
</Link>
</li>
);
};

const renderSectionItem: RenderSectionItemFunction = ({ label, section }, index, level) => {
return (
<li key={`${level}-${index}`}>
{label}
<div>
({section})
</div>
</li>
);
};

function renderItem(userId: string) {
const fct: RenderItemFunction = (item, index, level) => {
return isNavigationLink(item) ? renderLinkItem(item, index, level, userId) : renderSectionItem(item, index, level);
};

return fct;
}

const renderSection: RenderSectionFunction = (elements, index, level) => {
return (
<ul key={`${level}-${index}`}>
{elements}
</ul>
);
};

export function UserProfileLayout() {
const { userId } = useParams();

const navigationItems = useNavigationItems({ menuId: "/user-profile" });
const navigationElements = useRenderedNavigationItems(navigationItems, renderItem(userId), renderSection);

return (
<>
<nav>{navigationElements}</nav>
<Outlet />
</>
);
}
```

```tsx !#6 remote-module/src/register.tsx
import type { ModuleRegisterFunction, FireflyRuntime } from "@squide/firefly";

export const register: ModuleRegisterFunction<FireflyRuntime> = (runtime) => {
runtime.registerNavigationItem({
$label: "User profile",
to: "/user-profile/:userId"
}, {
menuId: "/user-profile"
});
}
```


1 change: 1 addition & 0 deletions docs/reference/routing/useRouteMatch.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
order: 70
toc:
depth: 2-3
---
Expand Down
13 changes: 12 additions & 1 deletion docs/reference/runtime/runtime-class.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ A Squide navigation item can either be a `NavigationLink` or a `NavigationSectio
- `NavigationSection` accept the following properties:
- `$label`: The section text.
- `$priority`: An order priority affecting the position of the item in the menu (higher first)
- `$addiltionalProps`: Additional properties to be forwarded to the section renderer.
- `$additionalProps`: Additional properties to be forwarded to the section renderer.
- `children`: The section content.
- `NavigationLink` accept any properties of a React Router [Link](https://reactrouter.com/en/main/components/link) component with the addition of:
- `$label`: The link text.
Expand Down Expand Up @@ -339,6 +339,17 @@ runtime.registerNavigationItem({
});
```

### Use dynamic segments

```ts !#3
runtime.registerNavigationItem({
$label: "User profile",
to: "/user-profile/:userId"
});
```

[!ref text="Learn more about rendering navigation items with dynamic segments"](../routing/useRenderedNavigationItems.md#render-dynamic-segments)

### Use a React element as navigation item label

```tsx !#4-7
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@
"update-outdated-deps": "pnpm update -r --latest"
},
"devDependencies": {
"@changesets/changelog-github": "0.4.8",
"@changesets/cli": "2.26.2",
"@typescript-eslint/parser": "6.13.0",
"@workleap/eslint-plugin": "3.0.0",
"@changesets/changelog-github": "0.5.0",
"@changesets/cli": "2.27.1",
"@typescript-eslint/parser": "6.21.0",
"@workleap/eslint-plugin": "3.0.1",
"@workleap/typescript-configs": "3.0.2",
"cross-env": "7.0.3",
"eslint": "8.54.0",
"eslint": "8.56.0",
"jest": "29.7.0",
"netlify-cli": "17.7.0",
"netlify-cli": "17.16.1",
"retypeapp": "3.5.0",
"ts-node": "10.9.1",
"typescript": "5.2.2"
"ts-node": "10.9.2",
"typescript": "5.3.3"
},
"engines": {
"node": ">=18.0.0"
Expand Down
24 changes: 12 additions & 12 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@
"react-dom": "*"
},
"devDependencies": {
"@swc/core": "1.3.99",
"@swc/helpers": "0.5.3",
"@swc/jest": "0.2.29",
"@testing-library/react": "14.1.2",
"@types/jest": "29.5.10",
"@types/react": "18.2.39",
"@types/react-dom": "18.2.17",
"@workleap/eslint-plugin": "3.0.0",
"@workleap/swc-configs": "2.1.2",
"@workleap/tsup-configs": "3.0.1",
"@swc/core": "1.4.0",
"@swc/helpers": "0.5.6",
"@swc/jest": "0.2.36",
"@testing-library/react": "14.2.1",
"@types/jest": "29.5.12",
"@types/react": "18.2.55",
"@types/react-dom": "18.2.19",
"@workleap/eslint-plugin": "3.0.1",
"@workleap/swc-configs": "2.2.1",
"@workleap/tsup-configs": "3.0.2",
"@workleap/typescript-configs": "3.0.2",
"jest": "29.7.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"ts-jest": "29.1.1",
"ts-jest": "29.1.2",
"tsup": "8.0.1",
"typescript": "5.2.2"
"typescript": "5.3.3"
},
"dependencies": {
"eventemitter3": "5.0.1"
Expand Down
8 changes: 4 additions & 4 deletions packages/fakes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
"build": "tsup --config ./tsup.build.ts"
},
"devDependencies": {
"@types/jest": "29.5.10",
"@workleap/eslint-plugin": "3.0.0",
"@workleap/tsup-configs": "3.0.1",
"@types/jest": "29.5.12",
"@workleap/eslint-plugin": "3.0.1",
"@workleap/tsup-configs": "3.0.2",
"@workleap/typescript-configs": "3.0.2",
"jest": "29.7.0",
"tsup": "8.0.1",
"typescript": "5.2.2"
"typescript": "5.3.3"
},
"dependencies": {
"@squide/core": "workspace:*"
Expand Down
Loading

0 comments on commit a448347

Please sign in to comment.