Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit afadbfae473c8788637066c820fc0921f1d711f5 @tj tj committed Oct 9, 2011
3 .gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+*.sock
4 .npmignore
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
5 History.md
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
7 Makefile
@@ -0,0 +1,7 @@
+
+ui:
+ @rm -fr build
+ @mkdir build
+ @./support/build.js dialog confirmation
+
+.PHONY: ui
29 Readme.md
@@ -0,0 +1,29 @@
+
+# uikit
+
+ JavaScript + CSS UI components
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66 build/ui.css
@@ -0,0 +1,66 @@
+#dialog {
+ position: absolute;
+ left: 50%;
+ top: 150px;
+ max-width: 600px;
+ border: 1px solid #eee;
+ border-bottom-color: #cacaca;
+ -webkit-transition: opacity 300ms, top 300ms;
+ -webkit-border-radius: 3px;
+ -webkit-box-shadow: 0 1px 4px 0 #ddd;
+}
+
+#dialog .content {
+ padding: 10px 20px;
+ min-width: 150px;
+}
+
+#dialog h1 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: normal;
+}
+
+#dialog p {
+ margin: 0;
+ padding: 0;
+ font-size: .8em;
+}
+
+#dialog.hide {
+ opacity: 0;
+ top: -500px;
+}
+
+#dialog .actions button {
+ padding: 0;
+ background: transparent;
+ border: none;
+ outline: none;
+ cursor: pointer;
+}
+
+#dialog .actions button.main {
+ padding: 5px 10px;
+ background: -webkit-linear-gradient(top, #fff 20%, #eee);
+ border: 1px solid #eee;
+ border-bottom-color: #cacaca;
+ -webkit-border-radius: 3px;
+ font-size: .70em;
+ outline: none;
+}
+
+#dialog .actions button.main:hover {
+ background: -webkit-linear-gradient(top, #fff 50%, #eee);
+}
+
+#dialog .actions button.main:active {
+ background: -webkit-linear-gradient(bottom, #fff 20%, #eee);
+}
+.confirmation .actions {
+ border-top: 1px solid #eee;
+ padding: 5px;
+ text-align: right;
+ background: #fafafa;
+ -webkit-box-shadow: inset 0 1px 0 white;
+}
169 build/ui.js
@@ -0,0 +1,169 @@
+
+// dialog component
+
+;(function(html){
+
+ /**
+ * Active dialog.
+ */
+
+ var active;
+
+ /**
+ * Initialize a new `Dialog` dialog.
+ *
+ * Options:
+ *
+ * - `title` dialog title
+ * - `message` a message to display
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ Dialog = function Dialog(options) {
+ options = options || {};
+ this.template = html;
+ this.render(options);
+ if (active) active.hide();
+ active = this;
+ };
+
+ /**
+ * Render with the given `options`.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ Dialog.prototype.render = function(options){
+ var el = this.el = $(this.template);
+ el.find('h1').text(options.title);
+ el.find('p').text(options.message);
+ setTimeout(function(){
+ el.removeClass('hide');
+ }, 0);
+ };
+
+ /**
+ * Show the dialog.
+ *
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+ Dialog.prototype.show = function(){
+ this.el.appendTo('body');
+ this.el.css({ marginLeft: -(this.el.width() / 2) + 'px' });
+ return this;
+ };
+
+ /**
+ * Hide the dialog with optional delay of `ms`,
+ * otherwise the dialog is removed immediately.
+ *
+ * @return {Number} ms
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+ Dialog.prototype.hide = function(ms){
+ var self = this;
+
+ // duration
+ if (ms) {
+ setTimeout(function(){
+ self.hide();
+ }, ms);
+ return this;
+ }
+
+ // hide / remove
+ this.el.addClass('hide');
+ setTimeout(function(self){
+ self.close();
+ }, 2000, this);
+
+ return this;
+ };
+
+ /**
+ * Hide the dialog without potential animation.
+ *
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+ Dialog.prototype.close = function(){
+ this.el.remove();
+ return this;
+ };
+
+})("<div id=\"dialog\" class=\"hide\">\n <div class=\"content\">\n <h1>Title</h1>\n <p>Message</p>\n </div>\n</div>");
+// confirmation component
+
+;(function(html){
+
+ /**
+ * Initialize a new `Confirmation` dialog.
+ *
+ * Options:
+ *
+ * - `title` dialog title
+ * - `message` a message to display
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ Confirmation = function Confirmation(options) {
+ Dialog.call(this, options);
+ };
+
+ /**
+ * Inherit from `Dialog.prototype`.
+ */
+
+ Confirmation.prototype = new Dialog;
+
+ /**
+ * Show the confirmation dialog and invoke `fn(ok)`.
+ *
+ * @param {Function} fn
+ * @return {Confirmation} for chaining
+ * @api public
+ */
+
+ Confirmation.prototype.show = function(fn){
+ Dialog.prototype.show.call(this);
+ this.callback = fn;
+ return this;
+ };
+
+ /**
+ * Render with the given `options`.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ Confirmation.prototype.render = function(options){
+ Dialog.prototype.render.call(this, options);
+ var self = this
+ , actions = $(html);
+
+ this.el.addClass('confirmation');
+ this.el.append(actions);
+
+ actions.find('.cancel').click(function(){
+ self.callback(false);
+ self.hide();
+ });
+
+ actions.find('.ok').click(function(){
+ self.callback(true);
+ self.hide();
+ });
+ };
+
+})("<div class=\"actions\">\n <button class=\"cancel\">Cancel</button>\n <button class=\"ok main\">Ok</button>\n</div>");
2 index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/uikit');
7 lib/components/confirmation/confirmation.css
@@ -0,0 +1,7 @@
+.confirmation .actions {
+ border-top: 1px solid #eee;
+ padding: 5px;
+ text-align: right;
+ background: #fafafa;
+ box-shadow: inset 0 1px 0 white;
+}
4 lib/components/confirmation/confirmation.html
@@ -0,0 +1,4 @@
+<div class="actions">
+ <button class="cancel">Cancel</button>
+ <button class="ok main">Ok</button>
+</div>
62 lib/components/confirmation/confirmation.js
@@ -0,0 +1,62 @@
+
+/**
+ * Initialize a new `Confirmation` dialog.
+ *
+ * Options:
+ *
+ * - `title` dialog title
+ * - `message` a message to display
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+Confirmation = function Confirmation(options) {
+ Dialog.call(this, options);
+};
+
+/**
+ * Inherit from `Dialog.prototype`.
+ */
+
+Confirmation.prototype = new Dialog;
+
+/**
+ * Show the confirmation dialog and invoke `fn(ok)`.
+ *
+ * @param {Function} fn
+ * @return {Confirmation} for chaining
+ * @api public
+ */
+
+Confirmation.prototype.show = function(fn){
+ Dialog.prototype.show.call(this);
+ this.callback = fn;
+ return this;
+};
+
+/**
+ * Render with the given `options`.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+Confirmation.prototype.render = function(options){
+ Dialog.prototype.render.call(this, options);
+ var self = this
+ , actions = $(html);
+
+ this.el.addClass('confirmation');
+ this.el.append(actions);
+
+ actions.find('.cancel').click(function(){
+ self.callback(false);
+ self.hide();
+ });
+
+ actions.find('.ok').click(function(){
+ self.callback(true);
+ self.hide();
+ });
+};
59 lib/components/dialog/dialog.css
@@ -0,0 +1,59 @@
+#dialog {
+ position: absolute;
+ left: 50%;
+ top: 150px;
+ max-width: 600px;
+ border: 1px solid #eee;
+ border-bottom-color: #cacaca;
+ transition: opacity 300ms, top 300ms;
+ border-radius: 3px;
+ box-shadow: 0 1px 4px 0 #ddd;
+}
+
+#dialog .content {
+ padding: 10px 20px;
+ min-width: 150px;
+}
+
+#dialog h1 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: normal;
+}
+
+#dialog p {
+ margin: 0;
+ padding: 0;
+ font-size: .8em;
+}
+
+#dialog.hide {
+ opacity: 0;
+ top: -500px;
+}
+
+#dialog .actions button {
+ padding: 0;
+ background: transparent;
+ border: none;
+ outline: none;
+ cursor: pointer;
+}
+
+#dialog .actions button.main {
+ padding: 5px 10px;
+ background: linear-gradient(top, #fff 20%, #eee);
+ border: 1px solid #eee;
+ border-bottom-color: #cacaca;
+ border-radius: 3px;
+ font-size: .70em;
+ outline: none;
+}
+
+#dialog .actions button.main:hover {
+ background: linear-gradient(top, #fff 50%, #eee);
+}
+
+#dialog .actions button.main:active {
+ background: linear-gradient(bottom, #fff 20%, #eee);
+}
6 lib/components/dialog/dialog.html
@@ -0,0 +1,6 @@
+<div id="dialog" class="hide">
+ <div class="content">
+ <h1>Title</h1>
+ <p>Message</p>
+ </div>
+</div>
96 lib/components/dialog/dialog.js
@@ -0,0 +1,96 @@
+
+/**
+ * Active dialog.
+ */
+
+var active;
+
+/**
+ * Initialize a new `Dialog` dialog.
+ *
+ * Options:
+ *
+ * - `title` dialog title
+ * - `message` a message to display
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+Dialog = function Dialog(options) {
+ options = options || {};
+ this.template = html;
+ this.render(options);
+ if (active) active.hide();
+ active = this;
+};
+
+/**
+ * Render with the given `options`.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+Dialog.prototype.render = function(options){
+ var el = this.el = $(this.template);
+ el.find('h1').text(options.title);
+ el.find('p').text(options.message);
+ setTimeout(function(){
+ el.removeClass('hide');
+ }, 0);
+};
+
+/**
+ * Show the dialog.
+ *
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+Dialog.prototype.show = function(){
+ this.el.appendTo('body');
+ this.el.css({ marginLeft: -(this.el.width() / 2) + 'px' });
+ return this;
+};
+
+/**
+ * Hide the dialog with optional delay of `ms`,
+ * otherwise the dialog is removed immediately.
+ *
+ * @return {Number} ms
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+Dialog.prototype.hide = function(ms){
+ var self = this;
+
+ // duration
+ if (ms) {
+ setTimeout(function(){
+ self.hide();
+ }, ms);
+ return this;
+ }
+
+ // hide / remove
+ this.el.addClass('hide');
+ setTimeout(function(self){
+ self.close();
+ }, 2000, this);
+
+ return this;
+};
+
+/**
+ * Hide the dialog without potential animation.
+ *
+ * @return {Dialog} for chaining
+ * @api public
+ */
+
+Dialog.prototype.close = function(){
+ this.el.remove();
+ return this;
+};
10 package.json
@@ -0,0 +1,10 @@
+{
+ "name": "uikit"
+ , "version": "0.0.1"
+ , "description": "JavaScript + CSS UI components"
+ , "keywords": []
+ , "author": "TJ Holowaychuk <tj@vision-media.ca>"
+ , "dependencies": {}
+ , "main": "index"
+ , "engines": { "node": "0.4.x" }
+}
85 support/build.js
@@ -0,0 +1,85 @@
+#!/usr/bin/env node
+
+
+/**
+ * Module dependencies.
+ */
+
+var fs = require('fs')
+ , path = require('path');
+
+// lib dir
+
+var lib = 'lib/components';
+
+// components to build
+
+var components = process.argv.slice(2);
+
+function next(i) {
+ var name = components[i];
+ if (!name) return;
+ build(name, function(){
+ next(++i);
+ });
+}
+
+// build em!
+
+console.log();
+next(0);
+process.on('exit', function(){
+ console.log();
+});
+
+/**
+ * Build the given component.
+ */
+
+function build(name, fn) {
+ var js = path.join(lib, name, name + '.js');
+ read(js, function(js){
+ var html = path.join(lib, name, name + '.html');
+ read(html, function(html){
+ js = '\n// ' + name + ' component\n\n'
+ + ';(function(html){\n'
+ + js.replace(/^/gm, ' ')
+ + '\n})(' + JSON.stringify(html) + ');';
+ append('build/ui.js', js, function(){
+ console.log(' \033[90mbuild \033[36m%s\033[m', name);
+ fn();
+ });
+ });
+ });
+
+ var css = path.join(lib, name, name + '.css');
+ read(css, function(css){
+ css = css
+ .replace(/transition/g, '-webkit-transition')
+ .replace(/box-shadow/g, '-webkit-box-shadow')
+ .replace(/border-radius/g, '-webkit-border-radius')
+ .replace(/linear-gradient/g, '-webkit-linear-gradient');
+ append('build/ui.css', css);
+ });
+}
+
+/**
+ * Append to `file`.
+ */
+
+function append(file, str, fn) {
+ fs.createWriteStream(file, { flags: 'a' })
+ .write(str);
+ fn && fn();
+}
+
+/**
+ * Read the given `file`.
+ */
+
+function read(file, fn) {
+ fs.readFile(file, 'utf8', function(err, str){
+ if (err) throw err;
+ fn(str);
+ });
+}
50 test/index.html
@@ -0,0 +1,50 @@
+<html>
+ <head>
+ <title>UIKit</title>
+ <script src="jquery.js"></script>
+ <script src="../build/ui.js"></script>
+ <link rel="stylesheet" href="../build/ui.css">
+ <script>
+ $(function(){
+ $('li:nth-child(1) a').click(function(){
+ var dialog = new Dialog({
+ title: 'Title'
+ , message: 'This is a dialog!'
+ });
+
+ dialog.show().hide(2000);
+ return false;
+ });
+
+ $('li:nth-child(2) a').click(function(){
+ var confirm = new Confirmation({
+ title: 'Delete user'
+ , message: 'Are you sure?'
+ });
+
+ confirm.show(function(ok){
+ if (ok) {
+ new Dialog({
+ title: 'User deleted'
+ , message: 'The user was successfully removed.'
+ }).show().hide(2000);
+ }
+ });
+ return false;
+ });
+ });
+ </script>
+ <style>
+ body {
+ padding: 50px 30px;
+ font: 14px/1.6 "Helvetica Neue", Helvetica, arial, sans-serif;
+ }
+ </style>
+ </head>
+ <body>
+ <ul>
+ <li><a href="#">Dialog</a></li>
+ <li><a href="#">Confirmation</a></li>
+ </ul>
+ </body>
+</html>
8,981 test/jquery.js
8,981 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.

0 comments on commit afadbfa

Please sign in to comment.