Skip to content

Commit

Permalink
feat(router): refactor interface to allow imports and track parameters
Browse files Browse the repository at this point in the history
release-npm

BREAKING CHANGE: Interface retains same features but has been overhauled and needs migration, see updated documentation.
  • Loading branch information
tobua committed Aug 11, 2024
1 parent 6038d26 commit 7c0bfec
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 290 deletions.
97 changes: 47 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,32 @@ Router for the Web.
## Installation

```sh
npm install epic-router
bun install epic-router
# Install a JSX rendering framework.
npm install preact
bun install epic-jsx / bun install preact
```

## Usage

```jsx
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Router, Page } from 'epic-router'
import { Page, addPage, back, configure, go, forward } from 'epic-router'
import { connect } from 'epic-state/connect'
import { render } from 'epic-jsx'

const { router } = configure<{ id: number }>('overview', undefined, undefined, connect)

// Declare some components used as pages.
const Overview = () => <p>Overview</p>
const About = () => <p>About</p>
const Article = ({ id }: { id: string }) => <p>Article: {id}</p>

// Configure available and initial pages before rendering.
Router.setPages(
{
overview: Overview,
'nested/about': About,
article: Article,
// Custom 404 page for missing routes.
404: Custom404
},
'overview' // Initial page.
)
const Article = () => <p>Article: {router.parameters.id}</p>

createRoot(document.body).render(
addPage('overview', Overview)
addPage('nested/about', About)
addPage('article', Article)
// Custom 404 page for missing routes.
addPage('404', () => <p>Not found!</p>)

render(
<div>
<button onClick={() => Router.go('nested/about')}>About</button>
<button onClick={() => Router.go('article', { id: 2 })}>Article 2</button>
Expand All @@ -66,36 +62,23 @@ Use the `<Page />` component anywhere in your layout to display the current page

## Router

```js
import { Router } from 'epic-router'
```

The `Router`-Store can be accessed from anywhere to access, configure and modify the state of the Router.

```ts
Router.setPages(pages: { [key: string]: React.ReactNode }, initialRoute: string)
import { configure, addPage, go, back, forward, initial } from 'epic-router'

// Setup and configure the Router.
const { router } = configure(initialRoute?: string, homeRoute?: string, initialParameters?: Parameters, connect?: typeof preactConnect)
// Register a page for a route.
addPage(route: string | number, component: JSX | ReactNode)
// Navigates to a route. Parameters will be added to the URL search query and together with the state (both optional) will be passed to the page component as props. If replace is true, `back()` will not lead to the previous page.
go(route: string, parameters: object = {}, state: object = {}, replace = false)
// go back one step in the history.
back()
// Go forward one step in the history.
forward()
// Go to the initial route.
initial()
```

Configure the route keys and their associated components, plus the route to be displayed initially.

```ts
Router.go(route: string, parameters: object = {}, state: object = {}, replace = false)
```

Navigates to a route. Parameters will be added to the URL search query and together with the state (both optional) will be passed to the page component as props. If replace is true, `back()` will not lead to the previous page.

`Router.back()` go back one step in the history.

`Router.forward()` go forward one step.

`Router.initial()` go to the initial route.

```ts
addPage(route: string, component: React.ReactNode)
```

Add a single page after initialization. This can be useful when pages are loaded on request.

```ts
// Currently active route.
Router.route => string
Expand All @@ -114,13 +97,27 @@ Router.history => History
The `404` page can be set to show a custom error page when a route is not found.

```tsx
import { Router } from 'epic-router'
import { addPage } from 'epic-router'

const Custom404 = () => <p>Page Not Found!</p>

Router.setPages({
404: Custom404,
})
addPage(404: Custom404)
```

### Parameters

Parameters will automatically be added to the URL and are accessible in different ways as shown below.

```tsx
import { configure, getRouter, type WithRouter } from 'epic-router'

type Parameters = { id: number }

const { router } = configure<Parameters>(...)

const Article = () => <p>Article: {router.parameters.id}</p>
const ArticleGlobal = () => <p>Article: {getRouter().parameters.id}</p>
const ArticleProps = ({ router }: WithRouter<Parameters>) => <p>Article: {router.parameters.id}</p>
```

## Notes
Expand Down
3 changes: 3 additions & 0 deletions demo/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const rsbuild = defineConfig({
entry: {
index: './index.tsx',
},
define: {
'process.env.PUBLIC_URL': '"/"',
},
},
html: {
title: 'epic-router Demo with epic-jsx',
Expand Down
25 changes: 12 additions & 13 deletions demo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { Page, back, create, forward, go } from 'epic-router'
import { Page, addPage, back, configure, go, forward } from 'epic-router'
import { connect } from 'epic-state/connect'
import { Exmpl } from 'exmpl'
import { render } from 'epic-jsx'

// TODO not working with globally registered plugin.
// plugin(connect)

const { router } = configure<{ id: number }>('overview', undefined, undefined, connect)

const Overview = () => <span>Overview</span>
const About = () => <span>About</span>
const Article = ({ id }: { id: string }) => <span>Article: {id}</span>
const Article = () => <span>Article: {router.parameters.id}</span>
const Nested = () => <span>Nested</span>
const Custom404 = () => <span>Page not found!</span>

create(
{
overview: Overview,
about: About,
article: Article,
'nested/overview': Nested,
404: Custom404,
},
'overview',
connect,
)
addPage('overview', Overview)
addPage('about', About)
addPage('article', Article)
addPage('nested/overview', Nested)
addPage('404', Custom404)

const Button = ({ text, onClick }) => (
<button
Expand Down
4 changes: 2 additions & 2 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"types": "tsc"
},
"dependencies": {
"@rsbuild/core": "^1.0.1-beta.10",
"@rsbuild/plugin-react": "^1.0.1-beta.10",
"@rsbuild/core": "^1.0.1-beta.11",
"@rsbuild/plugin-react": "^1.0.1-beta.11",
"epic-jsx": "^0.9.0",
"epic-state": "^0.8.2",
"exmpl": "^3.1.0",
Expand Down
22 changes: 9 additions & 13 deletions demo/preact/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { Page, back, create, forward, go } from 'epic-router'
import { Page, addPage, back, configure, go, forward } from 'epic-router'
import { connect } from 'epic-state/preact'
import { Exmpl } from 'exmpl'
import { render } from 'preact'

const { router } = configure<{ id: number }>('overview', undefined, undefined, connect)

const Overview = () => <span>Overview</span>
const About = () => <span>About</span>
const Article = ({ id }: { id: string }) => <span>Article: {id}</span>
const Article = () => <span>Article: {router.parameters.id}</span>
const Nested = () => <span>Nested</span>
const Custom404 = () => <span>Page not found!</span>

create(
{
overview: Overview,
about: About,
article: Article,
'nested/overview': Nested,
404: Custom404,
},
'overview',
connect,
)
addPage('overview', Overview)
addPage('about', About)
addPage('article', Article)
addPage('nested/overview', Nested)
addPage('404', Custom404)

const Button = ({ text, onClick }) => (
<button
Expand Down
4 changes: 2 additions & 2 deletions demo/preact/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"types": "tsc"
},
"dependencies": {
"@rsbuild/core": "^1.0.1-beta.10",
"@rsbuild/plugin-react": "^1.0.1-beta.10",
"@rsbuild/core": "^1.0.1-beta.11",
"@rsbuild/plugin-react": "^1.0.1-beta.11",
"epic-state": "^0.8.2",
"exmpl": "^3.1.0",
"preact": "^10.23.1",
Expand Down
Loading

0 comments on commit 7c0bfec

Please sign in to comment.