UNPKG

native-spa-route

Version:

provide SPA route's experience with native web component

378 lines (341 loc) 14.9 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="favicon.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Native SPA Route Demo</title> <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css" /> --> <!-- <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/shoelace.js"></script> --> </head> <body class="sl-theme-light"> <script type="module" async> import { preload } from /*IMPORTSOURCESTART*/'/src/main.ts'/*IMPORTSOURCEEND*/; preload(); </script> <style> :root { --font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; --font-family-mono: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } * { box-sizing: border-box; } body { margin: 0; padding: 5px; min-width: 100vw; min-height: 100vh; line-height: 1.4; font-family: var(--font-family-base); font-size: 16px; font-weight: 400; direction: ltr; font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { background-color: #61dafb; } native-route { visibility: hidden; } native-route:defined { /* display: block; */ visibility: visible; } native-route-container { visibility: hidden; } native-route-container:defined { visibility: visible; } .route-content { border: 1px solid #d5d5d5; border-radius: 3px; box-shadow: 0 0 5px 0px #d5d5d5d9; margin: 15px; min-height: 100px; } </style> <main> <p> provide SPA route's experience with native web component <div> <a href="https://github.com/Yiniau/native-spa-route">Github Repo</a> </div> </p> <p>NOTICE! this demo use `<code>:defined</code>` pseudo-class to avoid undefined element's inner content leak</p> <p>BTW. you can use `<code>disable-shadow</code>` to disable shadowDOM</p> <ul> <li><a href="/common">common</a></li> <li><a href="/root">nest path: root</a></li> <li><a href="/root/all">nest path: root/all</a></li> <div style="height: 16px"></div> <li> <a href="/cache-and-drop">cache and drop</a> </li> <native-route path="/cache-and-drop"> <ul> <li> <a href="/cache-and-drop/cache/input1">cache input 1</a> </li> <li> <a href="/cache-and-drop/cache/input2">cache input 2</a> </li> <li> <a href="/cache-and-drop/drop/input1">drop input 1 (will drop input value after switch route)</a> </li> <li> <a href="/cache-and-drop/drop/input2">drop input 2 (will drop input value after switch route)</a> </li> </ul> </native-route> <div style="height: 16px"></div> <li> <a href="/lazy">lazy demo</a> <native-route path="/lazy"> <ul> <li> <a href="/lazy/sl/button">@shoelace-style/shoelace Button</a> </li> <li> <a href="/lazy/sl/ready_button" >render shoelace Button after module ready, disable cache to get clear effect</a > </li> </ul> </native-route> </li> <div style="height: 16px"></div> <li> <a href="/custom-render" >custom render demo, this could be use to render react/vue/other render lib content<br/> <strong>If you are in a local environment, you need to additionally run the <code>pnpm run dev:demo</code> command</strong> </a> <native-route path="/custom-render"> <ul> <li> <a href="/custom-render/react/17/basic">react 17 demo</a> </li> <li> <a href="/custom-render/react/17/custom-render-name">react 17 custom render name</a> </li> <li> <a href="/custom-render/react/17/with-css">react 17 with css</a> </li> <li> <a href="/custom-render/vue/3/basic">vue 3 demo (enable drop)</a> </li> </ul> </native-route> </li> <div style="height: 16px"></div> <li> <a href="/append-direction/before">append before</a> </li> <li> <a href="/append-direction/after">append after</a> </li> <div style="height: 16px"></div> <li><a href="/loading">loading status</a></li> </ul> <h3>common demo area</h3> <div class="route-content"> <native-route path="/common" element="common"></native-route> <!-- basic useage --> <native-route path="/"> <!-- exact case, only active while pathname full match /root --> <native-route path="root" exact element="exact /root path route here" ></native-route> <native-route path="root" element="<div>ROOT HERE</div>"> <native-route path="all" element="<div>ALL HERE</div>"> </native-route> </native-route> </native-route> <native-route path="/cache-and-drop"> <native-route path="cache"> <native-route path="input1" element="<input>"></native-route> <native-route path="input2" element="<input>"></native-route> </native-route> <native-route path="drop"> <native-route path="input1" drop element="<input>"></native-route> <native-route path="input2" drop element="<input>"></native-route> </native-route> </native-route> <!-- lazy useage --> <native-route path="/lazy/sl"> <native-route path="button" url="//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/components/button/button.js" css-url='["https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css"]' element='<sl-button>Button</sl-button><sl-button variant="primary">Primary</sl-button><sl-button variant="neutral" loading>Neutral</sl-button>' lazy > </native-route> <native-route path="ready_button" url="//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/components/button/button.js" css-url='["//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css"]' element='<sl-button>Render After Ready Button</sl-button><sl-button variant="primary">Primary</sl-button><sl-button variant="neutral" loading>Neutral</sl-button>' render-after-ready lazy > </native-route> </native-route> <!-- custom render useage --> <native-route path="/custom-render"> <native-route path="react"> <native-route path="17/basic" lazy url="@PUBLICK_PATH/react17.js" custom-render></native-route> <native-route path="17/custom-render-name" lazy url="@PUBLICK_PATH/react17.js" custom-render="customRenderFunction"></native-route> <native-route path="17/with-css" lazy url="@PUBLICK_PATH/react17.js" custom-render="withCss" shadowCSSUrl="@PUBLICK_PATH/react17.css"></native-route> </native-route> <native-route path="vue"> <native-route drop path="3/basic" lazy url="@PUBLICK_PATH/vue3.js" shadowCSSUrl="@PUBLICK_PATH/vue3.css" custom-render></native-route> </native-route> </native-route> <!-- append direction --> <native-route path="/append-direction"> <native-route path="before" element="<strong>CENTER</strong>" append-direction="before"> <div slot>child before after</div> </native-route> <native-route path="after" element="<strong>CENTER</strong>"> <div slot>child append after</div> </native-route> </native-route> <native-route path="/loading" lazy url="//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/components/button/button.js" css-url="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css" render-after-ready loadingElement="<span>will show loading... 50000ms</span>" lockLoadingTime="50000" ></native-route> </div> <h3>common route container demo area</h3> <ul> <li><a href="/route-container">container (virtualNode, this route's active status will be ignored by container)</a></li> <li><a href="/route-container/not-match-any-route-asd123t9q3gjh34g1">unvalid route</a></li> <li><a href="/route-container/not-404">valid route</a></li> </ul> <div class="route-content"> <native-route-container root-path="/route-container"> <div slot="404" style="width: 100px; height: 50px; display: flex; align-items: center; justify-content: space-around;"> <strong>404</strong> </div> <div> <native-route path="/route-container" lazy url="//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/components/button/button.js" css-url="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css" render-after-ready loadingElement="<span>will show loading as last 96ms</span>" lockLoadingTime="96" element="<div><code>route container demo</code></div>" virtualNode > <native-route path="not-match-path_1jj41gn5og159" element="not match route, this content should not appear"></native-route> <native-route path="not-404" element="common content here"></native-route> </native-route> </div> </native-route-container> </div> <h3>no shadow dom route container demo area</h3> <ul> <li><a href="/light-dom-route-container">container</a></li> <li><a href="/light-dom-route-container/light-dom-not-match-any-route-asd123t9q3gjh34g1">unvalid route</a></li> <li><a href="/light-dom-route-container/not-404">valid route</a></li> </ul> <div class="route-content"> <native-route-container root-path="/light-dom-route-container" disableShadow> <native-route path="/light-dom-route-container" lazy url="//cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/components/button/button.js" css-url="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.83/dist/themes/light.css" render-after-ready loadingElement="<span>will show loading as last 96ms</span>" lockLoadingTime="96" element="<div><code>no shadow dom route container demo<br/>this line always visiable while location.href starts with `/light-dom-route-container`</code></div>" virtualNode > <native-route path="not-match-path_1jj41gn5og159" element="not match route, this content should not appear"></native-route> <native-route path="not-404" element="<span>common content here</span>"></native-route> </native-route> </native-route-container> </div> <h3>dynamic route path</h3> <ul> <li><a href="/dynamic-route">dynamic route</a></li> <li><a href="/dynamic-route/matched_1">matched value 1</a></li> <li><a href="/dynamic-route/matched_2">matched value 2</a></li> <li><a href="/dynamic-route/matched_3">matched value 3</a></li> <li><a href="/dynamic-route/matched_4">matched value 4</a></li> <li><a href="/dynamic-route/not-matched">not matched</a></li> </ul> <div class="route-content"> <native-route-container disableShadow root-path="/dynamic-route" element="<div><code>dynamic route</code></div>" > <native-route path="/dynamic-route"> <native-route path=":matched_[0-9]" element="matched"></native-route> <native-route path=":DEFAULT" element="not match"></native-route> </native-route> </native-route-container> </div> <h3>group route match mode</h3> <p> <section>group match mode will split path to <code style="background-color: #9e9e9e25; border-radius: 4px;">['before self route', 'self route', 'after self route']</code></section> <section> common match mode will split path to <code style="background-color: #9e9e9e25; border-radius: 4px;"> fullpath.split('/') </code> </section> </p> <ul> <li><a href="/group-match-route">group-match-route</a></li> <li><a href="/group-match-route/matched_1">matched value 1</a></li> <li><a href="/group-match-route/nest/route">nest route</a></li> <li><a href="/group-match-route/not-matched">not matched</a></li> </ul> <div class="route-content"> <native-route-container root-path="/group-match-route" disableShadow> <native-route path="/group-match-route" element="<div><code>group match mode</code></div>"> <native-route path="matched_1" element="matched value 1" groupMatchMode></native-route> <native-route path=":(?:^$)|(?:nest)|(?:nest/route)" element="nest route" groupMatchMode></native-route> <native-route path=":DEFAULT" element="not match" groupMatchMode></native-route>></native-route> </native-route> </native-route-container> </div> </main> <script type="module"> document.querySelectorAll('native-route-container').forEach(t => { console.log(t); t.set404Content(/* html */` <div style="width: 100px; height: 50px; display: flex; align-items: center; justify-content: space-around;"> <strong>404</strong> </div> `); }) history.pushState(history.state, '', location.pathname); </script> </body> </html>