Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

peppermint-router

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

peppermint-router - npm Package Compare versions

Comparing version 0.0.2 to 0.1.0

src/components/PromptNavigation.tsx

6

CHANGELOG.md

@@ -5,2 +5,8 @@ # Change Log

## [0.1.0 - 2018-07-26](https://github.com/alonrbar/peppermint-router/tree/v0.1.0)
### Added
- PromptNavigation component.
## [0.0.2 - 2018-07-26](https://github.com/alonrbar/peppermint-router/tree/v0.0.2)

@@ -7,0 +13,0 @@

26

dist/index.d.ts

@@ -79,2 +79,6 @@ import * as React from 'react';

//
// RouteFallback
//
export interface RouteFallbackProps {

@@ -84,2 +88,22 @@ component: React.ComponentType<any>;

export class RouteFallback extends React.Component<RouteFallbackProps> { }
export class RouteFallback extends React.Component<RouteFallbackProps> { }
//
// PromptNavigation
//
export interface PromptNavigationRenderProps {
isNavigating: boolean;
confirm: VoidFunction;
cancel: VoidFunction;
}
export type PromptNavigationRender = (props: PromptNavigationRenderProps) => React.ReactNode;
export interface PromptNavigationProps {
enabled?: boolean;
exitPrompt?: string;
children?: PromptNavigationRender;
}
export const PromptNavigation: React.FunctionComponent<PromptNavigationProps>;

167

dist/peppermint-router.cjs.js

@@ -7,5 +7,72 @@ 'use strict';

var React = require('react');
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty'));
var React = require('react');
function removeStart(str, ...toRemove) {
return removeSide(str, /^(\s*[\r\n]*)*/, String.prototype.startsWith, (s, tr) => s.substring(tr.length), ...toRemove);
}
function removeEnd(str, ...toRemove) {
return removeSide(str, /(\s*[\r\n]*)*$/, String.prototype.endsWith, (s, tr) => s.substring(0, s.length - tr.length), ...toRemove);
}
function removeSide(str, whitespaceReplacePattern, shouldRemove, remove, ...toRemove) {
// input validation
if (typeof str !== "string") {
throw new Error(`Missing arguement '${"str"}'.`);
}
if (!toRemove.every(tr => typeof tr === 'string')) {
throw new Error(`Invalid argument '${toRemove}'. Only strings expected.`);
} // default behavior: trim white spaces
if (!toRemove.length) {
return str.replace(whitespaceReplacePattern, "");
} // trim specified patterns
let result = str.substring(0);
let keepRunning = true;
while (result.length && keepRunning) {
keepRunning = false;
for (const trimStr of toRemove) {
if (!shouldRemove.call(result, trimStr)) continue;
result = remove(result, trimStr);
keepRunning = true;
}
}
return result;
}
class WaitHandle {
constructor() {
_defineProperty(this, "_resolve", void 0);
_defineProperty(this, "_reject", void 0);
_defineProperty(this, "promise", void 0);
this.promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}
wait() {
return this.promise;
}
resolve(result) {
this._resolve(result);
}
reject(err) {
this._reject(err);
}
}
const RouterContext =

@@ -15,2 +82,59 @@ /*#__PURE__*/

function PromptNavigation(props) {
const context = React.useContext(RouterContext);
const [state, setState] = React.useState({
isNavigating: false
});
React.useEffect(() => {
// in-app navigation handler
if (props.enabled !== false && props.children) {
context.router.onBeforeNavigation = async () => {
const confirmNavigation = new WaitHandle();
setState({
isNavigating: true,
confirmNavigation
});
let confirmed = true;
await confirmNavigation.wait().catch(() => confirmed = false);
return confirmed;
};
} // out-of-app navigation handler
if (props.enabled !== false && props.exitPrompt) {
context.router.onBeforeUnload = () => props.exitPrompt;
} // dispose
return () => {
context.router.onBeforeNavigation = null;
context.router.onBeforeUnload = null;
};
});
const clearState = () => setState({
isNavigating: false,
confirmNavigation: null
}); // render
if (props.enabled !== false && props.children) {
return props.children({
isNavigating: state.isNavigating,
confirm: () => {
const confirm = state.confirmNavigation;
clearState();
confirm && confirm.resolve();
},
cancel: () => {
const confirm = state.confirmNavigation;
clearState();
confirm && confirm.reject();
}
});
}
return null;
}
class Route extends React.Component {

@@ -70,41 +194,2 @@ constructor(...args) {

function removeStart(str, ...toRemove) {
return removeSide(str, /^(\s*[\r\n]*)*/, String.prototype.startsWith, (s, tr) => s.substring(tr.length), ...toRemove);
}
function removeEnd(str, ...toRemove) {
return removeSide(str, /(\s*[\r\n]*)*$/, String.prototype.endsWith, (s, tr) => s.substring(0, s.length - tr.length), ...toRemove);
}
function removeSide(str, whitespaceReplacePattern, shouldRemove, remove, ...toRemove) {
// input validation
if (typeof str !== "string") {
throw new Error(`Missing arguement '${"str"}'.`);
}
if (!toRemove.every(tr => typeof tr === 'string')) {
throw new Error(`Invalid argument '${toRemove}'. Only strings expected.`);
} // default behavior: trim white spaces
if (!toRemove.length) {
return str.replace(whitespaceReplacePattern, "");
} // trim specified patterns
let result = str.substring(0);
let keepRunning = true;
while (result.length && keepRunning) {
keepRunning = false;
for (const trimStr of toRemove) {
if (!shouldRemove.call(result, trimStr)) continue;
result = remove(result, trimStr);
keepRunning = true;
}
}
return result;
}
class HashRouter {

@@ -143,3 +228,2 @@ constructor() {

// restore location hash
window.history.replaceState(null, null, this._currentRoute.path);
this.goTo(this._currentRoute.path);

@@ -347,2 +431,3 @@ return;

exports.HashRouter = HashRouter;
exports.PromptNavigation = PromptNavigation;
exports.Route = Route;

@@ -349,0 +434,0 @@ exports.RouteFallback = RouteFallback;

@@ -0,4 +1,71 @@

import { createContext, useContext, useState, useEffect, Component, createElement } from 'react';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import { createContext, Component, createElement } from 'react';
function removeStart(str, ...toRemove) {
return removeSide(str, /^(\s*[\r\n]*)*/, String.prototype.startsWith, (s, tr) => s.substring(tr.length), ...toRemove);
}
function removeEnd(str, ...toRemove) {
return removeSide(str, /(\s*[\r\n]*)*$/, String.prototype.endsWith, (s, tr) => s.substring(0, s.length - tr.length), ...toRemove);
}
function removeSide(str, whitespaceReplacePattern, shouldRemove, remove, ...toRemove) {
// input validation
if (typeof str !== "string") {
throw new Error(`Missing arguement '${"str"}'.`);
}
if (!toRemove.every(tr => typeof tr === 'string')) {
throw new Error(`Invalid argument '${toRemove}'. Only strings expected.`);
} // default behavior: trim white spaces
if (!toRemove.length) {
return str.replace(whitespaceReplacePattern, "");
} // trim specified patterns
let result = str.substring(0);
let keepRunning = true;
while (result.length && keepRunning) {
keepRunning = false;
for (const trimStr of toRemove) {
if (!shouldRemove.call(result, trimStr)) continue;
result = remove(result, trimStr);
keepRunning = true;
}
}
return result;
}
class WaitHandle {
constructor() {
_defineProperty(this, "_resolve", void 0);
_defineProperty(this, "_reject", void 0);
_defineProperty(this, "promise", void 0);
this.promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}
wait() {
return this.promise;
}
resolve(result) {
this._resolve(result);
}
reject(err) {
this._reject(err);
}
}
const RouterContext =

@@ -8,2 +75,59 @@ /*#__PURE__*/

function PromptNavigation(props) {
const context = useContext(RouterContext);
const [state, setState] = useState({
isNavigating: false
});
useEffect(() => {
// in-app navigation handler
if (props.enabled !== false && props.children) {
context.router.onBeforeNavigation = async () => {
const confirmNavigation = new WaitHandle();
setState({
isNavigating: true,
confirmNavigation
});
let confirmed = true;
await confirmNavigation.wait().catch(() => confirmed = false);
return confirmed;
};
} // out-of-app navigation handler
if (props.enabled !== false && props.exitPrompt) {
context.router.onBeforeUnload = () => props.exitPrompt;
} // dispose
return () => {
context.router.onBeforeNavigation = null;
context.router.onBeforeUnload = null;
};
});
const clearState = () => setState({
isNavigating: false,
confirmNavigation: null
}); // render
if (props.enabled !== false && props.children) {
return props.children({
isNavigating: state.isNavigating,
confirm: () => {
const confirm = state.confirmNavigation;
clearState();
confirm && confirm.resolve();
},
cancel: () => {
const confirm = state.confirmNavigation;
clearState();
confirm && confirm.reject();
}
});
}
return null;
}
class Route extends Component {

@@ -63,41 +187,2 @@ constructor(...args) {

function removeStart(str, ...toRemove) {
return removeSide(str, /^(\s*[\r\n]*)*/, String.prototype.startsWith, (s, tr) => s.substring(tr.length), ...toRemove);
}
function removeEnd(str, ...toRemove) {
return removeSide(str, /(\s*[\r\n]*)*$/, String.prototype.endsWith, (s, tr) => s.substring(0, s.length - tr.length), ...toRemove);
}
function removeSide(str, whitespaceReplacePattern, shouldRemove, remove, ...toRemove) {
// input validation
if (typeof str !== "string") {
throw new Error(`Missing arguement '${"str"}'.`);
}
if (!toRemove.every(tr => typeof tr === 'string')) {
throw new Error(`Invalid argument '${toRemove}'. Only strings expected.`);
} // default behavior: trim white spaces
if (!toRemove.length) {
return str.replace(whitespaceReplacePattern, "");
} // trim specified patterns
let result = str.substring(0);
let keepRunning = true;
while (result.length && keepRunning) {
keepRunning = false;
for (const trimStr of toRemove) {
if (!shouldRemove.call(result, trimStr)) continue;
result = remove(result, trimStr);
keepRunning = true;
}
}
return result;
}
class HashRouter {

@@ -136,3 +221,2 @@ constructor() {

// restore location hash
window.history.replaceState(null, null, this._currentRoute.path);
this.goTo(this._currentRoute.path);

@@ -339,3 +423,3 @@ return;

export { HashRouter, Route, RouteFallback, RouterContext, RouterView };
export { HashRouter, PromptNavigation, Route, RouteFallback, RouterContext, RouterView };
//# sourceMappingURL=peppermint-router.esm.js.map
{
"name": "peppermint-router",
"description": "Lightweight hash router for React",
"version": "0.0.2",
"version": "0.1.0",
"author": "Alon Bar",

@@ -16,7 +16,8 @@ "license": "MIT",

"scripts": {
"dev": "rollup -c -w",
"dev": "concurrently \"yarn build -w\" \"yarn typecheck --watch\"",
"typecheck": "tsc --noEmit",
"lint": "eslint \"./src/**/!(*.d).ts\"",
"test": "cd test && yarn start",
"release": "yarn typecheck && yarn lint && rollup -c"
"build": "rollup -c",
"release": "yarn typecheck && yarn lint && yarn build"
},

@@ -46,2 +47,3 @@ "dependencies": {

"babel-plugin-ts-nameof": "0.3.0",
"concurrently": "4.1.1",
"eslint": "5.16.0",

@@ -48,0 +50,0 @@ "eslint-plugin-react": "7.14.3",

@@ -5,2 +5,9 @@ # peppermint-router

[![package size](https://img.shields.io/bundlephobia/minzip/peppermint-router?label=minified%20gzipped)](https://bundlephobia.com/result?p=peppermint-router)
[![npm version](https://img.shields.io/npm/v/peppermint-router.svg?label=version)](https://www.npmjs.com/package/peppermint-router)
[![npm license](https://img.shields.io/npm/l/peppermint-router.svg)](https://www.npmjs.com/package/peppermint-router)
[![dependencies](https://david-dm.org/alonrbar/peppermint-router.svg)](https://github.com/alonrbar/peppermint-router)
## The gist
```jsx

@@ -14,1 +21,36 @@ <RouterView>

```
## Prompt navigation
```jsx
<PromptNavigation
enabled={true}
exitPrompt="Leave the application?"
>
{({ isNavigating, confirm, cancel }) => (
isNavigating && (
<div>
<span>Move to another page?</span>
<button onClick={confirm}>Confirm</button>
<button onClick={cancel}>Cancel</button>
</div>
)
)}
</PromptNavigation>
```
## Why?
- Extremely compact - less than 2kb gzipped!
- Does not require special `<Link>` tags and other boilerplate.
- `<PromptNavigation>` component with custom prompt out of the box.
## Why not?
- Only hash routes
- No SSR support
- No React Native support
## Changelog
The change log can be found [here](https://github.com/alonrbar/peppermint-router/blob/master/CHANGELOG.md).

@@ -0,1 +1,2 @@

export * from './PromptNavigation';
export * from './Route';

@@ -2,0 +3,0 @@ export * from './RouteFallback';

@@ -169,3 +169,2 @@ import { IMap, removeEnd, removeStart } from '../utils';

// restore location hash
window.history.replaceState(null, null, this._currentRoute.path);
this.goTo(this._currentRoute.path);

@@ -172,0 +171,0 @@ return;

export * from './types';
export * from './utils';
export * from './waitHandle';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc