Socket
Socket
Sign inDemoInstall

react-breadcrumbs-dynamic

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-breadcrumbs-dynamic - npm Package Compare versions

Comparing version 1.0.10 to 1.0.11

coverage/lcov-report/src/through.js.html

307

dist/src/index.js

@@ -6,17 +6,6 @@ 'use strict';

});
exports.Breadcrumbs = exports.BreadcrumbsItem = exports.BreadcrumbsProvider = exports.Item = exports.Dummy = undefined;
exports.Breadcrumbs = exports.BreadcrumbsItem = exports.BreadcrumbsProvider = exports.Item = exports.Dummy = exports.withBreadcrumbsItem = exports.withBreadcrumbs = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _class2, _temp, _initialiseProps, _class3, _temp2;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.withBreadcrumbs = withBreadcrumbs;
exports.withBreadcrumbsItem = withBreadcrumbsItem;
var _react = require('react');

@@ -30,101 +19,14 @@

var _reactBroadcast = require('react-broadcast');
var _reactThrough = require('react-through');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
var withBreadcrumbs = exports.withBreadcrumbs = (0, _reactThrough.throughInterface)('breadcrumbs');
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var withBreadcrumbsItem = exports.withBreadcrumbsItem = (0, _reactThrough.throughAgent)('breadcrumbs', 'to');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var MAX_DATA_NUM = 1000000;
function withBreadcrumbs(BreadcrumbsComponent) {
var Breadcrumbs = function Breadcrumbs(props, context) {
return _react2.default.createElement(
_reactBroadcast.Subscriber,
{ channel: 'breadcrumbs' },
function (breadcrumbs) {
return _react2.default.createElement(BreadcrumbsComponent, _extends({}, props, { breadcrumbs: breadcrumbs }));
}
);
};
return Breadcrumbs;
}
function withBreadcrumbsItem(BreadcrumbsComponent) {
var WithBreadcrumbsItem = function (_React$Component) {
_inherits(WithBreadcrumbsItem, _React$Component);
function WithBreadcrumbsItem(props, context) {
_classCallCheck(this, WithBreadcrumbsItem);
var _this = _possibleConstructorReturn(this, (WithBreadcrumbsItem.__proto__ || Object.getPrototypeOf(WithBreadcrumbsItem)).call(this, props, context));
_this.componentWillMount = function () {
_this.update(_this.data);
};
_this.componentWillUnmount = function () {
_this.update({});
};
_this.item = function (elem) {
var data = !elem || !elem.props.to ? {} : _defineProperty({}, elem.props.to, elem.props);
_this.update(data);
};
_this.items = function (elem) {
var data = {};
_react2.default.Children.forEach(elem.props.children, function (elem) {
if (!elem || !elem.props.to) {
return;
}
data[elem.props.to] = elem.props;
});
_this.update(data);
};
_this.update = function (data) {
var remove = Object.keys(_this.data).filter(function (to) {
return !data.hasOwnProperty(to);
});
remove.forEach(function (to) {
return _this.props.breadcrumbs.remove(to);
});
Object.keys(data).forEach(function (to) {
return _this.props.breadcrumbs.install(to, data[to], true);
});
_this.data = data;
};
_this.data = {};
return _this;
}
_createClass(WithBreadcrumbsItem, [{
key: 'render',
value: function render() {
var item = this.item,
items = this.items;
var bc = Object.assign({ item: item, items: items }, this.props.breadcrumbs);
return _react2.default.createElement(BreadcrumbsComponent, _extends({}, this.props, { breadcrumbs: bc }));
}
}]);
return WithBreadcrumbsItem;
}(_react2.default.Component);
return withBreadcrumbs(WithBreadcrumbsItem);
}
var Dummy = exports.Dummy = function Dummy() {
return null;
};
var Item = exports.Item = function Item() {

@@ -134,196 +36,6 @@ return null;

var BreadcrumbsProvider = exports.BreadcrumbsProvider = (_temp = _class2 = function (_React$Component2) {
_inherits(BreadcrumbsProvider, _React$Component2);
var BreadcrumbsProvider = exports.BreadcrumbsProvider = _reactThrough.ThroughProvider;
function BreadcrumbsProvider(props) {
_classCallCheck(this, BreadcrumbsProvider);
var BreadcrumbsItem = exports.BreadcrumbsItem = (0, _reactThrough.throughAgentFactory)('breadcrumbs', 'to');
var _this2 = _possibleConstructorReturn(this, (BreadcrumbsProvider.__proto__ || Object.getPrototypeOf(BreadcrumbsProvider)).call(this, props));
_initialiseProps.call(_this2);
_this2.state = {
dataNum: MAX_DATA_NUM
};
_this2.data = {};
_this2.timer = undefined;
_this2.dataNum = MAX_DATA_NUM;
_this2.mounted = false;
return _this2;
}
_createClass(BreadcrumbsProvider, [{
key: 'componentWillMount',
value: function componentWillMount() {
this.canSetState = true;
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.canSetState = false;
}
}, {
key: 'doUpdate',
value: function doUpdate(syncUpdate) {
var _this3 = this;
++this.dataNum;
if (syncUpdate) {
if (this.canSetState) {
this.setState({ dataNum: this.dataNum });
}
return;
}
if (!this.timer) {
this.timer = setTimeout(function () {
if (_this3.dataNum > MAX_DATA_NUM) {
_this3.dataNum = 0;
}
if (_this3.canSetState) {
_this3.setState({ dataNum: _this3.dataNum });
}
_this3.timer = undefined;
}, 0);
}
}
}, {
key: '_diffAndComplicatedCounts',
value: function _diffAndComplicatedCounts(prevProps, props) {
var keys = Object.keys(prevProps).concat(Object.keys(props));
// reflect types in the documentation if changed
var quicks = ['string', 'number', 'undefined', 'boolean', 'symbol'];
var _keys$reduce = keys.reduce(function (stat, k) {
return [stat[0] + (prevProps[k] !== props[k] ? 1 : 0), stat[1] + (!quicks.includes(_typeof(props[k])) ? 1 : 0)];
}, [0, 0]),
_keys$reduce2 = _slicedToArray(_keys$reduce, 2),
diff = _keys$reduce2[0],
comp = _keys$reduce2[1];
return [diff, comp];
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
_reactBroadcast.Broadcast,
{ channel: 'breadcrumbs', value: {
data: this.data,
install: this.install,
remove: this.remove
} },
this.props.children
);
}
}]);
return BreadcrumbsProvider;
}(_react2.default.Component), _class2.propTypes = {
shouldBreadcrumbsUpdate: _propTypes2.default.func
}, _initialiseProps = function _initialiseProps() {
var _this4 = this;
this.install = function (to, props) {
var syncUpdate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
if (!(typeof to === 'string' || to instanceof String) || !(props instanceof Object && !(props instanceof Array))) {
throw new Error("type error: breadcrumbs.install(to:string, props:Object)");
}
var prevProps = _this4.data[to] || {};
if (_this4.props.shouldBreadcrumbsUpdate) {
var diff = _this4.props.shouldBreadcrumbsUpdate(prevProps, props);
if (!diff) return;
syncUpdate = true;
} else {
var _diffAndComplicatedCo = _this4._diffAndComplicatedCounts(prevProps, props),
_diffAndComplicatedCo2 = _slicedToArray(_diffAndComplicatedCo, 2),
_diff = _diffAndComplicatedCo2[0],
comp = _diffAndComplicatedCo2[1];
if (!_diff) return;
if (undefined === syncUpdate) {
syncUpdate = !comp;
}
}
var data = Object.assign({}, _this4.data);
data[to] = _extends({}, props);
_this4.data = data;
_this4.doUpdate(syncUpdate);
};
this.remove = function (to) {
if (_this4.data.hasOwnProperty(to)) {
var data = Object.assign({}, _this4.data);
delete data[to];
_this4.data = data;
_this4.doUpdate(true);
}
};
}, _temp);
var BreadcrumbsItem_ = (_temp2 = _class3 = function (_React$Component3) {
_inherits(BreadcrumbsItem_, _React$Component3);
function BreadcrumbsItem_(props) {
_classCallCheck(this, BreadcrumbsItem_);
var _this5 = _possibleConstructorReturn(this, (BreadcrumbsItem_.__proto__ || Object.getPrototypeOf(BreadcrumbsItem_)).call(this, props));
var _props$breadcrumbs = props.breadcrumbs,
install = _props$breadcrumbs.install,
remove = _props$breadcrumbs.remove;
_this5.install = install;
_this5.remove = remove;
return _this5;
}
_createClass(BreadcrumbsItem_, [{
key: 'componentWillMount',
value: function componentWillMount() {
var _props = this.props,
breadcrumbs = _props.breadcrumbs,
props = _objectWithoutProperties(_props, ['breadcrumbs']);
this.install(props.to, props);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(_ref2) {
var breadcrumbs = _ref2.breadcrumbs,
nextProps = _objectWithoutProperties(_ref2, ['breadcrumbs']);
var props = _objectWithoutProperties(this.props, []);
delete props.breadcrumbs;
if (this.props.to !== nextProps.to) {
this.remove(this.props.to);
}
this.install(nextProps.to, nextProps);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.remove(this.props.to);
}
}, {
key: 'render',
value: function render() {
return null;
}
}]);
return BreadcrumbsItem_;
}(_react2.default.Component), _class3.propTypes = {
to: _propTypes2.default.string.isRequired
}, _temp2);
var BreadcrumbsItem = exports.BreadcrumbsItem = withBreadcrumbs(BreadcrumbsItem_);
function propsRenAndDup(props, ren, dup) {

@@ -341,4 +53,3 @@ var p = Object.assign({}, props);

var Breadcrumbs_ = function Breadcrumbs_(props) {
var data = props.breadcrumbs.data;
var data = props.breadcrumbs;
var pathnames = Object.keys(data).sort(function (a, b) {

@@ -373,2 +84,2 @@ return a.length - b.length;

var Breadcrumbs = exports.Breadcrumbs = withBreadcrumbs(Breadcrumbs_);
var Breadcrumbs = exports.Breadcrumbs = (0, _reactThrough.throughContainer)('breadcrumbs')(Breadcrumbs_);
{
"name": "react-breadcrumbs-dynamic",
"version": "1.0.10",
"version": "1.0.11",
"description": "React dynamic breadcrumbs extremely flexible and easy to use",

@@ -26,2 +26,4 @@ "main": "dist/src/index.js",

"babel-cli": "^6.24.1",
"babel-core": "^6.26.0",
"babel-jest": "^21.2.0",
"babel-loader": "^7.1.1",

@@ -33,16 +35,18 @@ "babel-plugin-transform-decorators-legacy": "^1.3.4",

"chai": "^4.1.2",
"codecov": "^2.3.0",
"enzyme": "^2.9.1",
"codecov": "^3.0.0",
"enzyme": "^3.2.0",
"enzyme-adapter-react-15": "^1.0.5",
"jest": "^21.2.1",
"react": "^15.6.2",
"react-addons-test-utils": "^15.6.2",
"react-bootstrap": "^0.31.2",
"react-bootstrap": "^0.31.5",
"react-dom": "^15.6.2",
"react-router-bootstrap": "^0.24.4",
"react-router-dom": "^4.2.2",
"webpack": "^3.3.0",
"webpack-dev-server": "^2.9.1"
"react-test-renderer": "^16.2.0",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.7"
},
"dependencies": {
"react-broadcast": "^0.5.2"
"react-through": "^1.0.2"
},

@@ -69,3 +73,7 @@ "jest": {

"jsx"
]
],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.jsx$": "babel-jest"
}
},

@@ -89,4 +97,5 @@ "scripts": {

"prepublish": "npm run build",
"test": "jest --coverage"
"test": "jest --coverage",
"test-debug": "jest --bail --verbose"
}
}

@@ -34,2 +34,3 @@ # react-breadcrumbs-dynamic

# definitions may be installed if typescript is used
# ( worked for 1.0.10, leave feedback if any )
npm install --save @types/react-breadcrumbs-dynamic

@@ -40,15 +41,15 @@ ```

Add a `<BreadcrumbsProvider/>` component to the root of your React component
tree like you do it for `react-redux` or `react-router`.
In the react tree the `BreadcrumbsProvider` component must be parent of all
components of this library with any deeps of nesting. See also
*Advanced Usage and Performance* section.
Add a `<ThroughProvider/>` component to the root of your React component
tree like you do it for `react-redux` or `react-router` if you does not use
that yet. Read more about `ThroughProvider` in
[react-through](https://github.com/oklas/react-through) manual.
The `through area` name used by this library is `breadcrumbs`
``` javascript
import {BreadcrumbsProvider} from 'react-breadcrumbs-dynamic'
import {ThroughProvider} from 'react-through'
const theApp = (
<BreadcrumbsProvider>
<ThroughProvider>
<App />
</BreadcrumbsProvider>
</ThroughProvider>
)

@@ -62,7 +63,9 @@

The breadcrumbs instance is implemented in the `Breadcrumbs` component. The
`Breadcrumbs` component needs to be configured, however all params have default
value. In this example the `react-router` v4 routing specification is used.
Please note that `item` and `finalItem` require react component (class) instead
of react element. However `separator` requires react element.
The breadcrumbs instance is implemented in the `Breadcrumbs` component, which is
the `through container` in terms of
[react-through](https://github.com/oklas/react-through).
The `Breadcrumbs` component needs to be configured, however all params have
default value. In this example the `react-router` v4 routing specification is
used. Please note that `item` and `finalItem` require react component (class)
instead of react element. However `separator` requires react element.

@@ -99,7 +102,12 @@ ``` javascript

and with correspondent breadcrumbs. Each component may add its breadcrumbs
item. The `BreadcrumbsItem` component mandatory requires the `to` prop which
item by instantiate `BreadcrumbsItem` component. The `BreadcrumbsItem`
component which is the `through agent` with bearing key in prop `to` in
terms of [react-through](https://github.com/oklas/react-through).
The `BreadcrumbsItem` component mandatory requires the `to` prop which
contains bearing key with URL for breadcrumbs working. So if you use simple
`<a>` tag for breadcrumb url - you need to use the `duplicateProps` and/or
`renameProps`, or need to specify both `to` and `href`.
See also *Advanced Usage and Performance* section.
Read also *Advanced Usage and Performance* section in
[react-through](https://github.com/oklas/react-through) manual.

@@ -120,3 +128,2 @@ Simple configure of the breadcrumbs items:

const User = (props) => (

@@ -153,146 +160,8 @@ <div>

If you use library or if you think that it is good for use -
let people know about that - click the star.
___
# Advanced Usage and Performance
This library makes everything possible to make the things simple and effective.
However, the library cannot know about your application state nor
can undertake deep inspections of your data to detect changes in efficiency
considerations.
## Avoid to pass arrays/objects/jsx in props of `BreadcrumbsItem`
When jsx code like this: `<tag>...</tag>` or `<Component t='...'/>`
is evaluated the new react element instance is created even if the same props
was passed. Same thing is when code contains `{}` or `[]` - the new object or
array is created in-place. All this cases represents new instance which is
considered as value change event even if this arrays/objects/jsx have same
values in depth.
The Library does not analyze data into depth to detect changes. So when you
pass new react element or newly created array or object to `BreadcrumbsItem`
as props it receives same props with new value. It gives proper result but
applying params will be defered to additional tree rerendering step and
executed after all again.
Full complete list of types allowed as `BreadcrumbsItem` props for better
performance:
* string
* number
* undefined
* boolean
* symbol
So to avoid additional processing you should not specify arrays or objects or react
elements (ie jsx) as props of `BreadcrumbsItem` in `render()` method:
``` javascript
render() {
return <BreadcrumbsItem to='/' title={<b>Main Page</b>} x={[1,2,3]}/> // bad
}
render() {
return <BreadcrumbsItem to='/'><b>Main Page</b></BreadcrumbsItem> // bad
}
render() {
return <BreadcrumbsItem to='/'>Main Page</BreadcrumbsItem> // good
}
```
## Custom update filter
Another way is to use breadcrumbs item update filter. This is achieved by
specifying the function in `shouldBreadcrumbsUpdate` param of
`BreadcrumbsProvider` like this:
``` javascript
const theApp = (
<BreadcrumbsProvider
shouldBreadcrumbsUpdate = {
(prevProps, props) => {
// custom breadcrumbs item update filter condition
return prevProps.to != props.to
}
}
/>
<App />
</BreadcrumbsProvider>
)
```
The item update filter must guarantee that the difference in the params
are really due to different source data. For example condition
`{k:'v'} != {k:'v'}` shows that this is the different data, although in
fact source data is the same and has not been changed.
**Warning:** if update filter determines the data changing at the time when
the original data has been unchanged this forms an infinite loop.
On the other hand, if some data is not recognized as changed, the breadcrumbs
will not be updated and will not look like expected.
## Alternate usage
An alternative, more flexible and at the same time more complicated way is to
update breadcrumbs only when related to breadcrubms item data is changed.
The library provides interface for that. The higher order
component creation function `withBreadcrumbsItem` will integrate `breadcrumbs`
object with `item()` and `items()` functions into props of your `Component`.
**Warning**: Never call `breadcrumbs.item()` or `breadcrumbs.items()` from
`render()` or `componentWillUpdate()` methods or from `constructor()` of your
component. This means breadcrumbs item must be not depend from state of
your current "with breadcrubms" component.
This way allows to specify arrays and objects and react elements (i.e. jsx) in
props but functions `breadcrumbs.item()` or `breadcrumbs.items()` must be
called from the `if` statement, where is the update condition which
checks for changes the application related to breadcrubms item data.
**Warning:** if update condition determines the data changing at the time when
the original data has been unchanged this forms an infinite loop.
``` javascript
import { withBreadcrumbsItem, Dummy as Item } from 'react-breadcrumbs-dynamic'
@withBreadcrumbsItem
class CustomComponent extends React.Component {
static propTypes = {
breadcrumbs: PropTypes.object,
}
componentWillMount() {
this.configureBreadcrumbs(this.props)
}
componentWillReceiveProps(nextProps) {
// mandatory required update filter condition
if( this.props.slug !== nextProps.slug ) {
this.configureBreadcrumbs(nextProps)
}
}
configureBreadcrumbs = (props) => {
props.breadcrumbs.items(
<div>
<Item to='/' some={[1,2,3]}><b>Home</b></Item>
<Item to=`/${props.slug}`><b>{props.slug}</b></Item>
</div>
)
}
render() {
return (
<div />
)
}
}
```
# The components and functions

@@ -322,11 +191,2 @@

## `BreadcrumbsProvider` component props
The `BreadcrumbsProvider` props:
* `shouldBreadcrumbsUpdate` - custom breadcrumbs item update filter which is
the function with two args, where first arg is `prevProps` and second arg is
`props` - previous and current breadcrumbs item props respectively.
## `withBreadcrumbsItem()` function

@@ -336,6 +196,7 @@

custom react component and return appropriate component which will have
`breadcrumbs` in its props with methods `item()` and `items()`.
`breadcrumbs` in its props with methods `item()` and `items()`
like `throughAgent` from [react-through](https://github.com/oklas/react-through).
## `this.props.breadcrumbs.item()` and `this.props.breadcrumbs.items()`
### `this.props.breadcrumbs.item()` and `this.props.breadcrumbs.items()`

@@ -342,0 +203,0 @@ Methods to configure breadcrumbs item of your current react component.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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