mirror of
https://github.com/danbulant/nollup-apexcharts-bug
synced 2026-07-04 10:30:55 +00:00
initial commit
This commit is contained in:
commit
73f8c00f95
96 changed files with 18419 additions and 0 deletions
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
**/node_modules/
|
||||
/dist/
|
||||
.DS_Store
|
||||
**/.history
|
||||
src/tmp/
|
||||
.routify
|
||||
.netlify
|
||||
assets/build
|
||||
.vercel
|
||||
7
.nolluprc.js
Normal file
7
.nolluprc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
hot: true,
|
||||
contentBase: 'assets',
|
||||
publicPath: 'build',
|
||||
historyApiFallback: '__app.html',
|
||||
port: 5000
|
||||
}
|
||||
73
README.md
Normal file
73
README.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
### Oh hai! ❤
|
||||
We've created a new project called [**stackmix**](https://github.com/roxiness/stackmix). It's an experimental CLI that let's you customize new Routify templates. Go check it out!
|
||||
|
||||
---
|
||||
|
||||
|
||||
# routify-starter
|
||||
|
||||
Starter template for [Routify](https://github.com/roxiness/routify).
|
||||
|
||||
### Get started
|
||||
|
||||
#### Starter templates
|
||||
| Template | Description |
|
||||
|-------------------------------------------|-------------------------------------------------------------|
|
||||
| [master](https://example.routify.dev/) | Default template, includes examples folder |
|
||||
| [blog](https://blog-example.routify.dev/) | Generates a blog from local markdown posts. Includes mdsvex |
|
||||
| [auth](https://auth-example.routify.dev/) | Embedded login on protected pages. Includes Auth0 |
|
||||
|
||||
To use a template, run:
|
||||
|
||||
`npx @roxi/routify init`
|
||||
|
||||
or
|
||||
|
||||
`npx @roxi/routify init --branch <branch-name>`
|
||||
|
||||
The above commands will populate the current directory, they don't create a new one.
|
||||
|
||||
### npm scripts
|
||||
|
||||
| Syntax | Description |
|
||||
|------------------|-----------------------------------------------------------------------------------|
|
||||
| `dev` | Development (port 5000) |
|
||||
| `dev:nollup` | Development with crazy fast rebuilds (port 5000) |
|
||||
| `dev-dynamic` | Development with dynamic imports |
|
||||
| `build` | Build a bundled app with SSR + prerendering and dynamic imports |
|
||||
| `serve` | Run after a build to preview. Serves SPA on 5000 and SSR on 5005 |
|
||||
| `deploy:*` | Deploy to netlify or now |
|
||||
| `export` | Create static pages from content in dist folder (used by `npm run build`) |
|
||||
|
||||
### SSR and pre-rendering
|
||||
|
||||
SSR and pre-rendering are included in the default build process.
|
||||
|
||||
`npm run deploy:(now|netlify)` will deploy the app with SSR and prerendering included.
|
||||
|
||||
To render async data, call the `$ready()` helper whenever your data is ready.
|
||||
|
||||
If $ready() is present, rendering will be delayed till the function has been called.
|
||||
|
||||
Otherwise it will be rendered instantly.
|
||||
|
||||
See [src/pages/example/api/[showId].svelte](https://github.com/roxiness/routify-starter/blob/master/src/pages/example/api/%5BshowId%5D.svelte) for an example.
|
||||
|
||||
### Production
|
||||
|
||||
* For SPA or SSR apps please make sure that url rewrite is enabled on the server.
|
||||
* For SPA redirect to `__app.html`.
|
||||
* For SSR redirect to the lambda function or express server.
|
||||
|
||||
### Typescript
|
||||
|
||||
For Typescript, we recommend [@lamualfa](https://github.com/lamualfa) excellent [routify-ts](https://github.com/lamualfa/routify-ts/)
|
||||
|
||||
New project: `npx routify-ts init <project-name> [routify-init-args]`
|
||||
|
||||
Existing project: `npx routify-ts convert [project-directory]`
|
||||
|
||||
|
||||
### Issues?
|
||||
|
||||
File on Github! See https://github.com/sveltech/routify/issues .
|
||||
16
api/netlify/package.json
Normal file
16
api/netlify/package.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "ssr",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "ssr.js",
|
||||
"scripts": {
|
||||
"build": "node utils/build.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.8.8",
|
||||
"tossr": "^1.3.1"
|
||||
}
|
||||
}
|
||||
11
api/netlify/ssr.js
Normal file
11
api/netlify/ssr.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
const fs = require('fs')
|
||||
const { tossr } = require('tossr')
|
||||
const { script, template } = require('./bundle.json')
|
||||
|
||||
exports.handler = async (event, context) => {
|
||||
const qs = Object.entries(event.queryStringParameters)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('&');
|
||||
const body = await tossr(template, script, `${event.path}?${qs}`);
|
||||
return { statusCode: 200, body: body + '\n<!--ssr rendered-->' }
|
||||
}
|
||||
26
api/netlify/utils/build.js
Normal file
26
api/netlify/utils/build.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Creates a JSON and inlines it with esbuild for ssr.js to consume
|
||||
* {
|
||||
* data: duh,
|
||||
* script: inlined main.js
|
||||
* template: __app.html
|
||||
* }
|
||||
*/
|
||||
|
||||
const { resolve } = require('path')
|
||||
const { readFileSync, writeFileSync } = require('fs')
|
||||
const { build } = require('esbuild')
|
||||
|
||||
const scriptPath = resolve(__dirname, '../../../dist/build/main.js')
|
||||
const templatePath = resolve(__dirname, '../../../dist/__app.html')
|
||||
const bundlePath = resolve(__dirname, '../build/bundle.js')
|
||||
|
||||
build({ entryPoints: [scriptPath], outfile: bundlePath, bundle: true }).then(() => {
|
||||
const bundle = {
|
||||
date: new Date,
|
||||
script: readFileSync(bundlePath, 'utf8'),
|
||||
template: readFileSync(templatePath, 'utf8')
|
||||
}
|
||||
|
||||
writeFileSync(resolve(__dirname, '../bundle.json'), JSON.stringify(bundle, null, 2))
|
||||
})
|
||||
36
api/vercel-ssr/build.js
Normal file
36
api/vercel-ssr/build.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
const { resolve } = require('path')
|
||||
const { existsSync } = require('fs')
|
||||
const { execSync } = require('child_process')
|
||||
const { rollup } = require('rollup')
|
||||
|
||||
const shouldBuildSpa = process.env.NOW_GITHUB_DEPLOYMENT || process.env.NOW_BUILDER
|
||||
const script = resolve(__dirname, '../../dist/build/main.js')
|
||||
const bundlePath = resolve(__dirname, '../../dist/build/bundle.js')
|
||||
|
||||
build()
|
||||
|
||||
|
||||
async function build() {
|
||||
if (shouldBuildSpa)
|
||||
execSync('npm install && npm run build:app', { cwd: resolve('..', '..'), stdio: 'inherit' })
|
||||
else
|
||||
await waitForAppToExist()
|
||||
|
||||
buildSSRBundle()
|
||||
}
|
||||
|
||||
async function waitForAppToExist() {
|
||||
while (!existsSync(script)) {
|
||||
console.log(`checking if "${script}" exists`)
|
||||
await new Promise(r => setTimeout(r, 2000))
|
||||
}
|
||||
console.log(`found "${script}"`)
|
||||
}
|
||||
|
||||
async function buildSSRBundle() {
|
||||
const bundle = await rollup({
|
||||
input: script,
|
||||
inlineDynamicImports: true,
|
||||
})
|
||||
await bundle.write({ format: 'umd', file: bundlePath, name: 'roxi-ssr' })
|
||||
}
|
||||
11
api/vercel-ssr/index.js
Normal file
11
api/vercel-ssr/index.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
const fs = require('fs')
|
||||
const { tossr } = require('tossr')
|
||||
|
||||
const script = fs.readFileSync(require.resolve('../../dist/build/bundle.js'), 'utf8')
|
||||
const template = fs.readFileSync(require.resolve('../../dist/__app.html'), 'utf8')
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const html = await tossr(template, script, req.url, {})
|
||||
res.send(html + '\n<!--ssr rendered-->')
|
||||
}
|
||||
|
||||
8
api/vercel-ssr/package.json
Normal file
8
api/vercel-ssr/package.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"scripts": {
|
||||
"vercel-build": "node ./build.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^2.28.2"
|
||||
}
|
||||
}
|
||||
1
assets/404.svg
Normal file
1
assets/404.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><linearGradient id="a" x1="2.625" x2="25.637" y1="13.491" y2="13.491" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><path fill="url(#a)" d="M10.5 15.5H12v.5c0 .3.2.5.5.5s.5-.2.5-.5v-.5h.5c.3 0 .5-.2.5-.5s-.2-.5-.5-.5H13V13c0-.3-.2-.5-.5-.5s-.5.2-.5.5v1.5h-.9l.6-3.4c.1-.3-.1-.5-.4-.6-.3-.1-.5.1-.6.4l-.8 4c0 .1 0 .3.1.4s.4.2.5.2z"/><linearGradient id="b" x1="2.625" x2="25.637" y1="13.491" y2="13.491" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><path fill="url(#b)" d="M20.5 15.5H22v.5c0 .3.2.5.5.5s.5-.2.5-.5v-.5h.5c.3 0 .5-.2.5-.5s-.2-.5-.5-.5H23V13c0-.3-.2-.5-.5-.5s-.5.2-.5.5v1.5h-.9l.6-3.4c.1-.3-.1-.5-.4-.6-.3-.1-.5.1-.6.4l-.8 4c0 .1 0 .3.1.4s.4.2.5.2z"/><linearGradient id="c" x1="2.625" x2="25.637" y1="22" y2="22" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><path fill="url(#c)" d="M6.5 21.5h-.6c-.1-.3-.2-.6-.4-.9l.5-.4c.2-.2.2-.5 0-.7s-.5-.2-.7 0l-.4.4c-.3-.2-.6-.3-.9-.4V19c0-.3-.2-.5-.5-.5s-.5.2-.5.5v.6c-.3.1-.6.2-.9.4l-.4-.4c-.2-.2-.5-.2-.7 0s-.2.4 0 .6l.4.4c-.2.3-.3.6-.4.9H.5c-.3 0-.5.2-.5.5s.2.5.5.5h.6c.1.3.2.6.4.9l-.5.4c-.2.2-.2.5 0 .7.1.1.2.1.4.1s.3 0 .4-.1l.4-.4c.3.2.6.3.9.4v.5c0 .3.2.5.5.5s.4-.2.4-.5v-.6c.3-.1.6-.2.9-.4l.4.4c.1.1.2.1.4.1s.3 0 .4-.1c.2-.2.2-.5 0-.7l-.4-.4c.2-.3.3-.6.4-.9h.6c.1.1.3-.1.3-.4s-.2-.5-.5-.5zm-3 2c-.8 0-1.5-.7-1.5-1.5 0-.4.2-.8.4-1.1.3-.3.7-.4 1.1-.4.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5z"/><linearGradient id="d" x1="2.625" x2="25.637" y1="22" y2="22" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><circle cx="3.5" cy="22" r=".5" fill="url(#d)"/><linearGradient id="e" x1="2.625" x2="25.637" y1="16" y2="16" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><path fill="url(#e)" d="M31.5 12h-.8l.6-.6c.2-.2.2-.5 0-.7l-1.4-1.4c-.2-.2-.5-.2-.7 0l-.6.6V9c0-.3-.2-.5-.5-.5h-1V8c0-.8-.7-1.5-1.5-1.5h-17C7.7 6.5 7 7.2 7 8v5.6c-.3.1-.6.2-.9.4l-.4-.4c-.2-.2-.5-.2-.7 0s-.2.4 0 .6l.4.4c-.2.3-.3.6-.4.9h-.5c-.3 0-.5.2-.5.5s.2.5.5.5h.6c.1.3.2.6.4.9l-.5.4c-.2.2-.2.5 0 .7.1.1.2.1.4.1s.3 0 .4-.1l.4-.4c.3.2.6.3.9.4V20c0 .8.7 1.5 1.5 1.5H14v3h-3.5c-.3 0-.5.2-.5.5s.2.5.5.5h13c.3 0 .5-.2.5-.5s-.2-.5-.5-.5H20v-3h5.5c.8 0 1.5-.7 1.5-1.5v-1.5h1c.3 0 .5-.2.5-.5v-.8l.6.6c.2.2.5.2.7 0l1.4-1.4c.2-.2.2-.5 0-.7l-.5-.7h.8c.3 0 .5-.2.5-.5v-2c0-.3-.2-.5-.5-.5zm-4.5.5c.6 0 1 .4 1 1s-.4 1-1 1v-2zm-18.5-5h17c.3 0 .5.2.5.5v9.5H8V8c0-.3.2-.5.5-.5zM7 17.4c-.6-.2-1-.8-1-1.4 0-.4.2-.8.4-1.1.2-.2.4-.3.6-.3v2.8zm12 7.1h-4v-3h4v3zm6.5-4h-17c-.3 0-.5-.2-.5-.5v-1.5h18V20c0 .3-.2.5-.5.5zM31 14h-.7c-.2 0-.4.1-.5.4-.1.2-.1.4-.2.6-.1.2-.1.4.1.6l.5.5-.7.7-.5-.6c-.2-.2-.4-.2-.6-.1-.2.1-.4.2-.6.2-.2.1-.3.3-.3.5v.7H27v-2c1.1 0 2-.9 2-2s-.9-2-2-2v-2h.5v.7c0 .2.1.4.3.5.2.1.4.1.6.2.2.1.4.1.6-.1l.5-.5.7.7-.5.5c-.2.2-.2.4-.1.6.1.2.2.4.2.6.1.2.3.4.5.4h.7v.9z"/><linearGradient id="f" x1="2.625" x2="25.637" y1="13.5" y2="13.5" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2B2E81"/><stop offset="1" stop-color="#BE4F9C"/></linearGradient><path fill="url(#f)" d="M16.5 16.5h1c.8 0 1.5-.7 1.5-1.5v-3c0-.8-.7-1.5-1.5-1.5h-1c-.8 0-1.5.7-1.5 1.5v3c0 .8.7 1.5 1.5 1.5zM16 12c0-.3.2-.5.5-.5h1c.3 0 .5.2.5.5v3c0 .3-.2.5-.5.5h-1c-.3 0-.5-.2-.5-.5v-3z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
22
assets/__app.html
Normal file
22
assets/__app.html
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||
|
||||
<title>Svelte app</title>
|
||||
|
||||
<meta name="theme-color" content="#E938C2">
|
||||
<link rel="apple-touch-icon" href="/images/touch-icons/logo-192.png">
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel='icon' type='image/png' href='/favicon.png'>
|
||||
<link rel="modulepreload" href="/build/main.js" />
|
||||
|
||||
<script type="module" src="/build/main.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>Please enable Javascript for best experience.</noscript>
|
||||
</body>
|
||||
</html>
|
||||
BIN
assets/favicon.ico
Normal file
BIN
assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
assets/favicon.png
Normal file
BIN
assets/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
66
assets/global.css
Normal file
66
assets/global.css
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
html, body {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(0,100,200);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: rgb(0,80,160);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input, button, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.4em;
|
||||
margin: 0 0 0.5em 0;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
input:disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
color: #333;
|
||||
background-color: #f4f4f4;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
button:not(:disabled):active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
border-color: #666;
|
||||
}
|
||||
BIN
assets/images/touch-icons/logo-192.png
Normal file
BIN
assets/images/touch-icons/logo-192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/images/touch-icons/logo-800.png
Normal file
BIN
assets/images/touch-icons/logo-800.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
21
assets/manifest.json
Normal file
21
assets/manifest.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#E938C2",
|
||||
"name": "Routify app",
|
||||
"short_name": "Routify app",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/touch-icons/logo-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/images/touch-icons/logo-800.png",
|
||||
"sizes": "800x800",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable any"
|
||||
}
|
||||
]
|
||||
}
|
||||
2
assets/robots.txt
Normal file
2
assets/robots.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
23
netlify.toml
Normal file
23
netlify.toml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
[build]
|
||||
publish = "dist"
|
||||
functions = "api/netlify"
|
||||
command = "npm run build && cd api/netlify && npm run build"
|
||||
|
||||
# Dev doesn't work yet. Any takers?
|
||||
# [dev]
|
||||
# command = "npm run dev:ssr"
|
||||
# targetPort = 5000
|
||||
# publish = "assets"
|
||||
# autoLaunch = true
|
||||
|
||||
[[redirects]]
|
||||
# SSR and SPA
|
||||
from = "/*"
|
||||
to = "/.netlify/functions/ssr"
|
||||
status = 200
|
||||
|
||||
# SPA only
|
||||
# from = "/*"
|
||||
# to = "/__app.html"
|
||||
# status = 200
|
||||
11798
package-lock.json
generated
Normal file
11798
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
61
package.json
Normal file
61
package.json
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"name": "svelte-app",
|
||||
"version": "1.0.0",
|
||||
"@comments scripts": {
|
||||
"dev": "develop with blazing fast rebuilds",
|
||||
"dev:features": "develop with features like SSR and serviceworker enabled",
|
||||
"build": "run build scripts below",
|
||||
"build:app": "build single page application (SPA)",
|
||||
"build:static": "Generate static pages",
|
||||
"serve": "serve content in 'dist' folder",
|
||||
"rollup": "run the rollup bundler",
|
||||
"nollup": "run the nollup no-bundler",
|
||||
"routify": "run routify"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "run-p routify nollup",
|
||||
"dev:ssr": "run-p routify rollup",
|
||||
"build": "run-s build:*",
|
||||
"build:app": "routify -b && rollup -c",
|
||||
"build:static": "spank",
|
||||
"serve": "spassr --ssr",
|
||||
"rollup": "rollup -cw",
|
||||
"nollup": "nollup -c --verbose",
|
||||
"routify": "routify"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^19.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||
"@roxi/routify": "^2.18.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"nollup": "^0.16.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.2.14",
|
||||
"postcss-import": "^14.0.1",
|
||||
"rollup": "^2.47.0",
|
||||
"rollup-plugin-hot": "^0.1.1",
|
||||
"rollup-plugin-livereload": "^2.0.0",
|
||||
"rollup-plugin-svelte": "^7.1.0",
|
||||
"rollup-plugin-svelte-hot": "^1.0.0-7",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-workbox": "^5.2.1",
|
||||
"spank": "^1.7.0",
|
||||
"spassr": "^2.6.0",
|
||||
"svelte": "^3.38.2",
|
||||
"svelte-preprocess": "^4.7.3",
|
||||
"tossr": "^1.4.2"
|
||||
},
|
||||
"routify": {
|
||||
"extensions": "svelte,html,svx,md"
|
||||
},
|
||||
"spassr": {},
|
||||
"spank": {
|
||||
"blacklist": [
|
||||
"/example/modal/basic/4"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.28.1"
|
||||
}
|
||||
}
|
||||
4325
pnpm-lock.yaml
Normal file
4325
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
94
rollup.config.js
Normal file
94
rollup.config.js
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import svelte from 'rollup-plugin-svelte-hot';
|
||||
import Hmr from 'rollup-plugin-hot'
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import livereload from 'rollup-plugin-livereload';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import { copySync, removeSync } from 'fs-extra'
|
||||
import { spassr } from 'spassr'
|
||||
import getConfig from '@roxi/routify/lib/utils/config'
|
||||
import autoPreprocess from 'svelte-preprocess'
|
||||
import postcssImport from 'postcss-import'
|
||||
import { injectManifest } from 'rollup-plugin-workbox'
|
||||
|
||||
|
||||
const { distDir } = getConfig() // use Routify's distDir for SSOT
|
||||
const assetsDir = 'assets'
|
||||
const buildDir = `${distDir}/build`
|
||||
const isNollup = !!process.env.NOLLUP
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
// clear previous builds
|
||||
removeSync(distDir)
|
||||
removeSync(buildDir)
|
||||
|
||||
|
||||
const serve = () => ({
|
||||
writeBundle: async () => {
|
||||
const options = {
|
||||
assetsDir: [assetsDir, distDir],
|
||||
entrypoint: `${assetsDir}/__app.html`,
|
||||
script: `${buildDir}/main.js`
|
||||
}
|
||||
spassr({ ...options, port: 5000 })
|
||||
spassr({ ...options, ssr: true, port: 5005, ssrOptions: { inlineDynamicImports: true, dev: true } })
|
||||
}
|
||||
})
|
||||
const copyToDist = () => ({ writeBundle() { copySync(assetsDir, distDir) } })
|
||||
|
||||
|
||||
export default {
|
||||
preserveEntrySignatures: false,
|
||||
input: [`src/main.js`],
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: 'esm',
|
||||
dir: buildDir,
|
||||
// for performance, disabling filename hashing in development
|
||||
chunkFileNames:`[name]${production && '-[hash]' || ''}.js`
|
||||
},
|
||||
plugins: [
|
||||
svelte({
|
||||
emitCss: false,
|
||||
hot: isNollup,
|
||||
preprocess: [
|
||||
autoPreprocess({
|
||||
postcss: { plugins: [postcssImport()] },
|
||||
defaults: { style: 'postcss' }
|
||||
})
|
||||
]
|
||||
}),
|
||||
|
||||
// resolve matching modules from current working directory
|
||||
resolve({
|
||||
browser: true,
|
||||
dedupe: importee => !!importee.match(/svelte(\/|$)/)
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
production && terser(),
|
||||
!production && !isNollup && serve(),
|
||||
!production && !isNollup && livereload(distDir), // refresh entire window when code is updated
|
||||
!production && isNollup && Hmr({ inMemory: true, public: assetsDir, }), // refresh only updated code
|
||||
{
|
||||
// provide node environment on the client
|
||||
transform: code => ({
|
||||
code: code.replace(/process\.env\.NODE_ENV/g, `"${process.env.NODE_ENV}"`),
|
||||
map: { mappings: '' }
|
||||
})
|
||||
},
|
||||
injectManifest({
|
||||
globDirectory: assetsDir,
|
||||
globPatterns: ['**/*.{js,css,svg}', '__app.html'],
|
||||
swSrc: `src/sw.js`,
|
||||
swDest: `${distDir}/serviceworker.js`,
|
||||
maximumFileSizeToCacheInBytes: 10000000, // 10 MB,
|
||||
mode: 'production'
|
||||
}),
|
||||
production && copyToDist(),
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false,
|
||||
buildDelay: 100,
|
||||
}
|
||||
}
|
||||
6
sandbox.config.json
Normal file
6
sandbox.config.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"container": {
|
||||
"port": 5000,
|
||||
"template": "node"
|
||||
}
|
||||
}
|
||||
10
src/App.svelte
Normal file
10
src/App.svelte
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
import { Router } from "@roxi/routify";
|
||||
import { routes } from "../.routify/routes";
|
||||
</script>
|
||||
|
||||
<style global>
|
||||
@import "../assets/global.css";
|
||||
</style>
|
||||
|
||||
<Router {routes} />
|
||||
20
src/Serviceworker.svelte
Normal file
20
src/Serviceworker.svelte
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
/**
|
||||
* This file handles serviceworker registration
|
||||
* To enable it, import it from another file, ie. src/pages/_layout.svelte
|
||||
* ⚠ The imported component could get treeshaken if not used, eg. <SW />
|
||||
* For configuring the serviceworker, refer to sw.js
|
||||
*/
|
||||
if ("serviceWorker" in navigator) {
|
||||
import("workbox-window").then(async ({ Workbox }) => {
|
||||
const wb = new Workbox("/serviceworker.js");
|
||||
const registration = await wb.register();
|
||||
|
||||
// Reload the page if the PWA has been updated. Change strategy if needed.
|
||||
wb.addEventListener("redundant", () => {
|
||||
location.reload();
|
||||
console.log("updated app");
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
14
src/chart.js
Normal file
14
src/chart.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import ApexCharts from "apexcharts";
|
||||
|
||||
export const chart = (node, options) => {
|
||||
console.log(ApexCharts);
|
||||
let myChart = new ApexCharts(node, options)
|
||||
myChart.render()
|
||||
|
||||
return {
|
||||
update(options) {
|
||||
myChart.updateOptions(options)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
6
src/main.js
Normal file
6
src/main.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import HMR from '@roxi/routify/hmr'
|
||||
import App from './App.svelte';
|
||||
|
||||
const app = HMR(App, { target: document.body }, 'routify-app')
|
||||
|
||||
export default app;
|
||||
24
src/pages/_fallback.svelte
Normal file
24
src/pages/_fallback.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.huge {
|
||||
font-size: 12rem;
|
||||
}
|
||||
.e404 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="e404">
|
||||
<div class="huge">404</div>
|
||||
<div class="big">Page not found.
|
||||
<!-- link to the parent folder of _fallback.svelte -->
|
||||
<a href={$url('../')}>Go back</a>
|
||||
</div>
|
||||
</div>
|
||||
2
src/pages/_layout.svelte
Normal file
2
src/pages/_layout.svelte
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<!-- routify:options preload="proximity" -->
|
||||
<slot />
|
||||
110
src/pages/example/Splash.svelte
Normal file
110
src/pages/example/Splash.svelte
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<script>
|
||||
import { draw } from 'svelte/transition'
|
||||
let duration = 2000
|
||||
let drawing = true
|
||||
let show = false
|
||||
let error = false
|
||||
setTimeout(() => (show = true))
|
||||
setTimeout(() => (drawing = false), 1800)
|
||||
setTimeout(() => (error = true), 5000)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin: 0;
|
||||
}
|
||||
.error {min-height: 100px}
|
||||
.svg {
|
||||
width: 200px;
|
||||
margin: auto;
|
||||
}
|
||||
path {
|
||||
transition: 0.3s ease;
|
||||
stroke-width: 1;
|
||||
stroke: black;
|
||||
stroke-width: 0;
|
||||
}
|
||||
.svg.drawing path {
|
||||
stroke-width: 2;
|
||||
fill-opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<div class="svg" class:drawing>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
style="isolation:isolate"
|
||||
viewBox="0 0 1000 1000">
|
||||
<defs>
|
||||
<clipPath id="_clipPath_40vHZL606H8eXCPAFONHYpjfq1ISybTL">
|
||||
<rect width="1000" height="1000" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clip-path="url(#_clipPath_40vHZL606H8eXCPAFONHYpjfq1ISybTL)">
|
||||
<linearGradient
|
||||
id="_lgradient_2"
|
||||
x1="-0.011142038971568513"
|
||||
y1="-0.011791871475954507"
|
||||
x2="0.9938039543302696"
|
||||
y2="0.9909604299907665"
|
||||
gradientTransform="matrix(532,0,0,368.749,249,625.251)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="1.7391304347826086%"
|
||||
stop-opacity="1"
|
||||
style="stop-color:rgb(255,124,247)" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-opacity="1"
|
||||
style="stop-color:rgb(255,203,252)" />
|
||||
</linearGradient>
|
||||
{#if show}
|
||||
<path
|
||||
transition:draw|local={{ duration }}
|
||||
d=" M 564.251 625.251 L 659 720 L 700 675 L 781 994 L 457 921 L 506
|
||||
873 L 249 626 L 249 626 L 542.5 626 C 549.812 626 557.065 625.748
|
||||
564.251 625.251 Z "
|
||||
fill="url(#_lgradient_2)" />
|
||||
<linearGradient
|
||||
id="_lgradient_3"
|
||||
x1="0.13056277056277052"
|
||||
y1="0.05232744783306609"
|
||||
x2="0.9350649350649348"
|
||||
y2="0.7710005350454795"
|
||||
gradientTransform="matrix(770,0,0,623,84,3)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="2.1739130434782608%"
|
||||
stop-opacity="1"
|
||||
style="stop-color:rgb(241,93,232)" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-opacity="1"
|
||||
style="stop-color:rgb(184,58,177)" />
|
||||
</linearGradient>
|
||||
<path
|
||||
transition:draw|local={{ duration }}
|
||||
d=" M 542.5 215.388 L 84 215.388 L 203 3 L 542.5 3 L 542.5 3 C
|
||||
714.422 3 854 142.578 854 314.5 C 854 486.422 714.422 626 542.5 626
|
||||
L 249 626 L 364 413.612 L 542.5 413.612 L 542.5 413.612 C 597.201
|
||||
413.612 641.612 369.201 641.612 314.5 C 641.612 259.799 597.201
|
||||
215.388 542.5 215.388 L 542.5 215.388 L 542.5 215.388 Z "
|
||||
fill="url(#_lgradient_3)" />
|
||||
{/if}
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 style="">Generating routes...</h1>
|
||||
<div class="error">
|
||||
{#if error}
|
||||
<h3>Your app should probably have loaded by now</h3>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
18
src/pages/example/_components/CrudWidget/Index.svelte
Normal file
18
src/pages/example/_components/CrudWidget/Index.svelte
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<script>
|
||||
import { leftover } from "@roxi/routify";
|
||||
import list from "./_list.svelte";
|
||||
import update from "./_update.svelte";
|
||||
import view from "./_view.svelte";
|
||||
export let data;
|
||||
const components = { list, update, view };
|
||||
|
||||
$: [id, action = "view"] = $leftover.split("/");
|
||||
$: component = (id && components[action]) || list;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div style="width: 512px; margin: auto;" class="card shadow">
|
||||
<h1 style="text-align: center; margin-top: -8px">CrudWidget</h1>
|
||||
<svelte:component this={component} {data} {id} />
|
||||
</div>
|
||||
</div>
|
||||
25
src/pages/example/_components/CrudWidget/_list.svelte
Normal file
25
src/pages/example/_components/CrudWidget/_list.svelte
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.item {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
height: 128px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="items">
|
||||
{#each data as item}
|
||||
<a href={$url('../:id', { id: item.id })} class="item">
|
||||
{#each Object.entries(item).slice(0, 3) as [name, value]}
|
||||
<div>
|
||||
<b>{name}:</b>
|
||||
{value}
|
||||
</div>
|
||||
{/each}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
18
src/pages/example/_components/CrudWidget/_update.svelte
Normal file
18
src/pages/example/_components/CrudWidget/_update.svelte
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
export let data, id;
|
||||
$: item = data.filter(item => item.id == id)[0];
|
||||
</script>
|
||||
|
||||
<div >
|
||||
<div >
|
||||
{#each Object.entries(item) as [name, value]}
|
||||
<div>
|
||||
<b>{name}:</b>
|
||||
<input type="text" {value}>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<br>
|
||||
<a href="{$url('../:id', {id})}">Back</a>
|
||||
</div>
|
||||
22
src/pages/example/_components/CrudWidget/_view.svelte
Normal file
22
src/pages/example/_components/CrudWidget/_view.svelte
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
export let data = [],
|
||||
id;
|
||||
$: item = data.filter(item => item.id == id)[0];
|
||||
</script>
|
||||
|
||||
{#if item}
|
||||
<div>
|
||||
<div>
|
||||
{#each Object.entries(item) as [name, value]}
|
||||
<div>
|
||||
<b>{name}:</b>
|
||||
{value}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<br />
|
||||
<a href={$url('../', { id })}>[Back]</a>
|
||||
<a href={$url('../:id/update', { id })}>[Update]</a>
|
||||
</div>
|
||||
{/if}
|
||||
107
src/pages/example/_components/NavLinks.svelte
Normal file
107
src/pages/example/_components/NavLinks.svelte
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<script>
|
||||
import { url, isActive } from "@roxi/routify";
|
||||
let show = false;
|
||||
const _links = [
|
||||
["/", "⯇ BACK TO APP"],
|
||||
["./index", "Home"],
|
||||
["./modal", "Modal"],
|
||||
["./reset", "Reset"],
|
||||
["./layouts", "Layouts"],
|
||||
["./widget", "Widget"],
|
||||
["./aliasing", "Aliasing"],
|
||||
["./404", "404"],
|
||||
["./api", "Api"],
|
||||
["./app", "App"],
|
||||
["./transitions/tabs", "Transitions"],
|
||||
];
|
||||
|
||||
function handleBurger() {
|
||||
show = !show;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
aside {
|
||||
text-align: center;
|
||||
}
|
||||
nav {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
.mobile-nav {
|
||||
font-size: 18px;
|
||||
background: white;
|
||||
padding: 8px;
|
||||
box-shadow: 0px 5px 20px 5px rgba(0, 0, 0, 0.075);
|
||||
display: block;
|
||||
}
|
||||
.mobile-nav * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title {
|
||||
|
||||
top: 6px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.burger {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 4px;
|
||||
}
|
||||
nav {
|
||||
display: none;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
nav {
|
||||
margin: 16px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 5px 20px 5px rgba(0, 0, 0, 0.075);
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
.link {
|
||||
padding: 0 16px;
|
||||
min-width: 56px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
nav.show {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<aside>
|
||||
<nav class="mobile-nav">
|
||||
<span class="burger" on:click={handleBurger}>☰</span>
|
||||
<span class="title">Routify Examples</span>
|
||||
<span />
|
||||
</nav>
|
||||
<nav class:show on:click={() => (show = false)}>
|
||||
{#each _links as [path, name]}
|
||||
<a class="link" class:active={$isActive(path)} href={$url(path)}>
|
||||
{name}
|
||||
</a>
|
||||
{/each}
|
||||
</nav>
|
||||
</aside>
|
||||
26
src/pages/example/_components/RenderStatus.svelte
Normal file
26
src/pages/example/_components/RenderStatus.svelte
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<script>
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
let show = true;
|
||||
let render = window.__preRendered ? "prerender" : window.__ssrRendered ? "ssr" : "spa";
|
||||
setTimeout(() => {
|
||||
show = false;
|
||||
}, 3000);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.box {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
padding: 8px 16px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
color: #777;
|
||||
}
|
||||
</style>
|
||||
|
||||
{#if show}
|
||||
<div transition:fade|local class="box">source: {render}</div>
|
||||
{/if}
|
||||
6
src/pages/example/_components/RoutifyIntro.svelte
Normal file
6
src/pages/example/_components/RoutifyIntro.svelte
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<h1>Routify Starter</h1>
|
||||
|
||||
To see an example app, go to
|
||||
<a href="/example">/example</a>
|
||||
|
||||
<p>To delete the example app, simply delete the ./src/pages/example folder.</p>
|
||||
1
src/pages/example/_components/assets/kevin.js
Normal file
1
src/pages/example/_components/assets/kevin.js
Normal file
File diff suppressed because one or more lines are too long
1
src/pages/example/_components/assets/logo.js
Normal file
1
src/pages/example/_components/assets/logo.js
Normal file
File diff suppressed because one or more lines are too long
359
src/pages/example/_data.js
Normal file
359
src/pages/example/_data.js
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
export const todos = [
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 1,
|
||||
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
|
||||
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 2,
|
||||
"title": "qui est esse",
|
||||
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 3,
|
||||
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
|
||||
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 4,
|
||||
"title": "eum et est occaecati",
|
||||
"body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 5,
|
||||
"title": "nesciunt quas odio",
|
||||
"body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 6,
|
||||
"title": "dolorem eum magni eos aperiam quia",
|
||||
"body": "ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate dolores velit et doloremque molestiae"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 7,
|
||||
"title": "magnam facilis autem",
|
||||
"body": "dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo aut saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 8,
|
||||
"title": "dolorem dolore est ipsam",
|
||||
"body": "dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor voluptatum modi aut vitae"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 9,
|
||||
"title": "nesciunt iure omnis dolorem tempora et accusantium",
|
||||
"body": "consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam aut nobis\net est aut quod aut provident voluptas autem voluptas"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 10,
|
||||
"title": "optio molestias id quia eum",
|
||||
"body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error"
|
||||
}
|
||||
]
|
||||
|
||||
export const users = [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Leanne Graham",
|
||||
"username": "Bret",
|
||||
"email": "Sincere@april.biz",
|
||||
"address": {
|
||||
"street": "Kulas Light",
|
||||
"suite": "Apt. 556",
|
||||
"city": "Gwenborough",
|
||||
"zipcode": "92998-3874",
|
||||
"geo": {
|
||||
"lat": "-37.3159",
|
||||
"lng": "81.1496"
|
||||
}
|
||||
},
|
||||
"phone": "1-770-736-8031 x56442",
|
||||
"website": "hildegard.org",
|
||||
"company": {
|
||||
"name": "Romaguera-Crona",
|
||||
"catchPhrase": "Multi-layered client-server neural-net",
|
||||
"bs": "harness real-time e-markets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Ervin Howell",
|
||||
"username": "Antonette",
|
||||
"email": "Shanna@melissa.tv",
|
||||
"address": {
|
||||
"street": "Victor Plains",
|
||||
"suite": "Suite 879",
|
||||
"city": "Wisokyburgh",
|
||||
"zipcode": "90566-7771",
|
||||
"geo": {
|
||||
"lat": "-43.9509",
|
||||
"lng": "-34.4618"
|
||||
}
|
||||
},
|
||||
"phone": "010-692-6593 x09125",
|
||||
"website": "anastasia.net",
|
||||
"company": {
|
||||
"name": "Deckow-Crist",
|
||||
"catchPhrase": "Proactive didactic contingency",
|
||||
"bs": "synergize scalable supply-chains"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Clementine Bauch",
|
||||
"username": "Samantha",
|
||||
"email": "Nathan@yesenia.net",
|
||||
"address": {
|
||||
"street": "Douglas Extension",
|
||||
"suite": "Suite 847",
|
||||
"city": "McKenziehaven",
|
||||
"zipcode": "59590-4157",
|
||||
"geo": {
|
||||
"lat": "-68.6102",
|
||||
"lng": "-47.0653"
|
||||
}
|
||||
},
|
||||
"phone": "1-463-123-4447",
|
||||
"website": "ramiro.info",
|
||||
"company": {
|
||||
"name": "Romaguera-Jacobson",
|
||||
"catchPhrase": "Face to face bifurcated interface",
|
||||
"bs": "e-enable strategic applications"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Patricia Lebsack",
|
||||
"username": "Karianne",
|
||||
"email": "Julianne.OConner@kory.org",
|
||||
"address": {
|
||||
"street": "Hoeger Mall",
|
||||
"suite": "Apt. 692",
|
||||
"city": "South Elvis",
|
||||
"zipcode": "53919-4257",
|
||||
"geo": {
|
||||
"lat": "29.4572",
|
||||
"lng": "-164.2990"
|
||||
}
|
||||
},
|
||||
"phone": "493-170-9623 x156",
|
||||
"website": "kale.biz",
|
||||
"company": {
|
||||
"name": "Robel-Corkery",
|
||||
"catchPhrase": "Multi-tiered zero tolerance productivity",
|
||||
"bs": "transition cutting-edge web services"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Chelsey Dietrich",
|
||||
"username": "Kamren",
|
||||
"email": "Lucio_Hettinger@annie.ca",
|
||||
"address": {
|
||||
"street": "Skiles Walks",
|
||||
"suite": "Suite 351",
|
||||
"city": "Roscoeview",
|
||||
"zipcode": "33263",
|
||||
"geo": {
|
||||
"lat": "-31.8129",
|
||||
"lng": "62.5342"
|
||||
}
|
||||
},
|
||||
"phone": "(254)954-1289",
|
||||
"website": "demarco.info",
|
||||
"company": {
|
||||
"name": "Keebler LLC",
|
||||
"catchPhrase": "User-centric fault-tolerant solution",
|
||||
"bs": "revolutionize end-to-end systems"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Mrs. Dennis Schulist",
|
||||
"username": "Leopoldo_Corkery",
|
||||
"email": "Karley_Dach@jasper.info",
|
||||
"address": {
|
||||
"street": "Norberto Crossing",
|
||||
"suite": "Apt. 950",
|
||||
"city": "South Christy",
|
||||
"zipcode": "23505-1337",
|
||||
"geo": {
|
||||
"lat": "-71.4197",
|
||||
"lng": "71.7478"
|
||||
}
|
||||
},
|
||||
"phone": "1-477-935-8478 x6430",
|
||||
"website": "ola.org",
|
||||
"company": {
|
||||
"name": "Considine-Lockman",
|
||||
"catchPhrase": "Synchronised bottom-line interface",
|
||||
"bs": "e-enable innovative applications"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Kurtis Weissnat",
|
||||
"username": "Elwyn.Skiles",
|
||||
"email": "Telly.Hoeger@billy.biz",
|
||||
"address": {
|
||||
"street": "Rex Trail",
|
||||
"suite": "Suite 280",
|
||||
"city": "Howemouth",
|
||||
"zipcode": "58804-1099",
|
||||
"geo": {
|
||||
"lat": "24.8918",
|
||||
"lng": "21.8984"
|
||||
}
|
||||
},
|
||||
"phone": "210.067.6132",
|
||||
"website": "elvis.io",
|
||||
"company": {
|
||||
"name": "Johns Group",
|
||||
"catchPhrase": "Configurable multimedia task-force",
|
||||
"bs": "generate enterprise e-tailers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Nicholas Runolfsdottir V",
|
||||
"username": "Maxime_Nienow",
|
||||
"email": "Sherwood@rosamond.me",
|
||||
"address": {
|
||||
"street": "Ellsworth Summit",
|
||||
"suite": "Suite 729",
|
||||
"city": "Aliyaview",
|
||||
"zipcode": "45169",
|
||||
"geo": {
|
||||
"lat": "-14.3990",
|
||||
"lng": "-120.7677"
|
||||
}
|
||||
},
|
||||
"phone": "586.493.6943 x140",
|
||||
"website": "jacynthe.com",
|
||||
"company": {
|
||||
"name": "Abernathy Group",
|
||||
"catchPhrase": "Implemented secondary concept",
|
||||
"bs": "e-enable extensible e-tailers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Glenna Reichert",
|
||||
"username": "Delphine",
|
||||
"email": "Chaim_McDermott@dana.io",
|
||||
"address": {
|
||||
"street": "Dayna Park",
|
||||
"suite": "Suite 449",
|
||||
"city": "Bartholomebury",
|
||||
"zipcode": "76495-3109",
|
||||
"geo": {
|
||||
"lat": "24.6463",
|
||||
"lng": "-168.8889"
|
||||
}
|
||||
},
|
||||
"phone": "(775)976-6794 x41206",
|
||||
"website": "conrad.com",
|
||||
"company": {
|
||||
"name": "Yost and Sons",
|
||||
"catchPhrase": "Switchable contextually-based project",
|
||||
"bs": "aggregate real-time technologies"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Clementina DuBuque",
|
||||
"username": "Moriah.Stanton",
|
||||
"email": "Rey.Padberg@karina.biz",
|
||||
"address": {
|
||||
"street": "Kattie Turnpike",
|
||||
"suite": "Suite 198",
|
||||
"city": "Lebsackbury",
|
||||
"zipcode": "31428-2261",
|
||||
"geo": {
|
||||
"lat": "-38.2386",
|
||||
"lng": "57.2232"
|
||||
}
|
||||
},
|
||||
"phone": "024-648-3804",
|
||||
"website": "ambrose.net",
|
||||
"company": {
|
||||
"name": "Hoeger LLC",
|
||||
"catchPhrase": "Centralized empowering task-force",
|
||||
"bs": "target end-to-end models"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
export const posts = [
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 1,
|
||||
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
|
||||
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 2,
|
||||
"title": "qui est esse",
|
||||
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 3,
|
||||
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
|
||||
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 4,
|
||||
"title": "eum et est occaecati",
|
||||
"body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 5,
|
||||
"title": "nesciunt quas odio",
|
||||
"body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 6,
|
||||
"title": "dolorem eum magni eos aperiam quia",
|
||||
"body": "ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate dolores velit et doloremque molestiae"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 7,
|
||||
"title": "magnam facilis autem",
|
||||
"body": "dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo aut saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 8,
|
||||
"title": "dolorem dolore est ipsam",
|
||||
"body": "dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor voluptatum modi aut vitae"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 9,
|
||||
"title": "nesciunt iure omnis dolorem tempora et accusantium",
|
||||
"body": "consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam aut nobis\net est aut quod aut provident voluptas autem voluptas"
|
||||
},
|
||||
{
|
||||
"userId": 1,
|
||||
"id": 10,
|
||||
"title": "optio molestias id quia eum",
|
||||
"body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error"
|
||||
}
|
||||
]
|
||||
24
src/pages/example/_fallback.svelte
Normal file
24
src/pages/example/_fallback.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.huge {
|
||||
font-size: 12rem;
|
||||
}
|
||||
.e404 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="e404">
|
||||
<div class="huge">404</div>
|
||||
<div class="big">Page not found.
|
||||
<!-- link to the parent folder of _fallback.svelte -->
|
||||
<a href={$url('../')}>Go back</a>
|
||||
</div>
|
||||
</div>
|
||||
54
src/pages/example/_reset.svelte
Normal file
54
src/pages/example/_reset.svelte
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
import NavLinks from "./_components/NavLinks.svelte";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.example {
|
||||
background-color: #ffeffe;
|
||||
background-attachment: fixed;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
* :global(.card) {
|
||||
border-radius: 0.25rem;
|
||||
border-width: 1px;
|
||||
border: 1px solid #e2e8f0;
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
}
|
||||
|
||||
* :global(.shadow) {
|
||||
box-shadow: 0px 5px 20px 5px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
|
||||
.main {
|
||||
overflow: auto;
|
||||
height: calc(100%);
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Reset files doesn't inherit the parent scope.
|
||||
This ensures that the example app doesn't inherit
|
||||
layouts from the main app. -->
|
||||
<div class="example">
|
||||
<div class="nav">
|
||||
<NavLinks />
|
||||
<!-- we load RenderStatus popup dynamically as it's not
|
||||
important and we don't want to slow down the initial load -->
|
||||
{#await import('./_components/RenderStatus.svelte') then Module}
|
||||
<svelte:component this={Module.default} />
|
||||
{/await}
|
||||
</div>
|
||||
<div class="main">
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
15
src/pages/example/aliasing/_layout.svelte
Normal file
15
src/pages/example/aliasing/_layout.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
<div style="text-align: center">
|
||||
<div style="font-weight: bold">
|
||||
<a href={$url('./')}>Aliasing</a> |
|
||||
<a href={$url('./v1')}>V1</a> |
|
||||
<a href={$url('./v1.1')}>V1.1</a>
|
||||
</div>
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
3
src/pages/example/aliasing/index.svelte
Normal file
3
src/pages/example/aliasing/index.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
<p>Pages can redirect to other pages while not changing the current URL.</p>
|
||||
<p>By using _fallback.svelte we can reference whole libraries and modules instead of having to duplicate them.</p>
|
||||
4
src/pages/example/aliasing/v1.1/_fallback.svelte
Normal file
4
src/pages/example/aliasing/v1.1/_fallback.svelte
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<script>
|
||||
import {goto, leftover} from '@roxi/routify'
|
||||
$goto('../../v1/'+$leftover, null, true, true)
|
||||
</script>
|
||||
22
src/pages/example/aliasing/v1.1/_layout.svelte
Normal file
22
src/pages/example/aliasing/v1.1/_layout.svelte
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
<p>V1.1 has only one file: feature2.svelte</p>
|
||||
<p>The rest are handled with _fallback.svelte, which redirects to v1</p>
|
||||
|
||||
<code>
|
||||
<pre>
|
||||
/** _fallback.svelte **/
|
||||
import {`{(goto, leftover)}`} from '@roxi/routify'
|
||||
$goto('../../v1/'+$leftover, null, true, true)
|
||||
</pre>
|
||||
</code>
|
||||
|
||||
<a href={$url('./feature1')}>Feature 1</a>
|
||||
<a href={$url('./feature2')}>Feature 2</a>
|
||||
<a href={$url('./feature3')}>Feature 3</a>
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
3
src/pages/example/aliasing/v1.1/feature2.svelte
Normal file
3
src/pages/example/aliasing/v1.1/feature2.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Feature 2</h1>
|
||||
|
||||
<b>v1.1 feature</b>
|
||||
1
src/pages/example/aliasing/v1.1/index.svelte
Normal file
1
src/pages/example/aliasing/v1.1/index.svelte
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>Welcome to v2</h1>
|
||||
16
src/pages/example/aliasing/v1/_layout.svelte
Normal file
16
src/pages/example/aliasing/v1/_layout.svelte
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
</script>
|
||||
|
||||
<p>V1 has three files, which can be seen in the links below </p>
|
||||
|
||||
|
||||
<a href={$url('./feature1')}>Feature 1</a> |
|
||||
<a href={$url('./feature2')}>Feature 2</a> |
|
||||
<a href={$url('./feature3')}>Feature 3</a>
|
||||
|
||||
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
3
src/pages/example/aliasing/v1/feature1.svelte
Normal file
3
src/pages/example/aliasing/v1/feature1.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Feature 1</h1>
|
||||
|
||||
<b>v1 feature</b>
|
||||
3
src/pages/example/aliasing/v1/feature2.svelte
Normal file
3
src/pages/example/aliasing/v1/feature2.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Feature 2</h1>
|
||||
|
||||
<b>v1 feature</b>
|
||||
3
src/pages/example/aliasing/v1/feature3.svelte
Normal file
3
src/pages/example/aliasing/v1/feature3.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<h1>Feature 3</h1>
|
||||
|
||||
<b>v1 feature</b>
|
||||
1
src/pages/example/aliasing/v1/index.svelte
Normal file
1
src/pages/example/aliasing/v1/index.svelte
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>Welcome to v1</h1>
|
||||
30
src/pages/example/api/[showId].svelte
Normal file
30
src/pages/example/api/[showId].svelte
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import { ready, url, params } from "@roxi/routify";
|
||||
let series = {};
|
||||
|
||||
$: updateShow($params.showId);
|
||||
|
||||
function updateShow(id) {
|
||||
fetch(`https://api.tvmaze.com/shows/${id}`)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
series = json;
|
||||
$ready();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div style="text-align: center; max-width: 540px; margin: auto">
|
||||
<h4>
|
||||
<a href={$url('./')}>Go back</a>
|
||||
</h4>
|
||||
|
||||
{#if series.id}
|
||||
<img src={series.image.medium.replace('http:', 'https:')} alt="cover" style="height: 295px" />
|
||||
<h1>{series.name} ({series.premiered.split('-')[0]})</h1>
|
||||
<p>
|
||||
{@html series.summary}
|
||||
</p>
|
||||
<a href={series.url}>Read more on TVMaze</a>
|
||||
{/if}
|
||||
</div>
|
||||
16
src/pages/example/api/_layout.svelte
Normal file
16
src/pages/example/api/_layout.svelte
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<script>
|
||||
const movies = [
|
||||
[32, "Fargo"],
|
||||
[179, "The Wire"],
|
||||
[318, "Community"],
|
||||
[5, "True Detective"],
|
||||
[532, "Scrubs"],
|
||||
[30960, "Cobra Kai"],
|
||||
[530, "Seinfeld"],
|
||||
[347, "It's Always Sunny in Philadelphia"]
|
||||
];
|
||||
</script>
|
||||
|
||||
<slot scoped={{movies}}>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
20
src/pages/example/api/index.svelte
Normal file
20
src/pages/example/api/index.svelte
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
import { url, prefetch } from "@roxi/routify";
|
||||
export let scoped;
|
||||
const options = {
|
||||
validFor: 3600 * 24 * 31, // don't refresh assets on the page for a month
|
||||
writeHeaders: true // useful for debugging
|
||||
};
|
||||
const { movies } = scoped;
|
||||
// console.log(movies)
|
||||
</script>
|
||||
|
||||
<div style="text-align: center">
|
||||
{#each movies as [showId, title]}
|
||||
<h3>
|
||||
<a use:prefetch={options} href={$url('./:showId', { showId })}>
|
||||
{title}
|
||||
</a>
|
||||
</h3>
|
||||
{/each}
|
||||
</div>
|
||||
24
src/pages/example/app/_fallback.svelte
Normal file
24
src/pages/example/app/_fallback.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.huge {
|
||||
font-size: 12rem;
|
||||
}
|
||||
.e404 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="e404">
|
||||
<div class="huge">404</div>
|
||||
<div class="big">Page not found.
|
||||
<!-- link to the parent folder of _fallback.svelte -->
|
||||
<a href={$url('./')}>Go back</a>
|
||||
</div>
|
||||
</div>
|
||||
27
src/pages/example/app/_reset.svelte
Normal file
27
src/pages/example/app/_reset.svelte
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<script>
|
||||
import { goto, url } from "@roxi/routify";
|
||||
import { user } from "./_store";
|
||||
|
||||
/** We set the static parameter to true since we don't want to change the browser's URL
|
||||
* Notice the $: prefix which makes the statement reactive. This way if the user logs
|
||||
* out the $goto is called again.
|
||||
* **/
|
||||
$: if (!$user) $goto("./login", {}, true);
|
||||
|
||||
function logout() {
|
||||
$user = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if $user}
|
||||
<a href={$url('/example')}>Back to examples</a>
|
||||
<a href={$url('./')}>Home</a>
|
||||
<a href={$url('./about')}>About</a>
|
||||
<button on:click={logout} style="position: absolute; right: 24px">
|
||||
Logout
|
||||
</button>
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
{/if}
|
||||
3
src/pages/example/app/_store.js
Normal file
3
src/pages/example/app/_store.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import {writable} from 'svelte/store'
|
||||
|
||||
export const user = writable(false)
|
||||
1
src/pages/example/app/index.svelte
Normal file
1
src/pages/example/app/index.svelte
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>Welcome logged in user</h1>
|
||||
2
src/pages/example/app/login/_reset.svelte
Normal file
2
src/pages/example/app/login/_reset.svelte
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<!-- We don't want to inherit the parent layout on the login page, so we use a reset to clear the scope. -->
|
||||
<slot></slot>
|
||||
40
src/pages/example/app/login/index.svelte
Normal file
40
src/pages/example/app/login/index.svelte
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<script>
|
||||
import { user } from "../_store.js";
|
||||
import { goto, url } from "@roxi/routify";
|
||||
|
||||
let username = "anything";
|
||||
let password = "goes";
|
||||
|
||||
function login() {
|
||||
$user = { username };
|
||||
/** We want to $goto our current location.
|
||||
* Since we're now logged in, we shouldn't be redirected to this login page again.
|
||||
* **/
|
||||
$goto(window.location.href);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div style="width: 256px; margin: 128px auto; text-align: center">
|
||||
<h1>Login</h1>
|
||||
<input type="text" bind:value={username} />
|
||||
<br />
|
||||
<input type="text" bind:value={password} />
|
||||
<br />
|
||||
<button on:click={login}>Submit</button>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
This login page is actually located at
|
||||
<a href={$url()}>{$url()}</a>
|
||||
</p>
|
||||
<p>
|
||||
You are seeing it here, because we're using $goto with the static option
|
||||
enabled. This renders the login page, without changing the URL in the
|
||||
browser.
|
||||
</p>
|
||||
<p>
|
||||
On submit, we're "redirected" to the current URL in your browser.
|
||||
</p>
|
||||
</div>
|
||||
24
src/pages/example/index.svelte
Normal file
24
src/pages/example/index.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import base64Logo from "./_components/assets/logo.js";
|
||||
</script>
|
||||
|
||||
<!-- routify:option name="example-app" -->
|
||||
|
||||
<div style="width: 100%; text-align: center; margin-top: 4rem;">
|
||||
<img src="data:image/png;base64, {base64Logo}" alt="logo" style="max-width: 100%; padding-bottom: 128px" />
|
||||
<div>
|
||||
<b>Guide:</b>
|
||||
<br />
|
||||
<a href="https://routify.dev">https://routify.dev</a>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<div>
|
||||
<b>This template:</b>
|
||||
<br />
|
||||
<a href="https://github.com/roxiness/routify-starter">
|
||||
https://github.com/roxiness/routify-starter
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
30
src/pages/example/layouts/_layout.svelte
Normal file
30
src/pages/example/layouts/_layout.svelte
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.layout-container :global(.card) {
|
||||
width: 66%;
|
||||
margin: 16px;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
box-shadow: 0px 5px 20px 5px rgba(0, 0, 0, 0.075);
|
||||
display: inline-block;
|
||||
}
|
||||
* > :global(.layout-container) {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div >
|
||||
<div class="layout-container">
|
||||
<div class="card">
|
||||
<a href={$url('./child')}>Child</a>
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
15
src/pages/example/layouts/child/_layout.svelte
Normal file
15
src/pages/example/layouts/child/_layout.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="layout-container">
|
||||
<div class="card">
|
||||
<a href={$url('./grandchild')}>Grandchild</a>
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
13
src/pages/example/layouts/child/grandchild/_layout.svelte
Normal file
13
src/pages/example/layouts/child/grandchild/_layout.svelte
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="layout-container">
|
||||
<div class="card">
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
3
src/pages/example/layouts/child/grandchild/index.svelte
Normal file
3
src/pages/example/layouts/child/grandchild/index.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<div style="text-align: center">
|
||||
<h4>I'm src/pages/example/nesting/child/grandchild/index.svelte</h4>
|
||||
</div>
|
||||
3
src/pages/example/layouts/child/index.svelte
Normal file
3
src/pages/example/layouts/child/index.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<div style="text-align: center">
|
||||
<h1>I'm src/pages/example/nesting/child/index.svelte</h1>
|
||||
</div>
|
||||
3
src/pages/example/layouts/index.svelte
Normal file
3
src/pages/example/layouts/index.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<div style="text-align: center">
|
||||
<h1>I'm src/pages/example/nesting/index.svelte</h1>
|
||||
</div>
|
||||
74
src/pages/example/modal/_layout.svelte
Normal file
74
src/pages/example/modal/_layout.svelte
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<script>
|
||||
import { url, route } from "@roxi/routify";
|
||||
|
||||
$: match = $route.path.match(/\/modal\/([^\/]+)\//);
|
||||
$: active = match && match[1];
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* :global(.cards) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* :global(.card) {
|
||||
border-radius: 0.25rem;
|
||||
border-width: 1px;
|
||||
border: 1px solid #e2e8f0;
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
list-style: none;
|
||||
width: 25%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
* :global(.container) {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding-top: 5rem;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
* :global(.modal) {
|
||||
margin: auto;
|
||||
background: white;
|
||||
font-size: 5rem;
|
||||
border: 1px solid #e2e8f0;
|
||||
width: 30%;
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div data-routify="scroll-lock">
|
||||
|
||||
<div class="center">
|
||||
<a href={$url('./basic')} class={active === 'basic' ? 'active' : ''}>
|
||||
Basic
|
||||
</a>
|
||||
<a href={$url('./animated')} class={active === 'animated' ? 'active' : ''}>
|
||||
Animated
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
</div>
|
||||
14
src/pages/example/modal/animated/[key].svelte
Normal file
14
src/pages/example/modal/animated/[key].svelte
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<script>
|
||||
import { goto } from "@roxi/routify";
|
||||
export let scoped
|
||||
$: ({ send, receive, key } = scoped);
|
||||
</script>
|
||||
|
||||
<div class="container" on:click={() => $goto('./')} >
|
||||
<div
|
||||
class="modal"
|
||||
in:receive|local={{ key: 'modal' }}
|
||||
out:send|local={{ key: 'modal' }}>
|
||||
{key}
|
||||
</div>
|
||||
</div>
|
||||
21
src/pages/example/modal/animated/_layout.svelte
Normal file
21
src/pages/example/modal/animated/_layout.svelte
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
import { url, context, afterPageLoad } from "@roxi/routify";
|
||||
import { crossfade, fade } from "svelte/transition";
|
||||
import Target from "./_target.svelte";
|
||||
|
||||
const [send, receive] = crossfade({});
|
||||
$: _key = $context.child && $context.child.params.key
|
||||
</script>
|
||||
|
||||
<div class="cards">
|
||||
{#each Array(12) as item, key}
|
||||
<a class="card" href={$url('./:key', { key })} style="background: #333">
|
||||
<!-- <Target/> is a placeholder that takes the size of its parent element.
|
||||
If a modal is show and its key matches this cards key, <Target/> is hidden.
|
||||
This triggers the modal transition. -->
|
||||
<Target {receive} {send} hide={key == _key} />
|
||||
<div class="content" style="color: white">{key}</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
<slot scoped={{ send, receive, fade, key: _key }} />
|
||||
21
src/pages/example/modal/animated/_target.svelte
Normal file
21
src/pages/example/modal/animated/_target.svelte
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
export let send, receive, hide;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
{#if !hide}
|
||||
<div
|
||||
class="canvas"
|
||||
in:receive|local={{ key: 'modal' }}
|
||||
out:send|local={{ key: 'modal' }} />
|
||||
{/if}
|
||||
0
src/pages/example/modal/animated/index.svelte
Normal file
0
src/pages/example/modal/animated/index.svelte
Normal file
11
src/pages/example/modal/basic/[key].svelte
Normal file
11
src/pages/example/modal/basic/[key].svelte
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<script>
|
||||
import { goto, url } from "@roxi/routify";
|
||||
export let key
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container" on:click={() => $goto('./')} >
|
||||
<div class="modal" >
|
||||
{key}
|
||||
</div>
|
||||
</div>
|
||||
15
src/pages/example/modal/basic/_layout.svelte
Normal file
15
src/pages/example/modal/basic/_layout.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
import { url, params } from "@roxi/routify";
|
||||
import { getContext } from "svelte";
|
||||
|
||||
</script>
|
||||
|
||||
<div class="cards">
|
||||
{#each Array(12) as item, key}
|
||||
<a class="card" href={$url('./:key', { key })}>
|
||||
<div class="content">{key}</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
0
src/pages/example/modal/basic/index.svelte
Normal file
0
src/pages/example/modal/basic/index.svelte
Normal file
0
src/pages/example/modal/index.svelte
Normal file
0
src/pages/example/modal/index.svelte
Normal file
24
src/pages/example/reset/_fallback.svelte
Normal file
24
src/pages/example/reset/_fallback.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.huge {
|
||||
font-size: 12rem;
|
||||
}
|
||||
.e404 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="e404">
|
||||
<div class="huge">404</div>
|
||||
<div class="big">Page not found.
|
||||
<!-- link to the parent folder of _fallback.svelte -->
|
||||
<a href={$url('../')}>Go back</a>
|
||||
</div>
|
||||
</div>
|
||||
3
src/pages/example/reset/_reset.svelte
Normal file
3
src/pages/example/reset/_reset.svelte
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<slot>
|
||||
<!-- optional fallback -->
|
||||
</slot>
|
||||
20
src/pages/example/reset/index.svelte
Normal file
20
src/pages/example/reset/index.svelte
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
import { url } from '@roxi/routify'
|
||||
import base64Kevin from "../_components/assets/kevin.js";
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.center {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<img src="data:image/png;base64, {base64Kevin}" alt="KEVIN!" class="center" />
|
||||
|
||||
<a href={$url('../../')}>Go back</a>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<script>
|
||||
import { url, isActive } from "@roxi/routify";
|
||||
export let urls, height;
|
||||
let linkElems = [];
|
||||
let overlay;
|
||||
let clientWidth
|
||||
$: urlsWithElem = linkElems.map((elem, i) => ({ ...urls[i], elem }));
|
||||
$: activeUrl = urlsWithElem.find(({active}) => active)
|
||||
$: if (overlay && clientWidth && activeUrl) copyDimensions(activeUrl.elem, overlay);
|
||||
$: color = activeUrl && activeUrl.color
|
||||
|
||||
function copyDimensions(source, target) {
|
||||
target.style.left = source.offsetLeft + "px";
|
||||
target.style.top = source.offsetTop + "px";
|
||||
target.style.width = source.clientWidth + "px";
|
||||
target.style.height = source.clientHeight + "px";
|
||||
}
|
||||
|
||||
const saveElement = el => (linkElems = [...linkElems, el]);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
width: 100%;
|
||||
background: white;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
a {
|
||||
padding: 0 16px;
|
||||
line-height: 100%;
|
||||
font-weight: 500;
|
||||
color: #aaa;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
transition: all 0.8s;
|
||||
/* transition-delay: 0.05s */
|
||||
}
|
||||
a.active {
|
||||
color: #fff;
|
||||
}
|
||||
.overlay {
|
||||
position: absolute;
|
||||
/* background: #555; */
|
||||
transition: 0.3s all;
|
||||
background: linear-gradient(
|
||||
rgba(0, 0, 0, 0.15),
|
||||
rgba(0, 0, 0, 0.15)
|
||||
)
|
||||
}
|
||||
</style>
|
||||
|
||||
<nav bind:clientWidth>
|
||||
{#each urls as { name, path, active, href }, i}
|
||||
<a
|
||||
style="line-height: {height}"
|
||||
{href}
|
||||
class:active
|
||||
use:saveElement>
|
||||
{name}
|
||||
</a>
|
||||
{/each}
|
||||
<div class="overlay" bind:this={overlay} style="background-color: {color}" />
|
||||
</nav>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<script>
|
||||
import { scale, fly } from "svelte/transition";
|
||||
import { route } from "@roxi/routify";
|
||||
import { Transition } from "@roxi/routify/decorators";
|
||||
|
||||
export let scoped;
|
||||
const { width } = scoped;
|
||||
|
||||
const configs = [
|
||||
{
|
||||
// New and old route are identical, do nothing
|
||||
condition: ({ routes }) => routes[0] === routes[1],
|
||||
transition: () => {}
|
||||
},
|
||||
{
|
||||
condition: c => c.toAncestor,
|
||||
transition: scale,
|
||||
inParams: { start: 1.2 },
|
||||
outParams: { start: 0.8 }
|
||||
},
|
||||
{
|
||||
condition: c => c.toDescendant,
|
||||
transition: scale,
|
||||
inParams: { start: 0.8 },
|
||||
outParams: { start: 1.2 }
|
||||
},
|
||||
{
|
||||
condition: c => c.toHigherIndex,
|
||||
transition: fly,
|
||||
inParams: { x: $width, duration: 500 },
|
||||
outParams: { x: -$width, duration: 500 }
|
||||
},
|
||||
{
|
||||
condition: c => c.toLowerIndex,
|
||||
transition: fly,
|
||||
inParams: { x: -$width, duration: 500 },
|
||||
outParams: { x: $width, duration: 500 }
|
||||
},
|
||||
{
|
||||
// No matching config. We don't want a transition
|
||||
condition: () => true,
|
||||
transition: () => {}
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<Transition {configs}>
|
||||
<slot />
|
||||
</Transition>
|
||||
58
src/pages/example/transitions/tabs/_reset.svelte
Normal file
58
src/pages/example/transitions/tabs/_reset.svelte
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<script>
|
||||
import { TabsTransition } from "@roxi/routify/decorators";
|
||||
import BottomNav from "./_components/BottomNav.svelte";
|
||||
import { url, isActive } from "@roxi/routify";
|
||||
|
||||
const _urls = [
|
||||
["./home", "Home", "#7fc5bb"],
|
||||
["./feed", "Feed", "#0bf5cc"],
|
||||
["./updates", "Updates", "#88f0d0"],
|
||||
["./settings", "Settings", "#a1fac3"],
|
||||
];
|
||||
$: urls = _urls.map(([path, name, color]) => ({
|
||||
name,
|
||||
href: $url(path),
|
||||
color,
|
||||
active: !!$isActive(path),
|
||||
}));
|
||||
</script>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
padding: 0;
|
||||
}
|
||||
* :global(.inset) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
main.inset {
|
||||
bottom: 64px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
* :global(*) {
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 8px 16px;
|
||||
background: #555;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="height: 100%">
|
||||
<main class="inset">
|
||||
<slot decorator={TabsTransition} />
|
||||
</main>
|
||||
<BottomNav {urls} height="64px" />
|
||||
</div>
|
||||
|
||||
<a href={$url('../../')}>Back to examples</a>
|
||||
|
||||
<!-- routify:options bundle=true -->
|
||||
20
src/pages/example/transitions/tabs/feed/[id]/index.svelte
Normal file
20
src/pages/example/transitions/tabs/feed/[id]/index.svelte
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
export let id;
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
a {
|
||||
font-size: 1.5em;
|
||||
padding: 12px 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="card" style="width: 512px;">
|
||||
<h1>{id}</h1>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<a href={$url('../../home')}>Go home</a>
|
||||
<a href={$url('../')}>Go back</a>
|
||||
19
src/pages/example/transitions/tabs/feed/_layout.svelte
Normal file
19
src/pages/example/transitions/tabs/feed/_layout.svelte
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<style>
|
||||
main {
|
||||
background: #0bf5cc;
|
||||
height: 100%;
|
||||
}
|
||||
* :global(.card) {
|
||||
background: white;
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
display: inline-block;
|
||||
box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
margin: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- routify:options index=1 -->
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
13
src/pages/example/transitions/tabs/feed/index.svelte
Normal file
13
src/pages/example/transitions/tabs/feed/index.svelte
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<script>
|
||||
import { url } from "@roxi/routify";
|
||||
</script>
|
||||
|
||||
<div style="padding-top: 20px">
|
||||
<h1>Feed</h1>
|
||||
</div>
|
||||
|
||||
{#each new Array(10) as item, id}
|
||||
<a class="card" href={$url('./:id', { id })}>
|
||||
<h3 class="item">{id}</h3>
|
||||
</a>
|
||||
{/each}
|
||||
13
src/pages/example/transitions/tabs/home.svelte
Normal file
13
src/pages/example/transitions/tabs/home.svelte
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<style>
|
||||
main {
|
||||
background: #7fc5bb;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- routify:options index=0 -->
|
||||
<main>
|
||||
<br />
|
||||
<h1>Home</h1>
|
||||
</main>
|
||||
4
src/pages/example/transitions/tabs/index.svelte
Normal file
4
src/pages/example/transitions/tabs/index.svelte
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<script>
|
||||
import { redirect } from '@roxi/routify'
|
||||
$redirect('./home')
|
||||
</script>
|
||||
12
src/pages/example/transitions/tabs/settings.svelte
Normal file
12
src/pages/example/transitions/tabs/settings.svelte
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<style>
|
||||
main {
|
||||
background: #a1fac3;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- routify:options index=3 -->
|
||||
<main>
|
||||
<br>
|
||||
<h1>Settings</h1>
|
||||
</main>
|
||||
14
src/pages/example/transitions/tabs/updates.svelte
Normal file
14
src/pages/example/transitions/tabs/updates.svelte
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<style>
|
||||
main {
|
||||
background: #88F0D0;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- routify:options index=2 -->
|
||||
|
||||
|
||||
<main>
|
||||
<br />
|
||||
<h1>Updates</h1>
|
||||
</main>
|
||||
16
src/pages/example/widget/_fallback.svelte
Normal file
16
src/pages/example/widget/_fallback.svelte
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<script>
|
||||
import CrudWidget from "../_components/CrudWidget/Index.svelte";
|
||||
import { users } from "../_data";
|
||||
</script>
|
||||
|
||||
<div style="text-align: center">
|
||||
<p>
|
||||
By using a _fallback.svelte in example/widget, we can grab the leftover URL
|
||||
and pass it to an embedded widget.
|
||||
</p>
|
||||
|
||||
<p>Alternatively, the widget can grab the leftover URL itself.</p>
|
||||
<p>This allows for reusable navigable components.</p>
|
||||
</div>
|
||||
|
||||
<CrudWidget data={users} />
|
||||
10
src/pages/index.svelte
Normal file
10
src/pages/index.svelte
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
import { metatags } from '@roxi/routify'
|
||||
import { chart } from "../chart";
|
||||
metatags.title = 'My Routify app'
|
||||
metatags.description = 'Description coming soon...'
|
||||
|
||||
var opts = {};
|
||||
</script>
|
||||
|
||||
<div use:chart={opts} />
|
||||
108
src/sw.js
Normal file
108
src/sw.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
// @ts-check
|
||||
|
||||
import { registerRoute, setDefaultHandler, setCatchHandler } from 'workbox-routing';
|
||||
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
|
||||
import { skipWaiting, clientsClaim } from 'workbox-core';
|
||||
import { precacheAndRoute, matchPrecache } from 'workbox-precaching';
|
||||
import { ExpirationPlugin } from 'workbox-expiration';
|
||||
import { RoutifyPlugin, freshCacheData } from '@roxi/routify/workbox-plugin'
|
||||
|
||||
|
||||
|
||||
/**********
|
||||
* CONFIG *
|
||||
**********/
|
||||
|
||||
const entrypointUrl = '__app.html' // entrypoint
|
||||
const fallbackImage = '404.svg'
|
||||
const files = self.__WB_MANIFEST // files matching globDirectory and globPattern in rollup.config.js
|
||||
|
||||
const externalAssetsConfig = () => ({
|
||||
cacheName: 'external',
|
||||
plugins: [
|
||||
RoutifyPlugin({
|
||||
validFor: 60 // cache is considered fresh for n seconds.
|
||||
}),
|
||||
new ExpirationPlugin({
|
||||
maxEntries: 50, // last used entries will be purged when we hit this limit
|
||||
purgeOnQuotaError: true // purge external assets on quota error
|
||||
})]
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
/**************
|
||||
* INITIALIZE *
|
||||
**************/
|
||||
|
||||
/**
|
||||
* precache all files
|
||||
* remember to precache __app.html and 404.svg if caching of all files is disabled
|
||||
*/
|
||||
precacheAndRoute(files)
|
||||
|
||||
/** precache only fallback files */
|
||||
// precacheAndRoute(files.filter(file =>
|
||||
// ['__app.html', '404.svg']
|
||||
// .includes(file.url)
|
||||
// ))
|
||||
|
||||
skipWaiting() // auto update service workers across all tabs when new release is available
|
||||
clientsClaim() // take control of client without having to wait for refresh
|
||||
|
||||
/**
|
||||
* manually upgrade service worker by sending a SKIP_WAITING message.
|
||||
* (remember to disable skipWaiting() above)
|
||||
*/
|
||||
// addEventListener('message', event => { if (event.data && event.data.type === 'SKIP_WAITING') skipWaiting(); });
|
||||
|
||||
|
||||
|
||||
/**********
|
||||
* ROUTES *
|
||||
**********/
|
||||
|
||||
// serve local pages from the SPA entry point (__app.html)
|
||||
registerRoute(isLocalPage, matchPrecache(entrypointUrl))
|
||||
|
||||
// serve local assets from cache first
|
||||
registerRoute(isLocalAsset, new CacheFirst())
|
||||
|
||||
// serve external assets from cache if they're fresh
|
||||
registerRoute(hasFreshCache, new CacheFirst(externalAssetsConfig()))
|
||||
|
||||
// serve external pages and assets
|
||||
setDefaultHandler(new NetworkFirst(externalAssetsConfig()));
|
||||
|
||||
// serve a fallback for 404s if possible or respond with an error
|
||||
setCatchHandler(async ({ event }) => {
|
||||
switch (event.request.destination) {
|
||||
case 'document':
|
||||
return await matchPrecache(entrypointUrl)
|
||||
case 'image':
|
||||
return await matchPrecache(fallbackImage)
|
||||
default:
|
||||
return Response.error();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
/**********
|
||||
* CONDITIONS *
|
||||
**********/
|
||||
|
||||
function isLocalAsset({ url, request }) { return url.host === self.location.host && request.destination != 'document' }
|
||||
function isLocalPage({ url, request }) { return url.host === self.location.host && request.destination === 'document' }
|
||||
function hasFreshCache(event) { return !!freshCacheData(event) }
|
||||
|
||||
/** Example condition */
|
||||
function hasWitheringCache(event) {
|
||||
const cache = freshCacheData(event)
|
||||
if (cache) {
|
||||
const { cachedAt, validFor, validLeft, validUntil } = cache
|
||||
// return true if half the fresh time has passed
|
||||
return validFor / 2 > validFor - validLeft
|
||||
}
|
||||
}
|
||||
17
vercel.json
Normal file
17
vercel.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"version": 2,
|
||||
"functions": {
|
||||
"api/vercel-ssr/index.js": {
|
||||
"includeFiles": "dist/**"
|
||||
}
|
||||
},
|
||||
"routes": [
|
||||
{
|
||||
"handle": "filesystem"
|
||||
},
|
||||
{
|
||||
"src": "/.*",
|
||||
"dest": "/api/vercel-ssr/index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue