Last active
December 18, 2015 15:50
-
-
Save matthewrobb/7b24f9d4affb04be7e9c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Shade = Shades; | |
const { Content, Slot } = Shades; | |
function PageFooter(props) { | |
return ( | |
<footer> | |
{props.children} | |
</footer> | |
); | |
} | |
function PageHeader(props) { | |
return ( | |
<Shade lightTree={props.children}> | |
<header> | |
<Slot name="title"> | |
<h1 className="header"></h1> | |
</Slot> | |
<Slot name="subtitle"> | |
<span className="subtitle"></span> | |
</Slot> | |
</header> | |
</Shade> | |
); | |
} | |
function PageBody(props) { | |
return ( | |
<div className="body"> | |
{props.children} | |
</div> | |
); | |
} | |
function Page({ children }) { | |
return ( | |
<Shade lightTree={children}> | |
<div className="page"> | |
<Slot name="header"> | |
<PageHeader /> | |
</Slot> | |
<Slot name="body"> | |
<PageBody /> | |
</Slot> | |
<Slot name="footer"> | |
<PageFooter /> | |
</Slot> | |
</div> | |
</Shade> | |
); | |
} | |
function ThingList(props) { | |
return ( | |
<Shade lightTree={props.children}> | |
<Slot name="thing"> | |
<ul> | |
<li></li> | |
</ul> | |
</Slot> | |
</Shade> | |
); | |
} | |
function MyPage() { | |
var things = [ | |
{ label: 'cup' }, | |
{ label: 'lamp' }, | |
{ label: 'shotgun' } | |
]; | |
return ( | |
<Page className="my-page"> | |
<Content slot="header"> | |
<Content slot="title">My Page</Content> | |
<Content slot="subtitle">The coolest</Content> | |
</Content> | |
<Content slot="body"> | |
<ThingList> | |
{things.map(thing => ( | |
<Content slot="thing"> | |
{thing.label} | |
</Content> | |
))} | |
</ThingList> | |
</Content> | |
<Content slot="footer"> | |
Footies! | |
</Content> | |
</Page> | |
); | |
} | |
React.render(<MyPage/>, document.getElementById('root')); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* ReactShades | |
* | |
*/ | |
var Shades = (function(){ | |
"use strict"; | |
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | |
var PureRenderMixin = React.addons.PureRenderMixin; | |
function Slot(props, context) { | |
var contents = context.lightTree[props.name]; | |
if (!contents) return React.createElement("span", null); | |
var root = React.Children.only(props.children || React.createElement("span", null)); | |
var inner = root && root.props.children; | |
var children = []; | |
var rootProps = {}; | |
contents.forEach(function (content) { | |
var _content$props = content.props; | |
var lightTree = _content$props.children; | |
var slot = _content$props.slot; | |
var props = _objectWithoutProperties(_content$props, ["children", "slot"]); | |
var child = lightTree || React.createElement("span", null); | |
if (inner) { | |
child = React.cloneElement(inner, props, lightTree); | |
} else { | |
rootProps = props; | |
} | |
children.push(child); | |
}); | |
return React.cloneElement(root, rootProps, children); | |
} | |
Slot.contextTypes = { | |
lightTree: React.PropTypes.object | |
}; | |
function Content(props) { | |
return React.createElement( | |
"div", | |
null, | |
props.children | |
); | |
} | |
var Shade = React.createClass({ | |
displayName: "Shade", | |
mixins: [PureRenderMixin], | |
statics: { | |
Content: Content, | |
Slot: Slot, | |
visit: function visit(nodes, visitor) { | |
React.Children.forEach(nodes, function (node, idx) { | |
if (visitor(node) !== false) { | |
Shade.visit(node.props.children, visitor); | |
} | |
}); | |
} | |
}, | |
childContextTypes: { | |
lightTree: React.PropTypes.object | |
}, | |
getChildContext: function getChildContext() { | |
var slots = {}; | |
Shade.visit(this.props.lightTree, function (child) { | |
if (child.type === Shade || child.type === Slot) { | |
return false; | |
} else if (!child.props.slot) { | |
return; | |
} | |
(slots[child.props.slot] || (slots[child.props.slot] = [])).push(child); | |
return false; | |
}); | |
return { | |
lightTree: slots | |
}; | |
}, | |
render: function render() { | |
return React.Children.only(this.props.children); | |
} | |
}); | |
return Shade; | |
})(React); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* ReactShades | |
* | |
*/ | |
var Shade = (function(React){ | |
const {PureRenderMixin} = React.addons; | |
function Slot(props, context) { | |
const contents = context.lightTree[props.name]; | |
if (!contents) return <span></span>; | |
const root = React.Children.only(props.children || <span></span>); | |
const inner = root && root.props.children; | |
var children = []; | |
var rootProps = {}; | |
contents.forEach(content => { | |
const { children: lightTree, slot, ...props } = content.props; | |
var child = lightTree || <span></span>; | |
if (inner) { | |
child = React.cloneElement(inner, props, lightTree); | |
} else { | |
rootProps = props; | |
} | |
children.push(child); | |
}); | |
return React.cloneElement(root, rootProps, children); | |
} | |
Slot.contextTypes = { | |
lightTree: React.PropTypes.object | |
}; | |
function Content(props) { | |
return <div>{props.children}</div>; | |
} | |
const Shade = React.createClass({ | |
mixins: [ PureRenderMixin ], | |
statics: { | |
Content, | |
Slot, | |
visit(nodes, visitor) { | |
React.Children.forEach(nodes, function(node, idx) { | |
if(visitor(node) !== false) { | |
Shade.visit(node.props.children, visitor); | |
} | |
}); | |
} | |
}, | |
childContextTypes: { | |
lightTree: React.PropTypes.object | |
}, | |
getChildContext() { | |
var slots = {}; | |
Shade.visit(this.props.lightTree, (child)=> { | |
if (child.type === Shade || child.type === Slot) { | |
return false; | |
} else if (!child.props.slot) { | |
return; | |
} | |
(slots[child.props.slot] || (slots[child.props.slot] = [])).push(child); | |
return false; | |
}); | |
return { | |
lightTree: slots | |
}; | |
}, | |
render() { | |
return React.Children.only(this.props.children); | |
} | |
}); | |
return Shade; | |
})(React); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment