├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── assets
├── screenshot.png
└── screenshot.psd
├── dev
├── app
│ ├── app.html
│ └── app.js
└── public
│ └── index.html
├── dist
├── ngjs-color-picker.js
└── ngjs-color-picker.js.map
├── package.json
├── source
└── ngjs-color-picker.js
├── test
├── directive.spec.js
└── karma.conf.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"]
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # /node_modules/* and /bower_components/* ignored by default
2 |
3 | # Ignore built files except build/index.js
4 | dist/*
5 | dev/*
6 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "angular",
3 | "rules": {
4 | "array-bracket-spacing": [2, "never"],
5 | "camelcase": 2,
6 | "comma-dangle": [2, "never"],
7 | "comma-spacing": [2, { "before": false, "after": true }],
8 | "comma-style": [2, "last"],
9 | "computed-property-spacing": [2, "never"],
10 | "default-case": 2,
11 | "dot-notation": 2,
12 | "eol-last": [2, "always"],
13 | "eqeqeq": [2, "always"],
14 | "func-call-spacing": [2, "never"],
15 | "indent": [2, 4],
16 | "key-spacing": [2, { "beforeColon": false }],
17 | "keyword-spacing": [2, { "before": true }],
18 | "linebreak-style": [2, "unix"],
19 | "max-len": [2, 100],
20 | "no-debugger": 2,
21 | "no-else-return": 2,
22 | "no-extra-semi": 2,
23 | "no-fallthrough": 2,
24 | "no-lonely-if": 2,
25 | "no-multiple-empty-lines": [2, {"max": 2, "maxEOF": 1}],
26 | "no-restricted-globals": [2, "event"],
27 | "no-trailing-spaces": 2,
28 | "no-unreachable": 2,
29 | "no-unused-vars": 2,
30 | "quotes": [2, "single"],
31 | "radix": 2,
32 | "semi": [2, "always"],
33 | "semi-spacing": [2, { "before": false, "after": true }],
34 | "strict": [2, "global"],
35 | "use-isnan": 2
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | bower_components/
3 | .DS_Store
4 | .DS_Store?
5 | ._*
6 | .Spotlight-V100
7 | .Trashes
8 | ehthumbs.db
9 | Thumbs.db
10 | .idea
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | os:
3 | - linux
4 | - windows
5 | node_js:
6 | - "stable"
7 | - "6"
8 | sudo: false
9 | before_script:
10 | - npm install -g jasmine-node codecov istanbul
11 | script:
12 | - npm run lint
13 | - npm run test
14 | - istanbul cover node_modules/jasmine/bin/jasmine.js
15 | - codecov
16 | cache:
17 | directories:
18 | - node_modules
19 | after_success:
20 | - bash <(curl -s https://codecov.io/bash)
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Simon Egersand
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ngjs-color-picker [](https://npmjs.org/package/ngjs-color-picker) [](https://travis-ci.org/simeg/ngjs-color-picker)
2 |
3 | A small directive which essentially is a color picker but with a few extra functions - for AngularJS. Based on [ng-color-picker](https://github.com/joujiahe/ng-color-picker).
4 |
5 | **Requirements**: Angular 1.2+
6 |
7 | 
8 |
9 | # Features
10 | - Customize the appearance of the color picker (vertical, horizontal, columns etc.)
11 | - Generate random colors
12 | - Generate gradient colors
13 |
14 | # Demo
15 | - [Demo](http://simeg.github.io/ngjs-color-picker)
16 | - [Plunker](http://embed.plnkr.co/INXf3efkYeP1gWaF9SId/preview)
17 |
18 | # Installation
19 | ## npm:
20 | ``` bash
21 | npm install --save ngjs-color-picker
22 | ```
23 |
24 | You may have to run
25 |
26 | ``` bash
27 | grunt wiredep
28 | ```
29 |
30 | to make grunt automatically add the needed files to your `index.html`.
31 |
32 | ## Manually:
33 | Clone or [download](https://github.com/simeg/ngjs-color-picker/archive/master.zip) the repository and include the production file in your application.
34 |
35 | ``` html
36 |
37 | ```
38 |
39 | Inject the directive as a dependency in your app:
40 |
41 | ``` javascript
42 | angular.module('myApp', ['ngjsColorPicker']);
43 | ```
44 |
45 | # Usage and documentation
46 | For documentation, examples and usage see the [GitHub page for this repository](http://simeg.github.io/ngjs-color-picker).
47 |
48 | ## Option prioritization
49 | 1. Custom colors
50 | 2. Random colors
51 | 3. Gradient
52 | 4. Default colors
53 |
54 | # Contribute :raised_hands:
55 | Run `npm install` and then you're able to start dev server with
56 | ``` bash
57 | npm run serve
58 | ```
59 |
60 | The server is then available at [http://localhost:8080](http://localhost:8080).
61 |
62 | The file `dev/app/ngjs-color-picker.js` is a symlink to `source/ngjs-color-picker.js`, so you can edit either one of them and the change will be shown on the dev server.
63 |
64 | (Development server environment created using awesome [angular-webpack](https://github.com/preboot/angular-webpack)).
65 |
66 | # TODO
67 | * **See [issues](https://github.com/simeg/ngjs-color-picker/issues)**
68 | * Click (or something) to get the hex-code for the color (rgb should also be available)
69 | * Add reverse option for gradient
70 | * Include color themes (Good palettes: http://jsfiddle.net/nicgirault/bqph3pkL/)
71 | * Add option to select rows instead of columns
72 |
--------------------------------------------------------------------------------
/assets/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simeg/ngjs-color-picker/d98dfe8cc0fd09d8043819ecae3eed20542c8870/assets/screenshot.png
--------------------------------------------------------------------------------
/assets/screenshot.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simeg/ngjs-color-picker/d98dfe8cc0fd09d8043819ecae3eed20542c8870/assets/screenshot.psd
--------------------------------------------------------------------------------
/dev/app/app.html:
--------------------------------------------------------------------------------
1 |
Basic usage example
2 |
3 |
4 |
5 |
6 |
7 | Example with larger size and round corners
8 |
9 |
10 |
11 |
12 |
13 | Example with random colors
14 |
15 |
16 |
17 |
18 |
19 | Example with gradient
20 |
21 |
22 |
23 |
24 |
25 | Example with vertical color picker
26 |
27 |
28 |
29 |
30 |
31 | Example with columns defined
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/dev/app/app.js:
--------------------------------------------------------------------------------
1 | import angular from 'angular';
2 | require('../../source/ngjs-color-picker.js');
3 |
4 | class AppCtrl {
5 | constructor() {
6 |
7 | // Set $scope variables here on _this_
8 | this.customOptions = {
9 | size: 30,
10 | roundCorners: true
11 | };
12 |
13 | this.optionsRandom = {
14 | randomColors: 10
15 | };
16 |
17 | this.optionsGradient = {
18 | start: '#BA693E',
19 | count: 10,
20 | step: 1
21 | };
22 |
23 | this.optionsVertical = {
24 | horizontal: false,
25 | total: 5
26 | };
27 |
28 | this.optionsColumn = {
29 | columns: 4,
30 | roundCorners: true
31 | };
32 | }
33 | }
34 |
35 | /* Angular configuration (no need to touch this) */
36 | let app = () => {
37 | return {
38 | template: require('./app.html'),
39 | controller: 'AppCtrl',
40 | controllerAs: 'app'
41 | }
42 | };
43 |
44 | const MODULE_NAME = 'app';
45 | angular.module(MODULE_NAME, ['ngjsColorPicker'])
46 | .directive('app', app)
47 | .controller('AppCtrl', AppCtrl);
48 |
49 | export default MODULE_NAME;
50 |
--------------------------------------------------------------------------------
/dev/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dev server - ngjs-color-picker
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/dist/ngjs-color-picker.js:
--------------------------------------------------------------------------------
1 | !function(o){function s(n){if(r[n])return r[n].exports;var t=r[n]={exports:{},id:n,loaded:!1};return o[n].call(t.exports,t,t.exports,s),t.loaded=!0,t.exports}var r={};return s.m=o,s.c=r,s.p="/",s(0)}([function(o,s){"use strict";angular.module("ngjsColorPicker",[]).directive("ngjsColorPicker",function(){var o='',s=[{selector:"ul",rules:["padding: 0","outline: none","list-style-type: none"]},{selector:"li",rules:["padding: 0","margin: 0","box-sizing: border-box","outline: none"]},{selector:"li.selectedColor",rules:["border: 1px solid #333"]},{selector:"li.hRDF",rules:["border-radius: 5px 0 0 5px"]},{selector:"li.hRDL",rules:["border-radius: 0 5px 5px 0"]},{selector:"li.vRDF",rules:["border-radius: 5px 5px 0 0"]},{selector:"li.vRDL",rules:["border-radius: 0 0 5px 5px"]},{selector:"li.tlRound",rules:["border-radius: 5px 0 0 0"]},{selector:"li.trRound",rules:["border-radius: 0 5px 0 0;"]},{selector:"li.brRound",rules:["border-radius: 0 0 5px 0;"]},{selector:"li.blRound",rules:["border-radius: 0 0 0 5px;"]}],r=["#7bd148","#5484ed","#a4bdfc","#46d6db","#7ae7bf","#51b749","#fbd75b","#ffb878","#ff887c","#dc2127","#dbadff","#e1e1e1"],n={colors:r,options:{size:20,columns:null,randomColors:null},gradient:null},t=function(o){o.colors=r,o.options=o.options||{},o.options.size=o.options.size||n.options.size,o.options.columns=o.options.columns||n.options.columns,o.options.randomColors=o.options.randomColors||n.options.randomColors,o.options.total=o.options.total||o.colors.length,o.options.horizontal=!o.options.hasOwnProperty("horizontal")||o.options.horizontal,o.options.roundCorners=!!o.options.hasOwnProperty("roundCorners")&&o.options.roundCorners,o.gradient=o.gradient||n.gradient,o.ulCss={},o.css={},o.css.display=o.options.horizontal?"inline-block":"block",o.css.width=o.css.height=o.options.size+"px"},e=function(o){if(o.customColors)o.colors=o.customColors;else if(o.options&&o.options.randomColors){if(o.options.randomColors>0){o.colors=[];for(var s=o.options.randomColors;0!==s;)o.colors.push(p()),s--}}else if(o.gradient){var r=a(o.gradient.start),n=/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(r);if(n){o.colors=[];for(var t=o.gradient.hasOwnProperty("count")?o.gradient.count:10,e=o.gradient.hasOwnProperty("step")?o.gradient.step:1;0!==t;)o.colors.push(f(0===o.colors.length?r:o.colors[o.colors.length-1],e)),e+=o.gradient.step,t--,"#ffffff"!==o.colors[o.colors.length-1].toLowerCase()&&"#000000"!==o.colors[o.colors.length-1]||(t=0)}}},l=function(o){var s=o.css.width.indexOf("p");o.ulCss.width=o.options.columns*parseInt(o.css.width.substr(0,s),10)+"px",o.ulCss.height=o.options.size*(o.colors.length/o.options.columns)+"px",o.css.cssFloat="left";var r=o.colors.length%o.options.columns===0;o.columnRound=r&&o.options.columns&&o.options.roundCorners},i=function(o){o.hzRound=o.options.horizontal&&o.options.roundCorners&&!o.options.columns,o.vertRound=!o.options.horizontal&&o.options.roundCorners&&!o.options.columns},c=function(o){o.selectedColor=o.selectedColor||o.colors[0]},u=function(o,s){var r="ngjs-color-picker";return r+" "+o+" {"+s.join(";")+"}"},d=function(){var o=s.map(function(o){return u(o.selector,o.rules)});angular.element(document).find("head").prepend('")},p=function(){return"#"+(Math.random().toString(16)+"000000").slice(2,8)},a=function(o){var s=+("#"===o.charAt(0));return"#"+o.substr(s).toLowerCase()},f=function(o,s){var r=parseInt(o.slice(1),16),n=Math.round(2.55*s),t=(r>>16)+n,e=(r>>8&255)+n,l=(255&r)+n;return"#"+(16777216+65536*(t<255?t<1?0:t:255)+256*(e<255?e<1?0:e:255)+(l<255?l<1?0:l:255)).toString(16).slice(1)};return{scope:{selectedColor:"=?",customColors:"=?",options:"=?",gradient:"=?"},restrict:"E",template:o,link:function(o){t(o),e(o),c(o),i(o),d(),o.options.columns&&l(o),o.getCss=function(s){return o.css.background=s,o.css},o.pick=function(s){o.selectedColor=s}}}})}]);
2 | //# sourceMappingURL=ngjs-color-picker.js.map
--------------------------------------------------------------------------------
/dist/ngjs-color-picker.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///ngjs-color-picker.js","webpack:///webpack/bootstrap e410ed00d5e1740fb921","webpack:///./source/ngjs-color-picker.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","m","c","p","angular","directive","template","styling","selector","rules","defaultColors","defaultValues","colors","options","size","columns","randomColors","gradient","setInitValues","scope","total","length","horizontal","hasOwnProperty","roundCorners","ulCss","css","display","width","height","setColors","customColors","push","getRandomHexColor","validHex","formatToHex","start","isOkHex","test","count","interval","step","shadeColor","toLowerCase","setColumns","indexOfPx","indexOf","parseInt","substr","cssFloat","isOkColumn","columnRound","setRoundedCorners","hzRound","vertRound","setInitialSelectedColor","selectedColor","getHtmlCssStyle","prefix","join","applyCssToHtml","styles","map","element","document","find","prepend","Math","random","toString","slice","hex","index","charAt","color","percent","num","amt","round","R","G","B","restrict","link","getCss","background","pick"],"mappings":"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","file":"ngjs-color-picker.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tangular.module('ngjsColorPicker', []).directive('ngjsColorPicker', function () {\n\t var template = '';\n\t\n\t var styling = [{\n\t selector: 'ul',\n\t rules: ['padding: 0', 'outline: none', 'list-style-type: none']\n\t }, {\n\t selector: 'li',\n\t rules: ['padding: 0', 'margin: 0', 'box-sizing: border-box', 'outline: none']\n\t }, {\n\t selector: 'li.selectedColor',\n\t rules: ['border: 1px solid #333']\n\t }, {\n\t selector: 'li.hRDF',\n\t rules: ['border-radius: 5px 0 0 5px']\n\t }, {\n\t selector: 'li.hRDL',\n\t rules: ['border-radius: 0 5px 5px 0']\n\t }, {\n\t selector: 'li.vRDF',\n\t rules: ['border-radius: 5px 5px 0 0']\n\t }, {\n\t selector: 'li.vRDL',\n\t rules: ['border-radius: 0 0 5px 5px']\n\t }, {\n\t selector: 'li.tlRound',\n\t rules: ['border-radius: 5px 0 0 0']\n\t }, {\n\t selector: 'li.trRound',\n\t rules: ['border-radius: 0 5px 0 0;']\n\t }, {\n\t selector: 'li.brRound',\n\t rules: ['border-radius: 0 0 5px 0;']\n\t }, {\n\t selector: 'li.blRound',\n\t rules: ['border-radius: 0 0 0 5px;']\n\t }];\n\t\n\t var defaultColors = ['#7bd148', '#5484ed', '#a4bdfc', '#46d6db', '#7ae7bf', '#51b749', '#fbd75b', '#ffb878', '#ff887c', '#dc2127', '#dbadff', '#e1e1e1'];\n\t\n\t var defaultValues = {\n\t colors: defaultColors,\n\t options: {\n\t size: 20,\n\t columns: null,\n\t randomColors: null\n\t },\n\t gradient: null\n\t };\n\t\n\t var setInitValues = function setInitValues(scope) {\n\t scope.colors = defaultColors;\n\t scope.options = scope.options || {};\n\t scope.options.size = scope.options.size || defaultValues.options.size;\n\t scope.options.columns = scope.options.columns || defaultValues.options.columns;\n\t scope.options.randomColors = scope.options.randomColors || defaultValues.options.randomColors;\n\t scope.options.total = scope.options.total || scope.colors.length;\n\t scope.options.horizontal = scope.options.hasOwnProperty('horizontal') ? scope.options.horizontal : true;\n\t scope.options.roundCorners = scope.options.hasOwnProperty('roundCorners') ? scope.options.roundCorners : false;\n\t scope.gradient = scope.gradient || defaultValues.gradient;\n\t\n\t scope.ulCss = {};\n\t scope.css = {};\n\t scope.css.display = scope.options.horizontal ? 'inline-block' : 'block';\n\t scope.css.width = scope.css.height = scope.options.size + 'px';\n\t };\n\t\n\t var setColors = function setColors(scope) {\n\t if (!!scope.customColors) {\n\t scope.colors = scope.customColors;\n\t } else if (scope.options && !!scope.options.randomColors) {\n\t if (scope.options.randomColors > 0) {\n\t scope.colors = [];\n\t var randomColors = scope.options.randomColors;\n\t while (randomColors !== 0) {\n\t scope.colors.push(getRandomHexColor());\n\t randomColors--;\n\t }\n\t } else {\n\t // TODO: Handle this\n\t // Random colors array is empty\n\t }\n\t } else if (!!scope.gradient) {\n\t // If step === 0 => nothing will happen.\n\t // If step === 1 => it will add 3 shades to all\n\t // colors (2.55 shades per 1%, rounded)\n\t var validHex = formatToHex(scope.gradient.start);\n\t var isOkHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(validHex);\n\t if (isOkHex) {\n\t scope.colors = [];\n\t var count = scope.gradient.hasOwnProperty('count') ? scope.gradient.count : 10;\n\t var interval = scope.gradient.hasOwnProperty('step') ? scope.gradient.step : 1;\n\t while (count !== 0) {\n\t scope.colors.push(shadeColor(scope.colors.length === 0 ? validHex : scope.colors[scope.colors.length - 1], interval));\n\t interval += scope.gradient.step;\n\t count--;\n\t\n\t // If black or white - stop generating more colors\n\t if (scope.colors[scope.colors.length - 1].toLowerCase() === '#ffffff' || scope.colors[scope.colors.length - 1] === '#000000') count = 0;\n\t }\n\t } else {\n\t // TODO: Handle this\n\t // Hex is not valid\n\t }\n\t }\n\t };\n\t\n\t var setColumns = function setColumns(scope) {\n\t // Uneven amount of columns => no round corners\n\t // => horizontal or vertical has no effect\n\t var indexOfPx = scope.css.width.indexOf('p');\n\t scope.ulCss.width = scope.options.columns * parseInt(scope.css.width.substr(0, indexOfPx), 10) + 'px';\n\t scope.ulCss.height = scope.options.size * (scope.colors.length / scope.options.columns) + 'px';\n\t scope.css.cssFloat = 'left';\n\t\n\t // Set rounded corners\n\t var isOkColumn = scope.colors.length % scope.options.columns === 0;\n\t scope.columnRound = isOkColumn && scope.options.columns && scope.options.roundCorners;\n\t };\n\t\n\t var setRoundedCorners = function setRoundedCorners(scope) {\n\t scope.hzRound = scope.options.horizontal && scope.options.roundCorners && !scope.options.columns;\n\t scope.vertRound = !scope.options.horizontal && scope.options.roundCorners && !scope.options.columns;\n\t };\n\t\n\t var setInitialSelectedColor = function setInitialSelectedColor(scope) {\n\t scope.selectedColor = scope.selectedColor || scope.colors[0];\n\t };\n\t\n\t var getHtmlCssStyle = function getHtmlCssStyle(selector, rules) {\n\t var prefix = 'ngjs-color-picker';\n\t return prefix + ' ' + selector + ' {' + rules.join(';') + '}';\n\t };\n\t\n\t var applyCssToHtml = function applyCssToHtml() {\n\t var styles = styling.map(function (element) {\n\t return getHtmlCssStyle(element.selector, element.rules);\n\t });\n\t\n\t angular.element(document).find('head').prepend('');\n\t };\n\t\n\t /* Util functions */\n\t var getRandomHexColor = function getRandomHexColor() {\n\t return '#' + (Math.random().toString(16) + '000000').slice(2, 8);\n\t };\n\t\n\t var formatToHex = function formatToHex(hex) {\n\t var index = +(hex.charAt(0) === '#');\n\t return '#' + hex.substr(index).toLowerCase();\n\t };\n\t\n\t var shadeColor = function shadeColor(color, percent) {\n\t var num = parseInt(color.slice(1), 16),\n\t amt = Math.round(2.55 * percent),\n\t R = (num >> 16) + amt,\n\t G = (num >> 8 & 0x00FF) + amt,\n\t B = (num & 0x0000FF) + amt;\n\t return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n\t };\n\t\n\t return {\n\t scope: {\n\t selectedColor: '=?',\n\t customColors: '=?',\n\t options: '=?',\n\t gradient: '=?'\n\t },\n\t restrict: 'E',\n\t template: template,\n\t link: function link(scope) {\n\t // element, attr\n\t\n\t setInitValues(scope);\n\t setColors(scope);\n\t setInitialSelectedColor(scope);\n\t setRoundedCorners(scope);\n\t applyCssToHtml();\n\t\n\t if (!!scope.options.columns) {\n\t setColumns(scope);\n\t }\n\t\n\t scope.getCss = function (color) {\n\t scope.css.background = color;\n\t return scope.css;\n\t };\n\t\n\t scope.pick = function (color) {\n\t scope.selectedColor = color;\n\t };\n\t }\n\t };\n\t});\n\n/***/ }\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// ngjs-color-picker.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap e410ed00d5e1740fb921","'use strict';\n\nangular.module('ngjsColorPicker', [])\n .directive('ngjsColorPicker', function() {\n var template =\n '';\n\n var styling = [\n {\n selector: 'ul',\n rules: [\n 'padding: 0',\n 'outline: none',\n 'list-style-type: none'\n ]\n },\n {\n selector: 'li',\n rules: [\n 'padding: 0',\n 'margin: 0',\n 'box-sizing: border-box',\n 'outline: none'\n ]\n },\n {\n selector: 'li.selectedColor',\n rules: [\n 'border: 1px solid #333'\n ]\n },\n {\n selector: 'li.hRDF',\n rules: [\n 'border-radius: 5px 0 0 5px'\n ]\n },\n {\n selector: 'li.hRDL',\n rules: [\n 'border-radius: 0 5px 5px 0'\n ]\n },\n {\n selector: 'li.vRDF',\n rules: [\n 'border-radius: 5px 5px 0 0'\n ]\n },\n {\n selector: 'li.vRDL',\n rules: [\n 'border-radius: 0 0 5px 5px'\n ]\n },\n {\n selector: 'li.tlRound',\n rules: [\n 'border-radius: 5px 0 0 0'\n ]\n },\n {\n selector: 'li.trRound',\n rules: [\n 'border-radius: 0 5px 0 0;'\n ]\n },\n {\n selector: 'li.brRound',\n rules: [\n 'border-radius: 0 0 5px 0;'\n ]\n },\n {\n selector: 'li.blRound',\n rules: [\n 'border-radius: 0 0 0 5px;'\n ]\n }\n ];\n\n var defaultColors = [\n '#7bd148',\n '#5484ed',\n '#a4bdfc',\n '#46d6db',\n '#7ae7bf',\n '#51b749',\n '#fbd75b',\n '#ffb878',\n '#ff887c',\n '#dc2127',\n '#dbadff',\n '#e1e1e1'\n ];\n\n var defaultValues = {\n colors: defaultColors,\n options: {\n size: 20,\n columns: null,\n randomColors: null\n },\n gradient: null\n };\n\n var setInitValues = function(scope) {\n scope.colors = defaultColors;\n scope.options = scope.options || {};\n scope.options.size = scope.options.size || defaultValues.options.size;\n scope.options.columns = scope.options.columns || defaultValues.options.columns;\n scope.options.randomColors =\n scope.options.randomColors || defaultValues.options.randomColors;\n scope.options.total = scope.options.total || scope.colors.length;\n scope.options.horizontal =\n (scope.options.hasOwnProperty('horizontal') ? scope.options.horizontal : true);\n scope.options.roundCorners =\n (scope.options.hasOwnProperty('roundCorners') ?\n scope.options.roundCorners : false);\n scope.gradient = scope.gradient || defaultValues.gradient;\n\n scope.ulCss = {};\n scope.css = {};\n scope.css.display = (scope.options.horizontal ? 'inline-block' : 'block');\n scope.css.width = scope.css.height = scope.options.size + 'px';\n };\n\n var setColors = function(scope) {\n if (!!scope.customColors) {\n scope.colors = scope.customColors;\n } else if (scope.options && !!scope.options.randomColors) {\n if (scope.options.randomColors > 0) {\n scope.colors = [];\n var randomColors = scope.options.randomColors;\n while (randomColors !== 0) {\n scope.colors.push(getRandomHexColor());\n randomColors--;\n }\n } else {\n // TODO: Handle this\n // Random colors array is empty\n }\n } else if (!!scope.gradient) {\n // If step === 0 => nothing will happen.\n // If step === 1 => it will add 3 shades to all\n // colors (2.55 shades per 1%, rounded)\n var validHex = formatToHex(scope.gradient.start);\n var isOkHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(validHex);\n if (isOkHex) {\n scope.colors = [];\n var count =\n (scope.gradient.hasOwnProperty('count') ? scope.gradient.count : 10);\n var interval =\n (scope.gradient.hasOwnProperty('step') ? scope.gradient.step : 1);\n while (count !== 0) {\n scope.colors.push(shadeColor(scope.colors.length === 0 ?\n validHex : scope.colors[scope.colors.length - 1], interval));\n interval+=scope.gradient.step;\n count--;\n\n // If black or white - stop generating more colors\n if (scope.colors[scope.colors.length - 1].toLowerCase() === '#ffffff' ||\n scope.colors[scope.colors.length - 1] === '#000000')\n count = 0;\n }\n } else {\n // TODO: Handle this\n // Hex is not valid\n }\n }\n };\n\n var setColumns = function(scope) {\n // Uneven amount of columns => no round corners\n // => horizontal or vertical has no effect\n var indexOfPx = scope.css.width.indexOf('p');\n scope.ulCss.width = scope.options.columns *\n (parseInt(scope.css.width.substr(0, indexOfPx), 10)) + 'px';\n scope.ulCss.height =\n scope.options.size * (scope.colors.length / scope.options.columns) + 'px';\n scope.css.cssFloat = 'left';\n\n // Set rounded corners\n var isOkColumn = (scope.colors.length % scope.options.columns) === 0;\n scope.columnRound =\n (isOkColumn && scope.options.columns && scope.options.roundCorners);\n };\n\n var setRoundedCorners = function(scope) {\n scope.hzRound = scope.options.horizontal && scope.options.roundCorners &&\n !scope.options.columns;\n scope.vertRound = !scope.options.horizontal && scope.options.roundCorners &&\n !scope.options.columns;\n };\n\n var setInitialSelectedColor = function(scope) {\n scope.selectedColor = scope.selectedColor || scope.colors[0];\n };\n\n var getHtmlCssStyle = function(selector, rules) {\n var prefix = 'ngjs-color-picker';\n return prefix + ' ' + selector + ' {' + rules.join(';') + '}';\n };\n\n var applyCssToHtml = function() {\n var styles = styling.map(function(element) {\n return getHtmlCssStyle(element.selector, element.rules);\n });\n\n angular.element(document).find('head').prepend(\n '');\n };\n\n /* Util functions */\n var getRandomHexColor = function() {\n return ('#' + (Math.random().toString(16) + '000000').slice(2, 8));\n };\n\n var formatToHex = function(hex) {\n var index = +(hex.charAt(0) === '#');\n return '#' + hex.substr(index).toLowerCase();\n };\n\n var shadeColor = function(color, percent) {\n var num = parseInt(color.slice(1), 16),\n amt = Math.round(2.55 * percent),\n R = (num >> 16) + amt,\n G = (num >> 8 & 0x00FF) + amt,\n B = (num & 0x0000FF) + amt;\n return '#' + (0x1000000 + (R<255?R<1?0:R:255)*0x10000 +\n (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);\n };\n\n return {\n scope: {\n selectedColor: '=?',\n customColors: '=?',\n options: '=?',\n gradient: '=?'\n },\n restrict: 'E',\n template: template,\n link: function(scope) { // element, attr\n\n setInitValues(scope);\n setColors(scope);\n setInitialSelectedColor(scope);\n setRoundedCorners(scope);\n applyCssToHtml();\n\n if (!!scope.options.columns) {\n setColumns(scope);\n }\n\n scope.getCss = function(color) {\n scope.css.background = color;\n return scope.css;\n };\n\n scope.pick = function(color) {\n scope.selectedColor = color;\n };\n\n }\n };\n\n });\n\n\n\n// WEBPACK FOOTER //\n// ./source/ngjs-color-picker.js"],"sourceRoot":""}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngjs-color-picker",
3 | "version": "1.1.2",
4 | "description": "A color picker with a few extra functions - for AngularJS",
5 | "main": "dist/ngjs-color-picker.js",
6 | "files": [
7 | "dist",
8 | "!dist/index.html"
9 | ],
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/simeg/ngjs-color-picker.git"
13 | },
14 | "keywords": [
15 | "colors",
16 | "color",
17 | "picker",
18 | "color-picker",
19 | "gradient",
20 | "angularjs",
21 | "directive"
22 | ],
23 | "author": "Simon Egersand ",
24 | "license": "MIT",
25 | "bugs": {
26 | "url": "https://github.com/simeg/ngjs-color-picker/issues"
27 | },
28 | "homepage": "https://github.com/simeg/ngjs-color-picker",
29 | "dependencies": {
30 | "angular": "^1.2"
31 | },
32 | "devDependencies": {
33 | "angular-mocks": "^1.5.8",
34 | "babel-core": "^6.2.1",
35 | "babel-loader": "^7.1.1",
36 | "babel-preset-es2015": "^6.1.18",
37 | "copy-webpack-plugin": "^4.0.1",
38 | "eslint": "^4.3.0",
39 | "eslint-config-angular": "^0.5.0",
40 | "eslint-plugin-angular": "^3.0.0",
41 | "extract-text-webpack-plugin": "^3.0.0",
42 | "file-loader": "^0.11.2",
43 | "html-webpack-plugin": "^2.7.1",
44 | "istanbul": "^0.4.5",
45 | "jasmine": "^2.5.2",
46 | "jasmine-core": "^2.5.2",
47 | "jasmine-node": "^1.14.5",
48 | "karma": "^1.3.0",
49 | "karma-jasmine": "^1.0.2",
50 | "karma-jasmine-jquery": "^0.1.1",
51 | "karma-mocha-reporter": "^2.2.0",
52 | "karma-phantomjs-launcher": "^1.0.2",
53 | "null-loader": "^0.1.1",
54 | "phantomjs-prebuilt": "^2.1.13",
55 | "postcss-loader": "^2.0.6",
56 | "raw-loader": "^0.5.1",
57 | "rimraf": "^2.5.1",
58 | "style-loader": "^0.18.2",
59 | "webpack": "^3.4.1",
60 | "webpack-dev-server": "^2.6.1",
61 | "webpack-node-externals": "^1.5.4"
62 | },
63 | "scripts": {
64 | "build": "rimraf dist && webpack --bail --progress --profile",
65 | "commit": "npm run pre-commit",
66 | "lint": "./node_modules/eslint/bin/eslint.js .eslintrc.yml './**/*.js'",
67 | "pre-commit": "npm run lint && npm run test",
68 | "serve": "webpack-dev-server --history-api-fallback --inline --progress",
69 | "test": "./node_modules/karma/bin/karma start ./test/karma.conf.js --single-run",
70 | "test:watch": "./node_modules/karma/bin/karma start ./test/karma.conf.js"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/source/ngjs-color-picker.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('ngjsColorPicker', [])
4 | .directive('ngjsColorPicker', function() {
5 | var template =
6 | '';
24 |
25 | var styling = [
26 | {
27 | selector: 'ul',
28 | rules: [
29 | 'padding: 0',
30 | 'outline: none',
31 | 'list-style-type: none'
32 | ]
33 | },
34 | {
35 | selector: 'li',
36 | rules: [
37 | 'padding: 0',
38 | 'margin: 0',
39 | 'box-sizing: border-box',
40 | 'outline: none'
41 | ]
42 | },
43 | {
44 | selector: 'li.selectedColor',
45 | rules: [
46 | 'border: 1px solid #333'
47 | ]
48 | },
49 | {
50 | selector: 'li.hRDF',
51 | rules: [
52 | 'border-radius: 5px 0 0 5px'
53 | ]
54 | },
55 | {
56 | selector: 'li.hRDL',
57 | rules: [
58 | 'border-radius: 0 5px 5px 0'
59 | ]
60 | },
61 | {
62 | selector: 'li.vRDF',
63 | rules: [
64 | 'border-radius: 5px 5px 0 0'
65 | ]
66 | },
67 | {
68 | selector: 'li.vRDL',
69 | rules: [
70 | 'border-radius: 0 0 5px 5px'
71 | ]
72 | },
73 | {
74 | selector: 'li.tlRound',
75 | rules: [
76 | 'border-radius: 5px 0 0 0'
77 | ]
78 | },
79 | {
80 | selector: 'li.trRound',
81 | rules: [
82 | 'border-radius: 0 5px 0 0;'
83 | ]
84 | },
85 | {
86 | selector: 'li.brRound',
87 | rules: [
88 | 'border-radius: 0 0 5px 0;'
89 | ]
90 | },
91 | {
92 | selector: 'li.blRound',
93 | rules: [
94 | 'border-radius: 0 0 0 5px;'
95 | ]
96 | }
97 | ];
98 |
99 | var defaultColors = [
100 | '#7bd148',
101 | '#5484ed',
102 | '#a4bdfc',
103 | '#46d6db',
104 | '#7ae7bf',
105 | '#51b749',
106 | '#fbd75b',
107 | '#ffb878',
108 | '#ff887c',
109 | '#dc2127',
110 | '#dbadff',
111 | '#e1e1e1'
112 | ];
113 |
114 | var defaultValues = {
115 | colors: defaultColors,
116 | options: {
117 | size: 20,
118 | columns: null,
119 | randomColors: null
120 | },
121 | gradient: null
122 | };
123 |
124 | var setInitValues = function(scope) {
125 | scope.colors = defaultColors;
126 | scope.options = scope.options || {};
127 | scope.options.size = scope.options.size || defaultValues.options.size;
128 | scope.options.columns = scope.options.columns || defaultValues.options.columns;
129 | scope.options.randomColors =
130 | scope.options.randomColors || defaultValues.options.randomColors;
131 | scope.options.total = scope.options.total || scope.colors.length;
132 | scope.options.horizontal =
133 | (scope.options.hasOwnProperty('horizontal') ? scope.options.horizontal : true);
134 | scope.options.roundCorners =
135 | (scope.options.hasOwnProperty('roundCorners') ?
136 | scope.options.roundCorners : false);
137 | scope.gradient = scope.gradient || defaultValues.gradient;
138 |
139 | scope.ulCss = {};
140 | scope.css = {};
141 | scope.css.display = (scope.options.horizontal ? 'inline-block' : 'block');
142 | scope.css.width = scope.css.height = scope.options.size + 'px';
143 | };
144 |
145 | var setColors = function(scope) {
146 | if (!!scope.customColors) {
147 | scope.colors = scope.customColors;
148 | } else if (scope.options && !!scope.options.randomColors) {
149 | if (scope.options.randomColors > 0) {
150 | scope.colors = [];
151 | var randomColors = scope.options.randomColors;
152 | while (randomColors !== 0) {
153 | scope.colors.push(getRandomHexColor());
154 | randomColors--;
155 | }
156 | } else {
157 | // TODO: Handle this
158 | // Random colors array is empty
159 | }
160 | } else if (!!scope.gradient) {
161 | // If step === 0 => nothing will happen.
162 | // If step === 1 => it will add 3 shades to all
163 | // colors (2.55 shades per 1%, rounded)
164 | var validHex = formatToHex(scope.gradient.start);
165 | var isOkHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(validHex);
166 | if (isOkHex) {
167 | scope.colors = [];
168 | var count =
169 | (scope.gradient.hasOwnProperty('count') ? scope.gradient.count : 10);
170 | var interval =
171 | (scope.gradient.hasOwnProperty('step') ? scope.gradient.step : 1);
172 | while (count !== 0) {
173 | scope.colors.push(shadeColor(scope.colors.length === 0 ?
174 | validHex : scope.colors[scope.colors.length - 1], interval));
175 | interval+=scope.gradient.step;
176 | count--;
177 |
178 | // If black or white - stop generating more colors
179 | if (scope.colors[scope.colors.length - 1].toLowerCase() === '#ffffff' ||
180 | scope.colors[scope.colors.length - 1] === '#000000')
181 | count = 0;
182 | }
183 | } else {
184 | // TODO: Handle this
185 | // Hex is not valid
186 | }
187 | }
188 | };
189 |
190 | var setColumns = function(scope) {
191 | // Uneven amount of columns => no round corners
192 | // => horizontal or vertical has no effect
193 | var indexOfPx = scope.css.width.indexOf('p');
194 | scope.ulCss.width = scope.options.columns *
195 | (parseInt(scope.css.width.substr(0, indexOfPx), 10)) + 'px';
196 | scope.ulCss.height =
197 | scope.options.size * (scope.colors.length / scope.options.columns) + 'px';
198 | scope.css.cssFloat = 'left';
199 |
200 | // Set rounded corners
201 | var isOkColumn = (scope.colors.length % scope.options.columns) === 0;
202 | scope.columnRound =
203 | (isOkColumn && scope.options.columns && scope.options.roundCorners);
204 | };
205 |
206 | var setRoundedCorners = function(scope) {
207 | scope.hzRound = scope.options.horizontal && scope.options.roundCorners &&
208 | !scope.options.columns;
209 | scope.vertRound = !scope.options.horizontal && scope.options.roundCorners &&
210 | !scope.options.columns;
211 | };
212 |
213 | var setInitialSelectedColor = function(scope) {
214 | scope.selectedColor = scope.selectedColor || scope.colors[0];
215 | };
216 |
217 | var getHtmlCssStyle = function(selector, rules) {
218 | var prefix = 'ngjs-color-picker';
219 | return prefix + ' ' + selector + ' {' + rules.join(';') + '}';
220 | };
221 |
222 | var applyCssToHtml = function() {
223 | var styles = styling.map(function(element) {
224 | return getHtmlCssStyle(element.selector, element.rules);
225 | });
226 |
227 | angular.element(document).find('head').prepend(
228 | '');
229 | };
230 |
231 | /* Util functions */
232 | var getRandomHexColor = function() {
233 | return ('#' + (Math.random().toString(16) + '000000').slice(2, 8));
234 | };
235 |
236 | var formatToHex = function(hex) {
237 | var index = +(hex.charAt(0) === '#');
238 | return '#' + hex.substr(index).toLowerCase();
239 | };
240 |
241 | var shadeColor = function(color, percent) {
242 | var num = parseInt(color.slice(1), 16),
243 | amt = Math.round(2.55 * percent),
244 | R = (num >> 16) + amt,
245 | G = (num >> 8 & 0x00FF) + amt,
246 | B = (num & 0x0000FF) + amt;
247 | return '#' + (0x1000000 + (R<255?R<1?0:R:255)*0x10000 +
248 | (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);
249 | };
250 |
251 | return {
252 | scope: {
253 | selectedColor: '=?',
254 | customColors: '=?',
255 | options: '=?',
256 | gradient: '=?'
257 | },
258 | restrict: 'E',
259 | template: template,
260 | link: function(scope) { // element, attr
261 |
262 | setInitValues(scope);
263 | setColors(scope);
264 | setInitialSelectedColor(scope);
265 | setRoundedCorners(scope);
266 | applyCssToHtml();
267 |
268 | if (!!scope.options.columns) {
269 | setColumns(scope);
270 | }
271 |
272 | scope.getCss = function(color) {
273 | scope.css.background = color;
274 | return scope.css;
275 | };
276 |
277 | scope.pick = function(color) {
278 | scope.selectedColor = color;
279 | };
280 |
281 | }
282 | };
283 |
284 | });
285 |
--------------------------------------------------------------------------------
/test/directive.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('ngjs-color-picker', function() {
4 | var $compile, $rootScope;
5 |
6 | beforeEach(module('ngjsColorPicker'));
7 |
8 | beforeEach(inject(function(_$compile_, _$rootScope_) {
9 | $compile = _$compile_;
10 | $rootScope = _$rootScope_;
11 | }));
12 |
13 | it('changes selected color on click', function() {
14 | var element = $compile('')($rootScope);
15 | $rootScope.$digest();
16 | var content = element.contents();
17 |
18 | var listItems = content.find('li');
19 | var firstListItem = listItems[0];
20 | var secondListItem = listItems[1];
21 | expect(firstListItem.outerHTML).toContain('class="ng-scope selectedColor"');
22 | secondListItem.click();
23 | expect(firstListItem.outerHTML).not.toContain('class="ng-scope selectedColor"');
24 | expect(secondListItem.outerHTML).toContain('class="ng-scope selectedColor"');
25 | });
26 |
27 | describe('without custom options', function() {
28 | var element, content;
29 | beforeEach(function() {
30 | element = $compile('')($rootScope);
31 | // angular.element(document).find('body').append(element);
32 | $rootScope.$digest();
33 | content = element.contents();
34 | });
35 |
36 | it('has default scope variables set', function() {
37 | var defaultOptions = {
38 | size: 20,
39 | columns: null,
40 | randomColors: null,
41 | total: 12,
42 | horizontal: true,
43 | roundCorners: false
44 | };
45 | expect(element.isolateScope().options).toEqual(defaultOptions);
46 | var defaultColors = [
47 | '#7bd148',
48 | '#5484ed',
49 | '#a4bdfc',
50 | '#46d6db',
51 | '#7ae7bf',
52 | '#51b749',
53 | '#fbd75b',
54 | '#ffb878',
55 | '#ff887c',
56 | '#dc2127',
57 | '#dbadff',
58 | '#e1e1e1'
59 | ];
60 | expect(element.isolateScope().colors).toEqual(defaultColors);
61 | });
62 |
63 | describe('renders', function() {
64 | it('list container element', function() {
65 | var listElement = element.find('ul');
66 | expect(listElement.length).toBe(1);
67 | });
68 |
69 | it('correct amount of color boxes', function() {
70 | var listItems = content.find('li');
71 | expect(listItems.length).toBe(12);
72 | });
73 |
74 | it('one selected color box', function() {
75 | var selectedItem = content.find('li.selectedColor');
76 | expect(selectedItem.length).toBe(1);
77 | });
78 |
79 | it('first color box as selected', function() {
80 | var listItems = content.find('li');
81 | var firstListItem = listItems[0];
82 | expect(firstListItem.outerHTML).toContain('class="ng-scope selectedColor"');
83 | });
84 |
85 | it('with default width and height', function() {
86 | var defaultWidth = '20px';
87 | var defaultHeight = '20px';
88 | var listItems = content.find('li');
89 | var listElement = listItems[0];
90 | expect(listElement.style.width).toEqual(defaultWidth);
91 | expect(listElement.style.height).toEqual(defaultHeight);
92 | });
93 |
94 | it('in horizontal mode', function() {
95 | var listItems = content.find('li');
96 | var blockElements = listItems.filter(function (index, item) {
97 | return item.style.display === 'block';
98 | });
99 | expect(blockElements.length).toEqual(0);
100 | });
101 |
102 | it('with default colors', function() {
103 | var defaultColors = [
104 | 'rgb(123, 209, 72)',
105 | 'rgb(84, 132, 237)',
106 | 'rgb(164, 189, 252)',
107 | 'rgb(70, 214, 219)',
108 | 'rgb(122, 231, 191)',
109 | 'rgb(81, 183, 73)',
110 | 'rgb(251, 215, 91)',
111 | 'rgb(255, 184, 120)',
112 | 'rgb(255, 136, 124)',
113 | 'rgb(220, 33, 39)',
114 | 'rgb(219, 173, 255)',
115 | 'rgb(225, 225, 225)'
116 | ];
117 | var listItems = content.find('li');
118 | var matches = listItems.filter(function (index, item) {
119 | return item.style.backgroundColor === defaultColors[index];
120 | });
121 | expect(matches.length).toEqual(listItems.length);
122 | });
123 | });
124 | });
125 |
126 | describe('with single custom option', function() {
127 | it('adds provided option to scope', function() {
128 | var $scope = $rootScope.$new();
129 | $scope.options = {
130 | customOption: 'shouldExist'
131 | };
132 | var element = $compile(
133 | '')($scope);
134 | expect(element.isolateScope().options.hasOwnProperty('customOption')).toEqual(true);
135 | expect(element.isolateScope().options.customOption).toEqual('shouldExist');
136 | });
137 |
138 | describe('(customColors)', function() {
139 | var element, content, customColors;
140 | beforeEach(function() {
141 | customColors = [
142 | 'rgb(27, 209, 72)',
143 | 'rgb(20, 132, 237)',
144 | 'rgb(161, 189, 252)',
145 | 'rgb(22, 214, 219)',
146 | 'rgb(26, 231, 191)',
147 | 'rgb(17, 183, 73)'
148 | ];
149 | var $scope = $rootScope.$new();
150 | $scope.customColors = customColors;
151 | element = $compile(
152 | '')($scope);
153 | $rootScope.$digest();
154 | content = element.contents();
155 | });
156 |
157 | it('renders with custom colors', function() {
158 | var listItems = content.find('li');
159 | var matches = listItems.filter(function (index, item) {
160 | return item.style.backgroundColor === customColors[index];
161 | });
162 | expect(matches.length).toEqual(listItems.length);
163 | });
164 | });
165 |
166 | describe('(total)', function() {
167 | var element, content;
168 | beforeEach(function() {
169 | var $scope = $rootScope.$new();
170 | $scope.options = { total: 3 };
171 | element = $compile(
172 | '')($scope);
173 | $rootScope.$digest();
174 | content = element.contents();
175 | });
176 |
177 | it('limits rendered list items', function() {
178 | var listItems = content.find('li');
179 | expect(listItems.length).toBe(3);
180 | });
181 | });
182 |
183 | describe('(selectedColor)', function() {
184 | var element, content;
185 | beforeEach(function() {
186 | var $scope = $rootScope.$new();
187 | $scope.selectedColor = '#46d6db';
188 | element = $compile('' +
189 | '')($scope);
190 | $rootScope.$digest();
191 | content = element.contents();
192 | });
193 |
194 | it('sets selected color as selected', function() {
195 | var listItems = content.find('li');
196 | var selectedListItem = listItems[3];
197 | expect(selectedListItem.outerHTML).toContain('class="ng-scope selectedColor"');
198 | });
199 | });
200 |
201 | describe('(size)', function() {
202 | var element, content;
203 | beforeEach(function() {
204 | var $scope = $rootScope.$new();
205 | $scope.options = { size: 30 };
206 | element = $compile(
207 | '')($scope);
208 | $rootScope.$digest();
209 | content = element.contents();
210 | });
211 |
212 | it('renders with correct size', function() {
213 | var customWidth = '30px';
214 | var customHeight = '30px';
215 | var listItems = content.find('li');
216 | var listElement = listItems[0];
217 | expect(listElement.style.width).toEqual(customWidth);
218 | expect(listElement.style.height).toEqual(customHeight);
219 | });
220 | });
221 |
222 | describe('(round corners)', function() {
223 | var element, content;
224 | beforeEach(function() {
225 | var $scope = $rootScope.$new();
226 | $scope.options = { roundCorners: true };
227 | element = $compile(
228 | '')($scope);
229 | $rootScope.$digest();
230 | content = element.contents();
231 | });
232 |
233 | it('renders with rounded corners', function() {
234 | var listItems = content.find('li');
235 | var firstListItem = listItems[0];
236 | var lastListItem = listItems[listItems.length - 1];
237 | expect(firstListItem.outerHTML).toContain('class="ng-scope selectedColor hRDF"');
238 | expect(lastListItem.outerHTML).toContain('class="ng-scope hRDL"');
239 | });
240 | });
241 |
242 | describe('(random colors)', function() {
243 | var element, content;
244 | beforeEach(function() {
245 | var $scope = $rootScope.$new();
246 | $scope.options = { randomColors: 10 };
247 | element = $compile(
248 | '')($scope);
249 | $rootScope.$digest();
250 | content = element.contents();
251 | });
252 |
253 | it('renders with random colors', function() {
254 | var sortedDefaultColorsInRgb = [
255 | 'rgb(123, 209, 72)',
256 | 'rgb(84, 132, 237)',
257 | 'rgb(164, 189, 252)',
258 | 'rgb(70, 214, 219)',
259 | 'rgb(122, 231, 191)',
260 | 'rgb(81, 183, 73)',
261 | 'rgb(251, 215, 91)',
262 | 'rgb(255, 184, 120)',
263 | 'rgb(255, 136, 124)',
264 | 'rgb(220, 33, 39)',
265 | 'rgb(219, 173, 255)',
266 | 'rgb(225, 225, 225)'
267 | ];
268 | sortedDefaultColorsInRgb.sort();
269 | var listItems = content.find('li');
270 | var randomColors = [];
271 | for (var i = 0; i < listItems.length; i++) {
272 | var item = listItems[i];
273 | randomColors.push(item.style.backgroundColor);
274 | }
275 | var sortedRandomColors = randomColors.slice();
276 | sortedRandomColors.sort();
277 | expect(sortedDefaultColorsInRgb).not.toEqual(sortedRandomColors);
278 | });
279 | });
280 |
281 | describe('(gradient colors)', function() {
282 | var element, content;
283 | beforeEach(function() {
284 | var $scope = $rootScope.$new();
285 | $scope.gradient = {
286 | start: '#BA693E',
287 | count: 10,
288 | step: 1
289 | };
290 | element = $compile(
291 | '')($scope);
292 | $rootScope.$digest();
293 | content = element.contents();
294 | });
295 |
296 | it('renders with gradient colors', function() {
297 | var listItems = content.find('li');
298 | var firstListItem = listItems[0];
299 | var lastListItem = listItems[listItems.length - 1];
300 | expect(firstListItem.style.backgroundColor).toEqual('rgb(189, 108, 65)');
301 | expect(lastListItem.style.backgroundColor).toEqual('rgb(255, 246, 203)');
302 | });
303 | });
304 |
305 | describe('(vertical direction)', function() {
306 | var element, content;
307 | beforeEach(function() {
308 | var $scope = $rootScope.$new();
309 | $scope.options = {
310 | horizontal: true
311 | };
312 | element = $compile(
313 | '')($scope);
314 | $rootScope.$digest();
315 | content = element.contents();
316 | });
317 |
318 | it('renders directive in vertical mode', function() {
319 | var listItems = content.find('li');
320 | var inlineBlockElements = listItems.filter(function (index, item) {
321 | return item.style.display === 'inline-block';
322 | });
323 | expect(inlineBlockElements.length).toEqual(listItems.length);
324 | });
325 | });
326 |
327 | describe('(columns)', function() {
328 | var element, content;
329 |
330 | var setupDirectiveWithNColumns = function (n) {
331 | var $scope = $rootScope.$new();
332 | $scope.options = {
333 | columns: n
334 | };
335 | element = $compile(
336 | '')($scope);
337 | $rootScope.$digest();
338 | content = element.contents();
339 | };
340 |
341 | var getListWidth = function(columns, listItemWidth) {
342 | listItemWidth = listItemWidth || 20; // 20 is default width
343 | return columns * listItemWidth + 'px';
344 | };
345 |
346 | var getListHeight = function (columns, listItemWidth, listLength) {
347 | return (listItemWidth * (listLength / columns)) + 'px';
348 | };
349 |
350 | it('renders directive in column mode', function() {
351 | setupDirectiveWithNColumns(4);
352 | var listContainer = element.find('ul')[0];
353 | expect(listContainer.style.width).not.toEqual('');
354 | expect(listContainer.style.height).not.toEqual('');
355 | var listItems = content.find('li');
356 | var floatLeftItems = listItems.filter(function (index, item) {
357 | return item.style.float === 'left';
358 | });
359 | expect(floatLeftItems.length).toEqual(listItems.length);
360 | });
361 |
362 | it('renders with specified columns', function() {
363 | for (var i = 1; i <= 10; i++) {
364 | var columns = i;
365 | setupDirectiveWithNColumns(columns);
366 | var listContainer = element.find('ul')[0];
367 | var listItems = content.find('li');
368 | var columnDirectiveWidth = getListWidth(columns, 20);
369 | var columnDirectiveHeight = getListHeight(columns, 20, listItems.length);
370 | expect(listContainer.style.width).toEqual(columnDirectiveWidth);
371 | expect(listContainer.style.height).toEqual(columnDirectiveHeight);
372 | }
373 | });
374 | });
375 | });
376 |
377 | describe('with multiple custom options', function () {
378 | describe('with prioritizes', function () {
379 | it('has custom colors as prio 1', function () {
380 | var $scope = $rootScope.$new();
381 | $scope.customColors = [
382 | 'rgb(27, 209, 72)',
383 | 'rgb(20, 132, 237)',
384 | 'rgb(161, 189, 252)',
385 | 'rgb(22, 214, 219)',
386 | 'rgb(26, 231, 191)',
387 | 'rgb(17, 183, 73)'
388 | ];
389 |
390 | $scope.options = {
391 | randomColors: 10
392 | };
393 |
394 | $scope.gradient = {
395 | start: '#BA693E',
396 | count: 10,
397 | step: 1
398 | };
399 |
400 | var element = $compile(
401 | '' +
402 | '')($scope);
403 | $rootScope.$digest();
404 | var content = element.contents();
405 |
406 | var listItems = content.find('li');
407 | var matches = listItems.filter(function (index, item) {
408 | return item.style.backgroundColor === $scope.customColors[index];
409 | });
410 | expect(matches.length).toEqual(listItems.length);
411 | });
412 |
413 | it('has random colors as prio 2', function () {
414 | var $scope = $rootScope.$new();
415 | $scope.options = {
416 | randomColors: 10
417 | };
418 |
419 | $scope.gradient = {
420 | start: '#BA693E',
421 | count: 10,
422 | step: 1
423 | };
424 |
425 | var element = $compile(
426 | '')($scope);
427 | $rootScope.$digest();
428 | var content = element.contents();
429 |
430 | // Check that first and last list elements do not match
431 | // provided gradient spectre. That is good enough.
432 | var listItems = content.find('li');
433 | var firstListItem = listItems[0];
434 | var lastListItem = listItems[listItems.length - 1];
435 | expect(firstListItem.style.backgroundColor).not.toEqual('rgb(189, 108, 65)');
436 | expect(lastListItem.style.backgroundColor).not.toEqual('rgb(255, 246, 203)');
437 | });
438 | });
439 | });
440 |
441 | });
442 |
--------------------------------------------------------------------------------
/test/karma.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(config) {
4 | config.set({
5 |
6 | // base path that will be used to resolve all patterns (eg. files, exclude)
7 | basePath: '../',
8 |
9 |
10 | // frameworks to use
11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12 | frameworks: ['jasmine-jquery', 'jasmine'],
13 |
14 |
15 | // list of files / patterns to load in the browser
16 | files: [
17 | 'node_modules/angular/angular.js',
18 | 'node_modules/angular-mocks/angular-mocks.js',
19 | 'source/**/*.js',
20 | 'css/**/*.css',
21 | 'test/**/*.spec.js'
22 | ],
23 |
24 |
25 | // list of files to exclude
26 | exclude: [
27 | ],
28 |
29 |
30 | // preprocess matching files before serving them to the browser
31 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
32 | preprocessors: {
33 | },
34 |
35 |
36 | // test results reporter to use
37 | // possible values: 'dots', 'progress'
38 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
39 | reporters: ['mocha'],
40 |
41 |
42 | // web server port
43 | port: 9876,
44 |
45 |
46 | // enable / disable colors in the output (reporters and logs)
47 | colors: true,
48 |
49 |
50 | // level of logging
51 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN ||
52 | // config.LOG_INFO || config.LOG_DEBUG
53 | logLevel: config.LOG_INFO,
54 |
55 |
56 | // enable / disable watching file and executing tests whenever any file changes
57 | autoWatch: true,
58 |
59 |
60 | // start these browsers
61 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
62 | browsers: ['PhantomJS'],
63 |
64 |
65 | // Continuous Integration mode
66 | // if true, Karma captures browsers, runs the tests and exits
67 | singleRun: false,
68 |
69 |
70 | // Concurrency level
71 | // how many browser should be started simultaneous
72 | concurrency: Infinity
73 | });
74 | };
75 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Modules
4 | var webpack = require('webpack');
5 | var HtmlWebpackPlugin = require('html-webpack-plugin');
6 | var CopyWebpackPlugin = require('copy-webpack-plugin');
7 |
8 | /**
9 | * Env
10 | * Get npm lifecycle event to identify the environment
11 | */
12 | var ENV = process.env.npm_lifecycle_event;
13 | var isProd = ENV === 'build';
14 |
15 | module.exports = function makeWebpackConfig () {
16 | /**
17 | * Config
18 | * Reference: http://webpack.github.io/docs/configuration.html
19 | * This is the object where all configuration gets set
20 | */
21 | var config = {};
22 |
23 | /**
24 | * Entry
25 | * Reference: http://webpack.github.io/docs/configuration.html#entry
26 | * Should be an empty object if it's generating a test build
27 | * Karma will set this when it's a test build
28 | */
29 | config.entry = {
30 | app: isProd ? './source/ngjs-color-picker.js' : './dev/app/app.js'
31 | };
32 |
33 | /**
34 | * Output
35 | * Reference: http://webpack.github.io/docs/configuration.html#output
36 | * Should be an empty object if it's generating a test build
37 | * Karma will handle setting it up for you when it's a test build
38 | */
39 | config.output = {
40 | // Absolute output directory
41 | path: __dirname + '/dist',
42 |
43 | // Output path from the view of the page
44 | // Uses webpack-dev-server in development
45 | publicPath: isProd ? '/' : 'http://localhost:8080/',
46 |
47 | // Filename for entry points
48 | // Only adds hash in build mode
49 | filename: isProd ? 'ngjs-color-picker.js' : '[name].bundle.js',
50 |
51 | // Filename for non-entry points
52 | // Only adds hash in build mode
53 | chunkFilename: isProd ? 'ngjs-color-picker.js' : '[name].bundle.js'
54 | };
55 |
56 | /**
57 | * Devtool
58 | * Reference: http://webpack.github.io/docs/configuration.html#devtool
59 | * Type of sourcemap to use per build type
60 | */
61 | if (isProd) {
62 | config.devtool = 'source-map';
63 | } else {
64 | config.devtool = 'eval-source-map';
65 | }
66 |
67 | /**
68 | * Loaders
69 | * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
70 | * List: http://webpack.github.io/docs/list-of-loaders.html
71 | * This handles most of the magic responsible for converting modules
72 | */
73 |
74 | // Initialize module
75 | config.module = {
76 | loaders: [{
77 | // JS LOADER
78 | // Reference: https://github.com/babel/babel-loader
79 | // Transpile .js files using babel-loader
80 | // Compiles ES6 and ES7 into ES5 code
81 | test: /\.js$/,
82 | loader: 'babel-loader',
83 | exclude: /node_modules/
84 | }, {
85 | // ASSET LOADER
86 | // Reference: https://github.com/webpack/file-loader
87 | // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
88 | // Rename the file using the asset hash
89 | // Pass along the updated reference to your code
90 | // You can add here any file extension you want to get copied to your output
91 | test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
92 | loader: 'file'
93 | }, {
94 | // HTML LOADER
95 | // Reference: https://github.com/webpack/raw-loader
96 | // Allow loading html through js
97 | test: /\.html$/,
98 | loader: 'raw-loader'
99 | }]
100 | };
101 |
102 | /**
103 | * Plugins
104 | * Reference: http://webpack.github.io/docs/configuration.html#plugins
105 | * List: http://webpack.github.io/docs/list-of-plugins.html
106 | */
107 | config.plugins = [];
108 |
109 | // Reference: https://github.com/ampedandwired/html-webpack-plugin
110 | // Render index.html
111 | config.plugins.push(
112 | new HtmlWebpackPlugin({
113 | template: './dev/public/index.html',
114 | inject: 'body'
115 | })
116 | );
117 |
118 | // Add build specific plugins
119 | if (isProd) {
120 | config.plugins.push(
121 | // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
122 | // Only emit files when there are no errors
123 | new webpack.NoErrorsPlugin(),
124 |
125 | // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
126 | // Dedupe modules in the output
127 | new webpack.optimize.DedupePlugin(),
128 |
129 | // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
130 | // Minify all javascript, switch loaders to minimizing mode
131 | new webpack.optimize.UglifyJsPlugin(),
132 |
133 | // Copy assets from the public folder
134 | // Reference: https://github.com/kevlened/copy-webpack-plugin
135 | new CopyWebpackPlugin([{
136 | from: __dirname + '/public'
137 | }])
138 | );
139 | }
140 |
141 | /**
142 | * Dev server configuration
143 | * Reference: http://webpack.github.io/docs/configuration.html#devserver
144 | * Reference: http://webpack.github.io/docs/webpack-dev-server.html
145 | */
146 | config.devServer = {
147 | contentBase: './dev/public',
148 | stats: 'minimal'
149 | };
150 |
151 | return config;
152 | }();
153 |
--------------------------------------------------------------------------------