Skip to content

Instantly share code, notes, and snippets.

@nhusher
Last active March 26, 2017 04:40
Show Gist options
  • Save nhusher/1d2e33e427b3d24d45fb to your computer and use it in GitHub Desktop.
Save nhusher/1d2e33e427b3d24d45fb to your computer and use it in GitHub Desktop.
Rendering the CC7 header in React
var React = require('react'),
utils = require('../util/react-dom-utils'),
html = utils.html,
make = utils.make;
var Chevron = make(function (p) {
var points = [
"M13.0490629,0.160143149",
"C13.2439546,-0.0533810496",
"13.6018161,-0.0533810496",
"13.8303098,0.160143149",
"C14.0565634,0.342714208",
"14.0565634,0.678477076",
"13.8303098,0.891476645",
"L7.3899234,6.86228476",
"C7.1950317,7.04590508",
"6.83773026,7.04590508",
"6.60979659,6.86228476",
"L0.170530232,0.891476645",
"C-0.0568434106,0.678477076",
"-0.0568434106,0.342714208",
"0.170530232,0.160143149",
"C0.398463908,-0.0533810496",
"0.755765346,-0.0533810496",
"0.983138988,0.160143149",
"L7.00070004,5.58323809",
"L13.0490629,0.160143149",
"Z" ];
return html(
[ 'svg.nav-menu-chevron',
{
width: '14px',
height: '7px',
pointerEvents: 'none',
version: "1.1",
viewBox: "0 0 14 7",
xmlns: "http://www.w3.org/2000/svg"
},
[ 'path', { d: points.join(' '), fill: '#ffffff' } ]
]);
});
var Header = make(function (p) {
return html(
[ 'div#navigation-block.application-container',
[ 'div.min_width_container',
[ 'div#branding-bar',
[ Logo, { locale: p.locale } ],
[ BrandingMenu, { brandingItems: p.brandingItems } ],
[ UserName, { displayName: p.displayName } ] ],
[ 'div#menu-bar',
[ AppMenu, { apps: p.apps, appName: p.appName } ],
[ MainMenu, { menu: p.menu } ]
]
]
]);
});
var Logo = make(function (p) {
return html([ 'div#logo', { className: p.locale } ]);
});
var BrandingMenu = make(function (p) {
return html(
[ 'ul#branding-list' ].concat(
[ [ 'li.branding-divider' ] ], // This is kinda ugly
p.brandingItems.map(function (it) {
return [ BrandingItem, it ];
})));
});
var BrandingItem = make(function (p) {
return html(
[ 'li.branding-item',
[ 'div.branding-link',
[ 'a',
{
target: p.target,
title: p.title,
href: p.href
},
p.title
]
]
]);
});
var UserName = make(function (p) {
return html(
[ 'div.user-name',
[ 'span.user-name-text',
[ 'a', { title: p.displayName }, p.displayName ]
]
]);
});
var AppMenu = make(function (p) {
return html(
[ 'div#application-menu',
[ 'div.expandable',
[ 'a#app-switcher-link',
{ href: 'javascript:void 0;' },
[ 'h2.application-name',
p.appName,
Chevron ] ],
[ 'ul#app-sub-menu.applications.sub-menu',
[ 'li.applications-section',
[ 'ul' ].concat(
p.apps.map(function (app) {
return [
'li.application',
[ 'a',
{
href: app.uri,
id: app.id,
className: app.className
},
app.title ] ];
}),
[ [ 'li.spacer' ] ])
]
]
]
]);
});
var MainMenu = make(function (p) {
return html(
[ 'div#main-menu',
[ 'ul.expanded-menu' ].concat(
p.menu.map(function(item) {
return [ MenuItem, item ]
})
)]);
});
var MenuItem = make(function (p) {
return html([
'li.menu-item',
{ className: p.children && p.children.length ? 'expandable' : '' },
[ 'a.parent-nav-item',
p.title,
Chevron ],
[ 'ul.sub-menu nav-item-sub-menu' ].concat(
p.children.map(function(c) {
return [
'li.sub-menu-item',
[ 'a', { href: c.uri }, c.title ]
];
}))
]);
});
var MyHeader = React.createFactory(Header);
console.log(React.renderToStaticMarkup(MyHeader({
locale: 'en_US',
displayName: "Nick Husher",
apps: [ {
uri: '/foo',
id: 'foo',
className: 'foo',
title: 'Foo App'
} ],
menu: [{
uri: '/something',
title: 'Something',
children: [{
uri: '/sub-something',
title: 'Sub Something'
}]
}],
appName: 'Inventory',
brandingItems: [ {
target: '_blank',
title: 'Privacy',
href: 'http://example.com'
}, {
title: 'Switch Account',
href: '#'
}, {
title: 'Log Out',
href: '/inventory/logout'
} ]
})));
var React = require('react'),
DOM = React.DOM,
NORMALIZE_REG = /([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?/;
function html(node) {
if(!Array.isArray(node)) {
throw new ReferenceError("Expected array argument to html fn");
}
if(typeof node[0] === 'function') {
return component(node)
}
var normalized = normalize(node[0]),
domFn = DOM[normalized.tag],
classList = normalized.classList,
id = normalized.id,
hasArgs = (typeof node[1] === 'object' && !Array.isArray(node[1])),
args = hasArgs ? node[1] : {},
parameters = node.slice(hasArgs ? 2 : 1).map(function(item) {
if(Array.isArray(item)) {
return html(item);
} else if(typeof item === 'string') {
return item;
} else if(typeof item === 'function') {
return component([ item ]);
}
});
if(!domFn) {
console.log(node);
throw new ReferenceError("React DOM function [" + normalized.tag + "] not found");
}
if(args.className && classList) {
classList = args.className.split(' ').concat(classList);
args.className = Object.keys(classList.reduce(function(acc, i) {
acc[i] = true;
return acc;
}, {})).join(' ');
} else if(classList) {
args.className = classList.join(' ');
}
args.id = args.id || id;
parameters.unshift(args);
return domFn.apply(DOM, parameters);
}
function normalize(nodeString) {
var parsed = NORMALIZE_REG.exec(nodeString),
tag = parsed[1],
id = parsed[2],
classes = parsed[3] ? parsed[3].split('.') : null;
return { tag: tag, id: id, classList: classes };
}
function component(node) {
return React.createElement.apply(React, node);
}
function make(renderDef) {
return React.createClass({
render: function () {
var args = [].slice.call(arguments);
return renderDef.apply(this, [ this.props ].concat(args));
}
});
}
exports.html = html;
exports.make = make;
<div class="application-container" id="navigation-block">
<div class="min_width_container">
<div id="branding-bar">
<div class="en_US" id="logo"></div>
<ul id="branding-list">
<li class="branding-divider"></li>
<li class="branding-item">
<div class="branding-link"><a target="_blank" title="Privacy" href="http://example.com">Privacy</a>
</div>
</li>
<li class="branding-item">
<div class="branding-link"><a title="Switch Account" href="#">Switch Account</a></div>
</li>
<li class="branding-item">
<div class="branding-link"><a title="Log Out" href="/inventory/logout">Log Out</a></div>
</li>
</ul>
<div class="user-name"><span class="user-name-text"><a title="Nick Husher">Nick Husher</a></span></div>
</div>
<div id="menu-bar">
<div id="application-menu">
<div class="expandable"><a href="javascript:void 0;" id="app-switcher-link">
<h2 class="application-name">Inventory
<svg width="14px" height="7px" version="1.1" viewBox="0 0 14 7" class="nav-menu-chevron">
<path
d="M13.0490629,0.160143149 C13.2439546,-0.0533810496 13.6018161,-0.0533810496 13.8303098,0.160143149 C14.0565634,0.342714208 14.0565634,0.678477076 13.8303098,0.891476645 L7.3899234,6.86228476 C7.1950317,7.04590508 6.83773026,7.04590508 6.60979659,6.86228476 L0.170530232,0.891476645 C-0.0568434106,0.678477076 -0.0568434106,0.342714208 0.170530232,0.160143149 C0.398463908,-0.0533810496 0.755765346,-0.0533810496 0.983138988,0.160143149 L7.00070004,5.58323809 L13.0490629,0.160143149 Z"
fill="#ffffff"></path>
</svg>
</h2>
</a>
<ul class="applications sub-menu" id="app-sub-menu">
<li class="applications-section">
<ul>
<li class="application"><a href="/foo" id="foo" class="foo">Foo App</a></li>
<li class="spacer"></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="main-menu">
<ul class="expanded-menu">
<li class="expandable menu-item"><a class="parent-nav-item">Something
<svg width="14px" height="7px" version="1.1" viewBox="0 0 14 7" class="nav-menu-chevron">
<path
d="M13.0490629,0.160143149 C13.2439546,-0.0533810496 13.6018161,-0.0533810496 13.8303098,0.160143149 C14.0565634,0.342714208 14.0565634,0.678477076 13.8303098,0.891476645 L7.3899234,6.86228476 C7.1950317,7.04590508 6.83773026,7.04590508 6.60979659,6.86228476 L0.170530232,0.891476645 C-0.0568434106,0.678477076 -0.0568434106,0.342714208 0.170530232,0.160143149 C0.398463908,-0.0533810496 0.755765346,-0.0533810496 0.983138988,0.160143149 L7.00070004,5.58323809 L13.0490629,0.160143149 Z"
fill="#ffffff"></path>
</svg>
</a>
<ul class="sub-menu">
<li class="sub-menu-item"><a href="/sub-something">Sub Something</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment