Skip to content

Commit

Permalink
🔨 Refactoring and configuration improvements (#4)
Browse files Browse the repository at this point in the history
* remove unused dependencies

* remove react-docgen from babel config

* add hot replacement to examples and watch mode to the lib

* update install documentation

* update doc

* version 0.0.2 with build
  • Loading branch information
bpetetot authored Apr 11, 2017
1 parent 18c7e10 commit dc6b565
Show file tree
Hide file tree
Showing 12 changed files with 544 additions and 68 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
# testing
/coverage

# production
/build

# misc
.DS_Store
.env
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
## hoc-react-datgui

> HOC adding a `dat.GUI` plugged to `React.Component` props.
> HOC adding `dat.GUI` plugged to `React.Component` props.
_*Library currently in development*_

### What's dat.GUI ?

`dat.GUI` is a lightweight graphical user interface for changing variables in JavaScript. Written by https://github.com/dataarts/

See some examples at http://workshop.chromeexperiments.com/examples/gui.

### Getting started

```
npm install hoc-react-datgui
```

#### withDatGui(Component, model)

Generate the `dat.GUI` following the given model object.
Expand Down
129 changes: 129 additions & 0 deletions build/DatGui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _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 _dat = require('dat.gui/build/dat.gui');

var _dat2 = _interopRequireDefault(_dat);

var _mapValues = require('lodash/mapValues');

var _mapValues2 = _interopRequireDefault(_mapValues);

var _forOwn = require('lodash/forOwn');

var _forOwn2 = _interopRequireDefault(_forOwn);

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; }

var DatGui = function (_Component) {
_inherits(DatGui, _Component);

function DatGui(props) {
_classCallCheck(this, DatGui);

var _this = _possibleConstructorReturn(this, (DatGui.__proto__ || Object.getPrototypeOf(DatGui)).call(this, props));

_this.componentDidMount = function () {
if (_this.container) {
// create dat.gui and add it to the dom
var gui = new _dat2.default.GUI({ autoPlace: false });
_this.container.appendChild(gui.domElement);

// Add each props to the dat.gui component
(0, _forOwn2.default)(_this.data, function (value, key) {
return _this.addGuiData(gui, key);
});
}
};

_this.addGuiData = function (gui, prop) {
var _this$props$data$prop = _this.props.data[prop],
type = _this$props$data$prop.type,
values = _this$props$data$prop.values,
min = _this$props$data$prop.min,
max = _this$props$data$prop.max,
step = _this$props$data$prop.step;

// Create appropriate data.gui controller

var controller = void 0;
switch (type) {
case 'enum':
controller = gui.add(_this.data, prop, values);
break;
case 'color':
controller = gui.addColor(_this.data, prop);
break;
case 'slider':
controller = gui.add(_this.data, prop, min, max);
break;
default:
controller = gui.add(_this.data, prop);
break;
}

// Add datgui constraints (for numbers only)
if (type === 'number') {
min !== undefined && controller.min(min);
max !== undefined && controller.max(max);
step !== undefined && controller.step(step);
}

// Update state when a data changes
if (type === 'object' || type === 'array') {
controller.onFinishChange(function (value) {
_this.props.onFinishChange(prop, value, type || (typeof value === 'undefined' ? 'undefined' : _typeof(value))); // TODO parse objects and arrays
});
} else if (type !== 'function') {
controller.onChange(function (value) {
_this.props.onChange(prop, value, type || (typeof value === 'undefined' ? 'undefined' : _typeof(value)));
});
}
};

_this.data = (0, _mapValues2.default)(props.data, function (obj) {
return obj.value;
}); // TODO parse objects and arrays
return _this;
}

_createClass(DatGui, [{
key: 'render',
value: function render() {
var _this2 = this;

return _react2.default.createElement('div', {
ref: function ref(e) {
_this2.container = e;
},
style: { position: 'absolute', right: '0px' }
});
}
}]);

return DatGui;
}(_react.Component);

