version inicial de libreria
This commit is contained in:
parent
785c748cb9
commit
9bb2653f9c
132
.gitignore
vendored
132
.gitignore
vendored
@ -1,132 +0,0 @@
|
||||
# ---> Node
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
22
LICENSE
22
LICENSE
@ -1,9 +1,21 @@
|
||||
MIT License
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 dehernandezm
|
||||
Copyright (c) 2017 Plotly, Inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
66
PivotTable.js
Normal file
66
PivotTable.js
Normal file
@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
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 _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _propTypes = require('prop-types');
|
||||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
var _Utilities = require('./Utilities');
|
||||
|
||||
var _TableRenderers = require('./TableRenderers');
|
||||
|
||||
var _TableRenderers2 = _interopRequireDefault(_TableRenderers);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
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; }
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
// eslint can't see inherited propTypes!
|
||||
|
||||
var PivotTable = function (_React$PureComponent) {
|
||||
_inherits(PivotTable, _React$PureComponent);
|
||||
|
||||
function PivotTable() {
|
||||
_classCallCheck(this, PivotTable);
|
||||
|
||||
return _possibleConstructorReturn(this, (PivotTable.__proto__ || Object.getPrototypeOf(PivotTable)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(PivotTable, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var Renderer = this.props.renderers[this.props.rendererName in this.props.renderers ? this.props.rendererName : Object.keys(this.props.renderers)[0]];
|
||||
return _react2.default.createElement(Renderer, this.props);
|
||||
}
|
||||
}]);
|
||||
|
||||
return PivotTable;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
PivotTable.propTypes = Object.assign({}, _Utilities.PivotData.propTypes, {
|
||||
rendererName: _propTypes2.default.string,
|
||||
renderers: _propTypes2.default.objectOf(_propTypes2.default.func)
|
||||
});
|
||||
|
||||
PivotTable.defaultProps = Object.assign({}, _Utilities.PivotData.defaultProps, {
|
||||
rendererName: 'Table',
|
||||
renderers: _TableRenderers2.default
|
||||
});
|
||||
|
||||
exports.default = PivotTable;
|
||||
module.exports = exports['default'];
|
||||
//# sourceMappingURL=PivotTable.js.map
|
1
PivotTable.js.map
Normal file
1
PivotTable.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["src/PivotTable.jsx"],"names":["PivotTable","Renderer","props","renderers","rendererName","Object","keys","React","PureComponent","propTypes","assign","PivotData","PropTypes","string","objectOf","func","defaultProps","TableRenderers"],"mappings":";;;;;;;;AAAA;;;;AACA;;;;AACA;;AACA;;;;;;;;;;;;AAEA;AACA;;IAEMA,U;;;;;;;;;;;6BACK;AACP,UAAMC,WAAW,KAAKC,KAAL,CAAWC,SAAX,CACf,KAAKD,KAAL,CAAWE,YAAX,IAA2B,KAAKF,KAAL,CAAWC,SAAtC,GACI,KAAKD,KAAL,CAAWE,YADf,GAEIC,OAAOC,IAAP,CAAY,KAAKJ,KAAL,CAAWC,SAAvB,EAAkC,CAAlC,CAHW,CAAjB;AAKA,aAAO,8BAAC,QAAD,EAAc,KAAKD,KAAnB,CAAP;AACD;;;;EARsBK,gBAAMC,a;;AAW/BR,WAAWS,SAAX,GAAuBJ,OAAOK,MAAP,CAAc,EAAd,EAAkBC,qBAAUF,SAA5B,EAAuC;AAC5DL,gBAAcQ,oBAAUC,MADoC;AAE5DV,aAAWS,oBAAUE,QAAV,CAAmBF,oBAAUG,IAA7B;AAFiD,CAAvC,CAAvB;;AAKAf,WAAWgB,YAAX,GAA0BX,OAAOK,MAAP,CAAc,EAAd,EAAkBC,qBAAUK,YAA5B,EAA0C;AAClEZ,gBAAc,OADoD;AAElED,aAAWc;AAFuD,CAA1C,CAA1B;;kBAKejB,U","file":"PivotTable.js","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport {PivotData} from './Utilities';\nimport TableRenderers from './TableRenderers';\n\n/* eslint-disable react/prop-types */\n// eslint can't see inherited propTypes!\n\nclass PivotTable extends React.PureComponent {\n render() {\n const Renderer = this.props.renderers[\n this.props.rendererName in this.props.renderers\n ? this.props.rendererName\n : Object.keys(this.props.renderers)[0]\n ];\n return <Renderer {...this.props} />;\n }\n}\n\nPivotTable.propTypes = Object.assign({}, PivotData.propTypes, {\n rendererName: PropTypes.string,\n renderers: PropTypes.objectOf(PropTypes.func),\n});\n\nPivotTable.defaultProps = Object.assign({}, PivotData.defaultProps, {\n rendererName: 'Table',\n renderers: TableRenderers,\n});\n\nexport default PivotTable;\n"]}
|
720
PivotTableUI.js
Normal file
720
PivotTableUI.js
Normal file
@ -0,0 +1,720 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.Dropdown = exports.DraggableAttribute = undefined;
|
||||
|
||||
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 _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _propTypes = require('prop-types');
|
||||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
var _immutabilityHelper = require('immutability-helper');
|
||||
|
||||
var _immutabilityHelper2 = _interopRequireDefault(_immutabilityHelper);
|
||||
|
||||
var _Utilities = require('./Utilities');
|
||||
|
||||
var _PivotTable = require('./PivotTable');
|
||||
|
||||
var _PivotTable2 = _interopRequireDefault(_PivotTable);
|
||||
|
||||
var _reactSortablejs = require('react-sortablejs');
|
||||
|
||||
var _reactSortablejs2 = _interopRequireDefault(_reactSortablejs);
|
||||
|
||||
var _reactDraggable = require('react-draggable');
|
||||
|
||||
var _reactDraggable2 = _interopRequireDefault(_reactDraggable);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
// eslint can't see inherited propTypes!
|
||||
|
||||
var DraggableAttribute = exports.DraggableAttribute = function (_React$Component) {
|
||||
_inherits(DraggableAttribute, _React$Component);
|
||||
|
||||
function DraggableAttribute(props) {
|
||||
_classCallCheck(this, DraggableAttribute);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, (DraggableAttribute.__proto__ || Object.getPrototypeOf(DraggableAttribute)).call(this, props));
|
||||
|
||||
_this.state = { open: false, filterText: '' };
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(DraggableAttribute, [{
|
||||
key: 'toggleValue',
|
||||
value: function toggleValue(value) {
|
||||
if (value in this.props.valueFilter) {
|
||||
this.props.removeValuesFromFilter(this.props.name, [value]);
|
||||
} else {
|
||||
this.props.addValuesToFilter(this.props.name, [value]);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'matchesFilter',
|
||||
value: function matchesFilter(x) {
|
||||
return x.toLowerCase().trim().includes(this.state.filterText.toLowerCase().trim());
|
||||
}
|
||||
}, {
|
||||
key: 'selectOnly',
|
||||
value: function selectOnly(e, value) {
|
||||
e.stopPropagation();
|
||||
this.props.setValuesInFilter(this.props.name, Object.keys(this.props.attrValues).filter(function (y) {
|
||||
return y !== value;
|
||||
}));
|
||||
}
|
||||
}, {
|
||||
key: 'getFilterBox',
|
||||
value: function getFilterBox() {
|
||||
var _this2 = this;
|
||||
|
||||
var showMenu = Object.keys(this.props.attrValues).length < this.props.menuLimit;
|
||||
|
||||
var values = Object.keys(this.props.attrValues);
|
||||
var shown = values.filter(this.matchesFilter.bind(this)).sort(this.props.sorter);
|
||||
|
||||
return _react2.default.createElement(
|
||||
_reactDraggable2.default,
|
||||
{ handle: '.pvtDragHandle' },
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{
|
||||
className: 'pvtFilterBox',
|
||||
style: {
|
||||
display: 'block',
|
||||
cursor: 'initial',
|
||||
zIndex: this.props.zIndex
|
||||
},
|
||||
onClick: function onClick() {
|
||||
return _this2.props.moveFilterBoxToTop(_this2.props.name);
|
||||
}
|
||||
},
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{ onClick: function onClick() {
|
||||
return _this2.setState({ open: false });
|
||||
}, className: 'pvtCloseX' },
|
||||
'\xD7'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'span',
|
||||
{ className: 'pvtDragHandle' },
|
||||
'\u2630'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'h4',
|
||||
null,
|
||||
this.props.name
|
||||
),
|
||||
showMenu || _react2.default.createElement(
|
||||
'p',
|
||||
null,
|
||||
'(too many values to show)'
|
||||
),
|
||||
showMenu && _react2.default.createElement(
|
||||
'p',
|
||||
null,
|
||||
_react2.default.createElement('input', {
|
||||
type: 'text',
|
||||
placeholder: 'Filter values',
|
||||
className: 'pvtSearch',
|
||||
value: this.state.filterText,
|
||||
onChange: function onChange(e) {
|
||||
return _this2.setState({
|
||||
filterText: e.target.value
|
||||
});
|
||||
}
|
||||
}),
|
||||
_react2.default.createElement('br', null),
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{
|
||||
role: 'button',
|
||||
className: 'pvtButton',
|
||||
onClick: function onClick() {
|
||||
return _this2.props.removeValuesFromFilter(_this2.props.name, Object.keys(_this2.props.attrValues).filter(_this2.matchesFilter.bind(_this2)));
|
||||
}
|
||||
},
|
||||
'Select ',
|
||||
values.length === shown.length ? 'All' : shown.length
|
||||
),
|
||||
' ',
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{
|
||||
role: 'button',
|
||||
className: 'pvtButton',
|
||||
onClick: function onClick() {
|
||||
return _this2.props.addValuesToFilter(_this2.props.name, Object.keys(_this2.props.attrValues).filter(_this2.matchesFilter.bind(_this2)));
|
||||
}
|
||||
},
|
||||
'Deselect ',
|
||||
values.length === shown.length ? 'All' : shown.length
|
||||
)
|
||||
),
|
||||
showMenu && _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'pvtCheckContainer' },
|
||||
shown.map(function (x) {
|
||||
return _react2.default.createElement(
|
||||
'p',
|
||||
{
|
||||
key: x,
|
||||
onClick: function onClick() {
|
||||
return _this2.toggleValue(x);
|
||||
},
|
||||
className: x in _this2.props.valueFilter ? '' : 'selected'
|
||||
},
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{ className: 'pvtOnly', onClick: function onClick(e) {
|
||||
return _this2.selectOnly(e, x);
|
||||
} },
|
||||
'only'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{ className: 'pvtOnlySpacer' },
|
||||
'\xA0'
|
||||
),
|
||||
x === '' ? _react2.default.createElement(
|
||||
'em',
|
||||
null,
|
||||
'null'
|
||||
) : x
|
||||
);
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: 'toggleFilterBox',
|
||||
value: function toggleFilterBox() {
|
||||
this.setState({ open: !this.state.open });
|
||||
this.props.moveFilterBoxToTop(this.props.name);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var filtered = Object.keys(this.props.valueFilter).length !== 0 ? 'pvtFilteredAttribute' : '';
|
||||
return _react2.default.createElement(
|
||||
'li',
|
||||
{ 'data-id': this.props.name },
|
||||
_react2.default.createElement(
|
||||
'span',
|
||||
{ className: 'pvtAttr ' + filtered },
|
||||
this.props.name,
|
||||
_react2.default.createElement(
|
||||
'span',
|
||||
{
|
||||
className: 'pvtTriangle',
|
||||
onClick: this.toggleFilterBox.bind(this)
|
||||
},
|
||||
' ',
|
||||
'\u25BE'
|
||||
)
|
||||
),
|
||||
this.state.open ? this.getFilterBox() : null
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return DraggableAttribute;
|
||||
}(_react2.default.Component);
|
||||
|
||||
DraggableAttribute.defaultProps = {
|
||||
valueFilter: {}
|
||||
};
|
||||
|
||||
DraggableAttribute.propTypes = {
|
||||
name: _propTypes2.default.string.isRequired,
|
||||
addValuesToFilter: _propTypes2.default.func.isRequired,
|
||||
removeValuesFromFilter: _propTypes2.default.func.isRequired,
|
||||
attrValues: _propTypes2.default.objectOf(_propTypes2.default.number).isRequired,
|
||||
valueFilter: _propTypes2.default.objectOf(_propTypes2.default.bool),
|
||||
moveFilterBoxToTop: _propTypes2.default.func.isRequired,
|
||||
sorter: _propTypes2.default.func.isRequired,
|
||||
menuLimit: _propTypes2.default.number,
|
||||
zIndex: _propTypes2.default.number
|
||||
};
|
||||
|
||||
var Dropdown = exports.Dropdown = function (_React$PureComponent) {
|
||||
_inherits(Dropdown, _React$PureComponent);
|
||||
|
||||
function Dropdown() {
|
||||
_classCallCheck(this, Dropdown);
|
||||
|
||||
return _possibleConstructorReturn(this, (Dropdown.__proto__ || Object.getPrototypeOf(Dropdown)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(Dropdown, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _this4 = this;
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'pvtDropdown', style: { zIndex: this.props.zIndex } },
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{
|
||||
onClick: function onClick(e) {
|
||||
e.stopPropagation();
|
||||
_this4.props.toggle();
|
||||
},
|
||||
className: 'pvtDropdownValue pvtDropdownCurrent ' + (this.props.open ? 'pvtDropdownCurrentOpen' : ''),
|
||||
role: 'button'
|
||||
},
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'pvtDropdownIcon' },
|
||||
this.props.open ? '×' : '▾'
|
||||
),
|
||||
this.props.current || _react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
'\xA0'
|
||||
)
|
||||
),
|
||||
this.props.open && _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'pvtDropdownMenu' },
|
||||
this.props.values.map(function (r) {
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{
|
||||
key: r,
|
||||
role: 'button',
|
||||
onClick: function onClick(e) {
|
||||
e.stopPropagation();
|
||||
if (_this4.props.current === r) {
|
||||
_this4.props.toggle();
|
||||
} else {
|
||||
_this4.props.setValue(r);
|
||||
}
|
||||
},
|
||||
className: 'pvtDropdownValue ' + (r === _this4.props.current ? 'pvtDropdownActiveValue' : '')
|
||||
},
|
||||
r
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Dropdown;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
var PivotTableUI = function (_React$PureComponent2) {
|
||||
_inherits(PivotTableUI, _React$PureComponent2);
|
||||
|
||||
function PivotTableUI(props) {
|
||||
_classCallCheck(this, PivotTableUI);
|
||||
|
||||
var _this5 = _possibleConstructorReturn(this, (PivotTableUI.__proto__ || Object.getPrototypeOf(PivotTableUI)).call(this, props));
|
||||
|
||||
_this5.state = {
|
||||
unusedOrder: [],
|
||||
zIndices: {},
|
||||
maxZIndex: 1000,
|
||||
openDropdown: false,
|
||||
attrValues: {},
|
||||
materializedInput: []
|
||||
};
|
||||
return _this5;
|
||||
}
|
||||
|
||||
_createClass(PivotTableUI, [{
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
this.materializeInput(this.props.data);
|
||||
}
|
||||
}, {
|
||||
key: 'componentDidUpdate',
|
||||
value: function componentDidUpdate() {
|
||||
this.materializeInput(this.props.data);
|
||||
}
|
||||
}, {
|
||||
key: 'materializeInput',
|
||||
value: function materializeInput(nextData) {
|
||||
if (this.state.data === nextData) {
|
||||
return;
|
||||
}
|
||||
var newState = {
|
||||
data: nextData,
|
||||
attrValues: {},
|
||||
materializedInput: []
|
||||
};
|
||||
var recordsProcessed = 0;
|
||||
_Utilities.PivotData.forEachRecord(newState.data, this.props.derivedAttributes, function (record) {
|
||||
newState.materializedInput.push(record);
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = Object.keys(record)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var attr = _step.value;
|
||||
|
||||
if (!(attr in newState.attrValues)) {
|
||||
newState.attrValues[attr] = {};
|
||||
if (recordsProcessed > 0) {
|
||||
newState.attrValues[attr].null = recordsProcessed;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var _attr in newState.attrValues) {
|
||||
var value = _attr in record ? record[_attr] : 'null';
|
||||
if (!(value in newState.attrValues[_attr])) {
|
||||
newState.attrValues[_attr][value] = 0;
|
||||
}
|
||||
newState.attrValues[_attr][value]++;
|
||||
}
|
||||
recordsProcessed++;
|
||||
});
|
||||
this.setState(newState);
|
||||
}
|
||||
}, {
|
||||
key: 'sendPropUpdate',
|
||||
value: function sendPropUpdate(command) {
|
||||
this.props.onChange((0, _immutabilityHelper2.default)(this.props, command));
|
||||
}
|
||||
}, {
|
||||
key: 'propUpdater',
|
||||
value: function propUpdater(key) {
|
||||
var _this6 = this;
|
||||
|
||||
return function (value) {
|
||||
return _this6.sendPropUpdate(_defineProperty({}, key, { $set: value }));
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: 'setValuesInFilter',
|
||||
value: function setValuesInFilter(attribute, values) {
|
||||
this.sendPropUpdate({
|
||||
valueFilter: _defineProperty({}, attribute, {
|
||||
$set: values.reduce(function (r, v) {
|
||||
r[v] = true;
|
||||
return r;
|
||||
}, {})
|
||||
})
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'addValuesToFilter',
|
||||
value: function addValuesToFilter(attribute, values) {
|
||||
if (attribute in this.props.valueFilter) {
|
||||
this.sendPropUpdate({
|
||||
valueFilter: _defineProperty({}, attribute, values.reduce(function (r, v) {
|
||||
r[v] = { $set: true };
|
||||
return r;
|
||||
}, {}))
|
||||
});
|
||||
} else {
|
||||
this.setValuesInFilter(attribute, values);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'removeValuesFromFilter',
|
||||
value: function removeValuesFromFilter(attribute, values) {
|
||||
this.sendPropUpdate({
|
||||
valueFilter: _defineProperty({}, attribute, { $unset: values })
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'moveFilterBoxToTop',
|
||||
value: function moveFilterBoxToTop(attribute) {
|
||||
this.setState((0, _immutabilityHelper2.default)(this.state, {
|
||||
maxZIndex: { $set: this.state.maxZIndex + 1 },
|
||||
zIndices: _defineProperty({}, attribute, { $set: this.state.maxZIndex + 1 })
|
||||
}));
|
||||
}
|
||||
}, {
|
||||
key: 'isOpen',
|
||||
value: function isOpen(dropdown) {
|
||||
return this.state.openDropdown === dropdown;
|
||||
}
|
||||
}, {
|
||||
key: 'makeDnDCell',
|
||||
value: function makeDnDCell(items, onChange, classes) {
|
||||
var _this7 = this;
|
||||
|
||||
return _react2.default.createElement(
|
||||
_reactSortablejs2.default,
|
||||
{
|
||||
options: {
|
||||
group: 'shared',
|
||||
ghostClass: 'pvtPlaceholder',
|
||||
filter: '.pvtFilterBox',
|
||||
preventOnFilter: false
|
||||
},
|
||||
tag: 'td',
|
||||
className: classes,
|
||||
onChange: onChange
|
||||
},
|
||||
items.map(function (x) {
|
||||
return _react2.default.createElement(DraggableAttribute, {
|
||||
name: x,
|
||||
key: x,
|
||||
attrValues: _this7.state.attrValues[x],
|
||||
valueFilter: _this7.props.valueFilter[x] || {},
|
||||
sorter: (0, _Utilities.getSort)(_this7.props.sorters, x),
|
||||
menuLimit: _this7.props.menuLimit,
|
||||
setValuesInFilter: _this7.setValuesInFilter.bind(_this7),
|
||||
addValuesToFilter: _this7.addValuesToFilter.bind(_this7),
|
||||
moveFilterBoxToTop: _this7.moveFilterBoxToTop.bind(_this7),
|
||||
removeValuesFromFilter: _this7.removeValuesFromFilter.bind(_this7),
|
||||
zIndex: _this7.state.zIndices[x] || _this7.state.maxZIndex
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _this8 = this;
|
||||
|
||||
var numValsAllowed = this.props.aggregators[this.props.aggregatorName]([])().numInputs || 0;
|
||||
|
||||
var aggregatorCellOutlet = this.props.aggregators[this.props.aggregatorName]([])().outlet;
|
||||
|
||||
var rendererName = this.props.rendererName in this.props.renderers ? this.props.rendererName : Object.keys(this.props.renderers)[0];
|
||||
|
||||
var rendererCell = _react2.default.createElement(
|
||||
'td',
|
||||
{ className: 'pvtRenderers' },
|
||||
_react2.default.createElement(Dropdown, {
|
||||
current: rendererName,
|
||||
values: Object.keys(this.props.renderers),
|
||||
open: this.isOpen('renderer'),
|
||||
zIndex: this.isOpen('renderer') ? this.state.maxZIndex + 1 : 1,
|
||||
toggle: function toggle() {
|
||||
return _this8.setState({
|
||||
openDropdown: _this8.isOpen('renderer') ? false : 'renderer'
|
||||
});
|
||||
},
|
||||
setValue: this.propUpdater('rendererName')
|
||||
})
|
||||
);
|
||||
|
||||
var sortIcons = {
|
||||
key_a_to_z: {
|
||||
rowSymbol: '↕',
|
||||
colSymbol: '↔',
|
||||
next: 'value_a_to_z'
|
||||
},
|
||||
value_a_to_z: {
|
||||
rowSymbol: '↓',
|
||||
colSymbol: '→',
|
||||
next: 'value_z_to_a'
|
||||
},
|
||||
value_z_to_a: { rowSymbol: '↑', colSymbol: '←', next: 'key_a_to_z' }
|
||||
};
|
||||
|
||||
var aggregatorCell = _react2.default.createElement(
|
||||
'td',
|
||||
{ className: 'pvtVals' },
|
||||
_react2.default.createElement(Dropdown, {
|
||||
current: this.props.aggregatorName,
|
||||
values: Object.keys(this.props.aggregators),
|
||||
open: this.isOpen('aggregators'),
|
||||
zIndex: this.isOpen('aggregators') ? this.state.maxZIndex + 1 : 1,
|
||||
toggle: function toggle() {
|
||||
return _this8.setState({
|
||||
openDropdown: _this8.isOpen('aggregators') ? false : 'aggregators'
|
||||
});
|
||||
},
|
||||
setValue: this.propUpdater('aggregatorName')
|
||||
}),
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{
|
||||
role: 'button',
|
||||
className: 'pvtRowOrder',
|
||||
onClick: function onClick() {
|
||||
return _this8.propUpdater('rowOrder')(sortIcons[_this8.props.rowOrder].next);
|
||||
}
|
||||
},
|
||||
sortIcons[this.props.rowOrder].rowSymbol
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{
|
||||
role: 'button',
|
||||
className: 'pvtColOrder',
|
||||
onClick: function onClick() {
|
||||
return _this8.propUpdater('colOrder')(sortIcons[_this8.props.colOrder].next);
|
||||
}
|
||||
},
|
||||
sortIcons[this.props.colOrder].colSymbol
|
||||
),
|
||||
numValsAllowed > 0 && _react2.default.createElement('br', null),
|
||||
new Array(numValsAllowed).fill().map(function (n, i) {
|
||||
return [_react2.default.createElement(Dropdown, {
|
||||
key: i,
|
||||
current: _this8.props.vals[i],
|
||||
values: Object.keys(_this8.state.attrValues).filter(function (e) {
|
||||
return !_this8.props.hiddenAttributes.includes(e) && !_this8.props.hiddenFromAggregators.includes(e);
|
||||
}),
|
||||
open: _this8.isOpen('val' + i),
|
||||
zIndex: _this8.isOpen('val' + i) ? _this8.state.maxZIndex + 1 : 1,
|
||||
toggle: function toggle() {
|
||||
return _this8.setState({
|
||||
openDropdown: _this8.isOpen('val' + i) ? false : 'val' + i
|
||||
});
|
||||
},
|
||||
setValue: function setValue(value) {
|
||||
return _this8.sendPropUpdate({
|
||||
vals: { $splice: [[i, 1, value]] }
|
||||
});
|
||||
}
|
||||
}), i + 1 !== numValsAllowed ? _react2.default.createElement('br', { key: 'br' + i }) : null];
|
||||
}),
|
||||
aggregatorCellOutlet && aggregatorCellOutlet(this.props.data)
|
||||
);
|
||||
|
||||
var unusedAttrs = Object.keys(this.state.attrValues).filter(function (e) {
|
||||
return !_this8.props.rows.includes(e) && !_this8.props.cols.includes(e) && !_this8.props.hiddenAttributes.includes(e) && !_this8.props.hiddenFromDragDrop.includes(e);
|
||||
}).sort((0, _Utilities.sortAs)(this.state.unusedOrder));
|
||||
|
||||
var unusedLength = unusedAttrs.reduce(function (r, e) {
|
||||
return r + e.length;
|
||||
}, 0);
|
||||
var horizUnused = unusedLength < this.props.unusedOrientationCutoff;
|
||||
|
||||
var unusedAttrsCell = this.makeDnDCell(unusedAttrs, function (order) {
|
||||
return _this8.setState({ unusedOrder: order });
|
||||
}, 'pvtAxisContainer pvtUnused ' + (horizUnused ? 'pvtHorizList' : 'pvtVertList'));
|
||||
|
||||
var colAttrs = this.props.cols.filter(function (e) {
|
||||
return !_this8.props.hiddenAttributes.includes(e) && !_this8.props.hiddenFromDragDrop.includes(e);
|
||||
});
|
||||
|
||||
var colAttrsCell = this.makeDnDCell(colAttrs, this.propUpdater('cols'), 'pvtAxisContainer pvtHorizList pvtCols');
|
||||
|
||||
var rowAttrs = this.props.rows.filter(function (e) {
|
||||
return !_this8.props.hiddenAttributes.includes(e) && !_this8.props.hiddenFromDragDrop.includes(e);
|
||||
});
|
||||
var rowAttrsCell = this.makeDnDCell(rowAttrs, this.propUpdater('rows'), 'pvtAxisContainer pvtVertList pvtRows');
|
||||
var outputCell = _react2.default.createElement(
|
||||
'td',
|
||||
{ className: 'pvtOutput' },
|
||||
_react2.default.createElement(_PivotTable2.default, (0, _immutabilityHelper2.default)(this.props, {
|
||||
data: { $set: this.state.materializedInput }
|
||||
}))
|
||||
);
|
||||
|
||||
if (horizUnused) {
|
||||
return _react2.default.createElement(
|
||||
'table',
|
||||
{ className: 'pvtUi' },
|
||||
_react2.default.createElement(
|
||||
'tbody',
|
||||
{ onClick: function onClick() {
|
||||
return _this8.setState({ openDropdown: false });
|
||||
} },
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
rendererCell,
|
||||
unusedAttrsCell
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
aggregatorCell,
|
||||
colAttrsCell
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
rowAttrsCell,
|
||||
outputCell
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return _react2.default.createElement(
|
||||
'table',
|
||||
{ className: 'pvtUi' },
|
||||
_react2.default.createElement(
|
||||
'tbody',
|
||||
{ onClick: function onClick() {
|
||||
return _this8.setState({ openDropdown: false });
|
||||
} },
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
rendererCell,
|
||||
aggregatorCell,
|
||||
colAttrsCell
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
unusedAttrsCell,
|
||||
rowAttrsCell,
|
||||
outputCell
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return PivotTableUI;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
PivotTableUI.propTypes = Object.assign({}, _PivotTable2.default.propTypes, {
|
||||
onChange: _propTypes2.default.func.isRequired,
|
||||
hiddenAttributes: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
||||
hiddenFromAggregators: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
||||
hiddenFromDragDrop: _propTypes2.default.arrayOf(_propTypes2.default.string),
|
||||
unusedOrientationCutoff: _propTypes2.default.number,
|
||||
menuLimit: _propTypes2.default.number
|
||||
});
|
||||
|
||||
PivotTableUI.defaultProps = Object.assign({}, _PivotTable2.default.defaultProps, {
|
||||
hiddenAttributes: [],
|
||||
hiddenFromAggregators: [],
|
||||
hiddenFromDragDrop: [],
|
||||
unusedOrientationCutoff: 85,
|
||||
menuLimit: 500
|
||||
});
|
||||
|
||||
exports.default = PivotTableUI;
|
||||
//# sourceMappingURL=PivotTableUI.js.map
|
1
PivotTableUI.js.map
Normal file
1
PivotTableUI.js.map
Normal file
File diff suppressed because one or more lines are too long
265
PlotlyRenderers.js
Normal file
265
PlotlyRenderers.js
Normal file
@ -0,0 +1,265 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
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; }; }();
|
||||
|
||||
exports.default = createPlotlyRenderers;
|
||||
|
||||
var _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _propTypes = require('prop-types');
|
||||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
var _Utilities = require('./Utilities');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
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; }
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
// eslint can't see inherited propTypes!
|
||||
|
||||
function makeRenderer(PlotlyComponent) {
|
||||
var traceOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var layoutOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
var transpose = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
||||
|
||||
var Renderer = function (_React$PureComponent) {
|
||||
_inherits(Renderer, _React$PureComponent);
|
||||
|
||||
function Renderer() {
|
||||
_classCallCheck(this, Renderer);
|
||||
|
||||
return _possibleConstructorReturn(this, (Renderer.__proto__ || Object.getPrototypeOf(Renderer)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(Renderer, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var pivotData = new _Utilities.PivotData(this.props);
|
||||
var rowKeys = pivotData.getRowKeys();
|
||||
var colKeys = pivotData.getColKeys();
|
||||
var traceKeys = transpose ? colKeys : rowKeys;
|
||||
if (traceKeys.length === 0) {
|
||||
traceKeys.push([]);
|
||||
}
|
||||
var datumKeys = transpose ? rowKeys : colKeys;
|
||||
if (datumKeys.length === 0) {
|
||||
datumKeys.push([]);
|
||||
}
|
||||
|
||||
var fullAggName = this.props.aggregatorName;
|
||||
var numInputs = this.props.aggregators[fullAggName]([])().numInputs || 0;
|
||||
if (numInputs !== 0) {
|
||||
fullAggName += ' of ' + this.props.vals.slice(0, numInputs).join(', ');
|
||||
}
|
||||
|
||||
var data = traceKeys.map(function (traceKey) {
|
||||
var values = [];
|
||||
var labels = [];
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = datumKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var datumKey = _step.value;
|
||||
|
||||
var val = parseFloat(pivotData.getAggregator(transpose ? datumKey : traceKey, transpose ? traceKey : datumKey).value());
|
||||
values.push(isFinite(val) ? val : null);
|
||||
labels.push(datumKey.join('-') || ' ');
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var trace = { name: traceKey.join('-') || fullAggName };
|
||||
if (traceOptions.type === 'pie') {
|
||||
trace.values = values;
|
||||
trace.labels = labels.length > 1 ? labels : [fullAggName];
|
||||
} else {
|
||||
trace.x = transpose ? values : labels;
|
||||
trace.y = transpose ? labels : values;
|
||||
}
|
||||
return Object.assign(trace, traceOptions);
|
||||
});
|
||||
|
||||
var titleText = fullAggName;
|
||||
var hAxisTitle = transpose ? this.props.rows.join('-') : this.props.cols.join('-');
|
||||
var groupByTitle = transpose ? this.props.cols.join('-') : this.props.rows.join('-');
|
||||
if (hAxisTitle !== '') {
|
||||
titleText += ' vs ' + hAxisTitle;
|
||||
}
|
||||
if (groupByTitle !== '') {
|
||||
titleText += ' by ' + groupByTitle;
|
||||
}
|
||||
|
||||
var layout = {
|
||||
title: titleText,
|
||||
hovermode: 'closest',
|
||||
/* eslint-disable no-magic-numbers */
|
||||
width: window.innerWidth / 1.5,
|
||||
height: window.innerHeight / 1.4 - 50
|
||||
/* eslint-enable no-magic-numbers */
|
||||
};
|
||||
|
||||
if (traceOptions.type === 'pie') {
|
||||
var columns = Math.ceil(Math.sqrt(data.length));
|
||||
var rows = Math.ceil(data.length / columns);
|
||||
layout.grid = { columns: columns, rows: rows };
|
||||
data.forEach(function (d, i) {
|
||||
d.domain = {
|
||||
row: Math.floor(i / columns),
|
||||
column: i - columns * Math.floor(i / columns)
|
||||
};
|
||||
if (data.length > 1) {
|
||||
d.title = d.name;
|
||||
}
|
||||
});
|
||||
if (data[0].labels.length === 1) {
|
||||
layout.showlegend = false;
|
||||
}
|
||||
} else {
|
||||
layout.xaxis = {
|
||||
title: transpose ? fullAggName : null,
|
||||
automargin: true
|
||||
};
|
||||
layout.yaxis = {
|
||||
title: transpose ? null : fullAggName,
|
||||
automargin: true
|
||||
};
|
||||
}
|
||||
|
||||
return _react2.default.createElement(PlotlyComponent, {
|
||||
data: data,
|
||||
layout: Object.assign(layout, layoutOptions, this.props.plotlyOptions),
|
||||
config: this.props.plotlyConfig,
|
||||
onUpdate: this.props.onRendererUpdate
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return Renderer;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
Renderer.defaultProps = Object.assign({}, _Utilities.PivotData.defaultProps, {
|
||||
plotlyOptions: {},
|
||||
plotlyConfig: {}
|
||||
});
|
||||
Renderer.propTypes = Object.assign({}, _Utilities.PivotData.propTypes, {
|
||||
plotlyOptions: _propTypes2.default.object,
|
||||
plotlyConfig: _propTypes2.default.object,
|
||||
onRendererUpdate: _propTypes2.default.func
|
||||
});
|
||||
|
||||
return Renderer;
|
||||
}
|
||||
|
||||
function makeScatterRenderer(PlotlyComponent) {
|
||||
var Renderer = function (_React$PureComponent2) {
|
||||
_inherits(Renderer, _React$PureComponent2);
|
||||
|
||||
function Renderer() {
|
||||
_classCallCheck(this, Renderer);
|
||||
|
||||
return _possibleConstructorReturn(this, (Renderer.__proto__ || Object.getPrototypeOf(Renderer)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(Renderer, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var pivotData = new _Utilities.PivotData(this.props);
|
||||
var rowKeys = pivotData.getRowKeys();
|
||||
var colKeys = pivotData.getColKeys();
|
||||
if (rowKeys.length === 0) {
|
||||
rowKeys.push([]);
|
||||
}
|
||||
if (colKeys.length === 0) {
|
||||
colKeys.push([]);
|
||||
}
|
||||
|
||||
var data = { x: [], y: [], text: [], type: 'scatter', mode: 'markers' };
|
||||
|
||||
rowKeys.map(function (rowKey) {
|
||||
colKeys.map(function (colKey) {
|
||||
var v = pivotData.getAggregator(rowKey, colKey).value();
|
||||
if (v !== null) {
|
||||
data.x.push(colKey.join('-'));
|
||||
data.y.push(rowKey.join('-'));
|
||||
data.text.push(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var layout = {
|
||||
title: this.props.rows.join('-') + ' vs ' + this.props.cols.join('-'),
|
||||
hovermode: 'closest',
|
||||
/* eslint-disable no-magic-numbers */
|
||||
xaxis: { title: this.props.cols.join('-'), automargin: true },
|
||||
yaxis: { title: this.props.rows.join('-'), automargin: true },
|
||||
width: window.innerWidth / 1.5,
|
||||
height: window.innerHeight / 1.4 - 50
|
||||
/* eslint-enable no-magic-numbers */
|
||||
};
|
||||
|
||||
return _react2.default.createElement(PlotlyComponent, {
|
||||
data: [data],
|
||||
layout: Object.assign(layout, this.props.plotlyOptions),
|
||||
config: this.props.plotlyConfig,
|
||||
onUpdate: this.props.onRendererUpdate
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return Renderer;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
Renderer.defaultProps = Object.assign({}, _Utilities.PivotData.defaultProps, {
|
||||
plotlyOptions: {},
|
||||
plotlyConfig: {}
|
||||
});
|
||||
Renderer.propTypes = Object.assign({}, _Utilities.PivotData.propTypes, {
|
||||
plotlyOptions: _propTypes2.default.object,
|
||||
plotlyConfig: _propTypes2.default.object,
|
||||
onRendererUpdate: _propTypes2.default.func
|
||||
});
|
||||
|
||||
return Renderer;
|
||||
}
|
||||
|
||||
function createPlotlyRenderers(PlotlyComponent) {
|
||||
return {
|
||||
'Grouped Column Chart': makeRenderer(PlotlyComponent, { type: 'bar' }, { barmode: 'group' }),
|
||||
'Stacked Column Chart': makeRenderer(PlotlyComponent, { type: 'bar' }, { barmode: 'relative' }),
|
||||
'Grouped Bar Chart': makeRenderer(PlotlyComponent, { type: 'bar', orientation: 'h' }, { barmode: 'group' }, true),
|
||||
'Stacked Bar Chart': makeRenderer(PlotlyComponent, { type: 'bar', orientation: 'h' }, { barmode: 'relative' }, true),
|
||||
'Line Chart': makeRenderer(PlotlyComponent),
|
||||
'Dot Chart': makeRenderer(PlotlyComponent, { mode: 'markers' }, {}, true),
|
||||
'Area Chart': makeRenderer(PlotlyComponent, { stackgroup: 1 }),
|
||||
'Scatter Chart': makeScatterRenderer(PlotlyComponent),
|
||||
'Multiple Pie Chart': makeRenderer(PlotlyComponent, { type: 'pie', scalegroup: 1, hoverinfo: 'label+value', textinfo: 'none' }, {}, true)
|
||||
};
|
||||
}
|
||||
module.exports = exports['default'];
|
||||
//# sourceMappingURL=PlotlyRenderers.js.map
|
1
PlotlyRenderers.js.map
Normal file
1
PlotlyRenderers.js.map
Normal file
File diff suppressed because one or more lines are too long
262
README.md
262
README.md
@ -1,3 +1,263 @@
|
||||
# v-react-pivottable
|
||||
|
||||
Customización de libreria de react-pivottable
|
||||
`v-react-pivottable` is a custom version of `react-pivottable` is a React-based pivot table library with drag'n'drop
|
||||
functionality. It is a React port of the jQuery-based
|
||||
[PivotTable.js](https://pivottable.js.org/) by the same author.
|
||||
|
||||
`react-pivottable` is part of Plotly's [React Component Suite](https://plot.ly/products/react/) for building data visualization Web apps and products.
|
||||
|
||||
## What does it do & where is the demo?
|
||||
|
||||
`react-pivottable`'s function is to enable data exploration and analysis by
|
||||
summarizing a data set into table or [Plotly.js](https://plot.ly/javascript/)
|
||||
chart with a true 2-d drag'n'drop UI, very similar to the one found in older
|
||||
versions of Microsoft Excel.
|
||||
|
||||
A [live demo can be found here](https://react-pivottable.js.org/).
|
||||
|
||||

|
||||
|
||||
## How can I use it in my project?
|
||||
|
||||
### Drag'n'drop UI with Table output only
|
||||
|
||||
Installation is via NPM and has a peer dependency on React:
|
||||
|
||||
```
|
||||
npm install --save react-pivottable react react-dom
|
||||
```
|
||||
|
||||
Basic usage is as follows. Note that `PivotTableUI` is a "dumb component" that
|
||||
maintains essentially no state of its own.
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PivotTableUI from 'react-pivottable/PivotTableUI';
|
||||
import 'react-pivottable/pivottable.css';
|
||||
|
||||
// see documentation for supported input formats
|
||||
const data = [['attribute', 'attribute2'], ['value1', 'value2']];
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = props;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PivotTableUI
|
||||
data={data}
|
||||
onChange={s => this.setState(s)}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, document.body);
|
||||
```
|
||||
|
||||
### Drag'n'drop UI with Plotly charts as well as Table output
|
||||
|
||||
The Plotly `react-plotly.js` component can be passed in via dependency
|
||||
injection. It has a peer dependency on `plotly.js`.
|
||||
|
||||
**Important:** If you build your project using webpack, you'll have to follow
|
||||
[these instructions](https://github.com/plotly/plotly.js#building-plotlyjs-with-webpack)
|
||||
in order to successfully bundle `plotly.js`. See below for how to avoid having
|
||||
to bundle `plotly.js`.
|
||||
|
||||
```
|
||||
npm install --save react-pivottable react-plotly.js plotly.js react react-dom
|
||||
```
|
||||
|
||||
To add the Plotly renderers to your app, you can use the following pattern:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import PivotTableUI from 'react-pivottable/PivotTableUI';
|
||||
import 'react-pivottable/pivottable.css';
|
||||
import TableRenderers from 'react-pivottable/TableRenderers';
|
||||
import Plot from 'react-plotly.js';
|
||||
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
|
||||
|
||||
// create Plotly renderers via dependency injection
|
||||
const PlotlyRenderers = createPlotlyRenderers(Plot);
|
||||
|
||||
// see documentation for supported input formats
|
||||
const data = [['attribute', 'attribute2'], ['value1', 'value2']];
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = props;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PivotTableUI
|
||||
data={data}
|
||||
onChange={s => this.setState(s)}
|
||||
renderers={Object.assign({}, TableRenderers, PlotlyRenderers)}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, document.body);
|
||||
```
|
||||
|
||||
#### With external `plotly.js`
|
||||
|
||||
If you would rather not install and bundle `plotly.js` but rather get it into
|
||||
your app via something like `<script>` tag, you can ignore `react-plotly.js`'
|
||||
peer-dependcy warning and handle the dependency injection like this:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import PivotTableUI from 'react-pivottable/PivotTableUI';
|
||||
import 'react-pivottable/pivottable.css';
|
||||
import TableRenderers from 'react-pivottable/TableRenderers';
|
||||
import createPlotlyComponent from 'react-plotly.js/factory';
|
||||
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
|
||||
|
||||
// create Plotly React component via dependency injection
|
||||
const Plot = createPlotlyComponent(window.Plotly);
|
||||
|
||||
// create Plotly renderers via dependency injection
|
||||
const PlotlyRenderers = createPlotlyRenderers(Plot);
|
||||
|
||||
// see documentation for supported input formats
|
||||
const data = [['attribute', 'attribute2'], ['value1', 'value2']];
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = props;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PivotTableUI
|
||||
data={data}
|
||||
onChange={s => this.setState(s)}
|
||||
renderers={Object.assign({}, TableRenderers, PlotlyRenderers)}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, document.body);
|
||||
```
|
||||
|
||||
## Properties and layered architecture
|
||||
|
||||
* `<PivotTableUI {...props} />`
|
||||
* `<PivotTable {...props} />`
|
||||
* `<Renderer {...props} />`
|
||||
* `PivotData(props)`
|
||||
|
||||
The interactive component provided by `react-pivottable` is `PivotTableUI`, but
|
||||
output rendering is delegated to the non-interactive `PivotTable` component,
|
||||
which accepts a subset of its properties. `PivotTable` can be invoked directly
|
||||
and is useful for outputting non-interactive saved snapshots of `PivotTableUI`
|
||||
configurations. `PivotTable` in turn delegates to a specific renderer component,
|
||||
such as the default `TableRenderer`, which accepts a subset of the same
|
||||
properties. Finally, most renderers will create non-React `PivotData` object to
|
||||
handle the actual computations, which also accepts a subset of the same props as
|
||||
the rest of the stack.
|
||||
|
||||
Here is a table of the properties accepted by this stack, including an
|
||||
indication of which layer consumes each, from the bottom up:
|
||||
|
||||
| Layer | Key & Type | Default Value | Description |
|
||||
| -------------- | ------------------------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `PivotData` | `data` <br /> see below for formats | (none, required) | data to be summarized |
|
||||
| `PivotData` | `rows` <br /> array of strings | `[]` | attribute names to prepopulate in row area |
|
||||
| `PivotData` | `cols` <br /> array of strings | `[]` | attribute names to prepopulate in cols area |
|
||||
| `PivotData` | `vals` <br /> array of strings | `[]` | attribute names used as arguments to aggregator (gets passed to aggregator generating function) |
|
||||
| `PivotData` | `aggregators` <br /> object of functions | `aggregators` from `Utilites` | dictionary of generators for aggregation functions in dropdown (see [original PivotTable.js documentation](https://github.com/nicolaskruchten/pivottable/wiki/Aggregators)) |
|
||||
| `PivotData` | `aggregatorName` <br /> string | first key in `aggregators` | key to `aggregators` object specifying the aggregator to use for computations |
|
||||
| `PivotData` | `valueFilter` <br /> object of arrays of strings | `{}` | object whose keys are attribute names and values are objects of attribute value-boolean pairs which denote records to include or exclude from computation and rendering; used to prepopulate the filter menus that appear on double-click |
|
||||
| `PivotData` | `sorters` <br /> object or function | `{}` | accessed or called with an attribute name and can return a [function which can be used as an argument to `array.sort`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) for output purposes. If no function is returned, the default sorting mechanism is a built-in "natural sort" implementation. Useful for sorting attributes like month names, see [original PivotTable.js example 1](http://nicolas.kruchten.com/pivottable/examples/mps_agg.html) and [original PivotTable.js example 2](http://nicolas.kruchten.com/pivottable/examples/montreal_2014.html). |
|
||||
| `PivotData` | `rowOrder` <br /> string | `"key_a_to_z"` | the order in which row data is provided to the renderer, must be one of `"key_a_to_z"`, `"value_a_to_z"`, `"value_z_to_a"`, ordering by value orders by row total |
|
||||
| `PivotData` | `colOrder` <br /> string | `"key_a_to_z"` | the order in which column data is provided to the renderer, must be one of `"key_a_to_z"`, `"value_a_to_z"`, `"value_z_to_a"`, ordering by value orders by column total |
|
||||
| `PivotData` | `derivedAttributes` <br /> object of functions | `{}` | defines derived attributes (see [original PivotTable.js documentation](https://github.com/nicolaskruchten/pivottable/wiki/Derived-Attributes)) |
|
||||
| `Renderer` | `<any>` | (none, optional) | Renderers may accept any additional properties |
|
||||
| `PivotTable` | `renderers` <br /> object of functions | `TableRenderers` | dictionary of renderer components |
|
||||
| `PivotTable` | `rendererName` <br /> string | first key in `renderers` | key to `renderers` object specifying the renderer to use |
|
||||
| `PivotTableUI` | `onChange` <br /> function | (none, required) | function called every time anything changes in the UI, with the new value of the properties needed to render the new state. This function must be hooked into a state-management system in order for the "dumb" `PivotTableUI` component to work. |
|
||||
| `PivotTableUI` | `hiddenAttributes` <br /> array of strings | `[]` | contains attribute names to omit from the UI |
|
||||
| `PivotTableUI` | `hiddenFromAggregators` <br /> array of strings | `[]` | contains attribute names to omit from the aggregator arguments dropdowns |
|
||||
| `PivotTableUI` | `hiddenFromDragDrop` <br /> array of strings | `[]` | contains attribute names to omit from the drag'n'drop portion of the UI |
|
||||
| `PivotTableUI` | `menuLimit` <br /> integer | 500 | maximum number of values to list in the double-click menu |
|
||||
| `PivotTableUI` | `unusedOrientationCutoff` <br /> integer | 85 | If the attributes' names' combined length in characters exceeds this value then the unused attributes area will be shown vertically to the left of the UI instead of horizontally above it. `0` therefore means 'always vertical', and `Infinity` means 'always horizontal'. |
|
||||
|
||||
### Accepted formats for `data`
|
||||
|
||||
#### Arrays of objects
|
||||
|
||||
One object per record, the object's keys are the attribute names.
|
||||
|
||||
_Note_: missing attributes or attributes with a value of `null` are treated as
|
||||
if the value was the string `"null"`.
|
||||
|
||||
```js
|
||||
const data = [
|
||||
{
|
||||
attr1: 'value1_attr1',
|
||||
attr2: 'value1_attr2',
|
||||
//...
|
||||
},
|
||||
{
|
||||
attr1: 'value2_attr1',
|
||||
attr2: 'value2_attr2',
|
||||
//...
|
||||
},
|
||||
//...
|
||||
];
|
||||
```
|
||||
|
||||
#### Arrays of arrays
|
||||
|
||||
One sub-array per record, the first sub-array contains the attribute names. If
|
||||
subsequent sub-arrays are shorter than the first one, the trailing values are
|
||||
treated as if they contained the string value `"null"`. If subsequent sub-arrays
|
||||
are longer than the first one, excess values are ignored. This format is
|
||||
compatible with the output of CSV parsing libraries like PapaParse.
|
||||
|
||||
```js
|
||||
const data = [
|
||||
['attr1', 'attr2'],
|
||||
['value1_attr1', 'value1_attr2'],
|
||||
['value2_attr1', 'value2_attr2'],
|
||||
//...
|
||||
];
|
||||
```
|
||||
|
||||
#### Functions that call back
|
||||
|
||||
The function will be called with a callback that takes an object as a parameter.
|
||||
|
||||
_Note_: missing attributes or attributes with a value of `null` are treated as
|
||||
if the value was the string `"null"`.
|
||||
|
||||
```js
|
||||
const data = function(callback) {
|
||||
callback({
|
||||
"attr1": "value1_attr1",
|
||||
"attr2": "value1_attr2",
|
||||
//...
|
||||
});
|
||||
callback({
|
||||
"attr1": "value2_attr1",
|
||||
"attr2": "value2_attr2",
|
||||
//...
|
||||
};
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
435
TableRenderers.js
Normal file
435
TableRenderers.js
Normal file
@ -0,0 +1,435 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
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 _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _propTypes = require('prop-types');
|
||||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
var _Utilities = require('./Utilities');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
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; }
|
||||
|
||||
// helper function for setting row/col-span in pivotTableRenderer
|
||||
var spanSize = function spanSize(arr, i, j) {
|
||||
var x = void 0;
|
||||
if (i !== 0) {
|
||||
var asc = void 0,
|
||||
end = void 0;
|
||||
var noDraw = true;
|
||||
for (x = 0, end = j, asc = end >= 0; asc ? x <= end : x >= end; asc ? x++ : x--) {
|
||||
if (arr[i - 1][x] !== arr[i][x]) {
|
||||
noDraw = false;
|
||||
}
|
||||
}
|
||||
if (noDraw) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
var len = 0;
|
||||
while (i + len < arr.length) {
|
||||
var asc1 = void 0,
|
||||
end1 = void 0;
|
||||
var stop = false;
|
||||
for (x = 0, end1 = j, asc1 = end1 >= 0; asc1 ? x <= end1 : x >= end1; asc1 ? x++ : x--) {
|
||||
if (arr[i][x] !== arr[i + len][x]) {
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
};
|
||||
|
||||
function redColorScaleGenerator(values) {
|
||||
var min = Math.min.apply(Math, values);
|
||||
var max = Math.max.apply(Math, values);
|
||||
return function (x) {
|
||||
// eslint-disable-next-line no-magic-numbers
|
||||
var nonRed = 255 - Math.round(255 * (x - min) / (max - min));
|
||||
return { backgroundColor: 'rgb(255,' + nonRed + ',' + nonRed + ')' };
|
||||
};
|
||||
}
|
||||
|
||||
function makeRenderer() {
|
||||
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
var TableRenderer = function (_React$PureComponent) {
|
||||
_inherits(TableRenderer, _React$PureComponent);
|
||||
|
||||
function TableRenderer() {
|
||||
_classCallCheck(this, TableRenderer);
|
||||
|
||||
return _possibleConstructorReturn(this, (TableRenderer.__proto__ || Object.getPrototypeOf(TableRenderer)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(TableRenderer, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _this2 = this;
|
||||
|
||||
var pivotData = new _Utilities.PivotData(this.props);
|
||||
var colAttrs = pivotData.props.cols;
|
||||
var rowAttrs = pivotData.props.rows;
|
||||
var rowKeys = pivotData.getRowKeys();
|
||||
var colKeys = pivotData.getColKeys();
|
||||
var grandTotalAggregator = pivotData.getAggregator([], []);
|
||||
|
||||
var valueCellColors = function valueCellColors() {};
|
||||
var rowTotalColors = function rowTotalColors() {};
|
||||
var colTotalColors = function colTotalColors() {};
|
||||
if (opts.heatmapMode) {
|
||||
var colorScaleGenerator = this.props.tableColorScaleGenerator;
|
||||
var rowTotalValues = colKeys.map(function (x) {
|
||||
return pivotData.getAggregator([], x).value();
|
||||
});
|
||||
rowTotalColors = colorScaleGenerator(rowTotalValues);
|
||||
var colTotalValues = rowKeys.map(function (x) {
|
||||
return pivotData.getAggregator(x, []).value();
|
||||
});
|
||||
colTotalColors = colorScaleGenerator(colTotalValues);
|
||||
|
||||
if (opts.heatmapMode === 'full') {
|
||||
var allValues = [];
|
||||
rowKeys.map(function (r) {
|
||||
return colKeys.map(function (c) {
|
||||
return allValues.push(pivotData.getAggregator(r, c).value());
|
||||
});
|
||||
});
|
||||
var colorScale = colorScaleGenerator(allValues);
|
||||
valueCellColors = function valueCellColors(r, c, v) {
|
||||
return colorScale(v);
|
||||
};
|
||||
} else if (opts.heatmapMode === 'row') {
|
||||
var rowColorScales = {};
|
||||
rowKeys.map(function (r) {
|
||||
var rowValues = colKeys.map(function (x) {
|
||||
return pivotData.getAggregator(r, x).value();
|
||||
});
|
||||
rowColorScales[r] = colorScaleGenerator(rowValues);
|
||||
});
|
||||
valueCellColors = function valueCellColors(r, c, v) {
|
||||
return rowColorScales[r](v);
|
||||
};
|
||||
} else if (opts.heatmapMode === 'col') {
|
||||
var colColorScales = {};
|
||||
colKeys.map(function (c) {
|
||||
var colValues = rowKeys.map(function (x) {
|
||||
return pivotData.getAggregator(x, c).value();
|
||||
});
|
||||
colColorScales[c] = colorScaleGenerator(colValues);
|
||||
});
|
||||
valueCellColors = function valueCellColors(r, c, v) {
|
||||
return colColorScales[c](v);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var getClickHandler = this.props.tableOptions && this.props.tableOptions.clickCallback ? function (value, rowValues, colValues) {
|
||||
var filters = {};
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = Object.keys(colAttrs || {})[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var i = _step.value;
|
||||
|
||||
var attr = colAttrs[i];
|
||||
if (colValues[i] !== null) {
|
||||
filters[attr] = colValues[i];
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = Object.keys(rowAttrs || {})[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var _i = _step2.value;
|
||||
|
||||
var attr = rowAttrs[_i];
|
||||
if (rowValues[_i] !== null) {
|
||||
filters[attr] = rowValues[_i];
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return function (e) {
|
||||
return _this2.props.tableOptions.clickCallback(e, value, filters, pivotData);
|
||||
};
|
||||
} : null;
|
||||
|
||||
return _react2.default.createElement(
|
||||
'table',
|
||||
{ className: 'pvtTable' },
|
||||
_react2.default.createElement(
|
||||
'thead',
|
||||
null,
|
||||
colAttrs.map(function (c, j) {
|
||||
return _react2.default.createElement(
|
||||
'tr',
|
||||
{ key: 'colAttr' + j },
|
||||
j === 0 && rowAttrs.length !== 0 && _react2.default.createElement('th', { colSpan: rowAttrs.length, rowSpan: colAttrs.length }),
|
||||
_react2.default.createElement(
|
||||
'th',
|
||||
{ className: 'pvtAxisLabel' },
|
||||
c
|
||||
),
|
||||
colKeys.map(function (colKey, i) {
|
||||
var x = spanSize(colKeys, i, j);
|
||||
if (x === -1) {
|
||||
return null;
|
||||
}
|
||||
return _react2.default.createElement(
|
||||
'th',
|
||||
{
|
||||
className: 'pvtColLabel',
|
||||
key: 'colKey' + i,
|
||||
colSpan: x,
|
||||
rowSpan: j === colAttrs.length - 1 && rowAttrs.length !== 0 ? 2 : 1
|
||||
},
|
||||
colKey[j]
|
||||
);
|
||||
}),
|
||||
j === 0 && _react2.default.createElement(
|
||||
'th',
|
||||
{
|
||||
className: 'pvtTotalLabel',
|
||||
rowSpan: colAttrs.length + (rowAttrs.length === 0 ? 0 : 1)
|
||||
},
|
||||
'Totals'
|
||||
)
|
||||
);
|
||||
}),
|
||||
rowAttrs.length !== 0 && _react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
rowAttrs.map(function (r, i) {
|
||||
return _react2.default.createElement(
|
||||
'th',
|
||||
{ className: 'pvtAxisLabel', key: 'rowAttr' + i },
|
||||
r
|
||||
);
|
||||
}),
|
||||
_react2.default.createElement(
|
||||
'th',
|
||||
{ className: 'pvtTotalLabel' },
|
||||
colAttrs.length === 0 ? 'Totals' : null
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'tbody',
|
||||
null,
|
||||
rowKeys.map(function (rowKey, i) {
|
||||
var totalAggregator = pivotData.getAggregator(rowKey, []);
|
||||
return _react2.default.createElement(
|
||||
'tr',
|
||||
{ key: 'rowKeyRow' + i },
|
||||
rowKey.map(function (txt, j) {
|
||||
var x = spanSize(rowKeys, i, j);
|
||||
if (x === -1) {
|
||||
return null;
|
||||
}
|
||||
return _react2.default.createElement(
|
||||
'th',
|
||||
{
|
||||
key: 'rowKeyLabel' + i + '-' + j,
|
||||
className: 'pvtRowLabel',
|
||||
rowSpan: x,
|
||||
colSpan: j === rowAttrs.length - 1 && colAttrs.length !== 0 ? 2 : 1
|
||||
},
|
||||
txt
|
||||
);
|
||||
}),
|
||||
colKeys.map(function (colKey, j) {
|
||||
var aggregator = pivotData.getAggregator(rowKey, colKey);
|
||||
return _react2.default.createElement(
|
||||
'td',
|
||||
{
|
||||
className: 'pvtVal',
|
||||
key: 'pvtVal' + i + '-' + j,
|
||||
onClick: getClickHandler && getClickHandler(aggregator.value(), rowKey, colKey),
|
||||
style: valueCellColors(rowKey, colKey, aggregator.value())
|
||||
},
|
||||
aggregator.format(aggregator.value())
|
||||
);
|
||||
}),
|
||||
_react2.default.createElement(
|
||||
'td',
|
||||
{
|
||||
className: 'pvtTotal',
|
||||
onClick: getClickHandler && getClickHandler(totalAggregator.value(), rowKey, [null]),
|
||||
style: colTotalColors(totalAggregator.value())
|
||||
},
|
||||
totalAggregator.format(totalAggregator.value())
|
||||
)
|
||||
);
|
||||
}),
|
||||
_react2.default.createElement(
|
||||
'tr',
|
||||
null,
|
||||
_react2.default.createElement(
|
||||
'th',
|
||||
{
|
||||
className: 'pvtTotalLabel',
|
||||
colSpan: rowAttrs.length + (colAttrs.length === 0 ? 0 : 1)
|
||||
},
|
||||
'Totals'
|
||||
),
|
||||
colKeys.map(function (colKey, i) {
|
||||
var totalAggregator = pivotData.getAggregator([], colKey);
|
||||
return _react2.default.createElement(
|
||||
'td',
|
||||
{
|
||||
className: 'pvtTotal',
|
||||
key: 'total' + i,
|
||||
onClick: getClickHandler && getClickHandler(totalAggregator.value(), [null], colKey),
|
||||
style: rowTotalColors(totalAggregator.value())
|
||||
},
|
||||
totalAggregator.format(totalAggregator.value())
|
||||
);
|
||||
}),
|
||||
_react2.default.createElement(
|
||||
'td',
|
||||
{
|
||||
onClick: getClickHandler && getClickHandler(grandTotalAggregator.value(), [null], [null]),
|
||||
className: 'pvtGrandTotal'
|
||||
},
|
||||
grandTotalAggregator.format(grandTotalAggregator.value())
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return TableRenderer;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
TableRenderer.defaultProps = _Utilities.PivotData.defaultProps;
|
||||
TableRenderer.propTypes = _Utilities.PivotData.propTypes;
|
||||
TableRenderer.defaultProps.tableColorScaleGenerator = redColorScaleGenerator;
|
||||
TableRenderer.defaultProps.tableOptions = {};
|
||||
TableRenderer.propTypes.tableColorScaleGenerator = _propTypes2.default.func;
|
||||
TableRenderer.propTypes.tableOptions = _propTypes2.default.object;
|
||||
return TableRenderer;
|
||||
}
|
||||
|
||||
var TSVExportRenderer = function (_React$PureComponent2) {
|
||||
_inherits(TSVExportRenderer, _React$PureComponent2);
|
||||
|
||||
function TSVExportRenderer() {
|
||||
_classCallCheck(this, TSVExportRenderer);
|
||||
|
||||
return _possibleConstructorReturn(this, (TSVExportRenderer.__proto__ || Object.getPrototypeOf(TSVExportRenderer)).apply(this, arguments));
|
||||
}
|
||||
|
||||
_createClass(TSVExportRenderer, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var pivotData = new _Utilities.PivotData(this.props);
|
||||
var rowKeys = pivotData.getRowKeys();
|
||||
var colKeys = pivotData.getColKeys();
|
||||
if (rowKeys.length === 0) {
|
||||
rowKeys.push([]);
|
||||
}
|
||||
if (colKeys.length === 0) {
|
||||
colKeys.push([]);
|
||||
}
|
||||
|
||||
var headerRow = pivotData.props.rows.map(function (r) {
|
||||
return r;
|
||||
});
|
||||
if (colKeys.length === 1 && colKeys[0].length === 0) {
|
||||
headerRow.push(this.props.aggregatorName);
|
||||
} else {
|
||||
colKeys.map(function (c) {
|
||||
return headerRow.push(c.join('-'));
|
||||
});
|
||||
}
|
||||
|
||||
var result = rowKeys.map(function (r) {
|
||||
var row = r.map(function (x) {
|
||||
return x;
|
||||
});
|
||||
colKeys.map(function (c) {
|
||||
var v = pivotData.getAggregator(r, c).value();
|
||||
row.push(v ? v : '');
|
||||
});
|
||||
return row;
|
||||
});
|
||||
|
||||
result.unshift(headerRow);
|
||||
|
||||
return _react2.default.createElement('textarea', {
|
||||
value: result.map(function (r) {
|
||||
return r.join('\t');
|
||||
}).join('\n'),
|
||||
style: { width: window.innerWidth / 2, height: window.innerHeight / 2 },
|
||||
readOnly: true
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return TSVExportRenderer;
|
||||
}(_react2.default.PureComponent);
|
||||
|
||||
TSVExportRenderer.defaultProps = _Utilities.PivotData.defaultProps;
|
||||
TSVExportRenderer.propTypes = _Utilities.PivotData.propTypes;
|
||||
|
||||
exports.default = {
|
||||
Table: makeRenderer(),
|
||||
'Table Heatmap': makeRenderer({ heatmapMode: 'full' }),
|
||||
'Table Col Heatmap': makeRenderer({ heatmapMode: 'col' }),
|
||||
'Table Row Heatmap': makeRenderer({ heatmapMode: 'row' }),
|
||||
'Exportable TSV': TSVExportRenderer
|
||||
};
|
||||
module.exports = exports['default'];
|
||||
//# sourceMappingURL=TableRenderers.js.map
|
1
TableRenderers.js.map
Normal file
1
TableRenderers.js.map
Normal file
File diff suppressed because one or more lines are too long
1035
Utilities.js
Normal file
1035
Utilities.js
Normal file
File diff suppressed because it is too large
Load Diff
1
Utilities.js.map
Normal file
1
Utilities.js.map
Normal file
File diff suppressed because one or more lines are too long
120
node_modules/classnames/HISTORY.md
generated
vendored
Normal file
120
node_modules/classnames/HISTORY.md
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
# Changelog
|
||||
|
||||
## v2.5.1 / 2023-12-29
|
||||
|
||||
- Remove `workspaces` field from package ([#350](https://github.com/JedWatson/classnames/pull/350))
|
||||
|
||||
## v2.5.0 / 2023-12-27
|
||||
|
||||
- Restore ability to pass a TypeScript `interface` ([#341](https://github.com/JedWatson/classnames/pull/341))
|
||||
- Add `exports` field to package ([#342](https://github.com/JedWatson/classnames/pull/342))
|
||||
|
||||
## v2.4.0 / 2023-12-26
|
||||
|
||||
- Use string concatenation to increase performance thanks [Jon Koops](https://github.com/jonkoops) ([#336](https://github.com/JedWatson/classnames/pull/336))
|
||||
|
||||
## v2.3.3 / 2023-12-21
|
||||
|
||||
- Fix default export, thanks [Remco Haszing](https://github.com/remcohaszing) ([#301](https://github.com/JedWatson/classnames/pull/301))
|
||||
- Fix types for read-only arrays, thanks [Ben Thompson](https://github.com/BenGearset) ([#307](https://github.com/JedWatson/classnames/pull/307))
|
||||
- Replace README examples with functional-style components, thanks [JoeDGit](https://github.com/JoeDGit) ([#303](https://github.com/JedWatson/classnames/pull/303))
|
||||
|
||||
## v2.3.2 / 2022-09-13
|
||||
|
||||
- Fix TypeScript types when using require, thanks [Mark Dalgleish](https://github.com/markdalgleish) ([#276](https://github.com/JedWatson/classnames/pull/276))
|
||||
- Fix toString as `[Object object]` in a vm, thanks [Remco Haszing](https://github.com/remcohaszing) ([#281](https://github.com/JedWatson/classnames/pull/281))
|
||||
|
||||
## v2.3.1 / 2021-04-03
|
||||
|
||||
- Fix bind/dedupe TypeScript types exports
|
||||
- Fix mapping Value types, thanks [Remco Haszing](https://github.com/remcohaszing)
|
||||
- Removed non-existent named exports from types, thanks [Remco Haszing](https://github.com/remcohaszing)
|
||||
|
||||
## v2.3.0 / 2021-04-01
|
||||
|
||||
- Added TypeScript types
|
||||
- Added consistent support for custom `.toString()` methods on arguments, thanks [Stanislav Titenko](https://github.com/resetko)
|
||||
|
||||
## v2.2.6 / 2018-06-08
|
||||
|
||||
- Fixed compatibility issue with usage in an es module environment
|
||||
|
||||
## v2.2.5 / 2016-05-02
|
||||
|
||||
- Improved performance of `dedupe` variant even further, thanks [Andres Suarez](https://github.com/zertosh)
|
||||
|
||||
## v2.2.4 / 2016-04-25
|
||||
|
||||
- Improved performance of `dedupe` variant by about 2x, thanks [Bartosz Gościński](https://github.com/bgoscinski)
|
||||
|
||||
## v2.2.3 / 2016-01-05
|
||||
|
||||
- Updated `bind` variant to use `[].join(' ')` as per the main script in 2.2.2
|
||||
|
||||
## v2.2.2 / 2016-01-04
|
||||
|
||||
- Switched from string concatenation to `[].join(' ')` for a slight performance gain in the main function.
|
||||
|
||||
## v2.2.1 / 2015-11-26
|
||||
|
||||
- Add deps parameter to the AMD module, fixes an issue using the Dojo loader, thanks [Chris Jordan](https://github.com/flipperkid)
|
||||
|
||||
## v2.2.0 / 2015-10-18
|
||||
|
||||
- added a new `bind` variant for use with [css-modules](https://github.com/css-modules/css-modules) and similar abstractions, thanks to [Kirill Yakovenko](https://github.com/blia)
|
||||
|
||||
## v2.1.5 / 2015-09-30
|
||||
|
||||
- reverted a new usage of `Object.keys` in `dedupe.js` that slipped through in the last release
|
||||
|
||||
## v2.1.4 / 2015-09-30
|
||||
|
||||
- new case added to benchmarks
|
||||
- safer `hasOwnProperty` check
|
||||
- AMD module is now named, so you can do the following:
|
||||
|
||||
```
|
||||
define(["classnames"], function (classNames) {
|
||||
var style = classNames("foo", "bar");
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
## v2.1.3 / 2015-07-02
|
||||
|
||||
- updated UMD wrapper to support AMD and CommonJS on the same pacge
|
||||
|
||||
## v2.1.2 / 2015-05-28
|
||||
|
||||
- added a proper UMD wrapper
|
||||
|
||||
## v2.1.1 / 2015-05-06
|
||||
|
||||
- minor performance improvement thanks to type caching
|
||||
- improved benchmarking and results output
|
||||
|
||||
## v2.1.0 / 2015-05-05
|
||||
|
||||
- added alternate `dedupe` version of classNames, which is slower (10x) but ensures that if a class is added then overridden by a falsy value in a subsequent argument, it is excluded from the result.
|
||||
|
||||
## v2.0.0 / 2015-05-03
|
||||
|
||||
- performance improvement; switched to `Array.isArray` for type detection, which is much faster in modern browsers. A polyfill is now required for IE8 support, see the Readme for details.
|
||||
|
||||
## v1.2.2 / 2015-04-28
|
||||
|
||||
- license comment updates to simiplify certain build scenarios
|
||||
|
||||
## v1.2.1 / 2015-04-22
|
||||
|
||||
- added safe exporting for requireJS usage
|
||||
- clarified Bower usage and instructions
|
||||
|
||||
## v1.2.0 / 2015-03-17
|
||||
|
||||
- added comprehensive support for array arguments, including nested arrays
|
||||
- simplified code slightly
|
||||
|
||||
## Previous
|
||||
|
||||
Please see the git history for the details of previous versions.
|
21
node_modules/classnames/LICENSE
generated
vendored
Normal file
21
node_modules/classnames/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Jed Watson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
219
node_modules/classnames/README.md
generated
vendored
Normal file
219
node_modules/classnames/README.md
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
# Classnames
|
||||
|
||||
> A simple JavaScript utility for conditionally joining classNames together.
|
||||
|
||||
<p>
|
||||
<a aria-label="NPM version" href="https://www.npmjs.com/package/classnames">
|
||||
<img alt="" src="https://img.shields.io/npm/v/classnames.svg?style=for-the-badge&labelColor=0869B8">
|
||||
</a>
|
||||
<a aria-label="License" href="#">
|
||||
<img alt="" src="https://img.shields.io/npm/l/classnames.svg?style=for-the-badge&labelColor=579805">
|
||||
</a>
|
||||
<a aria-label="Thinkmill Logo" href="https://www.thinkmill.com.au/open-source?utm_campaign=github-classnames">
|
||||
<img src="https://img.shields.io/badge/Sponsored%20BY%20Thinkmill-ed0000.svg?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTg2IiBoZWlnaHQ9IjU4NiIgdmlld0JveD0iMCAwIDU4NiA1ODYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xOTk2XzQwNikiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTU4NiAyOTNDNTg2IDQ1NC44MTkgNDU0LjgxOSA1ODYgMjkzIDU4NkMxMzEuMTgxIDU4NiAwIDQ1NC44MTkgMCAyOTNDMCAxMzEuMTgxIDEzMS4xODEgMCAyOTMgMEM0NTQuODE5IDAgNTg2IDEzMS4xODEgNTg2IDI5M1pNMjA1Ljc3NiAzNTguOTQ0QzE5MS4zNzYgMzU4Ljk0NCAxODUuOTA0IDM1Mi4zMiAxODUuOTA0IDMzNS45MDRWMjYyLjc1MkgyMTQuNDE2VjIzNy42OTZIMTg1LjkwNFYyMDEuMTJIMTUzLjA3MlYyMzcuNjk2SDEyOC41OTJWMjYyLjc1MkgxNTMuMDcyVjM0MC44QzE1My4wNzIgMzcyLjc2OCAxNjYuNjA4IDM4NS43MjggMTk3LjQyNCAzODUuNzI4QzIwMy40NzIgMzg1LjcyOCAyMTAuOTYgMzg0LjU3NiAyMTUuODU2IDM4My4xMzZWMzU3LjUwNEMyMTMuNTUyIDM1OC4zNjggMjA5LjUyIDM1OC45NDQgMjA1Ljc3NiAzNTguOTQ0Wk00MDcuMzc2IDIzNC4yNEMzODUuMiAyMzQuMjQgMzcxLjA4OCAyNDQuMDMyIDM2MC40MzIgMjYwLjczNkMzNTIuOTQ0IDI0My40NTYgMzM3LjM5MiAyMzQuMjQgMzE3LjIzMiAyMzQuMjRDMjk5Ljk1MiAyMzQuMjQgMjg2Ljk5MiAyNDEuMTUyIDI3Ni42MjQgMjU1LjI2NEgyNzYuMDQ4VjIzNy42OTZIMjQ0LjY1NlYzODRIMjc3LjQ4OFYzMDUuNjY0QzI3Ny40ODggMjc3LjQ0IDI4OC43MiAyNjAuNzM2IDMwOC4zMDQgMjYwLjczNkMzMjUuMjk2IDI2MC43MzYgMzM0LjUxMiAyNzIuODMyIDMzNC41MTIgMjkzLjU2OFYzODRIMzY3LjM0NFYzMDUuMDg4QzM2Ny4zNDQgMjc3LjE1MiAzNzguODY0IDI2MC43MzYgMzk4LjE2IDI2MC43MzZDNDE0LjU3NiAyNjAuNzM2IDQyNC42NTYgMjcxLjEwNCA0MjQuNjU2IDI5Ny4wMjRWMzg0SDQ1Ny40ODhWMjkzLjg1NkM0NTcuNDg4IDI1NC40IDQzOC40OCAyMzQuMjQgNDA3LjM3NiAyMzQuMjRaIiBmaWxsPSJ3aGl0ZSIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE5OTZfNDA2Ij4KPHJlY3Qgd2lkdGg9IjU4NiIgaGVpZ2h0PSI1ODYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==&labelColor=C60200&locoColor=white&logoWidth=0">
|
||||
</a>
|
||||
|
||||
</p>
|
||||
|
||||
Install from the [npm registry](https://www.npmjs.com/) with your package manager:
|
||||
```bash
|
||||
npm install classnames
|
||||
```
|
||||
|
||||
Use with [Node.js](https://nodejs.org/en/), [Browserify](https://browserify.org/), or [webpack](https://webpack.github.io/):
|
||||
|
||||
```js
|
||||
const classNames = require('classnames');
|
||||
classNames('foo', 'bar'); // => 'foo bar'
|
||||
```
|
||||
|
||||
Alternatively, you can simply include `index.js` on your page with a standalone `<script>` tag and it will export a global `classNames` method, or define the module if you are using RequireJS.
|
||||
|
||||
### Project philosophy
|
||||
|
||||
We take the stability and performance of this package seriously, because it is run millions of times a day in browsers all around the world. Updates are thoroughly reviewed for performance implications before being released, and we have a comprehensive test suite.
|
||||
|
||||
Classnames follows the [SemVer](https://semver.org/) standard for versioning.
|
||||
|
||||
There is also a [Changelog](https://github.com/JedWatson/classnames/blob/master/HISTORY.md).
|
||||
|
||||
## Usage
|
||||
|
||||
The `classNames` function takes any number of arguments which can be a string or object.
|
||||
The argument `'foo'` is short for `{ foo: true }`. If the value associated with a given key is falsy, that key won't be included in the output.
|
||||
|
||||
```js
|
||||
classNames('foo', 'bar'); // => 'foo bar'
|
||||
classNames('foo', { bar: true }); // => 'foo bar'
|
||||
classNames({ 'foo-bar': true }); // => 'foo-bar'
|
||||
classNames({ 'foo-bar': false }); // => ''
|
||||
classNames({ foo: true }, { bar: true }); // => 'foo bar'
|
||||
classNames({ foo: true, bar: true }); // => 'foo bar'
|
||||
|
||||
// lots of arguments of various types
|
||||
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
|
||||
|
||||
// other falsy values are just ignored
|
||||
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
|
||||
```
|
||||
|
||||
Arrays will be recursively flattened as per the rules above:
|
||||
|
||||
```js
|
||||
const arr = ['b', { c: true, d: false }];
|
||||
classNames('a', arr); // => 'a b c'
|
||||
```
|
||||
|
||||
### Dynamic class names with ES2015
|
||||
|
||||
If you're in an environment that supports [computed keys](https://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer) (available in ES2015 and Babel) you can use dynamic class names:
|
||||
|
||||
```js
|
||||
let buttonType = 'primary';
|
||||
classNames({ [`btn-${buttonType}`]: true });
|
||||
```
|
||||
|
||||
### Usage with React.js
|
||||
|
||||
This package is the official replacement for `classSet`, which was originally shipped in the React.js Addons bundle.
|
||||
|
||||
One of its primary use cases is to make dynamic and conditional `className` props simpler to work with (especially more so than conditional string manipulation). So where you may have the following code to generate a `className` prop for a `<button>` in React:
|
||||
|
||||
```js
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export default function Button (props) {
|
||||
const [isPressed, setIsPressed] = useState(false);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
let btnClass = 'btn';
|
||||
if (isPressed) btnClass += ' btn-pressed';
|
||||
else if (isHovered) btnClass += ' btn-over';
|
||||
|
||||
return (
|
||||
<button
|
||||
className={btnClass}
|
||||
onMouseDown={() => setIsPressed(true)}
|
||||
onMouseUp={() => setIsPressed(false)}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
{props.label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
You can express the conditional classes more simply as an object:
|
||||
|
||||
```js
|
||||
import React, { useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default function Button (props) {
|
||||
const [isPressed, setIsPressed] = useState(false);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const btnClass = classNames({
|
||||
btn: true,
|
||||
'btn-pressed': isPressed,
|
||||
'btn-over': !isPressed && isHovered,
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
className={btnClass}
|
||||
onMouseDown={() => setIsPressed(true)}
|
||||
onMouseUp={() => setIsPressed(false)}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
{props.label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Because you can mix together object, array and string arguments, supporting optional `className` props is also simpler as only truthy arguments get included in the result:
|
||||
|
||||
```js
|
||||
const btnClass = classNames('btn', this.props.className, {
|
||||
'btn-pressed': isPressed,
|
||||
'btn-over': !isPressed && isHovered,
|
||||
});
|
||||
```
|
||||
|
||||
### Alternate `dedupe` version
|
||||
|
||||
There is an alternate version of `classNames` available which correctly dedupes classes and ensures that falsy classes specified in later arguments are excluded from the result set.
|
||||
|
||||
This version is slower (about 5x) so it is offered as an opt-in.
|
||||
|
||||
To use the dedupe version with Node.js, Browserify, or webpack:
|
||||
|
||||
```js
|
||||
const classNames = require('classnames/dedupe');
|
||||
|
||||
classNames('foo', 'foo', 'bar'); // => 'foo bar'
|
||||
classNames('foo', { foo: false, bar: true }); // => 'bar'
|
||||
```
|
||||
|
||||
For standalone (global / AMD) use, include `dedupe.js` in a `<script>` tag on your page.
|
||||
|
||||
### Alternate `bind` version (for [css-modules](https://github.com/css-modules/css-modules))
|
||||
|
||||
If you are using [css-modules](https://github.com/css-modules/css-modules), or a similar approach to abstract class 'names' and the real `className` values that are actually output to the DOM, you may want to use the `bind` variant.
|
||||
|
||||
_Note that in ES2015 environments, it may be better to use the "dynamic class names" approach documented above._
|
||||
|
||||
```js
|
||||
const classNames = require('classnames/bind');
|
||||
|
||||
const styles = {
|
||||
foo: 'abc',
|
||||
bar: 'def',
|
||||
baz: 'xyz',
|
||||
};
|
||||
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
const className = cx('foo', ['bar'], { baz: true }); // => 'abc def xyz'
|
||||
```
|
||||
|
||||
Real-world example:
|
||||
|
||||
```js
|
||||
/* components/submit-button.js */
|
||||
import { useState } from 'react';
|
||||
import classNames from 'classnames/bind';
|
||||
import styles from './submit-button.css';
|
||||
|
||||
const cx = classNames.bind(styles);
|
||||
|
||||
export default function SubmitButton ({ store, form }) {
|
||||
const [submissionInProgress, setSubmissionInProgress] = useState(store.submissionInProgress);
|
||||
const [errorOccurred, setErrorOccurred] = useState(store.errorOccurred);
|
||||
const [valid, setValid] = useState(form.valid);
|
||||
|
||||
const text = submissionInProgress ? 'Processing...' : 'Submit';
|
||||
const className = cx({
|
||||
base: true,
|
||||
inProgress: submissionInProgress,
|
||||
error: errorOccurred,
|
||||
disabled: valid,
|
||||
});
|
||||
|
||||
return <button className={className}>{text}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
## Polyfills needed to support older browsers
|
||||
|
||||
#### `classNames >=2.0.0`
|
||||
|
||||
`Array.isArray`: see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) for details about unsupported older browsers (e.g. <= IE8) and a simple polyfill.
|
||||
|
||||
## LICENSE [MIT](LICENSE)
|
||||
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Copyright of the Typescript bindings are respective of each contributor listed in the definition file.
|
17
node_modules/classnames/bind.d.ts
generated
vendored
Normal file
17
node_modules/classnames/bind.d.ts
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import { ArgumentArray } from './index.js';
|
||||
|
||||
declare namespace classNames {
|
||||
type Binding = Record<string, string>;
|
||||
}
|
||||
|
||||
interface ClassNames {
|
||||
(this: classNames.Binding | undefined, ...args: ArgumentArray): string;
|
||||
|
||||
default: ClassNames;
|
||||
}
|
||||
|
||||
declare const classNames: ClassNames;
|
||||
|
||||
export as namespace classNames;
|
||||
|
||||
export = classNames;
|
77
node_modules/classnames/bind.js
generated
vendored
Normal file
77
node_modules/classnames/bind.js
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
/* global define */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var hasOwn = {}.hasOwnProperty;
|
||||
|
||||
function classNames () {
|
||||
var classes = '';
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
if (arg) {
|
||||
classes = appendClass(classes, parseValue.call(this, arg));
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
function parseValue (arg) {
|
||||
if (typeof arg === 'string' || typeof arg === 'number') {
|
||||
return this && this[arg] || arg;
|
||||
}
|
||||
|
||||
if (typeof arg !== 'object') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Array.isArray(arg)) {
|
||||
return classNames.apply(this, arg);
|
||||
}
|
||||
|
||||
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
|
||||
return arg.toString();
|
||||
}
|
||||
|
||||
var classes = '';
|
||||
|
||||
for (var key in arg) {
|
||||
if (hasOwn.call(arg, key) && arg[key]) {
|
||||
classes = appendClass(classes, this && this[key] || key);
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
function appendClass (value, newClass) {
|
||||
if (!newClass) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
return value + ' ' + newClass;
|
||||
}
|
||||
|
||||
return value + newClass;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
classNames.default = classNames;
|
||||
module.exports = classNames;
|
||||
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
|
||||
// register as 'classnames', consistent with npm package name
|
||||
define('classnames', [], function () {
|
||||
return classNames;
|
||||
});
|
||||
} else {
|
||||
window.classNames = classNames;
|
||||
}
|
||||
}());
|
5
node_modules/classnames/dedupe.d.ts
generated
vendored
Normal file
5
node_modules/classnames/dedupe.d.ts
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import classNames = require('./index.js');
|
||||
|
||||
export as namespace classNames;
|
||||
|
||||
export = classNames;
|
115
node_modules/classnames/dedupe.js
generated
vendored
Normal file
115
node_modules/classnames/dedupe.js
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
/* global define */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var classNames = (function () {
|
||||
// don't inherit from Object so we can skip hasOwnProperty check later
|
||||
// http://stackoverflow.com/questions/15518328/creating-js-object-with-object-createnull#answer-21079232
|
||||
function StorageObject() {}
|
||||
StorageObject.prototype = Object.create(null);
|
||||
|
||||
function _parseArray (resultSet, array) {
|
||||
var length = array.length;
|
||||
|
||||
for (var i = 0; i < length; ++i) {
|
||||
_parse(resultSet, array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var hasOwn = {}.hasOwnProperty;
|
||||
|
||||
function _parseNumber (resultSet, num) {
|
||||
resultSet[num] = true;
|
||||
}
|
||||
|
||||
function _parseObject (resultSet, object) {
|
||||
if (object.toString !== Object.prototype.toString && !object.toString.toString().includes('[native code]')) {
|
||||
resultSet[object.toString()] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (var k in object) {
|
||||
if (hasOwn.call(object, k)) {
|
||||
// set value to false instead of deleting it to avoid changing object structure
|
||||
// https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#de-referencing-misconceptions
|
||||
resultSet[k] = !!object[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var SPACE = /\s+/;
|
||||
function _parseString (resultSet, str) {
|
||||
var array = str.split(SPACE);
|
||||
var length = array.length;
|
||||
|
||||
for (var i = 0; i < length; ++i) {
|
||||
resultSet[array[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
function _parse (resultSet, arg) {
|
||||
if (!arg) return;
|
||||
var argType = typeof arg;
|
||||
|
||||
// 'foo bar'
|
||||
if (argType === 'string') {
|
||||
_parseString(resultSet, arg);
|
||||
|
||||
// ['foo', 'bar', ...]
|
||||
} else if (Array.isArray(arg)) {
|
||||
_parseArray(resultSet, arg);
|
||||
|
||||
// { 'foo': true, ... }
|
||||
} else if (argType === 'object') {
|
||||
_parseObject(resultSet, arg);
|
||||
|
||||
// '130'
|
||||
} else if (argType === 'number') {
|
||||
_parseNumber(resultSet, arg);
|
||||
}
|
||||
}
|
||||
|
||||
function _classNames () {
|
||||
// don't leak arguments
|
||||
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
|
||||
var len = arguments.length;
|
||||
var args = Array(len);
|
||||
for (var i = 0; i < len; i++) {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
|
||||
var classSet = new StorageObject();
|
||||
_parseArray(classSet, args);
|
||||
|
||||
var list = [];
|
||||
|
||||
for (var k in classSet) {
|
||||
if (classSet[k]) {
|
||||
list.push(k)
|
||||
}
|
||||
}
|
||||
|
||||
return list.join(' ');
|
||||
}
|
||||
|
||||
return _classNames;
|
||||
})();
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
classNames.default = classNames;
|
||||
module.exports = classNames;
|
||||
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
|
||||
// register as 'classnames', consistent with npm package name
|
||||
define('classnames', [], function () {
|
||||
return classNames;
|
||||
});
|
||||
} else {
|
||||
window.classNames = classNames;
|
||||
}
|
||||
}());
|
32
node_modules/classnames/index.d.ts
generated
vendored
Normal file
32
node_modules/classnames/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// LICENSE is MIT
|
||||
//
|
||||
// Copyright (c) 2018
|
||||
// Dave Keen <http://www.keendevelopment.ch>
|
||||
// Adi Dahiya <https://github.com/adidahiya>
|
||||
// Jason Killian <https://github.com/JKillian>
|
||||
// Sean Kelley <https://github.com/seansfkelley>
|
||||
// Michal Adamczyk <https://github.com/mradamczyk>
|
||||
// Marvin Hagemeister <https://github.com/marvinhagemeister>
|
||||
|
||||
declare namespace classNames {
|
||||
type Value = string | number | boolean | undefined | null;
|
||||
type Mapping = Record<string, any>;
|
||||
interface ArgumentArray extends Array<Argument> {}
|
||||
interface ReadonlyArgumentArray extends ReadonlyArray<Argument> {}
|
||||
type Argument = Value | Mapping | ArgumentArray | ReadonlyArgumentArray;
|
||||
}
|
||||
|
||||
interface ClassNames {
|
||||
(...args: classNames.ArgumentArray): string;
|
||||
|
||||
default: ClassNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple JavaScript utility for conditionally joining classNames together.
|
||||
*/
|
||||
declare const classNames: ClassNames;
|
||||
|
||||
export as namespace classNames;
|
||||
|
||||
export = classNames;
|
77
node_modules/classnames/index.js
generated
vendored
Normal file
77
node_modules/classnames/index.js
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
/* global define */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var hasOwn = {}.hasOwnProperty;
|
||||
|
||||
function classNames () {
|
||||
var classes = '';
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
if (arg) {
|
||||
classes = appendClass(classes, parseValue(arg));
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
function parseValue (arg) {
|
||||
if (typeof arg === 'string' || typeof arg === 'number') {
|
||||
return arg;
|
||||
}
|
||||
|
||||
if (typeof arg !== 'object') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Array.isArray(arg)) {
|
||||
return classNames.apply(null, arg);
|
||||
}
|
||||
|
||||
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
|
||||
return arg.toString();
|
||||
}
|
||||
|
||||
var classes = '';
|
||||
|
||||
for (var key in arg) {
|
||||
if (hasOwn.call(arg, key) && arg[key]) {
|
||||
classes = appendClass(classes, key);
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
function appendClass (value, newClass) {
|
||||
if (!newClass) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
return value + ' ' + newClass;
|
||||
}
|
||||
|
||||
return value + newClass;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
classNames.default = classNames;
|
||||
module.exports = classNames;
|
||||
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
|
||||
// register as 'classnames', consistent with npm package name
|
||||
define('classnames', [], function () {
|
||||
return classNames;
|
||||
});
|
||||
} else {
|
||||
window.classNames = classNames;
|
||||
}
|
||||
}());
|
78
node_modules/classnames/package.json
generated
vendored
Normal file
78
node_modules/classnames/package.json
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "classnames",
|
||||
"version": "2.5.1",
|
||||
"description": "A simple utility for conditionally joining classNames together",
|
||||
"author": "Jed Watson",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/JedWatson/classnames.git"
|
||||
},
|
||||
"type": "commonjs",
|
||||
"main": "./index.js",
|
||||
"types": "./index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./index.js": {
|
||||
"types": "./index.d.ts",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./bind": {
|
||||
"types": "./bind.d.ts",
|
||||
"default": "./bind.js"
|
||||
},
|
||||
"./bind.js": {
|
||||
"types": "./bind.d.ts",
|
||||
"default": "./bind.js"
|
||||
},
|
||||
"./dedupe": {
|
||||
"types": "./dedupe.d.ts",
|
||||
"default": "./dedupe.js"
|
||||
},
|
||||
"./dedupe.js": {
|
||||
"types": "./dedupe.d.ts",
|
||||
"default": "./dedupe.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node --test ./tests/*.mjs",
|
||||
"bench": "node ./benchmarks/run.js",
|
||||
"bench-browser": "rollup --plugin commonjs,json,node-resolve ./benchmarks/runInBrowser.js --file ./benchmarks/runInBrowser.bundle.js && http-server -c-1 ./benchmarks",
|
||||
"check-types": "tsd"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"css",
|
||||
"classes",
|
||||
"classname",
|
||||
"classnames",
|
||||
"util",
|
||||
"utility"
|
||||
],
|
||||
"files": [
|
||||
"HISTORY.md",
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"*.d.ts",
|
||||
"*.js"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"classnames-local": "file:.",
|
||||
"classnames-npm": "npm:classnames@*",
|
||||
"http-server": "^14.1.1",
|
||||
"markdown-table": "^3.0.3",
|
||||
"rollup": "^4.9.1",
|
||||
"tinybench": "^2.5.1",
|
||||
"tsd": "^0.30.1"
|
||||
},
|
||||
"tsd": {
|
||||
"directory": "./tests"
|
||||
}
|
||||
}
|
409
node_modules/react-draggable/CHANGELOG.md
generated
vendored
Normal file
409
node_modules/react-draggable/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,409 @@
|
||||
# Changelog
|
||||
|
||||
### 3.3.2 (Aug 16, 2019)
|
||||
|
||||
- Use `all: inherit` instead of `background: transparent;` to fix selection styles.
|
||||
- Fixes https://github.com/mzabriskie/react-draggable/issues/315
|
||||
|
||||
### 3.3.1 (Aug 12, 2019)
|
||||
|
||||
- Fix React 16.9 `componentWillMount` deprecation.
|
||||
|
||||
### 3.3.0 (Apr 18, 2019)
|
||||
|
||||
- Addition of `positionOffset` prop, which can be Numbers (px) or string percentages (like `"10%"`). See the README for more.
|
||||
|
||||
### 3.2.1 (Mar 1, 2019)
|
||||
|
||||
- Reverted https://github.com/mzabriskie/react-draggable/pull/361.
|
||||
|
||||
### ~3.2.0 (Feb 27, 2019)~
|
||||
|
||||
> Note: this release has been pulled due to an inadvertent breaking change. See https://github.com/mzabriskie/react-draggable/issues/391
|
||||
|
||||
- Feature: `defaultPosition` now allows string offsets (like {x: '10%', y: '10%'}) then calculates deltas from there. See the examples and the PR [#361](https://github.com/mzabriskie/react-draggable/pull/361/). Thanks to @tnrich and @eric-burel.
|
||||
- Bugfix: Export `DraggableEvent` type for Flow consumers. Thanks @elie222.
|
||||
|
||||
### 3.1.1 (Dec 21, 2018)
|
||||
|
||||
- Bugfix: Minor type change on DraggableEventHandler TypeScript export ([#374](https://github.com/mzabriskie/react-draggable/pull/374))
|
||||
|
||||
### 3.1.0 (Dec 21, 2018)
|
||||
|
||||
- Feature: Added `scale` prop ([#352](https://github.com/mzabriskie/react-draggable/pull/352))
|
||||
- Thanks, @wootencl
|
||||
- Bugfix: Remove process.browser which is missing in browser ([#329]((https://github.com/mzabriskie/react-draggable/pull/329))
|
||||
- Bugfix: Fix selection api on IE ([#292](https://github.com/mzabriskie/react-draggable/pull/292))
|
||||
- Bugfix: Fixes some issues in the type definitions for TypeScript ([#331]((https://github.com/mzabriskie/react-draggable/pull/331))
|
||||
- Bugfix: Fix compare where portal elements are different instance to main window ([#359]((https://github.com/mzabriskie/react-draggable/pull/359))
|
||||
|
||||
### 3.0.5 (Jan 11, 2018)
|
||||
|
||||
- Bugfix: Fix crash in test environments during removeUserSelectStyles().
|
||||
|
||||
### 3.0.4 (Nov 27, 2017)
|
||||
|
||||
- Bugfix: Fix "Cannot call property 'call' of undefined" (matchesSelector)
|
||||
- Fixes [#300](https://github.com/mzabriskie/react-draggable/issues/300)
|
||||
|
||||
### 3.0.3 (Aug 31, 2017)
|
||||
|
||||
- Bugfix: Fix deprecation warnings caused by `import * as React` (Flow best practice).
|
||||
- See https://github.com/facebook/react/issues/10583
|
||||
|
||||
### 3.0.2 (Aug 22, 2017)
|
||||
|
||||
> 3.0.0 and 3.0.1 have been unpublished due to a large logfile making it into the package.
|
||||
|
||||
- Bugfix: Tweaked `.npmignore`.
|
||||
|
||||
### 3.0.1 (Aug 21, 2017)
|
||||
|
||||
- Bugfix: Flow-type should no longer throw errors for consumers.
|
||||
- It appears Flow can't resolve a sub-package's interfaces.
|
||||
|
||||
### 3.0.0 (Aug 21, 2017)
|
||||
|
||||
> Due to an export change, this is semver-major.
|
||||
|
||||
- Breaking: For TypeScript users, `<Draggable>` is now exported as `module.exports` and `module.exports.default`.
|
||||
- Potentially Breaking: We no longer set `user-select: none` on all elements while dragging. Instead,
|
||||
the [`::selection` psuedo element](https://developer.mozilla.org/en-US/docs/Web/CSS/::selection) is used.
|
||||
- Depending on your application, this could cause issues, so be sure to test.
|
||||
- Bugfix: Pass bounded `x`/`y` to callbacks. See [#226](https://github.com/mzabriskie/react-draggable/pull/226).
|
||||
- Internal: Upgraded dependencies.
|
||||
|
||||
### 2.2.6 (Apr 30, 2017)
|
||||
|
||||
- Bugfix: Missing export default on TS definition (thanks @lostfictions)
|
||||
- Internal: TS test suite (thanks @lostfictions)
|
||||
|
||||
### 2.2.5 (Apr 28, 2017)
|
||||
|
||||
- Bugfix: Typescript definition was incorrect. [#244](https://github.com/mzabriskie/react-draggable/issues/244)
|
||||
|
||||
### 2.2.4 (Apr 27, 2017)
|
||||
|
||||
- Internal: Moved `PropTypes` access to `prop-types` package for React 15.5 (prep for 16)
|
||||
- Feature: Added TypeScript definitions (thanks @erfangc)
|
||||
- Bugfix: No longer can erroneously add user-select style multiple times
|
||||
- Bugfix: OffsetParent with padding problem, fixes [#218](https://github.com/mzabriskie/react-draggable/issues/218)
|
||||
- Refactor: Misc example updates.
|
||||
|
||||
### 2.2.3 (Nov 21, 2016)
|
||||
|
||||
- Bugfix: Fix an issue with the entire window scrolling on a drag on iDevices. Thanks @JaneCoder. See #183
|
||||
|
||||
### 2.2.2 (Sep 14, 2016)
|
||||
|
||||
- Bugfix: Fix references to global when grabbing `SVGElement`, see [#162](https://github.com/mzabriskie/react-draggable/issues/162)
|
||||
- Bugfix: Get `ownerDocument` before `onStop`, fixes [#198](https://github.com/mzabriskie/react-draggable/issues/198)
|
||||
|
||||
### 2.2.1 (Aug 11, 2016)
|
||||
|
||||
- Bugfix: Fix `getComputedStyle` error: see [#186](https://github.com/mzabriskie/react-draggable/issues/186), #190
|
||||
|
||||
### 2.2.0 (Jul 29, 2016)
|
||||
|
||||
- Addition: `offsetParent` property for an arbitrary ancestor for offset calculations.
|
||||
- Fixes e.g. dragging with a floating `offsetParent`.
|
||||
- Ref: https://github.com/mzabriskie/react-draggable/issues/170
|
||||
- Enhancement: Make this library iframe-aware.
|
||||
- Ref: https://github.com/mzabriskie/react-draggable/pull/177
|
||||
- Thanks to @acusti for tests
|
||||
- Bugfix: Lint/Test Fixes for new Flow & React versions
|
||||
|
||||
### 2.1.2 (Jun 5, 2016)
|
||||
|
||||
- Bugfix: Fix `return false` to cancel `onDrag` breaking on both old and new browsers due to missing `typeArg` and/or
|
||||
unsupported `MouseEventConstructor`. Fixes [#164](https://github.com/mzabriskie/react-draggable/issues/164).
|
||||
|
||||
### 2.1.1 (May 22, 2016)
|
||||
|
||||
- Bugfix: `<DraggableCore>` wasn't calling back with the DOM node.
|
||||
- Internal: Rework test suite to use power-assert.
|
||||
|
||||
### 2.1.0 (May 20, 2016)
|
||||
|
||||
- Fix improperly missed `handle` or `cancel` selectors if the event originates from a child of the handle or cancel.
|
||||
- Fixes a longstanding issue, [#88](https://github.com/mzabriskie/react-draggable/pull/88)
|
||||
- This was pushed to a minor release as there may be edge cases (perhaps workarounds) where this changes behavior.
|
||||
|
||||
### 2.0.2 (May 19, 2016)
|
||||
|
||||
- Fix `cannot access clientX of undefined` on some touch-enabled platforms.
|
||||
- Fixes [#159](https://github.com/mzabriskie/react-draggable/pull/159),
|
||||
[#118](https://github.com/mzabriskie/react-draggable/pull/118)
|
||||
- Fixed a bug with multi-finger multitouch if > 1 finger triggered an event at the same time.
|
||||
|
||||
### 2.0.1 (May 19, 2016)
|
||||
|
||||
- Finally fixed the IE10 constructor bug. Thanks @davidstubbs [#158](https://github.com/mzabriskie/react-draggable/pull/158)
|
||||
|
||||
### 2.0.0 (May 10, 2016)
|
||||
|
||||
- This is a breaking change. See the changes below in the beta releases.
|
||||
- Note the changes to event callbacks and `position` / `defaultPosition`.
|
||||
- Changes from 2.0.0-beta3:
|
||||
- Small bugfixes for Flow 0.24 compatibility.
|
||||
- Don't assume `global.SVGElement`. Fixes JSDOM & [#123](https://github.com/mzabriskie/react-draggable/issues/123).
|
||||
|
||||
### 2.0.0-beta3 (Apr 19, 2016)
|
||||
|
||||
- Flow comments are now in the build. Other projects, such as React-Grid-Layout and React-Resizable, will
|
||||
rely on them in their build and export their own comments.
|
||||
|
||||
### 2.0.0-beta2 (Apr 14, 2016)
|
||||
|
||||
- We're making a small deviation from React Core's controlled vs. uncontrolled scheme; for convenience,
|
||||
`<Draggable>`s with a `position` property will still be draggable, but will revert to their old position
|
||||
on drag stop. Attach an `onStop` or `onDrag` handler to synchronize state.
|
||||
- A warning has been added informing users of this. If you make `<Draggable>` controlled but attach no callback
|
||||
handlers, a warning will be printed.
|
||||
|
||||
### 2.0.0-beta1 (Apr 14, 2016)
|
||||
|
||||
- Due to API changes, this is a major release.
|
||||
|
||||
#### Breaking Changes:
|
||||
|
||||
- Both `<DraggableCore>` and `<Draggable>` have had their callback types changed and unified.
|
||||
|
||||
```js
|
||||
type DraggableEventHandler = (e: Event, data: DraggableData) => void | false;
|
||||
type DraggableData = {
|
||||
node: HTMLElement,
|
||||
// lastX + deltaX === x
|
||||
x: number, y: number,
|
||||
deltaX: number, deltaY: number,
|
||||
lastX: number, lastY: number
|
||||
};
|
||||
```
|
||||
|
||||
- The `start` option has been renamed to `defaultPosition`.
|
||||
- The `zIndex` option has been removed.
|
||||
|
||||
#### Possibly Breaking Changes:
|
||||
|
||||
- When determining deltas, we now use a new method that checks the delta against the Draggable's `offsetParent`.
|
||||
This method allows us to support arbitrary nested scrollable ancestors without scroll handlers!
|
||||
- This may cause issues in certain layouts. If you find one, please open an issue.
|
||||
|
||||
#### Enhancements:
|
||||
|
||||
- `<Draggable>` now has a `position` attribute. Its relationship to `defaultPosition` is much like
|
||||
`value` to `defaultValue` on React `<input>` nodes. If set, the position is fixed and cannot be mutated.
|
||||
If empty, the component will manage its own state. See [#140](https://github.com/mzabriskie/react-draggable/pull/140)
|
||||
for more info & motivations.
|
||||
- Misc. bugfixes.
|
||||
|
||||
### 1.4.0-beta1 (Apr 13, 2016)
|
||||
|
||||
- Major improvements to drag tracking that now support even nested scroll boxes.
|
||||
- This revision is being done as a pre-release to ensure there are no unforeseen issues with the offset changes.
|
||||
|
||||
### 1.3.7 (Apr 8, 2016)
|
||||
|
||||
- Fix `user-select` prefixing, which may be different than the prefix required for `transform`.
|
||||
|
||||
### 1.3.6 (Apr 8, 2016)
|
||||
|
||||
- Republished after 1.3.5 contained a bundling error.
|
||||
|
||||
### 1.3.5 (Apr 8, 2016)
|
||||
|
||||
- Add React v15 to devDeps. `<Draggable>` supports both `v0.14` and `v15`.
|
||||
- Enhancement: Clean up usage of browser prefixes; modern browsers will no longer use them.
|
||||
- This also removes the duplicated `user-select` style that is created on the `<body>` while dragging.
|
||||
- Internal: Test fixes.
|
||||
|
||||
### 1.3.4 (Mar 5, 2016)
|
||||
|
||||
- Bugfix: Scrolling while dragging caused items to move unpredictably.
|
||||
|
||||
### 1.3.3 (Feb 11, 2016)
|
||||
|
||||
- Bugfix: #116: Android/Chrome are finicky; give up on canceling ghost clicks entirely.
|
||||
|
||||
### 1.3.2 (Feb 11, 2016)
|
||||
|
||||
- Bugfix: #116: Child inputs not focusing on touch events.
|
||||
|
||||
### 1.3.1 (Feb 10, 2016)
|
||||
|
||||
- Internal: Babel 6 and Flow definitions
|
||||
- Bugfix: 1.3.0 broke string bounds ('parent', selectors, etc.).
|
||||
- Bugfix: 1.3.0 wasn't updating deltaX and deltaY on a bounds hit.
|
||||
|
||||
### 1.3.0 (Feb 10, 2016)
|
||||
|
||||
- Possibly breaking change: bounds are calculated before `<Draggable>` fires `drag` events, as they should have been.
|
||||
- Added `'none'` axis type. This allows using `<Draggable>` somewhat like `<DraggableCore>` - state will be kept
|
||||
internally (which makes bounds checks etc possible), but updates will not be flushed to the DOM.
|
||||
- Performance tweaks.
|
||||
|
||||
### 1.2.0 (Feb 5, 2016)
|
||||
|
||||
- Added arbitrary boundary selector. Now you don't have to just use `'parent'`, you can select any element
|
||||
on the page, including `'body'`.
|
||||
- Bugfix: Prevent invariant if a `<Draggable>` is unmounted while dragging.
|
||||
- Bugfix: Fix #133, where items would eagerly start dragging off the mouse cursor if you hit boundaries and
|
||||
came back. This is due to how `<DraggableCore>` handles deltas only and does not keep state. Added new state
|
||||
properties `slackX` and `slackY` to `<Draggable>` to handle this and restore pre-v1 behavior.
|
||||
|
||||
### 1.1.3 (Nov 25, 2015)
|
||||
|
||||
- Bugfix: Server-side rendering with react-rails, which does bad things like mock `window`
|
||||
|
||||
### 1.1.2 (Nov 23, 2015)
|
||||
|
||||
- Bugfix: `<Draggable>` was calling back with clientX/Y, not offsetX/Y as it did pre-1.0. This unintended
|
||||
behavior has been fixed and a test has been added.
|
||||
|
||||
### 1.1.1 (Nov 14, 2015)
|
||||
|
||||
- Bugfix: Clean up scroll events if a component is unmounted before drag stops.
|
||||
- Bugfix: `NaN` was returning from scroll events due to event structure change.
|
||||
- Add scroll drag modulation test.
|
||||
|
||||
### 1.1.0 (Nov 14, 2015)
|
||||
|
||||
- Move `grid` into `<DraggableCore>` directly. It will continue to work on `<Draggable>`.
|
||||
- Development fixes.
|
||||
|
||||
### 1.0.2 (Nov 7, 2015)
|
||||
|
||||
- Fix `enableUserSelectHack` not properly disabling.
|
||||
- Fix a crash when the user scrolls the page with a Draggable active.
|
||||
|
||||
### 1.0.1 (Oct 28, 2015)
|
||||
|
||||
- Fix missing dist files for webpack.
|
||||
- Ignore non-primary clicks. Added `allowAnyClick` option to allow other click types.
|
||||
|
||||
### 1.0.0 (Oct 27, 2015)
|
||||
|
||||
- Breaking: Removed `resetState()` instance method
|
||||
- Breaking: Removed `moveOnStartChange` prop
|
||||
- Breaking: React `0.14` support only.
|
||||
- Refactored project.
|
||||
- Module now exports a `<DraggableCore>` element upon which `<Draggable>` is based.
|
||||
This module is useful for building libraries and is completely stateless.
|
||||
|
||||
### 0.8.5 (Oct 20, 2015)
|
||||
|
||||
- Bugfix: isElementSVG no longer can be overwritten by getInitialState (#83)
|
||||
- Bugfix: Fix for element prefixes in JSDOM
|
||||
|
||||
### 0.8.4 (Oct 15, 2015)
|
||||
|
||||
- Bugfix: SVG elements now properly use `transform` attribute instead of `style`. Thanks @martinRoss
|
||||
|
||||
### 0.8.3 (Oct 12, 2015)
|
||||
|
||||
- Bugfix: Short-circuiting drag throws due to `e.changedTouches` check.
|
||||
|
||||
### 0.8.2 (Sep 21, 2015)
|
||||
|
||||
- Handle scrolling while dragging. (#60)
|
||||
- Add multi-touch support. (#68)
|
||||
- IE fixes.
|
||||
- Documentation updates. (#77)
|
||||
|
||||
### 0.8.1 (June 3, 2015)
|
||||
|
||||
- Add `resetState()` instance method for use by parents. See README ("State Problems?").
|
||||
|
||||
### 0.8.0 (May 19, 2015)
|
||||
|
||||
- Touch/mouse events rework. Fixes #51, #37, and #43, as well as IE11 support.
|
||||
- Moved mousemove/mouseup and touch event handlers to document from window. Fixes IE9/10 support.
|
||||
IE8 is still not supported, as it is not supported by React.
|
||||
|
||||
### 0.7.4 (May 18, 2015)
|
||||
|
||||
- Fix a bug where a quick drag out of bounds to `0,0` would cause the element to remain in an inaccurate position,
|
||||
because the translation was removed from the CSS. See #55.
|
||||
|
||||
### 0.7.3 (May 13, 2015)
|
||||
|
||||
- Removed a `moveOnStartChange` optimization that was causing problems when attempting to move a `<Draggable>` back
|
||||
to its initial position. See https://github.com/STRML/react-grid-layout/issues/56
|
||||
|
||||
### 0.7.2 (May 8, 2015)
|
||||
|
||||
- Added `moveOnStartChange` property. See README.
|
||||
|
||||
### 0.7.1 (May 7, 2015)
|
||||
|
||||
- The `start` param is back. Pass `{x: Number, y: Number}` to kickoff the CSS transform. Useful in certain
|
||||
cases for simpler callback math (so you don't have to know its existing relative position and add it to
|
||||
the dragged position). Fixes #52.
|
||||
|
||||
### 0.7.0 (May 7, 2015)
|
||||
|
||||
- Breaking change: `bounds` with coordinates was confusing because it was using the item's width/height,
|
||||
which was not intuitive. When providing coordinates, `bounds` now simply restricts movement in each
|
||||
direction by that many pixels.
|
||||
|
||||
### 0.6.0 (May 2, 2015)
|
||||
|
||||
- Breaking change: Cancel dragging when onDrag or onStart handlers return an explicit `false`.
|
||||
- Fix sluggish movement when `grid` option was active.
|
||||
- Example updates.
|
||||
- Move `user-select:none` hack to document.body for better highlight prevention.
|
||||
- Add `bounds` option to restrict dragging within parent or within coordinates.
|
||||
|
||||
### 0.5.0 (May 2, 2015)
|
||||
|
||||
- Remove browserify browser config, reactify, and jsx pragma. Fixes #38
|
||||
- Use React.cloneElement instead of addons cloneWithProps (requires React 0.13)
|
||||
- Move to CSS transforms. Simplifies implementation and fixes #48, #34, #31.
|
||||
- Fixup linting and space/tab errors. Fixes #46.
|
||||
|
||||
### 0.4.3 (Apr 30, 2015)
|
||||
|
||||
- Fix React.addons error caused by faulty test.
|
||||
|
||||
### 0.4.2 (Apr 30, 2015)
|
||||
|
||||
- Add `"browser"` config to package.json for browserify imports (fix #45).
|
||||
- Remove unnecessary `emptyFunction` and `React.addons.classSet` imports.
|
||||
|
||||
### 0.4.1 (Apr 30, 2015)
|
||||
|
||||
- Remove react/addons dependency (now depending on `react` directly).
|
||||
- Add MIT License file.
|
||||
- Fix an issue where browser may be detected as touch-enabled but touch event isn't thrown.
|
||||
|
||||
### 0.4.0 (Jan 03, 2015)
|
||||
|
||||
- Improving accuracy of snap to grid
|
||||
- Updating to React 0.12
|
||||
- Adding dragging className
|
||||
- Adding reactify support for browserify
|
||||
- Fixing issue with server side rendering
|
||||
|
||||
### 0.3.0 (Oct 21, 2014)
|
||||
|
||||
- Adding support for touch devices
|
||||
|
||||
### 0.2.1 (Sep 10, 2014)
|
||||
|
||||
- Exporting as ReactDraggable
|
||||
|
||||
### 0.2.0 (Sep 10, 2014)
|
||||
|
||||
- Adding support for snapping to a grid
|
||||
- Adding support for specifying start position
|
||||
- Ensure event handlers are destroyed on unmount
|
||||
- Adding browserify support
|
||||
- Adding bower support
|
||||
|
||||
### 0.1.1 (Jul 26, 2014)
|
||||
|
||||
- Fixing dragging not stopping on mouseup in some cases
|
||||
|
||||
### 0.1.0 (Jul 25, 2014)
|
||||
|
||||
- Initial release
|
21
node_modules/react-draggable/LICENSE
generated
vendored
Normal file
21
node_modules/react-draggable/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
(MIT License)
|
||||
|
||||
Copyright (c) 2014-2016 Matt Zabriskie. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
319
node_modules/react-draggable/README.md
generated
vendored
Normal file
319
node_modules/react-draggable/README.md
generated
vendored
Normal file
@ -0,0 +1,319 @@
|
||||
# React-Draggable
|
||||
|
||||
[](https://travis-ci.org/mzabriskie/react-draggable)
|
||||
[](https://ci.appveyor.com/project/mzabriskie/react-draggable)
|
||||
[](http://npmjs.com/package/react-draggable)
|
||||
[]()
|
||||
[]()
|
||||
|
||||
A simple component for making elements draggable.
|
||||
|
||||
```js
|
||||
<Draggable>
|
||||
<div>I can now be moved around!</div>
|
||||
</Draggable>
|
||||
```
|
||||
|
||||
- [Demo](http://mzabriskie.github.io/react-draggable/example/)
|
||||
- [Changelog](CHANGELOG.md)
|
||||
|
||||
------
|
||||
|
||||
#### Technical Documentation
|
||||
|
||||
- [Installing](#installing)
|
||||
- [Exports](#exports)
|
||||
- [Draggable](#draggable)
|
||||
- [Draggable Usage](#draggable-usage)
|
||||
- [Draggable API](#draggable-api)
|
||||
- [Controlled vs. Uncontrolled](#controlled-vs-uncontrolled)
|
||||
- [DraggableCore](#draggablecore)
|
||||
- [DraggableCore API](#draggablecore-api)
|
||||
|
||||
|
||||
|
||||
### Installing
|
||||
|
||||
```bash
|
||||
$ npm install react-draggable
|
||||
```
|
||||
|
||||
If you aren't using browserify/webpack, a
|
||||
[UMD version of react-draggable](dist/react-draggable.js) is available. It is updated per-release only.
|
||||
This bundle is also what is loaded when installing from npm. It expects external `React` and `ReactDOM`.
|
||||
|
||||
If you want a UMD version of the latest `master` revision, you can generate it yourself from master by cloning this
|
||||
repository and running `$ make`. This will create umd dist files in the `dist/` folder.
|
||||
|
||||
### Exports
|
||||
|
||||
The default export is `<Draggable>`. At the `.DraggableCore` property is [`<DraggableCore>`](#draggablecore).
|
||||
Here's how to use it:
|
||||
|
||||
```js
|
||||
// ES6
|
||||
import Draggable from 'react-draggable'; // The default
|
||||
import {DraggableCore} from 'react-draggable'; // <DraggableCore>
|
||||
import Draggable, {DraggableCore} from 'react-draggable'; // Both at the same time
|
||||
|
||||
// CommonJS
|
||||
let Draggable = require('react-draggable');
|
||||
let DraggableCore = Draggable.DraggableCore;
|
||||
```
|
||||
|
||||
## `<Draggable>`
|
||||
|
||||
A `<Draggable>` element wraps an existing element and extends it with new event handlers and styles.
|
||||
It does not create a wrapper element in the DOM.
|
||||
|
||||
Draggable items are moved using CSS Transforms. This allows items to be dragged regardless of their current
|
||||
positioning (relative, absolute, or static). Elements can also be moved between drags without incident.
|
||||
|
||||
If the item you are dragging already has a CSS Transform applied, it will be overwritten by `<Draggable>`. Use
|
||||
an intermediate wrapper (`<Draggable><span>...</span></Draggable>`) in this case.
|
||||
|
||||
### Draggable Usage
|
||||
|
||||
View the [Demo](http://mzabriskie.github.io/react-draggable/example/) and its
|
||||
[source](/example/example.js) for more.
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Draggable from 'react-draggable';
|
||||
|
||||
class App extends React.Component {
|
||||
|
||||
eventLogger = (e: MouseEvent, data: Object) => {
|
||||
console.log('Event: ', e);
|
||||
console.log('Data: ', data);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Draggable
|
||||
axis="x"
|
||||
handle=".handle"
|
||||
defaultPosition={{x: 0, y: 0}}
|
||||
position={null}
|
||||
grid={[25, 25]}
|
||||
scale={1}
|
||||
onStart={this.handleStart}
|
||||
onDrag={this.handleDrag}
|
||||
onStop={this.handleStop}>
|
||||
<div>
|
||||
<div className="handle">Drag from here</div>
|
||||
<div>This readme is really dragging on...</div>
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App/>, document.body);
|
||||
```
|
||||
|
||||
### Draggable API
|
||||
|
||||
The `<Draggable/>` component transparently adds draggability to its children.
|
||||
|
||||
**Note**: Only a single child is allowed or an Error will be thrown.
|
||||
|
||||
For the `<Draggable/>` component to correctly attach itself to its child, the child element must provide support
|
||||
for the following props:
|
||||
- `style` is used to give the transform css to the child.
|
||||
- `className` is used to apply the proper classes to the object being dragged.
|
||||
- `onMouseDown`, `onMouseUp`, `onTouchStart`, and `onTouchEnd` are used to keep track of dragging state.
|
||||
|
||||
React.DOM elements support the above properties by default, so you may use those elements as children without
|
||||
any changes. If you wish to use a React component you created, you'll need to be sure to
|
||||
[transfer prop](https://facebook.github.io/react/docs/transferring-props.html).
|
||||
|
||||
#### `<Draggable>` Props:
|
||||
|
||||
```js
|
||||
//
|
||||
// Types:
|
||||
//
|
||||
type DraggableEventHandler = (e: Event, data: DraggableData) => void | false;
|
||||
type DraggableData = {
|
||||
node: HTMLElement,
|
||||
// lastX + deltaX === x
|
||||
x: number, y: number,
|
||||
deltaX: number, deltaY: number,
|
||||
lastX: number, lastY: number
|
||||
};
|
||||
|
||||
//
|
||||
// Props:
|
||||
//
|
||||
{
|
||||
// If set to `true`, will allow dragging on non left-button clicks.
|
||||
allowAnyClick: boolean,
|
||||
|
||||
// Determines which axis the draggable can move. This only affects
|
||||
// flushing to the DOM. Callbacks will still include all values.
|
||||
// Accepted values:
|
||||
// - `both` allows movement horizontally and vertically (default).
|
||||
// - `x` limits movement to horizontal axis.
|
||||
// - `y` limits movement to vertical axis.
|
||||
// - 'none' stops all movement.
|
||||
axis: string,
|
||||
|
||||
// Specifies movement boundaries. Accepted values:
|
||||
// - `parent` restricts movement within the node's offsetParent
|
||||
// (nearest node with position relative or absolute), or
|
||||
// - a selector, restricts movement within the targeted node
|
||||
// - An object with `left, top, right, and bottom` properties.
|
||||
// These indicate how far in each direction the draggable
|
||||
// can be moved.
|
||||
bounds: {left: number, top: number, right: number, bottom: number} | string,
|
||||
|
||||
// Specifies a selector to be used to prevent drag initialization.
|
||||
// Example: '.body'
|
||||
cancel: string,
|
||||
|
||||
// Class names for draggable UI.
|
||||
// Default to 'react-draggable', 'react-draggable-dragging', and 'react-draggable-dragged'
|
||||
defaultClassName: string,
|
||||
defaultClassNameDragging: string,
|
||||
defaultClassNameDragged: string,
|
||||
|
||||
// Specifies the `x` and `y` that the dragged item should start at.
|
||||
// This is generally not necessary to use (you can use absolute or relative
|
||||
// positioning of the child directly), but can be helpful for uniformity in
|
||||
// your callbacks and with css transforms.
|
||||
defaultPosition: {x: number, y: number},
|
||||
|
||||
// If true, will not call any drag handlers.
|
||||
disabled: boolean,
|
||||
|
||||
// Specifies the x and y that dragging should snap to.
|
||||
grid: [number, number],
|
||||
|
||||
// Specifies a selector to be used as the handle that initiates drag.
|
||||
// Example: '.handle'
|
||||
handle: string,
|
||||
|
||||
// If desired, you can provide your own offsetParent for drag calculations.
|
||||
// By default, we use the Draggable's offsetParent. This can be useful for elements
|
||||
// with odd display types or floats.
|
||||
offsetParent: HTMLElement,
|
||||
|
||||
// Called whenever the user mouses down. Called regardless of handle or
|
||||
// disabled status.
|
||||
onMouseDown: (e: MouseEvent) => void,
|
||||
|
||||
// Called when dragging starts. If `false` is returned any handler,
|
||||
// the action will cancel.
|
||||
onStart: DraggableEventHandler,
|
||||
|
||||
// Called while dragging.
|
||||
onDrag: DraggableEventHandler,
|
||||
|
||||
// Called when dragging stops.
|
||||
onStop: DraggableEventHandler,
|
||||
|
||||
// Much like React form elements, if this property is present, the item
|
||||
// becomes 'controlled' and is not responsive to user input. Use `position`
|
||||
// if you need to have direct control of the element.
|
||||
position: {x: number, y: number}
|
||||
|
||||
// A position offset to start with. Useful for giving an initial position
|
||||
// to the element. Differs from `defaultPosition` in that it does not
|
||||
// affect the postiion returned in draggable callbacks, and in that it
|
||||
// accepts strings, like `{x: '10%', y: '10%'}`.
|
||||
positionOffset: {x: number | string, y: number | string},
|
||||
|
||||
// Specifies the scale of the canvas your are dragging this element on. This allows
|
||||
// you to, for example, get the correct drag deltas while you are zoomed in or out via
|
||||
// a transform or matrix in the parent of this element.
|
||||
scale: number
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Note that sending `className`, `style`, or `transform` as properties will error - set them on the child element
|
||||
directly.
|
||||
|
||||
|
||||
## Controlled vs. Uncontrolled
|
||||
|
||||
`<Draggable>` is a 'batteries-included' component that manages its own state. If you want to completely
|
||||
control the lifecycle of the component, use `<DraggableCore>`.
|
||||
|
||||
For some users, they may want the nice state management that `<Draggable>` provides, but occasionally want
|
||||
to programmatically reposition their components. `<Draggable>` allows this customization via a system that
|
||||
is similar to how React handles form components.
|
||||
|
||||
If the prop `position: {x: number, y: number}` is defined, the `<Draggable>` will ignore its internal state and use
|
||||
the provided position instead. Alternatively, you can seed the position using `defaultPosition`. Technically, since
|
||||
`<Draggable>` works only on position deltas, you could also seed the initial position using CSS `top/left`.
|
||||
|
||||
We make one modification to the React philosophy here - we still allow dragging while a component is controlled.
|
||||
We then expect you to use at least an `onDrag` or `onStop` handler to synchronize state.
|
||||
|
||||
To disable dragging while controlled, send the prop `disabled={true}` - at this point the `<Draggable>` will operate
|
||||
like a completely static component.
|
||||
|
||||
## `<DraggableCore>`
|
||||
|
||||
For users that require absolute control, a `<DraggableCore>` element is available. This is useful as an abstraction
|
||||
over touch and mouse events, but with full control. `<DraggableCore>` has no internal state.
|
||||
|
||||
See [React-Resizable](https://github.com/STRML/react-resizable) and
|
||||
[React-Grid-Layout](https://github.com/STRML/react-grid-layout) for some usage examples.
|
||||
|
||||
`<DraggableCore>` is a useful building block for other libraries that simply want to abstract browser-specific
|
||||
quirks and receive callbacks when a user attempts to move an element. It does not set styles or transforms
|
||||
on itself and thus must have callbacks attached to be useful.
|
||||
|
||||
### DraggableCore API
|
||||
|
||||
`<DraggableCore>` takes a limited subset of options:
|
||||
|
||||
```js
|
||||
{
|
||||
allowAnyClick: boolean,
|
||||
cancel: string,
|
||||
disabled: boolean,
|
||||
enableUserSelectHack: boolean,
|
||||
offsetParent: HTMLElement,
|
||||
grid: [number, number],
|
||||
handle: string,
|
||||
onStart: DraggableEventHandler,
|
||||
onDrag: DraggableEventHandler,
|
||||
onStop: DraggableEventHandler,
|
||||
onMouseDown: (e: MouseEvent) => void,
|
||||
scale: number
|
||||
}
|
||||
```
|
||||
|
||||
Note that there is no start position. `<DraggableCore>` simply calls `drag` handlers with the below parameters,
|
||||
indicating its position (as inferred from the underlying MouseEvent) and deltas. It is up to the parent
|
||||
to set actual positions on `<DraggableCore>`.
|
||||
|
||||
Drag callbacks (`onStart`, `onDrag`, `onStop`) are called with the [same arguments as `<Draggable>`](#draggable-api).
|
||||
|
||||
----
|
||||
|
||||
### Contributing
|
||||
|
||||
- Fork the project
|
||||
- Run the project in development mode: `$ npm run dev`
|
||||
- Make changes.
|
||||
- Add appropriate tests
|
||||
- `$ npm test`
|
||||
- If tests don't pass, make them pass.
|
||||
- Update README with appropriate docs.
|
||||
- Commit and PR
|
||||
|
||||
### Release checklist
|
||||
|
||||
- Update CHANGELOG
|
||||
- `make release-patch`, `make release-minor`, or `make-release-major`
|
||||
- `make publish`
|
||||
|
||||
### License
|
||||
|
||||
MIT
|
28
node_modules/react-draggable/bower.json
generated
vendored
Normal file
28
node_modules/react-draggable/bower.json
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "react-draggable",
|
||||
"version": "3.3.2",
|
||||
"homepage": "https://github.com/mzabriskie/react-draggable",
|
||||
"authors": [
|
||||
"Matt Zabriskie",
|
||||
"Samuel Reed"
|
||||
],
|
||||
"description": "React draggable component",
|
||||
"main": "./dist/react-draggable.js",
|
||||
"keywords": [
|
||||
"react",
|
||||
"draggable"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"example",
|
||||
"lib",
|
||||
"node_modules",
|
||||
"script",
|
||||
"specs",
|
||||
"index.js",
|
||||
"karma.conf.js",
|
||||
"webpack.config.js",
|
||||
"package.json"
|
||||
]
|
||||
}
|
2214
node_modules/react-draggable/dist/react-draggable.js
generated
vendored
Normal file
2214
node_modules/react-draggable/dist/react-draggable.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/react-draggable/dist/react-draggable.js.map
generated
vendored
Normal file
1
node_modules/react-draggable/dist/react-draggable.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
node_modules/react-draggable/dist/react-draggable.min.js
generated
vendored
Normal file
2
node_modules/react-draggable/dist/react-draggable.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/react-draggable/dist/react-draggable.min.js.map
generated
vendored
Normal file
1
node_modules/react-draggable/dist/react-draggable.min.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
9
node_modules/react-draggable/index.js
generated
vendored
Normal file
9
node_modules/react-draggable/index.js
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
var Draggable = require('./lib/Draggable').default;
|
||||
|
||||
// Previous versions of this lib exported <Draggable> as the root export. As to not break
|
||||
// them, or TypeScript, we export *both* as the root and as 'default'.
|
||||
// See https://github.com/mzabriskie/react-draggable/pull/254
|
||||
// and https://github.com/mzabriskie/react-draggable/issues/266
|
||||
module.exports = Draggable;
|
||||
module.exports.default = Draggable;
|
||||
module.exports.DraggableCore = require('./lib/DraggableCore').default;
|
367
node_modules/react-draggable/lib/Draggable.js
generated
vendored
Normal file
367
node_modules/react-draggable/lib/Draggable.js
generated
vendored
Normal file
@ -0,0 +1,367 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactDOM from 'react-dom';
|
||||
import classNames from 'classnames';
|
||||
import {createCSSTransform, createSVGTransform} from './utils/domFns';
|
||||
import {canDragX, canDragY, createDraggableData, getBoundPosition} from './utils/positionFns';
|
||||
import {dontSetMe} from './utils/shims';
|
||||
import DraggableCore from './DraggableCore';
|
||||
import type {ControlPosition, PositionOffsetControlPosition, DraggableBounds, DraggableCoreProps} from './DraggableCore';
|
||||
import log from './utils/log';
|
||||
import type {DraggableEventHandler} from './utils/types';
|
||||
import type {Element as ReactElement} from 'react';
|
||||
|
||||
type DraggableState = {
|
||||
dragging: boolean,
|
||||
dragged: boolean,
|
||||
x: number, y: number,
|
||||
slackX: number, slackY: number,
|
||||
isElementSVG: boolean
|
||||
};
|
||||
|
||||
export type DraggableProps = {
|
||||
...$Exact<DraggableCoreProps>,
|
||||
axis: 'both' | 'x' | 'y' | 'none',
|
||||
bounds: DraggableBounds | string | false,
|
||||
defaultClassName: string,
|
||||
defaultClassNameDragging: string,
|
||||
defaultClassNameDragged: string,
|
||||
defaultPosition: ControlPosition,
|
||||
positionOffset: PositionOffsetControlPosition,
|
||||
position: ControlPosition,
|
||||
scale: number
|
||||
};
|
||||
|
||||
//
|
||||
// Define <Draggable>
|
||||
//
|
||||
|
||||
export default class Draggable extends React.Component<DraggableProps, DraggableState> {
|
||||
|
||||
static displayName = 'Draggable';
|
||||
|
||||
static propTypes = {
|
||||
// Accepts all props <DraggableCore> accepts.
|
||||
...DraggableCore.propTypes,
|
||||
|
||||
/**
|
||||
* `axis` determines which axis the draggable can move.
|
||||
*
|
||||
* Note that all callbacks will still return data as normal. This only
|
||||
* controls flushing to the DOM.
|
||||
*
|
||||
* 'both' allows movement horizontally and vertically.
|
||||
* 'x' limits movement to horizontal axis.
|
||||
* 'y' limits movement to vertical axis.
|
||||
* 'none' limits all movement.
|
||||
*
|
||||
* Defaults to 'both'.
|
||||
*/
|
||||
axis: PropTypes.oneOf(['both', 'x', 'y', 'none']),
|
||||
|
||||
/**
|
||||
* `bounds` determines the range of movement available to the element.
|
||||
* Available values are:
|
||||
*
|
||||
* 'parent' restricts movement within the Draggable's parent node.
|
||||
*
|
||||
* Alternatively, pass an object with the following properties, all of which are optional:
|
||||
*
|
||||
* {left: LEFT_BOUND, right: RIGHT_BOUND, bottom: BOTTOM_BOUND, top: TOP_BOUND}
|
||||
*
|
||||
* All values are in px.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```jsx
|
||||
* let App = React.createClass({
|
||||
* render: function () {
|
||||
* return (
|
||||
* <Draggable bounds={{right: 300, bottom: 300}}>
|
||||
* <div>Content</div>
|
||||
* </Draggable>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
bounds: PropTypes.oneOfType([
|
||||
PropTypes.shape({
|
||||
left: PropTypes.number,
|
||||
right: PropTypes.number,
|
||||
top: PropTypes.number,
|
||||
bottom: PropTypes.number
|
||||
}),
|
||||
PropTypes.string,
|
||||
PropTypes.oneOf([false])
|
||||
]),
|
||||
|
||||
defaultClassName: PropTypes.string,
|
||||
defaultClassNameDragging: PropTypes.string,
|
||||
defaultClassNameDragged: PropTypes.string,
|
||||
|
||||
/**
|
||||
* `defaultPosition` specifies the x and y that the dragged item should start at
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```jsx
|
||||
* let App = React.createClass({
|
||||
* render: function () {
|
||||
* return (
|
||||
* <Draggable defaultPosition={{x: 25, y: 25}}>
|
||||
* <div>I start with transformX: 25px and transformY: 25px;</div>
|
||||
* </Draggable>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
defaultPosition: PropTypes.shape({
|
||||
x: PropTypes.number,
|
||||
y: PropTypes.number
|
||||
}),
|
||||
positionOffset: PropTypes.shape({
|
||||
x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
y: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
|
||||
}),
|
||||
|
||||
/**
|
||||
* `position`, if present, defines the current position of the element.
|
||||
*
|
||||
* This is similar to how form elements in React work - if no `position` is supplied, the component
|
||||
* is uncontrolled.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```jsx
|
||||
* let App = React.createClass({
|
||||
* render: function () {
|
||||
* return (
|
||||
* <Draggable position={{x: 25, y: 25}}>
|
||||
* <div>I start with transformX: 25px and transformY: 25px;</div>
|
||||
* </Draggable>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
position: PropTypes.shape({
|
||||
x: PropTypes.number,
|
||||
y: PropTypes.number
|
||||
}),
|
||||
|
||||
/**
|
||||
* These properties should be defined on the child, not here.
|
||||
*/
|
||||
className: dontSetMe,
|
||||
style: dontSetMe,
|
||||
transform: dontSetMe
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
...DraggableCore.defaultProps,
|
||||
axis: 'both',
|
||||
bounds: false,
|
||||
defaultClassName: 'react-draggable',
|
||||
defaultClassNameDragging: 'react-draggable-dragging',
|
||||
defaultClassNameDragged: 'react-draggable-dragged',
|
||||
defaultPosition: {x: 0, y: 0},
|
||||
position: null,
|
||||
scale: 1
|
||||
};
|
||||
|
||||
constructor(props: DraggableProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
// Whether or not we are currently dragging.
|
||||
dragging: false,
|
||||
|
||||
// Whether or not we have been dragged before.
|
||||
dragged: false,
|
||||
|
||||
// Current transform x and y.
|
||||
x: props.position ? props.position.x : props.defaultPosition.x,
|
||||
y: props.position ? props.position.y : props.defaultPosition.y,
|
||||
|
||||
// Used for compensating for out-of-bounds drags
|
||||
slackX: 0, slackY: 0,
|
||||
|
||||
// Can only determine if SVG after mounting
|
||||
isElementSVG: false
|
||||
};
|
||||
|
||||
if (props.position && !(props.onDrag || props.onStop)) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('A `position` was applied to this <Draggable>, without drag handlers. This will make this ' +
|
||||
'component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the ' +
|
||||
'`position` of this element.');
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Check to see if the element passed is an instanceof SVGElement
|
||||
if(typeof window.SVGElement !== 'undefined' && ReactDOM.findDOMNode(this) instanceof window.SVGElement) {
|
||||
this.setState({ isElementSVG: true });
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Object) {
|
||||
// Set x/y if position has changed
|
||||
if (nextProps.position &&
|
||||
(!this.props.position ||
|
||||
nextProps.position.x !== this.props.position.x ||
|
||||
nextProps.position.y !== this.props.position.y
|
||||
)
|
||||
) {
|
||||
this.setState({ x: nextProps.position.x, y: nextProps.position.y });
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.setState({dragging: false}); // prevents invariant if unmounted while dragging
|
||||
}
|
||||
|
||||
onDragStart: DraggableEventHandler = (e, coreData) => {
|
||||
log('Draggable: onDragStart: %j', coreData);
|
||||
|
||||
// Short-circuit if user's callback killed it.
|
||||
const shouldStart = this.props.onStart(e, createDraggableData(this, coreData));
|
||||
// Kills start event on core as well, so move handlers are never bound.
|
||||
if (shouldStart === false) return false;
|
||||
|
||||
this.setState({dragging: true, dragged: true});
|
||||
};
|
||||
|
||||
onDrag: DraggableEventHandler = (e, coreData) => {
|
||||
if (!this.state.dragging) return false;
|
||||
log('Draggable: onDrag: %j', coreData);
|
||||
|
||||
const uiData = createDraggableData(this, coreData);
|
||||
|
||||
const newState: $Shape<DraggableState> = {
|
||||
x: uiData.x,
|
||||
y: uiData.y
|
||||
};
|
||||
|
||||
// Keep within bounds.
|
||||
if (this.props.bounds) {
|
||||
// Save original x and y.
|
||||
const {x, y} = newState;
|
||||
|
||||
// Add slack to the values used to calculate bound position. This will ensure that if
|
||||
// we start removing slack, the element won't react to it right away until it's been
|
||||
// completely removed.
|
||||
newState.x += this.state.slackX;
|
||||
newState.y += this.state.slackY;
|
||||
|
||||
// Get bound position. This will ceil/floor the x and y within the boundaries.
|
||||
const [newStateX, newStateY] = getBoundPosition(this, newState.x, newState.y);
|
||||
newState.x = newStateX;
|
||||
newState.y = newStateY;
|
||||
|
||||
// Recalculate slack by noting how much was shaved by the boundPosition handler.
|
||||
newState.slackX = this.state.slackX + (x - newState.x);
|
||||
newState.slackY = this.state.slackY + (y - newState.y);
|
||||
|
||||
// Update the event we fire to reflect what really happened after bounds took effect.
|
||||
uiData.x = newState.x;
|
||||
uiData.y = newState.y;
|
||||
uiData.deltaX = newState.x - this.state.x;
|
||||
uiData.deltaY = newState.y - this.state.y;
|
||||
}
|
||||
|
||||
// Short-circuit if user's callback killed it.
|
||||
const shouldUpdate = this.props.onDrag(e, uiData);
|
||||
if (shouldUpdate === false) return false;
|
||||
|
||||
this.setState(newState);
|
||||
};
|
||||
|
||||
onDragStop: DraggableEventHandler = (e, coreData) => {
|
||||
if (!this.state.dragging) return false;
|
||||
|
||||
// Short-circuit if user's callback killed it.
|
||||
const shouldStop = this.props.onStop(e, createDraggableData(this, coreData));
|
||||
if (shouldStop === false) return false;
|
||||
|
||||
log('Draggable: onDragStop: %j', coreData);
|
||||
|
||||
const newState: $Shape<DraggableState> = {
|
||||
dragging: false,
|
||||
slackX: 0,
|
||||
slackY: 0
|
||||
};
|
||||
|
||||
// If this is a controlled component, the result of this operation will be to
|
||||
// revert back to the old position. We expect a handler on `onDragStop`, at the least.
|
||||
const controlled = Boolean(this.props.position);
|
||||
if (controlled) {
|
||||
const {x, y} = this.props.position;
|
||||
newState.x = x;
|
||||
newState.y = y;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
};
|
||||
|
||||
render(): ReactElement<any> {
|
||||
let style = {}, svgTransform = null;
|
||||
|
||||
// If this is controlled, we don't want to move it - unless it's dragging.
|
||||
const controlled = Boolean(this.props.position);
|
||||
const draggable = !controlled || this.state.dragging;
|
||||
|
||||
const position = this.props.position || this.props.defaultPosition;
|
||||
const transformOpts = {
|
||||
// Set left if horizontal drag is enabled
|
||||
x: canDragX(this) && draggable ?
|
||||
this.state.x :
|
||||
position.x,
|
||||
|
||||
// Set top if vertical drag is enabled
|
||||
y: canDragY(this) && draggable ?
|
||||
this.state.y :
|
||||
position.y
|
||||
};
|
||||
|
||||
// If this element was SVG, we use the `transform` attribute.
|
||||
if (this.state.isElementSVG) {
|
||||
svgTransform = createSVGTransform(transformOpts, this.props.positionOffset);
|
||||
} else {
|
||||
// Add a CSS transform to move the element around. This allows us to move the element around
|
||||
// without worrying about whether or not it is relatively or absolutely positioned.
|
||||
// If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable>
|
||||
// has a clean slate.
|
||||
style = createCSSTransform(transformOpts, this.props.positionOffset);
|
||||
}
|
||||
|
||||
const {
|
||||
defaultClassName,
|
||||
defaultClassNameDragging,
|
||||
defaultClassNameDragged
|
||||
} = this.props;
|
||||
|
||||
const children = React.Children.only(this.props.children);
|
||||
|
||||
// Mark with class while dragging
|
||||
const className = classNames((children.props.className || ''), defaultClassName, {
|
||||
[defaultClassNameDragging]: this.state.dragging,
|
||||
[defaultClassNameDragged]: this.state.dragged
|
||||
});
|
||||
|
||||
// Reuse the child provided
|
||||
// This makes it flexible to use whatever element is wanted (div, ul, etc)
|
||||
return (
|
||||
<DraggableCore {...this.props} onStart={this.onDragStart} onDrag={this.onDrag} onStop={this.onDragStop}>
|
||||
{React.cloneElement(children, {
|
||||
className: className,
|
||||
style: {...children.props.style, ...style},
|
||||
transform: svgTransform
|
||||
})}
|
||||
</DraggableCore>
|
||||
);
|
||||
}
|
||||
}
|
422
node_modules/react-draggable/lib/DraggableCore.js
generated
vendored
Normal file
422
node_modules/react-draggable/lib/DraggableCore.js
generated
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {matchesSelectorAndParentsTo, addEvent, removeEvent, addUserSelectStyles, getTouchIdentifier,
|
||||
removeUserSelectStyles, styleHacks} from './utils/domFns';
|
||||
import {createCoreData, getControlPosition, snapToGrid} from './utils/positionFns';
|
||||
import {dontSetMe} from './utils/shims';
|
||||
import log from './utils/log';
|
||||
|
||||
import type {EventHandler, MouseTouchEvent} from './utils/types';
|
||||
import type {Element as ReactElement} from 'react';
|
||||
|
||||
// Simple abstraction for dragging events names.
|
||||
const eventsFor = {
|
||||
touch: {
|
||||
start: 'touchstart',
|
||||
move: 'touchmove',
|
||||
stop: 'touchend'
|
||||
},
|
||||
mouse: {
|
||||
start: 'mousedown',
|
||||
move: 'mousemove',
|
||||
stop: 'mouseup'
|
||||
}
|
||||
};
|
||||
|
||||
// Default to mouse events.
|
||||
let dragEventFor = eventsFor.mouse;
|
||||
|
||||
type DraggableCoreState = {
|
||||
dragging: boolean,
|
||||
lastX: number,
|
||||
lastY: number,
|
||||
touchIdentifier: ?number
|
||||
};
|
||||
|
||||
export type DraggableBounds = {
|
||||
left: number,
|
||||
right: number,
|
||||
top: number,
|
||||
bottom: number,
|
||||
};
|
||||
|
||||
export type DraggableData = {
|
||||
node: HTMLElement,
|
||||
x: number, y: number,
|
||||
deltaX: number, deltaY: number,
|
||||
lastX: number, lastY: number,
|
||||
};
|
||||
|
||||
export type DraggableEventHandler = (e: MouseEvent, data: DraggableData) => void;
|
||||
|
||||
export type ControlPosition = {x: number, y: number};
|
||||
export type PositionOffsetControlPosition = {x: number|string, y: number|string};
|
||||
|
||||
export type DraggableCoreProps = {
|
||||
allowAnyClick: boolean,
|
||||
cancel: string,
|
||||
children: ReactElement<any>,
|
||||
disabled: boolean,
|
||||
enableUserSelectHack: boolean,
|
||||
offsetParent: HTMLElement,
|
||||
grid: [number, number],
|
||||
handle: string,
|
||||
onStart: DraggableEventHandler,
|
||||
onDrag: DraggableEventHandler,
|
||||
onStop: DraggableEventHandler,
|
||||
onMouseDown: (e: MouseEvent) => void,
|
||||
};
|
||||
|
||||
//
|
||||
// Define <DraggableCore>.
|
||||
//
|
||||
// <DraggableCore> is for advanced usage of <Draggable>. It maintains minimal internal state so it can
|
||||
// work well with libraries that require more control over the element.
|
||||
//
|
||||
|
||||
export default class DraggableCore extends React.Component<DraggableCoreProps, DraggableCoreState> {
|
||||
|
||||
static displayName = 'DraggableCore';
|
||||
|
||||
static propTypes = {
|
||||
/**
|
||||
* `allowAnyClick` allows dragging using any mouse button.
|
||||
* By default, we only accept the left button.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
allowAnyClick: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* `disabled`, if true, stops the <Draggable> from dragging. All handlers,
|
||||
* with the exception of `onMouseDown`, will not fire.
|
||||
*/
|
||||
disabled: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* By default, we add 'user-select:none' attributes to the document body
|
||||
* to prevent ugly text selection during drag. If this is causing problems
|
||||
* for your app, set this to `false`.
|
||||
*/
|
||||
enableUserSelectHack: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* `offsetParent`, if set, uses the passed DOM node to compute drag offsets
|
||||
* instead of using the parent node.
|
||||
*/
|
||||
offsetParent: function(props: DraggableCoreProps, propName: $Keys<DraggableCoreProps>) {
|
||||
if (props[propName] && props[propName].nodeType !== 1) {
|
||||
throw new Error('Draggable\'s offsetParent must be a DOM Node.');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* `grid` specifies the x and y that dragging should snap to.
|
||||
*/
|
||||
grid: PropTypes.arrayOf(PropTypes.number),
|
||||
|
||||
/**
|
||||
* `scale` specifies the scale of the area you are dragging inside of. It allows
|
||||
* the drag deltas to scale correctly with how far zoomed in/out you are.
|
||||
*/
|
||||
scale: PropTypes.number,
|
||||
|
||||
/**
|
||||
* `handle` specifies a selector to be used as the handle that initiates drag.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```jsx
|
||||
* let App = React.createClass({
|
||||
* render: function () {
|
||||
* return (
|
||||
* <Draggable handle=".handle">
|
||||
* <div>
|
||||
* <div className="handle">Click me to drag</div>
|
||||
* <div>This is some other content</div>
|
||||
* </div>
|
||||
* </Draggable>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
handle: PropTypes.string,
|
||||
|
||||
/**
|
||||
* `cancel` specifies a selector to be used to prevent drag initialization.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```jsx
|
||||
* let App = React.createClass({
|
||||
* render: function () {
|
||||
* return(
|
||||
* <Draggable cancel=".cancel">
|
||||
* <div>
|
||||
* <div className="cancel">You can't drag from here</div>
|
||||
* <div>Dragging here works fine</div>
|
||||
* </div>
|
||||
* </Draggable>
|
||||
* );
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
cancel: PropTypes.string,
|
||||
|
||||
/**
|
||||
* Called when dragging starts.
|
||||
* If this function returns the boolean false, dragging will be canceled.
|
||||
*/
|
||||
onStart: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Called while dragging.
|
||||
* If this function returns the boolean false, dragging will be canceled.
|
||||
*/
|
||||
onDrag: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Called when dragging stops.
|
||||
* If this function returns the boolean false, the drag will remain active.
|
||||
*/
|
||||
onStop: PropTypes.func,
|
||||
|
||||
/**
|
||||
* A workaround option which can be passed if onMouseDown needs to be accessed,
|
||||
* since it'll always be blocked (as there is internal use of onMouseDown)
|
||||
*/
|
||||
onMouseDown: PropTypes.func,
|
||||
|
||||
/**
|
||||
* These properties should be defined on the child, not here.
|
||||
*/
|
||||
className: dontSetMe,
|
||||
style: dontSetMe,
|
||||
transform: dontSetMe
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
allowAnyClick: false, // by default only accept left click
|
||||
cancel: null,
|
||||
disabled: false,
|
||||
enableUserSelectHack: true,
|
||||
offsetParent: null,
|
||||
handle: null,
|
||||
grid: null,
|
||||
transform: null,
|
||||
onStart: function(){},
|
||||
onDrag: function(){},
|
||||
onStop: function(){},
|
||||
onMouseDown: function(){}
|
||||
};
|
||||
|
||||
state = {
|
||||
dragging: false,
|
||||
// Used while dragging to determine deltas.
|
||||
lastX: NaN, lastY: NaN,
|
||||
touchIdentifier: null
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
// Remove any leftover event handlers. Remove both touch and mouse handlers in case
|
||||
// some browser quirk caused a touch event to fire during a mouse move, or vice versa.
|
||||
const thisNode = ReactDOM.findDOMNode(this);
|
||||
if (thisNode) {
|
||||
const {ownerDocument} = thisNode;
|
||||
removeEvent(ownerDocument, eventsFor.mouse.move, this.handleDrag);
|
||||
removeEvent(ownerDocument, eventsFor.touch.move, this.handleDrag);
|
||||
removeEvent(ownerDocument, eventsFor.mouse.stop, this.handleDragStop);
|
||||
removeEvent(ownerDocument, eventsFor.touch.stop, this.handleDragStop);
|
||||
if (this.props.enableUserSelectHack) removeUserSelectStyles(ownerDocument);
|
||||
}
|
||||
}
|
||||
|
||||
handleDragStart: EventHandler<MouseTouchEvent> = (e) => {
|
||||
// Make it possible to attach event handlers on top of this one.
|
||||
this.props.onMouseDown(e);
|
||||
|
||||
// Only accept left-clicks.
|
||||
if (!this.props.allowAnyClick && typeof e.button === 'number' && e.button !== 0) return false;
|
||||
|
||||
// Get nodes. Be sure to grab relative document (could be iframed)
|
||||
const thisNode = ReactDOM.findDOMNode(this);
|
||||
if (!thisNode || !thisNode.ownerDocument || !thisNode.ownerDocument.body) {
|
||||
throw new Error('<DraggableCore> not mounted on DragStart!');
|
||||
}
|
||||
const {ownerDocument} = thisNode;
|
||||
|
||||
// Short circuit if handle or cancel prop was provided and selector doesn't match.
|
||||
if (this.props.disabled ||
|
||||
(!(e.target instanceof ownerDocument.defaultView.Node)) ||
|
||||
(this.props.handle && !matchesSelectorAndParentsTo(e.target, this.props.handle, thisNode)) ||
|
||||
(this.props.cancel && matchesSelectorAndParentsTo(e.target, this.props.cancel, thisNode))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set touch identifier in component state if this is a touch event. This allows us to
|
||||
// distinguish between individual touches on multitouch screens by identifying which
|
||||
// touchpoint was set to this element.
|
||||
const touchIdentifier = getTouchIdentifier(e);
|
||||
this.setState({touchIdentifier});
|
||||
|
||||
// Get the current drag point from the event. This is used as the offset.
|
||||
const position = getControlPosition(e, touchIdentifier, this);
|
||||
if (position == null) return; // not possible but satisfies flow
|
||||
const {x, y} = position;
|
||||
|
||||
// Create an event object with all the data parents need to make a decision here.
|
||||
const coreEvent = createCoreData(this, x, y);
|
||||
|
||||
log('DraggableCore: handleDragStart: %j', coreEvent);
|
||||
|
||||
// Call event handler. If it returns explicit false, cancel.
|
||||
log('calling', this.props.onStart);
|
||||
const shouldUpdate = this.props.onStart(e, coreEvent);
|
||||
if (shouldUpdate === false) return;
|
||||
|
||||
// Add a style to the body to disable user-select. This prevents text from
|
||||
// being selected all over the page.
|
||||
if (this.props.enableUserSelectHack) addUserSelectStyles(ownerDocument);
|
||||
|
||||
// Initiate dragging. Set the current x and y as offsets
|
||||
// so we know how much we've moved during the drag. This allows us
|
||||
// to drag elements around even if they have been moved, without issue.
|
||||
this.setState({
|
||||
dragging: true,
|
||||
|
||||
lastX: x,
|
||||
lastY: y
|
||||
});
|
||||
|
||||
// Add events to the document directly so we catch when the user's mouse/touch moves outside of
|
||||
// this element. We use different events depending on whether or not we have detected that this
|
||||
// is a touch-capable device.
|
||||
addEvent(ownerDocument, dragEventFor.move, this.handleDrag);
|
||||
addEvent(ownerDocument, dragEventFor.stop, this.handleDragStop);
|
||||
};
|
||||
|
||||
handleDrag: EventHandler<MouseTouchEvent> = (e) => {
|
||||
|
||||
// Prevent scrolling on mobile devices, like ipad/iphone.
|
||||
if (e.type === 'touchmove') e.preventDefault();
|
||||
|
||||
// Get the current drag point from the event. This is used as the offset.
|
||||
const position = getControlPosition(e, this.state.touchIdentifier, this);
|
||||
if (position == null) return;
|
||||
let {x, y} = position;
|
||||
|
||||
// Snap to grid if prop has been provided
|
||||
if (Array.isArray(this.props.grid)) {
|
||||
let deltaX = x - this.state.lastX, deltaY = y - this.state.lastY;
|
||||
[deltaX, deltaY] = snapToGrid(this.props.grid, deltaX, deltaY);
|
||||
if (!deltaX && !deltaY) return; // skip useless drag
|
||||
x = this.state.lastX + deltaX, y = this.state.lastY + deltaY;
|
||||
}
|
||||
|
||||
const coreEvent = createCoreData(this, x, y);
|
||||
|
||||
log('DraggableCore: handleDrag: %j', coreEvent);
|
||||
|
||||
// Call event handler. If it returns explicit false, trigger end.
|
||||
const shouldUpdate = this.props.onDrag(e, coreEvent);
|
||||
if (shouldUpdate === false) {
|
||||
try {
|
||||
// $FlowIgnore
|
||||
this.handleDragStop(new MouseEvent('mouseup'));
|
||||
} catch (err) {
|
||||
// Old browsers
|
||||
const event = ((document.createEvent('MouseEvents'): any): MouseTouchEvent);
|
||||
// I see why this insanity was deprecated
|
||||
// $FlowIgnore
|
||||
event.initMouseEvent('mouseup', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
this.handleDragStop(event);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
lastX: x,
|
||||
lastY: y
|
||||
});
|
||||
};
|
||||
|
||||
handleDragStop: EventHandler<MouseTouchEvent> = (e) => {
|
||||
if (!this.state.dragging) return;
|
||||
|
||||
const position = getControlPosition(e, this.state.touchIdentifier, this);
|
||||
if (position == null) return;
|
||||
const {x, y} = position;
|
||||
const coreEvent = createCoreData(this, x, y);
|
||||
|
||||
const thisNode = ReactDOM.findDOMNode(this);
|
||||
if (thisNode) {
|
||||
// Remove user-select hack
|
||||
if (this.props.enableUserSelectHack) removeUserSelectStyles(thisNode.ownerDocument);
|
||||
}
|
||||
|
||||
log('DraggableCore: handleDragStop: %j', coreEvent);
|
||||
|
||||
// Reset the el.
|
||||
this.setState({
|
||||
dragging: false,
|
||||
lastX: NaN,
|
||||
lastY: NaN
|
||||
});
|
||||
|
||||
// Call event handler
|
||||
this.props.onStop(e, coreEvent);
|
||||
|
||||
if (thisNode) {
|
||||
// Remove event handlers
|
||||
log('DraggableCore: Removing handlers');
|
||||
removeEvent(thisNode.ownerDocument, dragEventFor.move, this.handleDrag);
|
||||
removeEvent(thisNode.ownerDocument, dragEventFor.stop, this.handleDragStop);
|
||||
}
|
||||
};
|
||||
|
||||
onMouseDown: EventHandler<MouseTouchEvent> = (e) => {
|
||||
dragEventFor = eventsFor.mouse; // on touchscreen laptops we could switch back to mouse
|
||||
|
||||
return this.handleDragStart(e);
|
||||
};
|
||||
|
||||
onMouseUp: EventHandler<MouseTouchEvent> = (e) => {
|
||||
dragEventFor = eventsFor.mouse;
|
||||
|
||||
return this.handleDragStop(e);
|
||||
};
|
||||
|
||||
// Same as onMouseDown (start drag), but now consider this a touch device.
|
||||
onTouchStart: EventHandler<MouseTouchEvent> = (e) => {
|
||||
// We're on a touch device now, so change the event handlers
|
||||
dragEventFor = eventsFor.touch;
|
||||
|
||||
return this.handleDragStart(e);
|
||||
};
|
||||
|
||||
onTouchEnd: EventHandler<MouseTouchEvent> = (e) => {
|
||||
// We're on a touch device now, so change the event handlers
|
||||
dragEventFor = eventsFor.touch;
|
||||
|
||||
return this.handleDragStop(e);
|
||||
};
|
||||
|
||||
render() {
|
||||
// Reuse the child provided
|
||||
// This makes it flexible to use whatever element is wanted (div, ul, etc)
|
||||
return React.cloneElement(React.Children.only(this.props.children), {
|
||||
style: styleHacks(this.props.children.props.style),
|
||||
|
||||
// Note: mouseMove handler is attached to document so it will still function
|
||||
// when the user drags quickly and leaves the bounds of the element.
|
||||
onMouseDown: this.onMouseDown,
|
||||
onTouchStart: this.onTouchStart,
|
||||
onMouseUp: this.onMouseUp,
|
||||
onTouchEnd: this.onTouchEnd
|
||||
});
|
||||
}
|
||||
}
|
11
node_modules/react-draggable/lib/umd.js
generated
vendored
Normal file
11
node_modules/react-draggable/lib/umd.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import Draggable from './Draggable';
|
||||
import DraggableCore from './DraggableCore';
|
||||
|
||||
// Previous versions of this lib exported <Draggable> as the root export. As to not break
|
||||
// them, or TypeScript, we export *both* as the root and as 'default'.
|
||||
// See https://github.com/mzabriskie/react-draggable/pull/254
|
||||
// and https://github.com/mzabriskie/react-draggable/issues/266
|
||||
Draggable.default = Draggable;
|
||||
Draggable.DraggableCore = DraggableCore;
|
||||
|
||||
export default Draggable;
|
200
node_modules/react-draggable/lib/utils/domFns.js
generated
vendored
Normal file
200
node_modules/react-draggable/lib/utils/domFns.js
generated
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
// @flow
|
||||
import {findInArray, isFunction, int} from './shims';
|
||||
import browserPrefix, {browserPrefixToKey} from './getPrefix';
|
||||
|
||||
import type {ControlPosition, PositionOffsetControlPosition, MouseTouchEvent} from './types';
|
||||
|
||||
let matchesSelectorFunc = '';
|
||||
export function matchesSelector(el: Node, selector: string): boolean {
|
||||
if (!matchesSelectorFunc) {
|
||||
matchesSelectorFunc = findInArray([
|
||||
'matches',
|
||||
'webkitMatchesSelector',
|
||||
'mozMatchesSelector',
|
||||
'msMatchesSelector',
|
||||
'oMatchesSelector'
|
||||
], function(method){
|
||||
// $FlowIgnore: Doesn't think elements are indexable
|
||||
return isFunction(el[method]);
|
||||
});
|
||||
}
|
||||
|
||||
// Might not be found entirely (not an Element?) - in that case, bail
|
||||
// $FlowIgnore: Doesn't think elements are indexable
|
||||
if (!isFunction(el[matchesSelectorFunc])) return false;
|
||||
|
||||
// $FlowIgnore: Doesn't think elements are indexable
|
||||
return el[matchesSelectorFunc](selector);
|
||||
}
|
||||
|
||||
// Works up the tree to the draggable itself attempting to match selector.
|
||||
export function matchesSelectorAndParentsTo(el: Node, selector: string, baseNode: Node): boolean {
|
||||
let node = el;
|
||||
do {
|
||||
if (matchesSelector(node, selector)) return true;
|
||||
if (node === baseNode) return false;
|
||||
node = node.parentNode;
|
||||
} while (node);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function addEvent(el: ?Node, event: string, handler: Function): void {
|
||||
if (!el) { return; }
|
||||
if (el.attachEvent) {
|
||||
el.attachEvent('on' + event, handler);
|
||||
} else if (el.addEventListener) {
|
||||
el.addEventListener(event, handler, true);
|
||||
} else {
|
||||
// $FlowIgnore: Doesn't think elements are indexable
|
||||
el['on' + event] = handler;
|
||||
}
|
||||
}
|
||||
|
||||
export function removeEvent(el: ?Node, event: string, handler: Function): void {
|
||||
if (!el) { return; }
|
||||
if (el.detachEvent) {
|
||||
el.detachEvent('on' + event, handler);
|
||||
} else if (el.removeEventListener) {
|
||||
el.removeEventListener(event, handler, true);
|
||||
} else {
|
||||
// $FlowIgnore: Doesn't think elements are indexable
|
||||
el['on' + event] = null;
|
||||
}
|
||||
}
|
||||
|
||||
export function outerHeight(node: HTMLElement): number {
|
||||
// This is deliberately excluding margin for our calculations, since we are using
|
||||
// offsetTop which is including margin. See getBoundPosition
|
||||
let height = node.clientHeight;
|
||||
const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
|
||||
height += int(computedStyle.borderTopWidth);
|
||||
height += int(computedStyle.borderBottomWidth);
|
||||
return height;
|
||||
}
|
||||
|
||||
export function outerWidth(node: HTMLElement): number {
|
||||
// This is deliberately excluding margin for our calculations, since we are using
|
||||
// offsetLeft which is including margin. See getBoundPosition
|
||||
let width = node.clientWidth;
|
||||
const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
|
||||
width += int(computedStyle.borderLeftWidth);
|
||||
width += int(computedStyle.borderRightWidth);
|
||||
return width;
|
||||
}
|
||||
export function innerHeight(node: HTMLElement): number {
|
||||
let height = node.clientHeight;
|
||||
const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
|
||||
height -= int(computedStyle.paddingTop);
|
||||
height -= int(computedStyle.paddingBottom);
|
||||
return height;
|
||||
}
|
||||
|
||||
export function innerWidth(node: HTMLElement): number {
|
||||
let width = node.clientWidth;
|
||||
const computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
|
||||
width -= int(computedStyle.paddingLeft);
|
||||
width -= int(computedStyle.paddingRight);
|
||||
return width;
|
||||
}
|
||||
|
||||
// Get from offsetParent
|
||||
export function offsetXYFromParent(evt: {clientX: number, clientY: number}, offsetParent: HTMLElement): ControlPosition {
|
||||
const isBody = offsetParent === offsetParent.ownerDocument.body;
|
||||
const offsetParentRect = isBody ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();
|
||||
|
||||
const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;
|
||||
const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
export function createCSSTransform(controlPos: ControlPosition, positionOffset: PositionOffsetControlPosition): Object {
|
||||
const translation = getTranslation(controlPos, positionOffset, 'px');
|
||||
return {[browserPrefixToKey('transform', browserPrefix)]: translation };
|
||||
}
|
||||
|
||||
export function createSVGTransform(controlPos: ControlPosition, positionOffset: PositionOffsetControlPosition): string {
|
||||
const translation = getTranslation(controlPos, positionOffset, '');
|
||||
return translation;
|
||||
}
|
||||
export function getTranslation({x, y}: ControlPosition, positionOffset: PositionOffsetControlPosition, unitSuffix: string): string {
|
||||
let translation = `translate(${x}${unitSuffix},${y}${unitSuffix})`;
|
||||
if (positionOffset) {
|
||||
const defaultX = `${(typeof positionOffset.x === 'string') ? positionOffset.x : positionOffset.x + unitSuffix}`;
|
||||
const defaultY = `${(typeof positionOffset.y === 'string') ? positionOffset.y : positionOffset.y + unitSuffix}`;
|
||||
translation = `translate(${defaultX}, ${defaultY})` + translation;
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
|
||||
export function getTouch(e: MouseTouchEvent, identifier: number): ?{clientX: number, clientY: number} {
|
||||
return (e.targetTouches && findInArray(e.targetTouches, t => identifier === t.identifier)) ||
|
||||
(e.changedTouches && findInArray(e.changedTouches, t => identifier === t.identifier));
|
||||
}
|
||||
|
||||
export function getTouchIdentifier(e: MouseTouchEvent): ?number {
|
||||
if (e.targetTouches && e.targetTouches[0]) return e.targetTouches[0].identifier;
|
||||
if (e.changedTouches && e.changedTouches[0]) return e.changedTouches[0].identifier;
|
||||
}
|
||||
|
||||
// User-select Hacks:
|
||||
//
|
||||
// Useful for preventing blue highlights all over everything when dragging.
|
||||
|
||||
// Note we're passing `document` b/c we could be iframed
|
||||
export function addUserSelectStyles(doc: ?Document) {
|
||||
if (!doc) return;
|
||||
let styleEl = doc.getElementById('react-draggable-style-el');
|
||||
if (!styleEl) {
|
||||
styleEl = doc.createElement('style');
|
||||
styleEl.type = 'text/css';
|
||||
styleEl.id = 'react-draggable-style-el';
|
||||
styleEl.innerHTML = '.react-draggable-transparent-selection *::-moz-selection {all: inherit;}\n';
|
||||
styleEl.innerHTML += '.react-draggable-transparent-selection *::selection {all: inherit;}\n';
|
||||
doc.getElementsByTagName('head')[0].appendChild(styleEl);
|
||||
}
|
||||
if (doc.body) addClassName(doc.body, 'react-draggable-transparent-selection');
|
||||
}
|
||||
|
||||
export function removeUserSelectStyles(doc: ?Document) {
|
||||
try {
|
||||
if (doc && doc.body) removeClassName(doc.body, 'react-draggable-transparent-selection');
|
||||
// $FlowIgnore: IE
|
||||
if (doc.selection) {
|
||||
// $FlowIgnore: IE
|
||||
doc.selection.empty();
|
||||
} else {
|
||||
window.getSelection().removeAllRanges(); // remove selection caused by scroll
|
||||
}
|
||||
} catch (e) {
|
||||
// probably IE
|
||||
}
|
||||
}
|
||||
|
||||
export function styleHacks(childStyle: Object = {}): Object {
|
||||
// Workaround IE pointer events; see #51
|
||||
// https://github.com/mzabriskie/react-draggable/issues/51#issuecomment-103488278
|
||||
return {
|
||||
touchAction: 'none',
|
||||
...childStyle
|
||||
};
|
||||
}
|
||||
|
||||
export function addClassName(el: HTMLElement, className: string) {
|
||||
if (el.classList) {
|
||||
el.classList.add(className);
|
||||
} else {
|
||||
if (!el.className.match(new RegExp(`(?:^|\\s)${className}(?!\\S)`))) {
|
||||
el.className += ` ${className}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function removeClassName(el: HTMLElement, className: string) {
|
||||
if (el.classList) {
|
||||
el.classList.remove(className);
|
||||
} else {
|
||||
el.className = el.className.replace(new RegExp(`(?:^|\\s)${className}(?!\\S)`, 'g'), '');
|
||||
}
|
||||
}
|
47
node_modules/react-draggable/lib/utils/getPrefix.js
generated
vendored
Normal file
47
node_modules/react-draggable/lib/utils/getPrefix.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// @flow
|
||||
const prefixes = ['Moz', 'Webkit', 'O', 'ms'];
|
||||
export function getPrefix(prop: string='transform'): string {
|
||||
// Checking specifically for 'window.document' is for pseudo-browser server-side
|
||||
// environments that define 'window' as the global context.
|
||||
// E.g. React-rails (see https://github.com/reactjs/react-rails/pull/84)
|
||||
if (typeof window === 'undefined' || typeof window.document === 'undefined') return '';
|
||||
|
||||
const style = window.document.documentElement.style;
|
||||
|
||||
if (prop in style) return '';
|
||||
|
||||
for (let i = 0; i < prefixes.length; i++) {
|
||||
if (browserPrefixToKey(prop, prefixes[i]) in style) return prefixes[i];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function browserPrefixToKey(prop: string, prefix: string): string {
|
||||
return prefix ? `${prefix}${kebabToTitleCase(prop)}` : prop;
|
||||
}
|
||||
|
||||
export function browserPrefixToStyle(prop: string, prefix: string): string {
|
||||
return prefix ? `-${prefix.toLowerCase()}-${prop}` : prop;
|
||||
}
|
||||
|
||||
function kebabToTitleCase(str: string): string {
|
||||
let out = '';
|
||||
let shouldCapitalize = true;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
if (shouldCapitalize) {
|
||||
out += str[i].toUpperCase();
|
||||
shouldCapitalize = false;
|
||||
} else if (str[i] === '-') {
|
||||
shouldCapitalize = true;
|
||||
} else {
|
||||
out += str[i];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Default export is the prefix itself, like 'Moz', 'Webkit', etc
|
||||
// Note that you may have to re-test for certain things; for instance, Chrome 50
|
||||
// can handle unprefixed `transform`, but not unprefixed `user-select`
|
||||
export default getPrefix();
|
5
node_modules/react-draggable/lib/utils/log.js
generated
vendored
Normal file
5
node_modules/react-draggable/lib/utils/log.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
// @flow
|
||||
/*eslint no-console:0*/
|
||||
export default function log(...args: any) {
|
||||
if (process.env.DRAGGABLE_DEBUG) console.log(...args);
|
||||
}
|
135
node_modules/react-draggable/lib/utils/positionFns.js
generated
vendored
Normal file
135
node_modules/react-draggable/lib/utils/positionFns.js
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
// @flow
|
||||
import {isNum, int} from './shims';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {getTouch, innerWidth, innerHeight, offsetXYFromParent, outerWidth, outerHeight} from './domFns';
|
||||
|
||||
import type Draggable from '../Draggable';
|
||||
import type {Bounds, ControlPosition, DraggableData, MouseTouchEvent} from './types';
|
||||
import type DraggableCore from '../DraggableCore';
|
||||
|
||||
export function getBoundPosition(draggable: Draggable, x: number, y: number): [number, number] {
|
||||
// If no bounds, short-circuit and move on
|
||||
if (!draggable.props.bounds) return [x, y];
|
||||
|
||||
// Clone new bounds
|
||||
let {bounds} = draggable.props;
|
||||
bounds = typeof bounds === 'string' ? bounds : cloneBounds(bounds);
|
||||
const node = findDOMNode(draggable);
|
||||
|
||||
if (typeof bounds === 'string') {
|
||||
const {ownerDocument} = node;
|
||||
const ownerWindow = ownerDocument.defaultView;
|
||||
let boundNode;
|
||||
if (bounds === 'parent') {
|
||||
boundNode = node.parentNode;
|
||||
} else {
|
||||
boundNode = ownerDocument.querySelector(bounds);
|
||||
}
|
||||
if (!(boundNode instanceof ownerWindow.HTMLElement)) {
|
||||
throw new Error('Bounds selector "' + bounds + '" could not find an element.');
|
||||
}
|
||||
const nodeStyle = ownerWindow.getComputedStyle(node);
|
||||
const boundNodeStyle = ownerWindow.getComputedStyle(boundNode);
|
||||
// Compute bounds. This is a pain with padding and offsets but this gets it exactly right.
|
||||
bounds = {
|
||||
left: -node.offsetLeft + int(boundNodeStyle.paddingLeft) + int(nodeStyle.marginLeft),
|
||||
top: -node.offsetTop + int(boundNodeStyle.paddingTop) + int(nodeStyle.marginTop),
|
||||
right: innerWidth(boundNode) - outerWidth(node) - node.offsetLeft +
|
||||
int(boundNodeStyle.paddingRight) - int(nodeStyle.marginRight),
|
||||
bottom: innerHeight(boundNode) - outerHeight(node) - node.offsetTop +
|
||||
int(boundNodeStyle.paddingBottom) - int(nodeStyle.marginBottom)
|
||||
};
|
||||
}
|
||||
|
||||
// Keep x and y below right and bottom limits...
|
||||
if (isNum(bounds.right)) x = Math.min(x, bounds.right);
|
||||
if (isNum(bounds.bottom)) y = Math.min(y, bounds.bottom);
|
||||
|
||||
// But above left and top limits.
|
||||
if (isNum(bounds.left)) x = Math.max(x, bounds.left);
|
||||
if (isNum(bounds.top)) y = Math.max(y, bounds.top);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
export function snapToGrid(grid: [number, number], pendingX: number, pendingY: number): [number, number] {
|
||||
const x = Math.round(pendingX / grid[0]) * grid[0];
|
||||
const y = Math.round(pendingY / grid[1]) * grid[1];
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
export function canDragX(draggable: Draggable): boolean {
|
||||
return draggable.props.axis === 'both' || draggable.props.axis === 'x';
|
||||
}
|
||||
|
||||
export function canDragY(draggable: Draggable): boolean {
|
||||
return draggable.props.axis === 'both' || draggable.props.axis === 'y';
|
||||
}
|
||||
|
||||
// Get {x, y} positions from event.
|
||||
export function getControlPosition(e: MouseTouchEvent, touchIdentifier: ?number, draggableCore: DraggableCore): ?ControlPosition {
|
||||
const touchObj = typeof touchIdentifier === 'number' ? getTouch(e, touchIdentifier) : null;
|
||||
if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch
|
||||
const node = findDOMNode(draggableCore);
|
||||
// User can provide an offsetParent if desired.
|
||||
const offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body;
|
||||
return offsetXYFromParent(touchObj || e, offsetParent);
|
||||
}
|
||||
|
||||
// Create an data object exposed by <DraggableCore>'s events
|
||||
export function createCoreData(draggable: DraggableCore, x: number, y: number): DraggableData {
|
||||
const state = draggable.state;
|
||||
const isStart = !isNum(state.lastX);
|
||||
const node = findDOMNode(draggable);
|
||||
|
||||
if (isStart) {
|
||||
// If this is our first move, use the x and y as last coords.
|
||||
return {
|
||||
node,
|
||||
deltaX: 0, deltaY: 0,
|
||||
lastX: x, lastY: y,
|
||||
x, y,
|
||||
};
|
||||
} else {
|
||||
// Otherwise calculate proper values.
|
||||
return {
|
||||
node,
|
||||
deltaX: x - state.lastX, deltaY: y - state.lastY,
|
||||
lastX: state.lastX, lastY: state.lastY,
|
||||
x, y,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Create an data exposed by <Draggable>'s events
|
||||
export function createDraggableData(draggable: Draggable, coreData: DraggableData): DraggableData {
|
||||
const scale = draggable.props.scale;
|
||||
return {
|
||||
node: coreData.node,
|
||||
x: draggable.state.x + (coreData.deltaX / scale),
|
||||
y: draggable.state.y + (coreData.deltaY / scale),
|
||||
deltaX: (coreData.deltaX / scale),
|
||||
deltaY: (coreData.deltaY / scale),
|
||||
lastX: draggable.state.x,
|
||||
lastY: draggable.state.y
|
||||
};
|
||||
}
|
||||
|
||||
// A lot faster than stringify/parse
|
||||
function cloneBounds(bounds: Bounds): Bounds {
|
||||
return {
|
||||
left: bounds.left,
|
||||
top: bounds.top,
|
||||
right: bounds.right,
|
||||
bottom: bounds.bottom
|
||||
};
|
||||
}
|
||||
|
||||
function findDOMNode(draggable: Draggable | DraggableCore): HTMLElement {
|
||||
const node = ReactDOM.findDOMNode(draggable);
|
||||
if (!node) {
|
||||
throw new Error('<DraggableCore>: Unmounted during event!');
|
||||
}
|
||||
// $FlowIgnore we can't assert on HTMLElement due to tests... FIXME
|
||||
return node;
|
||||
}
|
25
node_modules/react-draggable/lib/utils/shims.js
generated
vendored
Normal file
25
node_modules/react-draggable/lib/utils/shims.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// @flow
|
||||
// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc
|
||||
export function findInArray(array: Array<any> | TouchList, callback: Function): any {
|
||||
for (let i = 0, length = array.length; i < length; i++) {
|
||||
if (callback.apply(callback, [array[i], i, array])) return array[i];
|
||||
}
|
||||
}
|
||||
|
||||
export function isFunction(func: any): boolean {
|
||||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]';
|
||||
}
|
||||
|
||||
export function isNum(num: any): boolean {
|
||||
return typeof num === 'number' && !isNaN(num);
|
||||
}
|
||||
|
||||
export function int(a: string): number {
|
||||
return parseInt(a, 10);
|
||||
}
|
||||
|
||||
export function dontSetMe(props: Object, propName: string, componentName: string) {
|
||||
if (props[propName]) {
|
||||
return new Error(`Invalid prop ${propName} passed to ${componentName} - do not set this, set it on the child.`);
|
||||
}
|
||||
}
|
30
node_modules/react-draggable/lib/utils/types.js
generated
vendored
Normal file
30
node_modules/react-draggable/lib/utils/types.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// @flow
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
export type DraggableEventHandler = (e: MouseEvent, data: DraggableData) => void | false;
|
||||
|
||||
export type DraggableData = {
|
||||
node: HTMLElement,
|
||||
x: number, y: number,
|
||||
deltaX: number, deltaY: number,
|
||||
lastX: number, lastY: number
|
||||
};
|
||||
|
||||
export type Bounds = {
|
||||
left: number, top: number, right: number, bottom: number
|
||||
};
|
||||
export type ControlPosition = {x: number, y: number};
|
||||
export type PositionOffsetControlPosition = {x: number|string, y: number|string};
|
||||
export type EventHandler<T> = (e: T) => void | false;
|
||||
|
||||
// Missing in Flow
|
||||
export class SVGElement extends HTMLElement {
|
||||
}
|
||||
|
||||
// Missing targetTouches
|
||||
export class TouchEvent2 extends TouchEvent {
|
||||
changedTouches: TouchList;
|
||||
targetTouches: TouchList;
|
||||
}
|
||||
|
||||
export type MouseTouchEvent = MouseEvent & TouchEvent2;
|
93
node_modules/react-draggable/package.json
generated
vendored
Normal file
93
node_modules/react-draggable/package.json
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
{
|
||||
"name": "react-draggable",
|
||||
"version": "3.3.2",
|
||||
"description": "React draggable component",
|
||||
"main": "dist/react-draggable.js",
|
||||
"browser": "dist/react-draggable.js",
|
||||
"scripts": {
|
||||
"test": "make test",
|
||||
"test-debug": "karma start --browsers=Chrome",
|
||||
"test-ie": "karma start --browsers=IE",
|
||||
"dev": "make dev",
|
||||
"build": "make clean build",
|
||||
"lint": "make lint",
|
||||
"flow": "flow"
|
||||
},
|
||||
"typings": "./typings/index.d.ts",
|
||||
"types": "./typings/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mzabriskie/react-draggable.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"draggable",
|
||||
"react-component"
|
||||
],
|
||||
"author": "Matt Zabriskie",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mzabriskie/react-draggable/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mzabriskie/react-draggable",
|
||||
"devDependencies": {
|
||||
"@types/react": "^16.0.25",
|
||||
"@types/react-dom": "^16.0.3",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^8.0.2",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-espower": "^2.3.2",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-plugin-transform-flow-comments": "^6.22.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"core-js": "^2.5.1",
|
||||
"eslint": "^4.12.0",
|
||||
"eslint-plugin-react": "^7.5.1",
|
||||
"flow-bin": "^0.69.0",
|
||||
"jasmine-core": "^2.8.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"karma": "^1.7.1",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-firefox-launcher": "^1.0.1",
|
||||
"karma-ie-launcher": "^1.0.0",
|
||||
"karma-jasmine": "^1.1.0",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"karma-phantomjs-shim": "^1.5.0",
|
||||
"karma-webpack": "^2.0.6",
|
||||
"lodash": "^4.17.4",
|
||||
"open": "0.0.5",
|
||||
"phantomjs-prebuilt": "^2.1.16",
|
||||
"power-assert": "^1.4.4",
|
||||
"pre-commit": "^1.2.2",
|
||||
"puppeteer": "^0.13.0",
|
||||
"react": "^16.1.1",
|
||||
"react-dom": "^16.1.1",
|
||||
"react-frame-component": "^2.0.0",
|
||||
"react-test-renderer": "^16.1.1",
|
||||
"rollup": "^0.57.1",
|
||||
"rollup-plugin-babel": "^3.0.3",
|
||||
"rollup-plugin-commonjs": "^9.1.0",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"rollup-plugin-replace": "^2.0.0",
|
||||
"rollup-plugin-size-snapshot": "^0.2.1",
|
||||
"rollup-plugin-uglify": "^3.0.0",
|
||||
"semver": "^5.4.1",
|
||||
"static-server": "^3.0.0",
|
||||
"typescript": "^2.6.1",
|
||||
"uglify-js": "^3.2.0",
|
||||
"webpack": "^3.8.1",
|
||||
"webpack-dev-server": "^2.9.5"
|
||||
},
|
||||
"precommit": [
|
||||
"lint",
|
||||
"test"
|
||||
],
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
}
|
61
node_modules/react-draggable/rollup.config.js
generated
vendored
Normal file
61
node_modules/react-draggable/rollup.config.js
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import babel from 'rollup-plugin-babel';
|
||||
import replace from 'rollup-plugin-replace';
|
||||
import uglify from 'rollup-plugin-uglify';
|
||||
import { sizeSnapshot } from 'rollup-plugin-size-snapshot';
|
||||
|
||||
const input = './lib/umd.js';
|
||||
|
||||
export default [
|
||||
{
|
||||
input,
|
||||
output: {
|
||||
file: 'dist/react-draggable.js',
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
name: 'ReactDraggable',
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM'
|
||||
}
|
||||
},
|
||||
external: ['react', 'react-dom'],
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
commonjs({ include: 'node_modules/**' }),
|
||||
babel({ exclude: 'node_modules/**', plugins: ['external-helpers'] }),
|
||||
replace({
|
||||
'process.env.DRAGGABLE_DEBUG': 'false',
|
||||
'process.env.NODE_ENV': JSON.stringify('development')
|
||||
}),
|
||||
sizeSnapshot()
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
input,
|
||||
output: {
|
||||
file: 'dist/react-draggable.min.js',
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
name: 'ReactDraggable',
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM'
|
||||
}
|
||||
},
|
||||
external: ['react', 'react-dom'],
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
commonjs({ include: 'node_modules/**' }),
|
||||
babel({ exclude: 'node_modules/**', plugins: ['external-helpers'] }),
|
||||
replace({
|
||||
'process.env.DRAGGABLE_DEBUG': 'false',
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
}),
|
||||
sizeSnapshot(),
|
||||
uglify()
|
||||
]
|
||||
}
|
||||
];
|
65
node_modules/react-draggable/typings/index.d.ts
generated
vendored
Normal file
65
node_modules/react-draggable/typings/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
declare module 'react-draggable' {
|
||||
import * as React from 'react';
|
||||
|
||||
export interface DraggableBounds {
|
||||
left: number
|
||||
right: number
|
||||
top: number
|
||||
bottom: number
|
||||
}
|
||||
|
||||
export interface DraggableProps extends DraggableCoreProps {
|
||||
axis: 'both' | 'x' | 'y' | 'none',
|
||||
bounds: DraggableBounds | string | false ,
|
||||
defaultClassName: string,
|
||||
defaultClassNameDragging: string,
|
||||
defaultClassNameDragged: string,
|
||||
defaultPosition: ControlPosition,
|
||||
positionOffset: PositionOffsetControlPosition,
|
||||
position: ControlPosition
|
||||
}
|
||||
|
||||
export type DraggableEvent = React.MouseEvent<HTMLElement | SVGElement>
|
||||
| React.TouchEvent<HTMLElement | SVGElement>
|
||||
| MouseEvent
|
||||
| TouchEvent
|
||||
|
||||
export type DraggableEventHandler = (
|
||||
e: DraggableEvent,
|
||||
data: DraggableData
|
||||
) => void | false;
|
||||
|
||||
export interface DraggableData {
|
||||
node: HTMLElement,
|
||||
x: number, y: number,
|
||||
deltaX: number, deltaY: number,
|
||||
lastX: number, lastY: number
|
||||
}
|
||||
|
||||
export type ControlPosition = {x: number, y: number};
|
||||
|
||||
export type PositionOffsetControlPosition = {x: number|string, y: number|string};
|
||||
|
||||
export interface DraggableCoreProps {
|
||||
allowAnyClick: boolean,
|
||||
cancel: string,
|
||||
disabled: boolean,
|
||||
enableUserSelectHack: boolean,
|
||||
offsetParent: HTMLElement,
|
||||
grid: [number, number],
|
||||
handle: string,
|
||||
onStart: DraggableEventHandler,
|
||||
onDrag: DraggableEventHandler,
|
||||
onStop: DraggableEventHandler,
|
||||
onMouseDown: (e: MouseEvent) => void,
|
||||
scale: number
|
||||
}
|
||||
|
||||
export default class Draggable extends React.Component<Partial<DraggableProps>, {}> {
|
||||
static defaultProps : DraggableProps;
|
||||
}
|
||||
|
||||
export class DraggableCore extends React.Component<Partial<DraggableCoreProps>, {}> {
|
||||
static defaultProps : DraggableCoreProps;
|
||||
}
|
||||
}
|
65
node_modules/react-draggable/typings/test.tsx
generated
vendored
Normal file
65
node_modules/react-draggable/typings/test.tsx
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import Draggable, {DraggableCore} from 'react-draggable';
|
||||
|
||||
const root = document.getElementById('root')
|
||||
|
||||
function handleStart() {}
|
||||
function handleDrag() {}
|
||||
function handleStop() {}
|
||||
function handleMouseDown() {}
|
||||
|
||||
ReactDOM.render(
|
||||
<Draggable
|
||||
axis="y"
|
||||
handle=".handle"
|
||||
cancel=".cancel"
|
||||
grid={[10, 10]}
|
||||
onStart={handleStart}
|
||||
onDrag={handleDrag}
|
||||
onStop={handleStop}
|
||||
offsetParent={document.body}
|
||||
allowAnyClick={true}
|
||||
onMouseDown={handleMouseDown}
|
||||
disabled={true}
|
||||
enableUserSelectHack={false}
|
||||
bounds={false}
|
||||
defaultClassName={'draggable'}
|
||||
defaultClassNameDragging={'dragging'}
|
||||
defaultClassNameDragged={'dragged'}
|
||||
defaultPosition={{x: 0, y: 0}}
|
||||
positionOffset={{x: 0, y: 0}}
|
||||
position={{x: 50, y: 50}}>
|
||||
<div className="foo bar">
|
||||
<div className="handle"/>
|
||||
<div className="cancel"/>
|
||||
</div>
|
||||
</Draggable>,
|
||||
root
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<DraggableCore
|
||||
handle=".handle"
|
||||
cancel=".cancel"
|
||||
allowAnyClick={true}
|
||||
disabled={true}
|
||||
onMouseDown={handleMouseDown}
|
||||
grid={[10, 10]}
|
||||
onStart={handleStart}
|
||||
onDrag={handleDrag}
|
||||
onStop={handleStop}
|
||||
offsetParent={document.body}
|
||||
enableUserSelectHack={false}>
|
||||
<div className="foo bar">
|
||||
<div className="handle"/>
|
||||
<div className="cancel"/>
|
||||
</div>
|
||||
</DraggableCore>,
|
||||
root
|
||||
);
|
||||
|
||||
|
||||
ReactDOM.render(<Draggable><div/></Draggable>, root);
|
||||
|
||||
ReactDOM.render(<DraggableCore><div/></DraggableCore>, root);
|
11
node_modules/react-draggable/typings/tsconfig.json
generated
vendored
Normal file
11
node_modules/react-draggable/typings/tsconfig.json
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
"strict": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"test.tsx"
|
||||
]
|
||||
}
|
48
node_modules/react-draggable/webpack.config.js
generated
vendored
Normal file
48
node_modules/react-draggable/webpack.config.js
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
output: {
|
||||
filename: './dist/react-draggable.js',
|
||||
sourceMapFilename: './dist/react-draggable.js.map',
|
||||
devtoolModuleFilenameTemplate: '../[resource-path]',
|
||||
library: 'ReactDraggable',
|
||||
libraryTarget: 'umd'
|
||||
},
|
||||
externals: {
|
||||
'react': {
|
||||
'commonjs': 'react',
|
||||
'commonjs2': 'react',
|
||||
'amd': 'react',
|
||||
// React dep should be available as window.React, not window.react
|
||||
'root': 'React'
|
||||
},
|
||||
'react-dom': {
|
||||
'commonjs': 'react-dom',
|
||||
'commonjs2': 'react-dom',
|
||||
'amd': 'react-dom',
|
||||
'root': 'ReactDOM'
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(?:js|es).?$/,
|
||||
loader: 'babel-loader?cacheDirectory',
|
||||
exclude: /(node_modules)/
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js']
|
||||
},
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
// Default values
|
||||
DRAGGABLE_DEBUG: false,
|
||||
NODE_ENV: 'production'
|
||||
}),
|
||||
// Scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
]
|
||||
};
|
8
node_modules/react-sortablejs/.eslintrc
generated
vendored
Normal file
8
node_modules/react-sortablejs/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "trendmicro",
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
}
|
||||
}
|
39
node_modules/react-sortablejs/.travis.yml
generated
vendored
Normal file
39
node_modules/react-sortablejs/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
group: edge
|
||||
|
||||
language: node_js
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
node_js:
|
||||
- '10'
|
||||
- '8'
|
||||
- '6'
|
||||
|
||||
before_install:
|
||||
- npm install -g npm
|
||||
- npm --version
|
||||
|
||||
after_success:
|
||||
- npm run coveralls
|
||||
- npm run coverage-clean
|
||||
|
||||
before_deploy:
|
||||
- echo "Deploying to GitHub releases"
|
||||
- ls -al releases
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: "1SCPI3pKviogeEFszgdLzTNywZ+ArYDgyezFRM345VRwiRPhWqRom21UkdgeYyEUsfFLEQ3Ms78hSWwgXmEk2UjvZIIPtdpI8KLD1cLqMSwMZSAVX4tuJN7uSo3nMt/W4UvSsWewxEv4WC6uwg1LwCCsxpEjkfvO4Ct1LvReT9JQAHHAZhM8FmGabNwk34ImZxqls3enxRODaHVz/BQwc6uw53HBcDhKnCYfjosyDFp1bXnQQXlD4ZwxWoAzdqswp7j5I44JxHmTcqT+grEd2clpqIuSomgHLmi9o5uVp0ervMrFVVFUEY0ZBUtV1RDzY/yTO9q63c+SvouPUWDwp6kjkexzFZqOLvjw8cdtCJWG3kNU3w49EI548tGyuqX95KLc5wqxU+yCIlCyAy3m7U6sxrxOQ8fStxmxwR2I4wbZPkgh4LD5yThItjB7i0Ax7eI5Ts2SYBrpe15tRqXrLc8/nE4EjEbomfzhjDN7T8MWf8j2zVCMnwCdSPhhI4C+Jegj0HG8gvq/gqiCgq26wdooBgVIN8rBG0XkrDRfuvWDyqAYHoKQv5FkOxNkdtuy2oBNIP6OU3J2Xh7c0hAcCS/jLddBthknZt3KJ1VidE1uY7SAKm+YF5VJLaGfLdYUlM/OHX7X2ICG7t11se7wm3+Fo/ZPeiLe611mHA+z6xA="
|
||||
file_glob: true
|
||||
file:
|
||||
- 'releases/*.*'
|
||||
overwrite: true
|
||||
skip_cleanup: true
|
||||
on:
|
||||
# https://docs.travis-ci.com/user/deployment#Conditional-Releases-with-on
|
||||
tags: true # Deploy app only when a tag is applied to the commit
|
||||
node: '6'
|
21
node_modules/react-sortablejs/LICENSE
generated
vendored
Normal file
21
node_modules/react-sortablejs/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Cheton Wu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
272
node_modules/react-sortablejs/README.md
generated
vendored
Normal file
272
node_modules/react-sortablejs/README.md
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
# react-sortablejs [](https://travis-ci.org/SortableJS/react-sortablejs) [](https://coveralls.io/github/SortableJS/react-sortablejs?branch=master)
|
||||
|
||||
[](https://www.npmjs.com/package/react-sortablejs)
|
||||
|
||||
A React component built on top of Sortable (https://github.com/SortableJS/Sortable).
|
||||
|
||||
- Demo: https://sortablejs.github.io/react-sortablejs/
|
||||
|
||||
The [sample code](https://github.com/SortableJS/react-sortablejs/blob/master/examples/index.jsx) can be found in the [examples](https://github.com/SortableJS/react-sortablejs/tree/master/examples) directory.
|
||||
|
||||
## Notice
|
||||
There is a major breaking change since v1.0. Checkout [Migration Guide](https://github.com/SortableJS/react-sortablejs/wiki/Migration-Guide) while upgrading from earlier versions.
|
||||
|
||||
## Installation
|
||||
|
||||
### Webpack or Browserify
|
||||
The easiest way to use react-sortablejs is to install it from npm and include it in your React build process using webpack or browserify.
|
||||
```bash
|
||||
npm install --save react react-dom sortablejs@1.6.1 # Install peerDependencies
|
||||
npm install --save react-sortablejs
|
||||
```
|
||||
|
||||
Checkout the [examples](https://github.com/SortableJS/react-sortablejs/tree/dev/examples) directory for a complete setup.
|
||||
|
||||
### Standalone ES5 module
|
||||
You can create a standalone ES5 module as shown below:
|
||||
```bash
|
||||
$ git clone https://github.com/SortableJS/react-sortablejs.git
|
||||
$ cd react-sortablejs
|
||||
$ npm install
|
||||
$ npm run build && npm run dist
|
||||
```
|
||||
|
||||
Then, include these scripts into your html file:
|
||||
```html
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="http://fb.me/react-0.14.7.js"></script>
|
||||
<script src="http://fb.me/react-dom-0.14.7.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/Sortable/1.4.2/Sortable.min.js"></script>
|
||||
<script src="dist/react-sortable.min.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
Use <b><ReactSortable /></b> instead of <b><Sortable /></b> in your JSX code since the Sortable library will export a <b>window.Sortable</b> object if you're running JSX code directly in the browser. For example:
|
||||
```js
|
||||
<ReactSortable
|
||||
tag="ul"
|
||||
onChange={(order) =>
|
||||
this.props.onChange(order);
|
||||
}}
|
||||
>
|
||||
{items}
|
||||
</ReactSortable>
|
||||
```
|
||||
|
||||
## Usage
|
||||
File: sortable-list.jsx
|
||||
```js
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import React from 'react';
|
||||
import Sortable from 'react-sortablejs';
|
||||
|
||||
// Functional Component
|
||||
const SortableList = ({ items, onChange }) => {
|
||||
let sortable = null; // sortable instance
|
||||
const reverseOrder = (evt) => {
|
||||
const order = sortable.toArray();
|
||||
onChange(order.reverse());
|
||||
};
|
||||
const listItems = items.map(val => (<li key={uniqueId()} data-id={val}>List Item: {val}</li>));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button type="button" onClick={reverseOrder}>Reverse Order</button>
|
||||
<Sortable
|
||||
// Sortable options (https://github.com/RubaXa/Sortable#options)
|
||||
options={{
|
||||
}}
|
||||
|
||||
// [Optional] Use ref to get the sortable instance
|
||||
// https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
|
||||
ref={(c) => {
|
||||
if (c) {
|
||||
sortable = c.sortable;
|
||||
}
|
||||
}}
|
||||
|
||||
// [Optional] A tag or react component to specify the wrapping element. Defaults to "div".
|
||||
// In a case of a react component it is required to has children in the component
|
||||
// and pass it down.
|
||||
tag="ul"
|
||||
|
||||
// [Optional] The onChange method allows you to implement a controlled component and keep
|
||||
// DOM nodes untouched. You have to change state to re-render the component.
|
||||
// @param {Array} order An ordered array of items defined by the `data-id` attribute.
|
||||
// @param {Object} sortable The sortable instance.
|
||||
// @param {Event} evt The event object.
|
||||
onChange={(order, sortable, evt) => {
|
||||
onChange(order);
|
||||
}}
|
||||
>
|
||||
{listItems}
|
||||
</Sortable>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SortableList.propTypes = {
|
||||
items: React.PropTypes.array,
|
||||
onChange: React.PropTypes.func
|
||||
};
|
||||
|
||||
export default SortableList;
|
||||
```
|
||||
|
||||
File: index.jsx
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import SortableList from './sortable-list';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
items: [1, 2, 3, 4, 5, 6]
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SortableList
|
||||
items={this.state.items}
|
||||
onChange={(items) => {
|
||||
this.setState({ items });
|
||||
}}
|
||||
>
|
||||
</SortableList>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('container')
|
||||
);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Uncontrolled Component
|
||||
An uncontrolled component allows [Sortable](https://github.com/RubaXa/Sortable) to touch DOM nodes. It's useful when you don't need to maintain any state changes.
|
||||
|
||||
```js
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Sortable from 'react-sortablejs';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
items: ['Apple', 'Banana', 'Cherry', 'Guava', 'Peach', 'Strawberry']
|
||||
};
|
||||
|
||||
render() {
|
||||
const items = this.state.items.map(val => (<li key={uniqueId()} data-id={val}>{val}</li>));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Sortable
|
||||
tag="ul" // Defaults to "div"
|
||||
>
|
||||
{items}
|
||||
</Sortable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('container')
|
||||
);
|
||||
```
|
||||
|
||||
### Controlled Component
|
||||
A controlled component will keep DOM nodes untouched. You have to change state to re-render the component.
|
||||
|
||||
```js
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Sortable from 'react-sortablejs';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
items: ['Apple', 'Banana', 'Cherry', 'Guava', 'Peach', 'Strawberry']
|
||||
};
|
||||
|
||||
render() {
|
||||
const items = this.state.items.map(val => (<li key={uniqueId()} data-id={val}>{val}</li>));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Sortable
|
||||
tag="ul" // Defaults to "div"
|
||||
onChange={(order, sortable, evt) => {
|
||||
this.setState({ items: order });
|
||||
}}
|
||||
>
|
||||
{items}
|
||||
</Sortable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('container')
|
||||
);
|
||||
```
|
||||
|
||||
### Shared Group
|
||||
An example of using the `group` option to drag elements from one list into another.
|
||||
|
||||
File: shared-group.jsx
|
||||
```js
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import React from 'react';
|
||||
import Sortable from 'react-sortablejs';
|
||||
|
||||
// Functional Component
|
||||
const SharedGroup = ({ items }) => {
|
||||
items = items.map(val => (<li key={uniqueId()} data-id={val}>{val}</li>));
|
||||
|
||||
return (
|
||||
<Sortable
|
||||
// See all Sortable options at https://github.com/RubaXa/Sortable#options
|
||||
options={{
|
||||
group: 'shared'
|
||||
}}
|
||||
tag="ul"
|
||||
>
|
||||
{items}
|
||||
</Sortable>
|
||||
);
|
||||
};
|
||||
|
||||
export default SharedGroup;
|
||||
```
|
||||
|
||||
File: index.jsx
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import SharedGroup from './shared-group';
|
||||
|
||||
const App = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<SharedGroup
|
||||
items={['Apple', 'Banaba', 'Cherry', 'Grape']}
|
||||
/>
|
||||
<br/>
|
||||
<SharedGroup
|
||||
items={['Lemon', 'Orange', 'Pear', 'Peach']}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('container'));
|
||||
```
|
7
node_modules/react-sortablejs/babel.config.js
generated
vendored
Normal file
7
node_modules/react-sortablejs/babel.config.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: '@trendmicro/babel-config',
|
||||
presets: [
|
||||
'@babel/preset-env',
|
||||
'@babel/preset-react'
|
||||
]
|
||||
};
|
30
node_modules/react-sortablejs/bower.json
generated
vendored
Normal file
30
node_modules/react-sortablejs/bower.json
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "react-sortablejs",
|
||||
"main": [
|
||||
"lib/index.js"
|
||||
],
|
||||
"homepage": "https://github.com/cheton/react-sortable",
|
||||
"authors": [
|
||||
"Cheton Wu <cheton@gmail.com>"
|
||||
],
|
||||
"description": "A React component built on top of Sortable (https://github.com/RubaXa/Sortable).",
|
||||
"dependencies": {
|
||||
"react": "^0.14.0 || ^15.0.0",
|
||||
"sortablejs": "^1.5.1"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-component",
|
||||
"sortable",
|
||||
"reorder",
|
||||
"drag",
|
||||
"mixin"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
422
node_modules/react-sortablejs/dist/react-sortable.js
generated
vendored
Normal file
422
node_modules/react-sortablejs/dist/react-sortable.js
generated
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
/*! react-sortablejs v1.5.1 | (c) 2019 Cheton Wu <cheton@gmail.com> | MIT | https://github.com/SortableJS/react-sortablejs */
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory(require("react"), require("sortablejs"));
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define(["react", "sortablejs"], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["ReactSortable"] = factory(require("react"), require("sortablejs"));
|
||||
else
|
||||
root["ReactSortable"] = factory(root["React"], root["Sortable"]);
|
||||
})(window, function(__WEBPACK_EXTERNAL_MODULE__5__, __WEBPACK_EXTERNAL_MODULE__6__) {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var Sortable = __webpack_require__(1).default;
|
||||
|
||||
module.exports = Sortable;
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _propTypes = _interopRequireDefault(__webpack_require__(2));
|
||||
|
||||
var _react = _interopRequireWildcard(__webpack_require__(5));
|
||||
|
||||
var _sortablejs = _interopRequireDefault(__webpack_require__(6));
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _extends() { _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; }; return _extends.apply(this, arguments); }
|
||||
|
||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
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 store = {
|
||||
nextSibling: null,
|
||||
activeComponent: null
|
||||
};
|
||||
|
||||
var Sortable =
|
||||
/*#__PURE__*/
|
||||
function (_Component) {
|
||||
_inherits(Sortable, _Component);
|
||||
|
||||
function Sortable() {
|
||||
var _getPrototypeOf2;
|
||||
|
||||
var _this;
|
||||
|
||||
_classCallCheck(this, Sortable);
|
||||
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Sortable)).call.apply(_getPrototypeOf2, [this].concat(args)));
|
||||
|
||||
_defineProperty(_assertThisInitialized(_this), "sortable", null);
|
||||
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(Sortable, [{
|
||||
key: "componentDidMount",
|
||||
value: function componentDidMount() {
|
||||
var _this2 = this;
|
||||
|
||||
var options = _objectSpread({}, this.props.options);
|
||||
|
||||
['onChoose', 'onStart', 'onEnd', 'onAdd', 'onUpdate', 'onSort', 'onRemove', 'onFilter', 'onMove', 'onClone'].forEach(function (name) {
|
||||
var eventHandler = options[name];
|
||||
|
||||
options[name] = function () {
|
||||
for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
||||
params[_key2] = arguments[_key2];
|
||||
}
|
||||
|
||||
var evt = params[0];
|
||||
|
||||
if (name === 'onChoose') {
|
||||
store.nextSibling = evt.item.nextElementSibling;
|
||||
store.activeComponent = _this2;
|
||||
} else if ((name === 'onAdd' || name === 'onUpdate') && _this2.props.onChange) {
|
||||
var items = _this2.sortable.toArray();
|
||||
|
||||
var remote = store.activeComponent;
|
||||
var remoteItems = remote.sortable.toArray();
|
||||
var referenceNode = store.nextSibling && store.nextSibling.parentNode !== null ? store.nextSibling : null;
|
||||
evt.from.insertBefore(evt.item, referenceNode);
|
||||
|
||||
if (remote !== _this2) {
|
||||
var remoteOptions = remote.props.options || {};
|
||||
|
||||
if (_typeof(remoteOptions.group) === 'object' && remoteOptions.group.pull === 'clone') {
|
||||
// Remove the node with the same data-reactid
|
||||
evt.item.parentNode.removeChild(evt.item);
|
||||
}
|
||||
|
||||
remote.props.onChange && remote.props.onChange(remoteItems, remote.sortable, evt);
|
||||
}
|
||||
|
||||
_this2.props.onChange && _this2.props.onChange(items, _this2.sortable, evt);
|
||||
}
|
||||
|
||||
if (evt.type === 'move') {
|
||||
var _evt = params[0],
|
||||
originalEvent = params[1];
|
||||
var canMove = eventHandler ? eventHandler(_evt, originalEvent) : true;
|
||||
return canMove;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
eventHandler && eventHandler(evt);
|
||||
}, 0);
|
||||
};
|
||||
});
|
||||
this.sortable = _sortablejs.default.create(this.node, options);
|
||||
}
|
||||
}, {
|
||||
key: "shouldComponentUpdate",
|
||||
value: function shouldComponentUpdate(nextProps) {
|
||||
// If onChange is null, it is an UnControlled component
|
||||
// Don't let React re-render it by setting return to false
|
||||
if (!nextProps.onChange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}, {
|
||||
key: "componentWillUnmount",
|
||||
value: function componentWillUnmount() {
|
||||
if (this.sortable) {
|
||||
this.sortable.destroy();
|
||||
this.sortable = null;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this3 = this;
|
||||
|
||||
var _this$props = this.props,
|
||||
Component = _this$props.tag,
|
||||
options = _this$props.options,
|
||||
onChange = _this$props.onChange,
|
||||
props = _objectWithoutProperties(_this$props, ["tag", "options", "onChange"]);
|
||||
|
||||
return _react.default.createElement(Component, _extends({}, props, {
|
||||
ref: function ref(node) {
|
||||
_this3.node = node;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}]);
|
||||
|
||||
return Sortable;
|
||||
}(_react.Component);
|
||||
|
||||
_defineProperty(Sortable, "propTypes", {
|
||||
options: _propTypes.default.object,
|
||||
onChange: _propTypes.default.func,
|
||||
tag: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]),
|
||||
style: _propTypes.default.object
|
||||
});
|
||||
|
||||
_defineProperty(Sortable, "defaultProps", {
|
||||
options: {},
|
||||
tag: 'div',
|
||||
style: {}
|
||||
});
|
||||
|
||||
var _default = Sortable;
|
||||
exports.default = _default;
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
if (false) { var throwOnDirectAccess, ReactIs; } else {
|
||||
// By explicitly using `prop-types` you are opting into new production behavior.
|
||||
// http://fb.me/prop-types-in-prod
|
||||
module.exports = __webpack_require__(3)();
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 3 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
var ReactPropTypesSecret = __webpack_require__(4);
|
||||
|
||||
function emptyFunction() {}
|
||||
function emptyFunctionWithReset() {}
|
||||
emptyFunctionWithReset.resetWarningCache = emptyFunction;
|
||||
|
||||
module.exports = function() {
|
||||
function shim(props, propName, componentName, location, propFullName, secret) {
|
||||
if (secret === ReactPropTypesSecret) {
|
||||
// It is still safe when called from React.
|
||||
return;
|
||||
}
|
||||
var err = new Error(
|
||||
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
|
||||
'Use PropTypes.checkPropTypes() to call them. ' +
|
||||
'Read more at http://fb.me/use-check-prop-types'
|
||||
);
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
};
|
||||
shim.isRequired = shim;
|
||||
function getShim() {
|
||||
return shim;
|
||||
};
|
||||
// Important!
|
||||
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
|
||||
var ReactPropTypes = {
|
||||
array: shim,
|
||||
bool: shim,
|
||||
func: shim,
|
||||
number: shim,
|
||||
object: shim,
|
||||
string: shim,
|
||||
symbol: shim,
|
||||
|
||||
any: shim,
|
||||
arrayOf: getShim,
|
||||
element: shim,
|
||||
elementType: shim,
|
||||
instanceOf: getShim,
|
||||
node: shim,
|
||||
objectOf: getShim,
|
||||
oneOf: getShim,
|
||||
oneOfType: getShim,
|
||||
shape: getShim,
|
||||
exact: getShim,
|
||||
|
||||
checkPropTypes: emptyFunctionWithReset,
|
||||
resetWarningCache: emptyFunction
|
||||
};
|
||||
|
||||
ReactPropTypes.PropTypes = ReactPropTypes;
|
||||
|
||||
return ReactPropTypes;
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 4 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
|
||||
|
||||
module.exports = ReactPropTypesSecret;
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 5 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = __WEBPACK_EXTERNAL_MODULE__5__;
|
||||
|
||||
/***/ }),
|
||||
/* 6 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = __WEBPACK_EXTERNAL_MODULE__6__;
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
2
node_modules/react-sortablejs/dist/react-sortable.min.js
generated
vendored
Normal file
2
node_modules/react-sortablejs/dist/react-sortable.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
56
node_modules/react-sortablejs/docs/app.css
generated
vendored
Normal file
56
node_modules/react-sortablejs/docs/app.css
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
html {
|
||||
background-image: -webkit-linear-gradient(bottom, #F4E2C9 20%, #F4D7C9 100%);
|
||||
background-image: -ms-linear-gradient(bottom, #F4E2C9 20%, #F4D7C9 100%);
|
||||
background-image: linear-gradient(to bottom, #F4E2C9 20%, #F4D7C9 100%);
|
||||
}
|
||||
|
||||
html, body {
|
||||
background-color: transparent;
|
||||
font-family: sans-serif;
|
||||
font-weight: 300;
|
||||
color: #333;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
margin: 0;
|
||||
margin-bottom: 20px;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
}
|
||||
a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
background-color: #ff7373;
|
||||
padding: 4px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.block-list {
|
||||
padding: 20px 0;
|
||||
max-width: 360px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
.block-list > * {
|
||||
padding: 10px 40px;
|
||||
}
|
||||
.block-list > *:first-child {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
.block-list > * {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.block-list > *:hover {
|
||||
cursor: move;
|
||||
}
|
29949
node_modules/react-sortablejs/docs/bundle.js
generated
vendored
Normal file
29949
node_modules/react-sortablejs/docs/bundle.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/react-sortablejs/docs/bundle.js.map
generated
vendored
Normal file
1
node_modules/react-sortablejs/docs/bundle.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
41
node_modules/react-sortablejs/docs/index.html
generated
vendored
Normal file
41
node_modules/react-sortablejs/docs/index.html
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv-"X-UA-Compatible" content="IE=edge">
|
||||
<title>react-sortable</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<link href="app.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse" style="border-radius: 0">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="http://cheton.github.io/react-sortable/">react-sortable</a>
|
||||
</div>
|
||||
<div class="navbar-right" style="margin: 0">
|
||||
<a
|
||||
class="btn btn-default navbar-btn"
|
||||
href="https://github.com/cheton/react-sortable"
|
||||
>
|
||||
<i class="fa fa-github fa-fw" style="font-size: 16px"></i>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<h3>A React component built on top of Sortable (<a href="https://github.com/RubaXa/Sortable">https://github.com/RubaXa/Sortable</a>).</h3>
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
<script type="text/javascript" src="bundle.js?5baf9df7dea3f1cda16b"></script></body>
|
||||
</html>
|
41
node_modules/react-sortablejs/examples/index.html
generated
vendored
Normal file
41
node_modules/react-sortablejs/examples/index.html
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv-"X-UA-Compatible" content="IE=edge">
|
||||
<title>react-sortable</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<link href="app.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse" style="border-radius: 0">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="http://cheton.github.io/react-sortable/">react-sortable</a>
|
||||
</div>
|
||||
<div class="navbar-right" style="margin: 0">
|
||||
<a
|
||||
class="btn btn-default navbar-btn"
|
||||
href="https://github.com/cheton/react-sortable"
|
||||
>
|
||||
<i class="fa fa-github fa-fw" style="font-size: 16px"></i>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<h3>A React component built on top of Sortable (<a href="https://github.com/RubaXa/Sortable">https://github.com/RubaXa/Sortable</a>).</h3>
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
237
node_modules/react-sortablejs/examples/index.jsx
generated
vendored
Normal file
237
node_modules/react-sortablejs/examples/index.jsx
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
import random from 'lodash/random';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
import uniq from 'lodash/uniq';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Sortable from '../src';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
simpleList: [1, 2, 3, 4, 5, 6],
|
||||
groupLeft: ['Apple', 'Banana', 'Cherry', 'Grape'],
|
||||
groupRight: ['Lemon', 'Orange', 'Pear', 'Peach'],
|
||||
cloneUncontrolled: ['Apple', 'Banana', 'Cherry', 'Guava', 'Grape', 'Kiwi', 'Lemon', 'Melon', 'Orange', 'Pear', 'Peach', 'Strawberry'],
|
||||
cloneControlledSource: ['Apple', 'Banana', 'Cherry', 'Guava', 'Grape', 'Kiwi', 'Lemon', 'Melon', 'Orange', 'Pear', 'Peach', 'Strawberry'],
|
||||
cloneControlledTarget: []
|
||||
};
|
||||
|
||||
simpleList = null;
|
||||
|
||||
addMoreItems = () => {
|
||||
const items = [
|
||||
'Apple',
|
||||
'Banana',
|
||||
'Cherry',
|
||||
'Guava',
|
||||
'Grape',
|
||||
'Kiwi',
|
||||
'Lemon',
|
||||
'Melon',
|
||||
'Orange',
|
||||
'Pear',
|
||||
'Peach',
|
||||
'Strawberry'
|
||||
];
|
||||
const i = random(0, items.length - 1);
|
||||
this.setState(state => ({
|
||||
groupLeft: state.groupLeft.concat(items[i])
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const simpleList = this.state.simpleList.map((val, key) => (
|
||||
<li key={uniqueId()} data-id={val}>List Item {val}</li>
|
||||
));
|
||||
const groupLeft = this.state.groupLeft.map((val, key) => (
|
||||
<div key={uniqueId()} data-id={val}>{val}</div>
|
||||
));
|
||||
const groupRight = this.state.groupRight.map((val, key) => (
|
||||
<div key={uniqueId()} data-id={val}>{val}</div>
|
||||
));
|
||||
const cloneUncontrolled = this.state.cloneUncontrolled.map((val, key) => (
|
||||
<li key={uniqueId()} data-id={val}>{val}</li>
|
||||
));
|
||||
const cloneControlledSource = this.state.cloneControlledSource.map((val, key) => (
|
||||
<li key={uniqueId()} data-id={val}>{val}</li>
|
||||
));
|
||||
const cloneControlledTarget = this.state.cloneControlledTarget.map((val, key) => (
|
||||
<li key={uniqueId()} data-id={val}>{val}</li>
|
||||
));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginTop: 50 }}>
|
||||
<div className="title">Simple List</div>
|
||||
<div className="form-group">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-default"
|
||||
onClick={(e) => {
|
||||
const order = this.simpleList.toArray();
|
||||
this.simpleList.sort(order.reverse());
|
||||
}}
|
||||
>
|
||||
Reverse Order
|
||||
</button>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-12">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150
|
||||
}}
|
||||
className="block-list"
|
||||
ref={c => {
|
||||
if (c) {
|
||||
this.simpleList = c.sortable;
|
||||
}
|
||||
}}
|
||||
tag="ul"
|
||||
>
|
||||
{simpleList}
|
||||
</Sortable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="title" style={{ marginTop: 50 }}>Shared Group</div>
|
||||
<div className="form-group">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-default"
|
||||
onClick={this.addMoreItems}
|
||||
>
|
||||
Add more items
|
||||
</button>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
group: {
|
||||
name: 'shared',
|
||||
pull: true,
|
||||
put: true
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
onChange={(items) => {
|
||||
this.setState({ groupLeft: items });
|
||||
}}
|
||||
>
|
||||
{groupLeft}
|
||||
</Sortable>
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
group: {
|
||||
name: 'shared',
|
||||
pull: true,
|
||||
put: true
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
onChange={(items) => {
|
||||
this.setState({ groupRight: items });
|
||||
}}
|
||||
>
|
||||
{groupRight}
|
||||
</Sortable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="title" style={{ marginTop: 50 }}>Uncontrolled Component</div>
|
||||
<h4>Clone items from left to right. DOM elements are duplicated.</h4>
|
||||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
sort: false,
|
||||
group: {
|
||||
name: 'clone1',
|
||||
pull: 'clone',
|
||||
put: false
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
tag="ul"
|
||||
>
|
||||
{cloneUncontrolled}
|
||||
</Sortable>
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
group: {
|
||||
name: 'clone1',
|
||||
pull: false,
|
||||
put: true
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
tag="ul"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="title" style={{ marginTop: 50 }}>Controlled Component</div>
|
||||
<h4>Clone items from left to right without duplication.</h4>
|
||||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
sort: false,
|
||||
group: {
|
||||
name: 'clone2',
|
||||
pull: true,
|
||||
put: true
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
onChange={(items) => {
|
||||
this.setState({ cloneControlledSource: items });
|
||||
}}
|
||||
tag="ul"
|
||||
>
|
||||
{cloneControlledSource}
|
||||
</Sortable>
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<Sortable
|
||||
options={{
|
||||
animation: 150,
|
||||
group: {
|
||||
name: 'clone2',
|
||||
pull: true,
|
||||
put: true
|
||||
}
|
||||
}}
|
||||
className="block-list"
|
||||
onChange={(items) => {
|
||||
items = uniq(items); // Remove duplicate items
|
||||
this.setState({ cloneControlledTarget: items });
|
||||
}}
|
||||
tag="ul"
|
||||
>
|
||||
{cloneControlledTarget}
|
||||
</Sortable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('container')
|
||||
);
|
109
node_modules/react-sortablejs/examples/webpack.config.js
generated
vendored
Normal file
109
node_modules/react-sortablejs/examples/webpack.config.js
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const stylusLoader = require('stylus-loader');
|
||||
const nib = require('nib');
|
||||
const babelConfig = require('../babel.config');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
entry: path.resolve(__dirname, 'index.jsx'),
|
||||
output: {
|
||||
path: path.join(__dirname, '../docs'),
|
||||
filename: 'bundle.js?[hash]'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
// http://survivejs.com/webpack_react/linting_in_webpack/
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: 'pre',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
loader: 'stylint-loader',
|
||||
enforce: 'pre'
|
||||
},
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
...babelConfig
|
||||
},
|
||||
exclude: /(node_modules|bower_components)/
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
modules: true,
|
||||
localIdentName: '[local]---[hash:base64:5]',
|
||||
camelCase: true,
|
||||
importLoaders: 1
|
||||
}
|
||||
},
|
||||
'stylus-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 8192
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
mimetype: 'application/font-woff'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
loader: 'file-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new stylusLoader.OptionsPlugin({
|
||||
default: {
|
||||
// nib - CSS3 extensions for Stylus
|
||||
use: [nib()],
|
||||
// no need to have a '@import "nib"' in the stylesheet
|
||||
import: ['~nib/lib/nib/index.styl']
|
||||
}
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: '../docs/index.html',
|
||||
template: 'index.html'
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.js', '.json', '.jsx']
|
||||
},
|
||||
// https://webpack.github.io/docs/webpack-dev-server.html#additional-configuration-options
|
||||
devServer: {
|
||||
noInfo: false,
|
||||
lazy: false,
|
||||
disableHostCheck: true,
|
||||
// https://webpack.github.io/docs/node.js-api.html#compiler
|
||||
watchOptions: {
|
||||
poll: true, // use polling instead of native watchers
|
||||
ignored: /node_modules/
|
||||
}
|
||||
}
|
||||
};
|
185
node_modules/react-sortablejs/lib/Sortable.js
generated
vendored
Normal file
185
node_modules/react-sortablejs/lib/Sortable.js
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _propTypes = _interopRequireDefault(require("prop-types"));
|
||||
|
||||
var _react = _interopRequireWildcard(require("react"));
|
||||
|
||||
var _sortablejs = _interopRequireDefault(require("sortablejs"));
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _extends() { _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; }; return _extends.apply(this, arguments); }
|
||||
|
||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
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 store = {
|
||||
nextSibling: null,
|
||||
activeComponent: null
|
||||
};
|
||||
|
||||
var Sortable =
|
||||
/*#__PURE__*/
|
||||
function (_Component) {
|
||||
_inherits(Sortable, _Component);
|
||||
|
||||
function Sortable() {
|
||||
var _getPrototypeOf2;
|
||||
|
||||
var _this;
|
||||
|
||||
_classCallCheck(this, Sortable);
|
||||
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Sortable)).call.apply(_getPrototypeOf2, [this].concat(args)));
|
||||
|
||||
_defineProperty(_assertThisInitialized(_this), "sortable", null);
|
||||
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(Sortable, [{
|
||||
key: "componentDidMount",
|
||||
value: function componentDidMount() {
|
||||
var _this2 = this;
|
||||
|
||||
var options = _objectSpread({}, this.props.options);
|
||||
|
||||
['onChoose', 'onStart', 'onEnd', 'onAdd', 'onUpdate', 'onSort', 'onRemove', 'onFilter', 'onMove', 'onClone'].forEach(function (name) {
|
||||
var eventHandler = options[name];
|
||||
|
||||
options[name] = function () {
|
||||
for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
||||
params[_key2] = arguments[_key2];
|
||||
}
|
||||
|
||||
var evt = params[0];
|
||||
|
||||
if (name === 'onChoose') {
|
||||
store.nextSibling = evt.item.nextElementSibling;
|
||||
store.activeComponent = _this2;
|
||||
} else if ((name === 'onAdd' || name === 'onUpdate') && _this2.props.onChange) {
|
||||
var items = _this2.sortable.toArray();
|
||||
|
||||
var remote = store.activeComponent;
|
||||
var remoteItems = remote.sortable.toArray();
|
||||
var referenceNode = store.nextSibling && store.nextSibling.parentNode !== null ? store.nextSibling : null;
|
||||
evt.from.insertBefore(evt.item, referenceNode);
|
||||
|
||||
if (remote !== _this2) {
|
||||
var remoteOptions = remote.props.options || {};
|
||||
|
||||
if (_typeof(remoteOptions.group) === 'object' && remoteOptions.group.pull === 'clone') {
|
||||
// Remove the node with the same data-reactid
|
||||
evt.item.parentNode.removeChild(evt.item);
|
||||
}
|
||||
|
||||
remote.props.onChange && remote.props.onChange(remoteItems, remote.sortable, evt);
|
||||
}
|
||||
|
||||
_this2.props.onChange && _this2.props.onChange(items, _this2.sortable, evt);
|
||||
}
|
||||
|
||||
if (evt.type === 'move') {
|
||||
var _evt = params[0],
|
||||
originalEvent = params[1];
|
||||
var canMove = eventHandler ? eventHandler(_evt, originalEvent) : true;
|
||||
return canMove;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
eventHandler && eventHandler(evt);
|
||||
}, 0);
|
||||
};
|
||||
});
|
||||
this.sortable = _sortablejs.default.create(this.node, options);
|
||||
}
|
||||
}, {
|
||||
key: "shouldComponentUpdate",
|
||||
value: function shouldComponentUpdate(nextProps) {
|
||||
// If onChange is null, it is an UnControlled component
|
||||
// Don't let React re-render it by setting return to false
|
||||
if (!nextProps.onChange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}, {
|
||||
key: "componentWillUnmount",
|
||||
value: function componentWillUnmount() {
|
||||
if (this.sortable) {
|
||||
this.sortable.destroy();
|
||||
this.sortable = null;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this3 = this;
|
||||
|
||||
var _this$props = this.props,
|
||||
Component = _this$props.tag,
|
||||
options = _this$props.options,
|
||||
onChange = _this$props.onChange,
|
||||
props = _objectWithoutProperties(_this$props, ["tag", "options", "onChange"]);
|
||||
|
||||
return _react.default.createElement(Component, _extends({}, props, {
|
||||
ref: function ref(node) {
|
||||
_this3.node = node;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}]);
|
||||
|
||||
return Sortable;
|
||||
}(_react.Component);
|
||||
|
||||
_defineProperty(Sortable, "propTypes", {
|
||||
options: _propTypes.default.object,
|
||||
onChange: _propTypes.default.func,
|
||||
tag: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]),
|
||||
style: _propTypes.default.object
|
||||
});
|
||||
|
||||
_defineProperty(Sortable, "defaultProps", {
|
||||
options: {},
|
||||
tag: 'div',
|
||||
style: {}
|
||||
});
|
||||
|
||||
var _default = Sortable;
|
||||
exports.default = _default;
|
5
node_modules/react-sortablejs/lib/index.js
generated
vendored
Normal file
5
node_modules/react-sortablejs/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var Sortable = require('./Sortable').default;
|
||||
|
||||
module.exports = Sortable;
|
80
node_modules/react-sortablejs/package.json
generated
vendored
Normal file
80
node_modules/react-sortablejs/package.json
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "react-sortablejs",
|
||||
"version": "1.5.1",
|
||||
"description": "A React component built on top of Sortable (https://github.com/SortableJS/Sortable).",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"prepublish": "npm run eslint && npm test && npm run build && npm run dist && npm run build-examples && npm run release",
|
||||
"build": "babel --out-dir ./lib ./src",
|
||||
"build-examples": "cd examples; webpack-cli",
|
||||
"dist": "webpack-cli; BUILD_ENV=dist webpack-cli",
|
||||
"release": "mkdir -p releases; cp -f dist/react-sortable.js releases/react-sortable-${npm_package_version}.js; cp -f dist/react-sortable.min.js releases/react-sortable-${npm_package_version}.min.js",
|
||||
"eslint": "eslint ./src",
|
||||
"precommit-check": "npm run eslint",
|
||||
"test": "tap test/*.js --node-arg=--require --node-arg=@babel/register --node-arg=--require --node-arg=@babel/polyfill",
|
||||
"coveralls": "tap test/*.js --coverage --coverage-report=text-lcov --nyc-arg=--require --nyc-arg=@babel/register --nyc-arg=--require --nyc-arg=@babel/polyfill | coveralls",
|
||||
"dev": "cd examples; webpack-dev-server --hot --inline --host 0.0.0.0 --port 8000 --content-base ../docs"
|
||||
},
|
||||
"pre-commit": [
|
||||
"precommit-check"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/SortableJS/react-sortablejs.git"
|
||||
},
|
||||
"author": "Cheton Wu <cheton@gmail.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/SortableJS/react-sortablejs/issues"
|
||||
},
|
||||
"homepage": "https://github.com/SortableJS/react-sortablejs",
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-component",
|
||||
"sortable",
|
||||
"reorder",
|
||||
"drag",
|
||||
"mixin"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"react": ">=15.0.0",
|
||||
"react-dom": ">=15.0.0",
|
||||
"sortablejs": "^1.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"prop-types": ">=15.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "~7.2.3",
|
||||
"@babel/core": "~7.2.2",
|
||||
"@babel/polyfill": "~7.2.5",
|
||||
"@babel/preset-env": "~7.2.3",
|
||||
"@babel/preset-react": "~7.0.0",
|
||||
"@babel/register": "~7.0.0",
|
||||
"@trendmicro/babel-config": "~1.0.0-alpha",
|
||||
"@trendmicro/react-anchor": "~0.5.6",
|
||||
"@trendmicro/react-buttons": "~1.3.1",
|
||||
"babel-eslint": "~10.0.1",
|
||||
"babel-loader": "~8.0.4",
|
||||
"coveralls": "~3.0.2",
|
||||
"eslint": "~5.11.1",
|
||||
"eslint-config-trendmicro": "~1.4.1",
|
||||
"eslint-loader": "~2.1.1",
|
||||
"eslint-plugin-import": "~2.14.0",
|
||||
"eslint-plugin-jsx-a11y": "~6.1.2",
|
||||
"eslint-plugin-react": "~7.11.1",
|
||||
"html-webpack-plugin": "~3.2.0",
|
||||
"lodash": "~4.17.4",
|
||||
"nib": "~1.1.2",
|
||||
"react": ">=15.0.0",
|
||||
"react-dom": ">=15.0.0",
|
||||
"sortablejs": "~1.6.1",
|
||||
"stylus-loader": "~3.0.1",
|
||||
"tap": "~12.1.1",
|
||||
"terser-webpack-plugin": "~1.2.1",
|
||||
"webpack": "~4.28.2",
|
||||
"webpack-cli": "~3.1.2",
|
||||
"webpack-dev-server": "~3.1.14",
|
||||
"which": "~1.2.14"
|
||||
}
|
||||
}
|
124
node_modules/react-sortablejs/src/Sortable.jsx
generated
vendored
Normal file
124
node_modules/react-sortablejs/src/Sortable.jsx
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/* eslint consistent-return: 0 */
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import SortableJS from 'sortablejs';
|
||||
|
||||
const store = {
|
||||
nextSibling: null,
|
||||
activeComponent: null
|
||||
};
|
||||
|
||||
class Sortable extends Component {
|
||||
static propTypes = {
|
||||
options: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
tag: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.func
|
||||
]),
|
||||
style: PropTypes.object
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
options: {},
|
||||
tag: 'div',
|
||||
style: {}
|
||||
};
|
||||
|
||||
sortable = null;
|
||||
|
||||
componentDidMount() {
|
||||
const options = { ...this.props.options };
|
||||
|
||||
[
|
||||
'onChoose',
|
||||
'onStart',
|
||||
'onEnd',
|
||||
'onAdd',
|
||||
'onUpdate',
|
||||
'onSort',
|
||||
'onRemove',
|
||||
'onFilter',
|
||||
'onMove',
|
||||
'onClone'
|
||||
].forEach((name) => {
|
||||
const eventHandler = options[name];
|
||||
|
||||
options[name] = (...params) => {
|
||||
const [evt] = params;
|
||||
|
||||
if (name === 'onChoose') {
|
||||
store.nextSibling = evt.item.nextElementSibling;
|
||||
store.activeComponent = this;
|
||||
} else if ((name === 'onAdd' || name === 'onUpdate') && this.props.onChange) {
|
||||
const items = this.sortable.toArray();
|
||||
const remote = store.activeComponent;
|
||||
const remoteItems = remote.sortable.toArray();
|
||||
|
||||
const referenceNode = (store.nextSibling && store.nextSibling.parentNode !== null) ? store.nextSibling : null;
|
||||
evt.from.insertBefore(evt.item, referenceNode);
|
||||
if (remote !== this) {
|
||||
const remoteOptions = remote.props.options || {};
|
||||
|
||||
if ((typeof remoteOptions.group === 'object') && (remoteOptions.group.pull === 'clone')) {
|
||||
// Remove the node with the same data-reactid
|
||||
evt.item.parentNode.removeChild(evt.item);
|
||||
}
|
||||
|
||||
remote.props.onChange && remote.props.onChange(remoteItems, remote.sortable, evt);
|
||||
}
|
||||
|
||||
this.props.onChange && this.props.onChange(items, this.sortable, evt);
|
||||
}
|
||||
|
||||
if (evt.type === 'move') {
|
||||
const [evt, originalEvent] = params;
|
||||
const canMove = eventHandler ? eventHandler(evt, originalEvent) : true;
|
||||
return canMove;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
eventHandler && eventHandler(evt);
|
||||
}, 0);
|
||||
};
|
||||
});
|
||||
|
||||
this.sortable = SortableJS.create(this.node, options);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
// If onChange is null, it is an UnControlled component
|
||||
// Don't let React re-render it by setting return to false
|
||||
if (!nextProps.onChange) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.sortable) {
|
||||
this.sortable.destroy();
|
||||
this.sortable = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
tag: Component,
|
||||
options, // eslint-disable-line
|
||||
onChange, // eslint-disable-line
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...props}
|
||||
ref={node => {
|
||||
this.node = node;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Sortable;
|
3
node_modules/react-sortablejs/src/index.js
generated
vendored
Normal file
3
node_modules/react-sortablejs/src/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
const Sortable = require('./Sortable').default;
|
||||
|
||||
module.exports = Sortable;
|
5
node_modules/react-sortablejs/test/index.js
generated
vendored
Normal file
5
node_modules/react-sortablejs/test/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { test } from 'tap';
|
||||
|
||||
test('noop', (t) => {
|
||||
t.end();
|
||||
});
|
48
node_modules/react-sortablejs/webpack.config.js
generated
vendored
Normal file
48
node_modules/react-sortablejs/webpack.config.js
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const pkg = require('./package.json');
|
||||
|
||||
const banner = pkg.name + ' v' + pkg.version + ' | (c) ' + new Date().getFullYear() + ' ' + pkg.author + ' | ' + pkg.license + ' | ' + pkg.homepage;
|
||||
const env = process.env.BUILD_ENV;
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: path.resolve(__dirname, 'lib/index.js'),
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: (env === 'dist') ? 'react-sortable.min.js' : 'react-sortable.js',
|
||||
libraryTarget: 'umd',
|
||||
library: 'ReactSortable'
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [
|
||||
(env === 'dist') && (
|
||||
new TerserPlugin()
|
||||
)
|
||||
].filter(Boolean)
|
||||
},
|
||||
plugins: [
|
||||
new webpack.BannerPlugin(banner),
|
||||
],
|
||||
externals: {
|
||||
'react': {
|
||||
root: 'React',
|
||||
commonjs2: 'react',
|
||||
commonjs: 'react',
|
||||
amd: 'react'
|
||||
},
|
||||
'react-dom': {
|
||||
root: 'ReactDOM',
|
||||
commonjs2: 'react-dom',
|
||||
commonjs: 'react-dom',
|
||||
amd: 'react-dom'
|
||||
},
|
||||
'sortablejs': {
|
||||
root: 'Sortable',
|
||||
commonjs2: 'sortablejs',
|
||||
commonjs: 'sortablejs',
|
||||
amd: 'sortablejs'
|
||||
}
|
||||
}
|
||||
};
|
82
package.json
Normal file
82
package.json
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "react-pivottable",
|
||||
"version": "0.11.0",
|
||||
"description": "A React-based pivot table",
|
||||
"main": "PivotTableUI.js",
|
||||
"files": [
|
||||
"PivotTable.js",
|
||||
"PivotTableUI.js",
|
||||
"PlotlyRenderers.js",
|
||||
"TableRenderers.js",
|
||||
"Utilities.js",
|
||||
"PivotTable.js.map",
|
||||
"PivotTableUI.js.map",
|
||||
"PlotlyRenderers.js.map",
|
||||
"TableRenderers.js.map",
|
||||
"Utilities.js.map",
|
||||
"pivottable.css"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server",
|
||||
"test:eslint": "eslint src/*.js* && echo 'eslint: \\033[0;32m'PASS'\\033[0m'",
|
||||
"test:eslint:fix": "eslint src/*.js* --fix",
|
||||
"test:prettier": "prettier -l \"src/*.js*\" && echo 'prettier: \\033[0;32m'PASS'\\033[0m'",
|
||||
"test:prettier:fix": "prettier --write \"src/*.js*\"",
|
||||
"test:jest": "jest",
|
||||
"test": "npm run test:eslint && npm run test:prettier && npm run test:jest",
|
||||
"clean": "rm -rf __tests__ PivotTable.js* PivotTableUI.js* PlotlyRenderers.js* TableRenderers.js* Utilities.js* pivottable.css",
|
||||
"build": "npm run clean && cp src/pivottable.css . && babel src --out-dir=. --source-maps --presets=env,react --plugins babel-plugin-add-module-exports",
|
||||
"doPublish": "npm run build && npm publish",
|
||||
"postpublish": "npm run clean",
|
||||
"deploy": "webpack -p && mv bundle.js examples && cd examples && git init && git add . && git commit -m build && git push --force git@github.com:plotly/react-pivottable.git master:gh-pages && rm -rf .git bundle.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/plotly/react-pivottable.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"pivottable"
|
||||
],
|
||||
"author": "Nicolas Kruchten <nicolas@kruchten.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/plotly/react-pivottable/issues"
|
||||
},
|
||||
"homepage": "https://github.com/plotly/react-pivottable#readme",
|
||||
"dependencies": {
|
||||
"immutability-helper": "^2.3.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-draggable": "^3.0.3",
|
||||
"react-sortablejs": "^1.3.4",
|
||||
"sortablejs": "^1.6.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=15.0.0",
|
||||
"react-dom": ">=15.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"css-loader": "^0.28.7",
|
||||
"eslint": "^4.5.0",
|
||||
"eslint-config-prettier": "^2.8.0",
|
||||
"eslint-plugin-import": "^2.7.0",
|
||||
"eslint-plugin-react": "^7.3.0",
|
||||
"jest": "^21.2.1",
|
||||
"papaparse": "^4.3.6",
|
||||
"prettier": "^1.8.2",
|
||||
"react": ">=15.0.0",
|
||||
"react-dom": ">=15.0.0",
|
||||
"react-dropzone": "^4.2.1",
|
||||
"react-hot-loader": "^3.1.1",
|
||||
"react-plotly.js": "^2.0.0",
|
||||
"style-loader": "^0.19.0",
|
||||
"webpack": "^3.8.1",
|
||||
"webpack-dev-server": "^2.9.3"
|
||||
}
|
||||
}
|
323
pivottable.css
Normal file
323
pivottable.css
Normal file
@ -0,0 +1,323 @@
|
||||
.pvtUi {
|
||||
color: #2a3f5f;
|
||||
font-family: Verdana;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.pvtUi select {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.pvtUi td.pvtOutput {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.pvtTable {
|
||||
font-size: 8pt;
|
||||
text-align: left;
|
||||
border-collapse: collapse;
|
||||
margin-top: 3px;
|
||||
margin-left: 3px;
|
||||
font-family: Verdana;
|
||||
}
|
||||
table.pvtTable thead tr th,
|
||||
table.pvtTable tbody tr th {
|
||||
background-color: #ebf0f8;
|
||||
border: 1px solid #c8d4e3;
|
||||
font-size: 8pt;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table.pvtTable .pvtColLabel {
|
||||
text-align: center;
|
||||
}
|
||||
table.pvtTable .pvtTotalLabel {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.pvtTable tbody tr td {
|
||||
color: #2a3f5f;
|
||||
padding: 5px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #c8d4e3;
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.pvtTotal,
|
||||
.pvtGrandTotal {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pvtRowOrder,
|
||||
.pvtColOrder {
|
||||
cursor: pointer;
|
||||
width: 15px;
|
||||
margin-left: 5px;
|
||||
display: inline-block;
|
||||
user-select: none;
|
||||
text-decoration: none !important;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.pvtAxisContainer,
|
||||
.pvtVals {
|
||||
border: 1px solid #a2b1c6;
|
||||
background: #f2f5fa;
|
||||
padding: 5px;
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.pvtRenderers {
|
||||
padding-left: 5px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pvtDropdown {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.pvtDropdownIcon {
|
||||
float: right;
|
||||
color: #a2b1c6;
|
||||
}
|
||||
.pvtDropdownCurrent {
|
||||
text-align: left;
|
||||
border: 1px solid #a2b1c6;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 210px;
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.pvtDropdownCurrentOpen {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.pvtDropdownMenu {
|
||||
background: white;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
margin-top: -1px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
border: 1px solid #a2b1c6;
|
||||
border-top: 1px solid #dfe8f3;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pvtDropdownValue {
|
||||
padding: 2px 5px;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
.pvtDropdownActiveValue {
|
||||
background: #ebf0f8;
|
||||
}
|
||||
|
||||
.pvtVals {
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.pvtRows {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.pvtAxisContainer li {
|
||||
padding: 8px 6px;
|
||||
list-style-type: none;
|
||||
cursor: move;
|
||||
}
|
||||
.pvtAxisContainer li.pvtPlaceholder {
|
||||
-webkit-border-radius: 5px;
|
||||
padding: 3px 15px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px dashed #a2b1c6;
|
||||
}
|
||||
.pvtAxisContainer li.pvtPlaceholder span.pvtAttr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pvtAxisContainer li span.pvtAttr {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
background: #f3f6fa;
|
||||
border: 1px solid #c8d4e3;
|
||||
padding: 2px 5px;
|
||||
white-space: nowrap;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.pvtTriangle {
|
||||
cursor: pointer;
|
||||
color: #506784;
|
||||
}
|
||||
|
||||
.pvtHorizList li {
|
||||
display: inline-block;
|
||||
}
|
||||
.pvtVertList {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.pvtFilteredAttribute {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sortable-chosen .pvtFilterBox {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.pvtCloseX {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.pvtDragHandle {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
cursor: move;
|
||||
color: #a2b1c6;
|
||||
}
|
||||
|
||||
.pvtButton {
|
||||
color: #506784;
|
||||
border-radius: 5px;
|
||||
padding: 3px 6px;
|
||||
background: #f2f5fa;
|
||||
border: 1px solid;
|
||||
border-color: #c8d4e3;
|
||||
font-size: 14px;
|
||||
margin: 3px;
|
||||
transition: 0.34s all cubic-bezier(0.19, 1, 0.22, 1);
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.pvtButton:hover {
|
||||
background: #e2e8f0;
|
||||
border-color: #a2b1c6;
|
||||
}
|
||||
|
||||
.pvtButton:active {
|
||||
background: #d1dae6;
|
||||
}
|
||||
|
||||
.pvtFilterBox input {
|
||||
border: 1px solid #c8d4e3;
|
||||
border-radius: 5px;
|
||||
color: #506784;
|
||||
padding: 0 3px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pvtFilterBox input:focus {
|
||||
border-color: #119dff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.pvtFilterBox {
|
||||
z-index: 100;
|
||||
width: 300px;
|
||||
border: 1px solid #506784;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
min-height: 100px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.pvtFilterBox h4 {
|
||||
margin: 15px;
|
||||
}
|
||||
.pvtFilterBox p {
|
||||
margin: 10px auto;
|
||||
}
|
||||
.pvtFilterBox button {
|
||||
color: #2a3f5f;
|
||||
}
|
||||
.pvtFilterBox input[type='text'] {
|
||||
width: 230px;
|
||||
color: #2a3f5f;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.pvtCheckContainer {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow-y: scroll;
|
||||
width: 100%;
|
||||
max-height: 30vh;
|
||||
border-top: 1px solid #dfe8f3;
|
||||
}
|
||||
|
||||
.pvtCheckContainer p {
|
||||
margin: 0;
|
||||
margin-bottom: 1px;
|
||||
padding: 3px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.pvtCheckContainer p.selected {
|
||||
background: #ebf0f8;
|
||||
}
|
||||
|
||||
.pvtOnly {
|
||||
display: none;
|
||||
width: 35px;
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
padding-left: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pvtOnlySpacer {
|
||||
display: block;
|
||||
width: 35px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.pvtCheckContainer p:hover .pvtOnly {
|
||||
display: block;
|
||||
}
|
||||
.pvtCheckContainer p:hover .pvtOnlySpacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pvtRendererArea {
|
||||
padding: 5px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user