From 7c0bfecc6f573a918e9cf8a0e44c504dae458bef Mon Sep 17 00:00:00 2001 From: Matthias Giger Date: Sun, 11 Aug 2024 10:26:34 +0200 Subject: [PATCH] feat(router): refactor interface to allow imports and track parameters release-npm BREAKING CHANGE: Interface retains same features but has been overhauled and needs migration, see updated documentation. --- README.md | 97 ++++++++++----------- demo/configuration.ts | 3 + demo/index.tsx | 25 +++--- demo/package.json | 4 +- demo/preact/index.tsx | 22 ++--- demo/preact/package.json | 4 +- index.tsx | 138 ++++++++++++++++++----------- test/epic/router.test.tsx | 148 ++++++++++++++++--------------- test/preact/router.test.tsx | 169 ++++++++++++++++++------------------ types.ts | 10 ++- 10 files changed, 330 insertions(+), 290 deletions(-) diff --git a/README.md b/README.md index eb3bd03..e26e455 100644 --- a/README.md +++ b/README.md @@ -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 = () =>

Overview

const About = () =>

About

-const Article = ({ id }: { id: string }) =>

Article: {id}

- -// 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 = () =>

Article: {router.parameters.id}

-createRoot(document.body).render( +addPage('overview', Overview) +addPage('nested/about', About) +addPage('article', Article) +// Custom 404 page for missing routes. +addPage('404', () =>

Not found!

) + +render(
@@ -66,36 +62,23 @@ Use the `` 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 @@ -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 = () =>

Page Not Found!

-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(...) + +const Article = () =>

Article: {router.parameters.id}

+const ArticleGlobal = () =>

Article: {getRouter().parameters.id}

+const ArticleProps = ({ router }: WithRouter) =>

Article: {router.parameters.id}

``` ## Notes diff --git a/demo/configuration.ts b/demo/configuration.ts index 06e3833..32d24d8 100644 --- a/demo/configuration.ts +++ b/demo/configuration.ts @@ -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', diff --git a/demo/index.tsx b/demo/index.tsx index 51f6d0b..bea53b6 100644 --- a/demo/index.tsx +++ b/demo/index.tsx @@ -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 = () => Overview const About = () => About -const Article = ({ id }: { id: string }) => Article: {id} +const Article = () => Article: {router.parameters.id} const Nested = () => Nested const Custom404 = () => Page not found! -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 }) => (