DatGui.propTypes = {
data: _react.PropTypes.object.isRequired,
onFinishChange: _react.PropTypes.func,
onChange: _react.PropTypes.func
};
exports.default = DatGui;
19 changes: 19 additions & 0 deletions build/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withDatGuiFromProps = exports.withDatGui = undefined;

var _withDatGui = require('./withDatGui');

var _withDatGui2 = _interopRequireDefault(_withDatGui);

var _withDatGuiFromProps = require('./withDatGuiFromProps');

var _withDatGuiFromProps2 = _interopRequireDefault(_withDatGuiFromProps);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.withDatGui = _withDatGui2.default;
exports.withDatGuiFromProps = _withDatGuiFromProps2.default;
70 changes: 70 additions & 0 deletions build/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mapAllDataToState = exports.mapDataToState = exports.mapModelToData = exports.mapPropsToModel = exports.getDisplayName = undefined;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _mapValues = require('lodash/mapValues');

var _mapValues2 = _interopRequireDefault(_mapValues);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var getDisplayName = exports.getDisplayName = function getDisplayName(c) {
return c.displayName || c.name || 'Component';
};

var mapPropsToModel = exports.mapPropsToModel = function mapPropsToModel(props) {
return (0, _mapValues2.default)(props, function (value) {
if (value !== undefined) {
return { type: typeof value === 'undefined' ? 'undefined' : _typeof(value), defaultValue: value };
}
return { type: 'string', defaultValue: '' };
});
};

var mapModelToData = exports.mapModelToData = function mapModelToData(model, props) {
return (0, _mapValues2.default)(model, function (value, prop) {
var type = value.type,
defaultValue = value.defaultValue;

var propValue = props[prop];

if (type === 'object') {
return JSON.stringify(propValue || defaultValue || {});
} else if (type === 'array') {
return JSON.stringify(propValue || defaultValue || []);
} else if (type === 'string') {
return propValue || defaultValue || '';
} else if (type === 'color') {
return propValue || defaultValue || '#FFFFFF';
} else if (type === 'number' || type === 'slider') {
return propValue || defaultValue || 0;
} else if (type === 'boolean') {
return propValue || defaultValue || true;
} else if (type === 'function') {
return propValue || defaultValue || function () {};
} else if (type === 'enum') {
return propValue || defaultValue || [];
}
return propValue || defaultValue;
});
};

var mapDataToState = exports.mapDataToState = function mapDataToState(value, prop, type) {
if (type === 'object' || type === 'array') {
return value && JSON.parse(value);
}
return value;
};

var mapAllDataToState = exports.mapAllDataToState = function mapAllDataToState(model, data) {
return (0, _mapValues2.default)(model, function (value, prop) {
var type = value.type;

return mapDataToState(data[prop], prop, type);
});
};
68 changes: 68 additions & 0 deletions build/withDatGui.1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _DatGui = require('./DatGui');

var _DatGui2 = _interopRequireDefault(_DatGui);

var _utils = require('./utils');

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; }

exports.default = function (WrappedComponent) {
var _class, _temp;

var model = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return _temp = _class = function (_Component) {
_inherits(_class, _Component);

function _class(props) {
_classCallCheck(this, _class);

var _this = _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).call(this, props));

_this.handleChange = function (prop, value, type) {
if (_this.state[prop] !== value) {
_this.data[prop] = value;
_this.setState(_defineProperty({}, prop, (0, _utils.mapDataToState)(value, prop, type)));
}
};

_this.render = function () {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_DatGui2.default, {
data: _this.data,
onChange: _this.handleChange,
onFinishChange: _this.handleChange
}),
_react2.default.createElement(WrappedComponent, _extends({}, _this.props, _this.state))
);
};

_this.data = (0, _utils.mapModelToData)(model, props);
_this.state = (0, _utils.mapAllDataToState)(model, _this.data);
return _this;
}

return _class;
}(_react.Component), _class.displayName = 'DatGui(' + (0, _utils.getDisplayName)(WrappedComponent) + ')', _temp;
};
Loading

0 comments on commit dc6b565

Please sign in to comment.