Building a date picker component
First install component(1) with npm:
$ npm install -g component
Or if you don’t have node installed at all, on OSX execute:
$ (cd /usr/local && \
curl -L# http://nodejs.org/dist/v0.8.15/node-v0.8.15-darwin-x86.tar.gz \
| tar -zx --strip 1) \
&& npm install -g component \
&& printf "installed component(1) %s\n" $(component --version)
Next you’ll need to bootstrap a new component, you can do this manually or use the quick component-create(1) command:
$ component create datepicker
repo (username/project): component/datepicker
description: Datepicker ui component built on component/calendar
does this component have js? y
does this component have css? y
does this component have html?
create : datepicker
create : datepicker/index.js
create : datepicker/datepicker.css
create : datepicker/Makefile
create : datepicker/Readme.md
create : datepicker/History.md
create : datepicker/.gitignore
create : datepicker/component.json
Adding dependencies
Next cd into the new directory and install the component/calendar component as a dependency:
$ component install component/calendar
install : component/calendar@master
dep : component/range@master
install : component/range@master
dep : component/jquery@master
install : component/jquery@master
dep : component/emitter@master
install : component/emitter@master
sep : component/in-groups-of@master
install : component/in-groups-of@master
fetch : component/calendar:index.js
fetch : component/calendar:lib/utils.js
fetch : component/calendar:lib/template.js
fetch : component/calendar:lib/calendar.js
fetch : component/calendar:lib/days.js
fetch : component/calendar:lib/calendar.css
fetch : component/range:index.js
fetch : component/jquery:index.js
fetch : component/in-groups-of:index.js
fetch : component/emitter:index.js
complete : component/range
complete : component/in-groups-of
complete : component/emitter
complete : component/jquery
complete : component/calendar
If you cat the component.json file you’ll see that component-install(1) has added the dependency for us:
cat component.json
{
"name": "datepicker",
"repo": "component/datepicker",
"description": "Datepicker ui component built on component/calendar",
"version": "0.0.1",
"keywords": [],
"dependencies": {
"component/calendar": "*"
},
"development": {},
"license": "MIT",
"scripts": [
"index.js"
],
"styles": [
"datepicker.css"
]
Creating the component
Like any other software it’s good to have a suite of tests, or at very least a functioning demo for developers and end-users. In this case we’ll just create example.html to test drive the date picker, create the file and add the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Datepicker</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="build/build.css">
<script src="build/build.js"></script>
</head>
<body>
<input type="text" name="date" placeholder="Choose a date">
<script>
var picker = require('datepicker');
var el = document.querySelector('[name=date]');
picker(el);
</script>
</body>
</html>
Our date picker is going to be pretty simple, we’re going to handle click events for the element passed to picker(), and then display the Calendar in a Popover instance, populating the input when a selection is made.
Before getting started you’ll want to install the popover component, event utility, and the optional “aurora” theme:
$ component install component/popover component/aurora component/event
Or with brace expansion:
$ component install component/{popover,aurora,event}
The following JavaScript snippet is what will go into ./index.js, the main entry-point script of the component. As you can see here the dependencies are explicitly required at the top of the file via the commonjs module system, making it very obvious what this module is interacting with. Next we export a single object, the Datepicker constructor itself which sets up a bit of event handling boilerplate.
var Calendar = require('calendar')
, Popover = require('popover')
, event = require('event')
module.exports = Datepicker;
function Datepicker(el) {
if (!(this instanceof Datepicker)) return new Datepicker(el);
this.el = el;
event.bind(el, 'click', this.onclick.bind(this));
}
Datepicker.prototype.onclick = function(e){
};
NOTE: The use of “event” may seem low-level here, and that’s because it is, the event module is nothing more than a cross-browser event binding utility. These APIs are not designed to be cute, they’re designed to drastically reduce the dependency bloat, by only using what your component needs. “Cute” APIs are provided by higher level components such as the jQuery-like dom component, and are typically recommended for app-level use only
To finish up the JavaScript portion of the Datepicker instantiate a new Calendar in the constructor, and add a classname for styling purposes. Next in the .onclick handler a new Popover is passed the cal element for its content, and a datepicker-popover classname is given here for styling purposes as well, then finally the call to popover.show(this.el) shows the popover relative to the <input> element.
var Calendar = require('calendar')
, Popover = require('popover')
, event = require('event')
module.exports = Datepicker;
function Datepicker(el) {
if (!(this instanceof Datepicker)) return new Datepicker(el);
this.el = el;
this.cal = new Calendar;
this.cal.el.addClass('datepicker-calendar');
event.bind(el, 'click', this.onclick.bind(this));
}
Datepicker.prototype.onclick = function(e){
this.cal.on('change', this.onchange.bind(this));
this.popover = new Popover(this.cal.el);
this.popover.classname = 'datepicker-popover popover';
this.popover.show(this.el);
};
Datepicker.prototype.onchange = function(date){
el.value = date.getFullYear()
+ '/'
+ date.getMonth()
+ '/'
+ date.getDate();
this.popover.hide();
};
Building the component
To build the component invoke the following component-build(1) command:
$ component build
Or simply use make, as the targets are already set up in the Makefile for you:
$ make
A new directory named ./build will now have been created for you with the resulting build.css and build.js files.
To make this process transparent in development I recommend using the watch command that some environments already have, for those that do not have it there’s watch(1). Before working on a component you may now simply watch the make command and chuck that process in the background to get out of your way:
$ watch make &
When you’re done invoke fg to foreground the job again, or kill it with:
$ kill %1
Styling the component
Without custom styling the Aurora calendar / popover themes will look something like the following, not exactly great for a date picker since the calendar already looks self-contained.

Add the following CSS to ./datepicker.css to cancel out the popover border for the datepicker popover only:
.datepicker-calendar {
font: 10px "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.datepicker-popover .tip-arrow {
top: auto;
}
.datepicker-popover .tip-inner {
border: none;
}
Now re-build and you should have the following completed datepicker:

Publishing
To “publish” the component all you need to do is push it to GitHub and then install with component install myname/datepicker! No fighting over names, you can call them whatever you like. To increase discoverability of your component you can then add it to the Wiki component listing and the component-search(1) command will index it.
Get the code for this component at component/datepicker.
For more on components check out the component repo and the Wiki.




