Skip to content

Commit

Permalink
Allow for codefinition of flexbox and regular svg styles
Browse files Browse the repository at this point in the history
  • Loading branch information
dlmanning committed Apr 25, 2015
1 parent a89809e commit 06350d2
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 30 deletions.
8 changes: 8 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"optional": [
"es7.decorators",
"es7.classProperties",
"optimisation.react.constantElements",
"runtime"
]
}
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./lib/flex.js');
239 changes: 239 additions & 0 deletions lib/flex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
'use strict';

var _extends = require('babel-runtime/helpers/extends')['default'];

var _inherits = require('babel-runtime/helpers/inherits')['default'];

var _get = require('babel-runtime/helpers/get')['default'];

var _createClass = require('babel-runtime/helpers/create-class')['default'];

var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];

var _Object$assign = require('babel-runtime/core-js/object/assign')['default'];

var _Object$keys = require('babel-runtime/core-js/object/keys')['default'];

var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default'];

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

var _React = require('react');

var _React2 = _interopRequireWildcard(_React);

var _EventEmitter = require('wolfy87-eventemitter');

var _EventEmitter2 = _interopRequireWildcard(_EventEmitter);

var _computeLayout = require('css-layout');

var _computeLayout2 = _interopRequireWildcard(_computeLayout);

var _isFlexBoxProperty = require('./flexbox-props');

var _isFlexBoxProperty2 = _interopRequireWildcard(_isFlexBoxProperty);

var Component = _React2['default'].Component;

var stylesRoot = { children: [] };

function setStyle(style) {
var styles = arguments[1] === undefined ? stylesRoot : arguments[1];
var path = arguments[2] === undefined ? [] : arguments[2];

if (styles.style === undefined) {
styles.style = style;
} else {
var childStyle = { style: style, children: [] };
styles.children.push(childStyle);
path.push(styles.children.length - 1);

styles = childStyle;
}

return {
path: path.slice(),
setStyle: (function (_setStyle) {
function setStyle(_x) {
return _setStyle.apply(this, arguments);
}

setStyle.toString = function () {
return _setStyle.toString();
};

return setStyle;
})(function (childStyle) {
return setStyle(childStyle, styles, path.slice());
})
};
}

var FlexContext = (function (_Component) {
function FlexContext(props, context) {
var _this = this;

_classCallCheck(this, FlexContext);

_get(Object.getPrototypeOf(FlexContext.prototype), 'constructor', this).call(this);

this.subscribeToLayoutChanges = function (cb) {
_this.layoutNotifier.on('layout-update', cb);
};

this.state = {};
this.layoutNotifier = new _EventEmitter2['default']();

var layout = props.layout || {};

var _setStyle2 = setStyle(layout);

var layoutFunc = _setStyle2.setStyle;

this.setStyle = layoutFunc;
}

_inherits(FlexContext, _Component);

_createClass(FlexContext, [{
key: 'subscribeToLayoutChanges',
value: undefined,
enumerable: true
}, {
key: 'getChildContext',
value: function getChildContext() {
return {
setStyle: this.setStyle,
subscribeToLayoutChanges: this.subscribeToLayoutChanges
};
}
}, {
key: 'render',
value: function render() {
return _React2['default'].createElement(
'g',
null,
this.props.children
);
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var flexLayout = _computeLayout2['default'](stylesRoot);
this.setState({ layout: flexLayout });

this.layoutNotifier.emit('layout-update', flexLayout);
}
}], [{
key: 'childContextTypes',
value: {
setStyle: _React2['default'].PropTypes.func.isRequired,
subscribeToLayoutChanges: _React2['default'].PropTypes.func.isRequired
},
enumerable: true
}]);

return FlexContext;
})(Component);

exports.FlexContext = FlexContext;
var FlexBox = function FlexBox(Composed) {
var componentStyles = arguments[1] === undefined ? {} : arguments[1];
return (function (_Component2) {
var _class = function (props, context) {
_classCallCheck(this, _class);

_get(Object.getPrototypeOf(_class.prototype), 'constructor', this).call(this);

var styles = _Object$assign(componentStyles, props.styles);

var _Object$keys$reduce = _Object$keys(styles).reduce(function (partitions, property) {
if (_isFlexBoxProperty2['default'](property)) {
partitions.flexStyles[property] = styles[property];
} else {
partitions.svgStyles[property] = styles[property];
}

return partitions;
}, { svgStyles: {}, flexStyles: {} });

var svgStyles = _Object$keys$reduce.svgStyles;
var flexStyles = _Object$keys$reduce.flexStyles;

var _context$setStyle = context.setStyle(flexStyles);

var setStyleFunc = _context$setStyle.setStyle;
var path = _context$setStyle.path;

this.setStyle = setStyleFunc;
this.pathToNode = path;

this.state = {
layout: { top: 0, left: 0, width: 0, height: 0 },
styles: svgStyles
};
};

_inherits(_class, _Component2);

_createClass(_class, [{
key: 'getMyLayout',
value: function getMyLayout(layout) {
this.pathToNode.forEach(function (childIndex) {
layout = layout.children[childIndex];
});

return layout;
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;

this.context.subscribeToLayoutChanges(function (layout) {
_this2.setState({ layout: _this2.getMyLayout(layout) });
});
}
}, {
key: 'getChildContext',
value: function getChildContext() {
return {
setStyle: this.setStyle
};
}
}, {
key: 'render',
value: function render() {
var transformation = 'translate(' + this.state.layout.left + ',' + this.state.layout.top + ')';
return _React2['default'].createElement(
'g',
{ transform: transformation },
_React2['default'].createElement(Composed, _extends({ layout: this.state.layout, style: this.state.styles }, this.props))
);
}
}], [{
key: 'displayName',
value: 'FlexBox',
enumerable: true
}, {
key: 'contextTypes',
value: {
setStyle: _React2['default'].PropTypes.func.isRequired,
subscribeToLayoutChanges: _React2['default'].PropTypes.func.isRequired
},
enumerable: true
}, {
key: 'childContextTypes',
value: {
setStyle: _React2['default'].PropTypes.func.isRequired
},
enumerable: true
}]);

return _class;
})(Component);
};
exports.FlexBox = FlexBox;
15 changes: 15 additions & 0 deletions lib/flexbox-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

