Skip to content

Commit

Permalink
Fork svelte-routing:
Browse files Browse the repository at this point in the history
- Add hooks to access contexts
- Append basepath on every navigation (not just Link 'to')
  • Loading branch information
mefechoel committed Apr 20, 2020
1 parent 99074ef commit f1d770f
Show file tree
Hide file tree
Showing 17 changed files with 1,762 additions and 102 deletions.
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[*.{js,jsx,ts,tsx,vue,svelte}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/build/*
public/index.html
45 changes: 45 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"plugins": [
"svelte3",
"react"
],
"extends": [
"airbnb"
],
"rules": {
"quotes": ["error", "double"],
"indent": "off",
"no-undef": "off",
"no-underscore-dangle": "off",
"arrow-parens": "off",
"implicit-arrow-linebreak": "off",
"operator-linebreak": "off",
"prefer-const": "off",
"object-curly-newline": "off",
"function-paren-newline": "off",
"no-confusing-arrow": "off",
"no-continue": "off",
"no-plusplus": "off"
},
"env": {
"es6": true,
"browser": true
},
"parserOptions": {
"ecmaVersion": 2019,
"sourceType": "module"
},
"overrides": [
{
"files": ["**/*.svelte"],
"processor": "svelte3/svelte3",
"rules": {
"import/first": "off",
"import/no-duplicates": "off",
"import/no-mutable-exports": "off",
"import/extensions": "off",
"import/no-unresolved": "off"
}
}
]
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules
package-lock.json
example/public/*
!example/public/global.css
!example/public/App.js
.vscode
4 changes: 4 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
trailingComma: "all",
svelteBracketNewLine: true,
};
6 changes: 5 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Copyright for portions of project svelte-navigator are held by [EmilTholin,
2017] as part of project svelte-routing. All other copyright for project
svelte-navigator are held by [Michel Strelow, 2020].

The MIT License (MIT)

Copyright (c) 2017 EmilTholin
Copyright (c) 2020 Michel Strelow

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
[![npm][npm]][npm-url]
# Svelte Navigator

# Svelte Routing

A declarative Svelte routing library with SSR support.
A declarative Svelte routing library.

## Getting started

Expand All @@ -11,15 +9,15 @@ Look at the [example folder][example-folder-url] for an example project setup.
## Install

```bash
npm install --save svelte-routing
npm install --save svelte-navigator
```

## Usage

```html
<!-- App.svelte -->
<script>
import { Router, Link, Route } from "svelte-routing";
import { Router, Link, Route } from "svelte-navigator";
import Home from "./routes/Home.svelte";
import About from "./routes/About.svelte";
import Blog from "./routes/Blog.svelte";
Expand Down Expand Up @@ -48,7 +46,7 @@ import App from "./App.svelte";

const app = new App({
target: document.getElementById("app"),
hydrate: true
hydrate: true,
});
```

Expand Down Expand Up @@ -80,10 +78,10 @@ The `Router` component supplies the `Link` and `Route` descendant components wit

###### Properties

| Property | Required | Default Value | Description |
| :--------: | :------: | :-----------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `basepath` | | `'/'` | The `basepath` property will be added to all the `to` properties of `Link` descendants and to all `path` properties of `Route` descendants. This property can be ignored in most cases, but if you host your application on e.g. `https://example.com/my-site`, the `basepath` should be set to `/my-site`. |
| `url` | | `''` | The `url` property is used in SSR to force the current URL of the application and will be used by all `Link` and `Route` descendants. A falsy value will be ignored by the `Router`, so it's enough to declare `export let url = '';` for your topmost component and only give it a value in SSR. |
| Property | Required | Default Value | Description |
| :--------: | :------: | :-----------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `basepath` | | `'/'` | The `basepath` property will be added to all `path` properties of `Route` descendants and to every navigation (from a `Link` with a `to` property, via `navigate`, etc.). This property can be ignored in most cases, but if you host your application on e.g. `https://example.com/my-site`, the `basepath` should be set to `/my-site`. |
| `url` | | `''` | The `url` property is used in SSR to force the current URL of the application and will be used by all `Link` and `Route` descendants. A falsy value will be ignored by the `Router`, so it's enough to declare `export let url = '';` for your topmost component and only give it a value in SSR. |

#### `Link`

Expand Down Expand Up @@ -181,7 +179,6 @@ In the browser we wait until all child `Route` components have registered with t

We therefore resort to picking the first matching `Route` that is registered on the server, so it is of utmost importance that you `sort your Route components from the most specific to the least specific if you are using SSR`.

[npm]: https://img.shields.io/npm/v/svelte-routing.svg
[npm-url]: https://npmjs.com/package/svelte-routing
[example-folder-url]: https://github.com/EmilTholin/svelte-routing/tree/master/example
[example-folder-navlink]: https://github.com/EmilTholin/svelte-routing/tree/master/example/src/components/NavLink.svelte
[npm-url]: https://npmjs.com/package/svelte-navigator
[example-folder-url]: https://github.com/mefechoel/svelte-navigator/tree/master/example
[example-folder-navlink]: https://github.com/mefechoel/svelte-navigator/tree/master/example/src/components/NavLink.svelte
36 changes: 32 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
{
"name": "svelte-routing",
"version": "1.4.2",
"name": "svelte-navigator",
"version": "0.1.0",
"description": "A declarative Svelte routing library with SSR support",
"main": "src/index.js",
"svelte": "src/index.js",
"author": "Emil Tholin @EmilTholin",
"author": "Michel Strelow @mefechoel",
"license": "MIT",
"repository": "EmilTholin/svelte-routing",
"repository": {
"type": "git",
"url": "https://github.com/mefechoel/svelte-navigator.git"
},
"bugs": {
"url": "https://github.com/mefechoel/svelte-navigator/issues"
},
"homepage": "https://github.com/mefechoel/svelte-navigator#readme",
"keywords": [
"svelte",
"router",
"routing",
"navigate",
"navigator",
"spa",
"declarative routing"
],
"peerDependencies": {
"svelte": "3.x"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.18.0",
"eslint-plugin-svelte3": "^2.7.3",
"prettier": "^1.19.1",
"prettier-plugin-svelte": "^0.7.0",
"svelte": "^3.20.1"
}
}
24 changes: 13 additions & 11 deletions src/Link.svelte
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
<script>
import { getContext, createEventDispatcher } from "svelte";
import { ROUTER, LOCATION } from "./contexts.js";
import { createEventDispatcher } from "svelte";
import { useLocation, useResolve } from "./contexts.js";
import { navigate } from "./history.js";
import { startsWith, resolve, shouldNavigate } from "./utils.js";
import { startsWith, shouldNavigate } from "./utils.js";

export let to = "#";
export let replace = false;
export let state = {};
export let getProps = () => ({});

const { base } = getContext(ROUTER);
const location = getContext(LOCATION);
const location = useLocation();
const dispatch = createEventDispatcher();

let href, isPartiallyCurrent, isCurrent, props;
$: href = to === "/" ? $base.uri : resolve(to, $base.uri);
let href;
let isPartiallyCurrent;
let isCurrent;
let props;
$: href = useResolve(to);
$: isPartiallyCurrent = startsWith($location.pathname, href);
$: isCurrent = href === $location.pathname;
$: ariaCurrent = isCurrent ? "page" : undefined;
$: props = getProps({
location: $location,
href,
isPartiallyCurrent,
isCurrent
isCurrent,
});

function onClick(event) {
Expand All @@ -33,11 +35,11 @@
// Don't push another entry to the history stack when the user
// clicks on a Link to the page they are currently on.
const shouldReplace = $location.pathname === href || replace;
navigate(href, { state, replace: shouldReplace });
navigate(href, { state, replace: shouldReplace, autoResolve: false });
}
}
</script>

<a href="{href}" aria-current="{ariaCurrent}" on:click="{onClick}" {...props}>
<slot></slot>
<a {href} aria-current={ariaCurrent} on:click={onClick} {...props}>
<slot />
</a>
12 changes: 9 additions & 3 deletions src/Route.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
path,
// If no path prop is given, this Route will act as the default Route
// that is rendered if no other Route in the Router is a match.
default: path === ""
default: path === "",
};
let routeParams = {};
let routeProps = {};
Expand All @@ -22,6 +22,7 @@
}

$: {
// eslint-disable-next-line no-shadow
const { path, component, ...rest } = $$props;
routeProps = rest;
}
Expand All @@ -39,8 +40,13 @@

{#if $activeRoute !== null && $activeRoute.route === route}
{#if component !== null}
<svelte:component this="{component}" location={$location} {...routeParams} {...routeProps} />
<svelte:component
this={component}
location={$location}
{...routeParams}
{...routeProps}
/>
{:else}
<slot params="{routeParams}" location={$location}></slot>
<slot params={routeParams} location={$location} />
{/if}
{/if}
30 changes: 16 additions & 14 deletions src/Router.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { writable, derived } from "svelte/store";
import { LOCATION, ROUTER } from "./contexts.js";
import { globalHistory } from "./history.js";
import { pick, match, stripSlashes, combinePaths } from "./utils.js";
import { pick, match, combinePaths } from "./utils.js";

export let basepath = "/";
export let url = null;
Expand All @@ -29,33 +29,33 @@
? routerContext.routerBase
: writable({
path: basepath,
uri: basepath
uri: basepath,
});

const routerBase = derived([base, activeRoute], ([base, activeRoute]) => {
const routerBase = derived([base, activeRoute], ([_base, _activeRoute]) => {
// If there is no activeRoute, the routerBase will be identical to the base.
if (activeRoute === null) {
return base;
if (_activeRoute === null) {
return _base;
}

const { path: basepath } = base;
const { route, uri } = activeRoute;
const { route, uri } = _activeRoute;
// Remove the potential /* or /*splatname from
// the end of the child Routes relative paths.
const path = route.default ? basepath : route.path.replace(/\*.*$/, "");
const path = route.default ? _base.path : route.path.replace(/\*.*$/, "");

return { path, uri };
});

function registerRoute(route) {
const { path: basepath } = $base;
let { path } = route;

// We store the original path in the _path property so we can reuse
// it when the basepath changes. The only thing that matters is that
// the route reference is intact, so mutation is fine.
// eslint-disable-next-line no-param-reassign
route._path = path;
route.path = combinePaths(basepath, path);
// eslint-disable-next-line no-param-reassign
route.path = combinePaths($base.path, path);

if (typeof window === "undefined") {
// In SSR we should set the activeRoute immediately if it is a match.
Expand Down Expand Up @@ -89,9 +89,11 @@
// This reactive statement will update all the Routes' path when
// the basepath changes.
$: {
const { path: basepath } = $base;
routes.update(rs => {
rs.forEach(r => (r.path = combinePaths(basepath, r._path)));
rs.forEach(route => {
// eslint-disable-next-line no-param-reassign
route.path = combinePaths($base.path, route._path);
});
return rs;
});
}
Expand Down Expand Up @@ -123,8 +125,8 @@
base,
routerBase,
registerRoute,
unregisterRoute
unregisterRoute,
});
</script>

<slot></slot>
<slot />
Loading

0 comments on commit f1d770f

Please # to comment.