Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Add Storage component.
Browse files Browse the repository at this point in the history
  • Loading branch information
T4rk1n committed Jul 27, 2018
1 parent b828083 commit 02320a8
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
105 changes: 105 additions & 0 deletions src/components/Storage.react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react';
import PropTypes from 'prop-types';

/**
* Wrapper around the Web Storage api.
* Persistent data storage on the client side. Keep the data upon refreshes.
*/
export default class Storage extends React.Component {
constructor(props) {
super(props);
this._backstore = props.storage_type === 'local' ?
window.localStorage : window.sessionStorage;
this.onStorageChange = this.onStorageChange.bind(this);
}

getItem(key) {
return JSON.parse(this._backstore.getItem(key));
}

setItem(key, value) {
this._backstore.setItem(key, typeof value === 'string' ?
value : JSON.stringify(value));
}

removeItem(key) {
this._backstore.removeItem(key);
}

onStorageChange(e) {
const { id, setProps} = this.props;
if (e.key === id && setProps && e.newValue !== e.oldValue) {
setProps({data: JSON.parse(e.newValue)});
}
}

componentWillMount() {
window.addEventListener('storage', this.onStorageChange);
const { setProps, id, data } = this.props;
if (setProps) {
// Take the data from storage, ignore the prop data on load.
const data = this.getItem(id);
if (data) {
setProps({data});
return;
}
}
if (data) {
this.setItem(id, data);
}
}

componentWillUnmount() {
window.removeEventListener('storage', this.onStorageChange);
}

componentDidUpdate() {
const { data, id, clear_data, setProps } = this.props;
if (clear_data) {
this.removeItem(id);
if (setProps) {
setProps({clear_data: false, data: null})
}
} else if (data) {
this.setItem(id, data);
}
}

render() {
return null;
}
}

Storage.defaultProps = {
storage_type: 'local',
clear_data: false
};

Storage.propTypes = {
/**
* The key of the storage.
*/
id: PropTypes.string.isRequired,

/**
* The type of the web storage.
* local -> window.localStorage: data is kept after the browser quit.
* session -> window.sessionStorage: data is cleared once the browser quit.
*/
storage_type: PropTypes.oneOf(['local', 'session']),

/**
* The stored data for the key.
*/
data: PropTypes.object,

/**
* Set to true to remove the data contained in `data_key`.
*/
clear_data: PropTypes.bool,

/**
* Dash-assigned callback that gets fired when the value changes.
*/
setProps: PropTypes.func
};
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import DatePickerRange from './components/DatePickerRange.react';
import Upload from './components/Upload.react';
import Tabs from './components/Tabs.react';
import Tab from './components/Tab.react';
import Storage from './components/Storage.react';

export {
Checklist,
Expand All @@ -40,5 +41,6 @@ export {
Textarea,
DatePickerSingle,
DatePickerRange,
Upload
Upload,
Storage
};

0 comments on commit 02320a8

Please sign in to comment.