var _Set = require('babel-runtime/core-js/set')['default'];

Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = isFlexBoxProperty;
var flexboxProperties = new _Set(['flexDirection', 'justifyContent', 'alignItems', 'alignSelf', 'position', 'flexWrap', 'flex', 'width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'margin', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom', 'padding', 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'borderWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth', 'borderBottomWidth', 'left', 'top', 'right', 'bottom']);

function isFlexBoxProperty(propertyName) {
return flexboxProperties.has(propertyName);
}

module.exports = exports['default'];
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
{
"name": "react-svg-flexbox",
"version": "1.0.0",
"name": "react-flexbox-svg",
"version": "0.9.0",
"description": "",
"main": "index.js",
"scripts": {
"test-serve": "webpack-dev-server --content-base test/ --hot --inline"
"test-serve": "webpack-dev-server --content-base test/ --hot --inline -d",
"prepublish": "babel src --out-dir lib"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "0.14.0-alpha",
"css-layout": "0.0.2",
"react": "0.14.0-alpha",
"wolfy87-eventemitter": "^4.2.11"
},
"devDependencies": {
"babel": "^5.1.11",
"babel-core": "^5.1.10",
"babel-loader": "^5.0.0",
"babel-runtime": "^5.1.11",
"webpack": "^1.8.5",
"webpack-dev-server": "^1.8.0"
}
Expand Down
29 changes: 25 additions & 4 deletions src/flex.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import EventEmitter from 'wolfy87-eventemitter';
import computeLayout from 'css-layout';
import isFlexBoxProperty from './flexbox-props';

const { Component } = React;

Expand Down Expand Up @@ -65,7 +66,7 @@ export class FlexContext extends Component {
}
}

export const FlexBox = (Composed, style = {}) => class extends Component {
export const FlexBox = (Composed, componentStyles = {}) => class extends Component {
static displayName = 'FlexBox';

static contextTypes = {
Expand All @@ -88,11 +89,27 @@ export const FlexBox = (Composed, style = {}) => class extends Component {
constructor (props, context) {
super();

const { setStyle: setStyleFunc, path} = context.setStyle(style);
const styles = Object.assign(componentStyles, props.styles);

const { svgStyles, flexStyles } = Object.keys(styles).reduce((partitions, property) => {
if (isFlexBoxProperty(property)) {
partitions.flexStyles[property] = styles[property];
} else {
partitions.svgStyles[property] = styles[property];
}

return partitions;
}, { svgStyles: {}, flexStyles: {} });

const { setStyle: setStyleFunc, path} = context.setStyle(flexStyles);

this.setStyle = setStyleFunc;
this.pathToNode = path;
this.state = { layout: { top: 0, left: 0, width: 0, height: 0} };

this.state = {
layout: { top: 0, left: 0, width: 0, height: 0},
styles: svgStyles
};
}

componentDidMount () {
Expand All @@ -109,7 +126,11 @@ export const FlexBox = (Composed, style = {}) => class extends Component {

render () {
const transformation = `translate(${this.state.layout.left},${this.state.layout.top})`
return <g transform={transformation}><Composed layout={this.state.layout} {...this.props}/></g>;
return (
<g transform={transformation}>
<Composed layout={this.state.layout} style={this.state.styles} {...this.props}/>
</g>
);
}

}
38 changes: 38 additions & 0 deletions src/flexbox-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const flexboxProperties = new Set([
'flexDirection',
'justifyContent',
'alignItems',
'alignSelf',
'position',
'flexWrap',
'flex',
'width',
'height',
'maxWidth',
'maxHeight',
'minWidth',
'minHeight',
'margin',
'marginLeft',
'marginRight',
'marginTop',
'marginBottom',
'padding',
'paddingLeft',
'paddingRight',
'paddingTop',
'paddingBottom',
'borderWidth',
'borderLeftWidth',
'borderRightWidth',
'borderTopWidth',
'borderBottomWidth',
'left',
'top',
'right',
'bottom'
]);

export default function isFlexBoxProperty (propertyName) {
return flexboxProperties.has(propertyName);
}
Loading

0 comments on commit 06350d2

Please sign in to comment.