├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .scripts ├── get_gh_pages_url.js ├── lint.cmd ├── mocha_runner.js ├── prepublish.cmd ├── prepublish.sh ├── publish_storybook.cmd ├── publish_storybook.sh ├── test-watch.cmd ├── test-watch.sh ├── test.cmd └── user │ ├── prepublish.sh │ └── pretest.js ├── .storybook ├── addons.js └── config.js ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── doc ├── screen1.png ├── screen2.png └── screen3.png ├── mochacfg.js ├── package.json ├── src ├── MaterialColorPicker.jsx ├── colors.js ├── done-black.js ├── stories │ └── index.js └── tests │ └── index.js ├── storybook.md ├── test └── mocha.opts └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | colors.js -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "rules": { 4 | "arrow-body-style": 0, 5 | "prefer-arrow-callback": 0, 6 | "func-names": 0, 7 | "eqeqeq": 1, 8 | "no-unused-vars": 1, 9 | "react/jsx-no-bind": 1, 10 | "react/jsx-uses-react": 1, 11 | "react/prefer-stateless-function": 0, 12 | // indentation 13 | "indent": [ 2, 4 ], 14 | // comment 15 | 'spaced-comment': ['warn', 'always', { 16 | exceptions: ['-', '+','todo'], 17 | markers: ['=', '!'] // space here to support sprockets directives 18 | }], 19 | }, 20 | "parserOptions": { 21 | "ecmaVersion": 6, 22 | "ecmaFeatures": { 23 | "experimentalObjectRestSpread": true 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .idea 4 | dist 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .scripts 2 | .storybook 3 | src 4 | doc 5 | .babelrc 6 | *.log 7 | -------------------------------------------------------------------------------- /.scripts/get_gh_pages_url.js: -------------------------------------------------------------------------------- 1 | // IMPORTANT 2 | // --------- 3 | // This is an auto generated file with React CDK. 4 | // Do not modify this file. 5 | 6 | const parse = require('git-url-parse'); 7 | var ghUrl = process.argv[2]; 8 | const parsedUrl = parse(ghUrl); 9 | 10 | const ghPagesUrl = 'https://' + parsedUrl.owner + '.github.io/' + parsedUrl.name; 11 | console.log(ghPagesUrl); 12 | -------------------------------------------------------------------------------- /.scripts/lint.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | call .\node_modules\.bin\eslint %1 --ext .jsx --ext .js %2 3 | rem Please no errors 4 | -------------------------------------------------------------------------------- /.scripts/mocha_runner.js: -------------------------------------------------------------------------------- 1 | // IMPORTANT 2 | // --------- 3 | // This is an auto generated file with React CDK. 4 | // Do not modify this file. 5 | // Use `.scripts/user/pretest.js instead`. 6 | 7 | require('babel-core/register'); 8 | require('babel-polyfill'); 9 | 10 | // Add jsdom support, which is required for enzyme. 11 | var jsdom = require('jsdom').jsdom; 12 | 13 | var exposedProperties = ['window', 'navigator', 'document']; 14 | 15 | global.document = jsdom(''); 16 | global.window = document.defaultView; 17 | Object.keys(document.defaultView).forEach((property) => { 18 | if (typeof global[property] === 'undefined') { 19 | exposedProperties.push(property); 20 | global[property] = document.defaultView[property]; 21 | } 22 | }); 23 | 24 | global.navigator = { 25 | userAgent: 'node.js' 26 | }; 27 | 28 | process.on('unhandledRejection', function (error) { 29 | console.error('Unhandled Promise Rejection:'); 30 | console.error(error && error.stack || error); 31 | }); 32 | 33 | require('./user/pretest.js'); 34 | -------------------------------------------------------------------------------- /.scripts/prepublish.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Transpiling 'src' into ES5 ... 3 | echo ... 4 | if exist dist ( 5 | rem rmdir /S /Q dist 6 | ) 7 | call .\node_modules\.bin\babel --ignore tests,stories --plugins "transform-runtime" ./src --out-dir ./dist 8 | echo ... 9 | echo Transpiling completed. -------------------------------------------------------------------------------- /.scripts/prepublish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # IMPORTANT 4 | # --------- 5 | # This is an auto generated file with React CDK. 6 | # Do not modify this file. 7 | # Use `.scripts/user/prepublish.sh instead`. 8 | 9 | echo "=> Transpiling 'src' into ES5 ..." 10 | echo "" 11 | rm -rf ./dist 12 | ./node_modules/.bin/babel --ignore tests,stories --plugins "transform-runtime" ./src --out-dir ./dist 13 | echo "" 14 | echo "=> Transpiling completed." 15 | 16 | . .scripts/user/prepublish.sh 17 | -------------------------------------------------------------------------------- /.scripts/publish_storybook.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal enabledelayedexpansion 4 | 5 | set GIT_URL_CMD=git config --get remote.origin.url 6 | for /F "usebackq delims=" %%v in (`%GIT_URL_CMD%`) do set GIT_URL=%%v 7 | 8 | if %GIT_URL%=="" ( 9 | echo This project is not configured with a remote git repo 10 | exit 1 11 | ) 12 | 13 | if exist .out ( 14 | rmdir /S /Q .out 15 | ) 16 | 17 | md .out 18 | 19 | call build-storybook -o .out 20 | 21 | cd .out 22 | 23 | git init 24 | git config user.name "GH Pages Bot" 25 | git config user.email "windows@ghbot.com" 26 | git add . 27 | git commit -m "Deploy Storybook to GitHub Pages" 28 | git push --force --quiet !GIT_URL! master:gh-pages 29 | 30 | cd .. 31 | rmdir /S /Q .out 32 | 33 | set GHP_URL_CMD=node .scripts/get_gh_pages_url.js !GIT_URL! 34 | for /F "usebackq delims=" %%w in (`%GHP_URL_CMD%`) do set GHP_URL=%%w 35 | 36 | echo ## Deploy >storybook.md 37 | echo Storybook deployed to: [!GHP_URL!](!GHP_URL!)>>storybook.md 38 | 39 | echo . 40 | echo Storybook deployed to: !GHP_URL! 41 | echo See the %cd%\storybook.md 42 | 43 | endlocal -------------------------------------------------------------------------------- /.scripts/publish_storybook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # IMPORTANT 4 | # --------- 5 | # This is an auto generated file with React CDK. 6 | # Do not modify this file. 7 | 8 | set -e # exit with nonzero exit code if anything fails 9 | 10 | # get GIT url 11 | 12 | GIT_URL=`git config --get remote.origin.url` 13 | if [[ $GIT_URL == "" ]]; then 14 | echo "This project is not configured with a remote git repo". 15 | exit 1 16 | fi 17 | 18 | # clear and re-create the out directory 19 | rm -rf .out || exit 0; 20 | mkdir .out; 21 | 22 | # run our compile script, discussed above 23 | build-storybook -o .out 24 | 25 | # go to the out directory and create a *new* Git repo 26 | cd .out 27 | git init 28 | 29 | # inside this git repo we'll pretend to be a new user 30 | git config user.name "GH Pages Bot" 31 | git config user.email "hello@ghbot.com" 32 | 33 | # The first and only commit to this new Git repo contains all the 34 | # files present with the commit message "Deploy to GitHub Pages". 35 | git add . 36 | git commit -m "Deploy Storybook to GitHub Pages" 37 | 38 | # Force push from the current repo's master branch to the remote 39 | # repo's gh-pages branch. (All previous history on the gh-pages branch 40 | # will be lost, since we are overwriting it.) We redirect any output to 41 | # /dev/null to hide any sensitive credential data that might otherwise be exposed. 42 | git push --force --quiet $GIT_URL master:gh-pages > /dev/null 2>&1 43 | cd .. 44 | rm -rf .out 45 | 46 | echo "" 47 | echo "=> Storybook deployed to: `node .scripts/get_gh_pages_url.js $GIT_URL`" 48 | -------------------------------------------------------------------------------- /.scripts/test-watch.cmd: -------------------------------------------------------------------------------- 1 | e:\Develop\NodeJS\cmder\vendor\git-for-windows\usr\bin\mintty.exe /bin/bash -l -------------------------------------------------------------------------------- /.scripts/test-watch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./node_modules/.bin/mocha --require .scripts/mocha_runner src/**/tests/**/*.js --watch --watch-extensions jsx 4 | 5 | -------------------------------------------------------------------------------- /.scripts/test.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | call .\node_modules\.bin\mocha --require .scripts/mocha_runner src/**/tests/**/*.js 3 | rem Please no errors 4 | 5 | -------------------------------------------------------------------------------- /.scripts/user/prepublish.sh: -------------------------------------------------------------------------------- 1 | # Use this file to your own code to run at NPM `prepublish` event. 2 | -------------------------------------------------------------------------------- /.scripts/user/pretest.js: -------------------------------------------------------------------------------- 1 | // Use this file to setup any test utilities. 2 | -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-knobs/register'; 2 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | // IMPORTANT 2 | // --------- 3 | // This is an auto generated file with React CDK. 4 | // Do not modify this file. 5 | 6 | import { configure } from '@storybook/react'; 7 | 8 | function loadStories() { 9 | require('../src/stories'); 10 | } 11 | 12 | configure(loadStories, module); 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### v1.0.0 4 | 5 | * First stable release 6 | 7 | props: initColor, onReset, onSubmit, resetLabel, style, submitLabel 8 | 9 | ### v1.1.0 10 | 11 | * Added props: onSelect, onHover -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to React Material Color Picker Component 2 | 3 | We welcome your help to make this component better. This document will help to streamline the contributing process and save everyone's precious time. 4 | 5 | ## Development Setup 6 | 7 | This component has been setup with [React CDK](https://github.com/kadirahq/react-cdk). Refer [React CDK documentation](https://github.com/kadirahq/react-cdk)) to get started with the development. 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 smArtLight. 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub version](https://badge.fury.io/gh/sm-react%2Freact-material-color-picker.svg)](https://badge.fury.io/gh/sm-react%2Freact-material-color-picker) 2 | [![npm version](https://badge.fury.io/js/react-material-color-picker.svg)](https://badge.fury.io/js/react-material-color-picker) 3 | [![@airbnb](https://img.shields.io/badge/code%20style-Airbnb-brightgreen.svg)](https://github.com/sm-react/react-material-color-picker/blob/master/.eslintrc) 4 | 5 | # React Material Color Picker Component 6 | 7 | [Material Design](https://material.google.com/) is a design language introduced by Google. If you want to find color inspiration for a specific design style based on [material color palette](https://material.google.com/style/color.html#), you can use this component as a development tool. You may find it useful while creating Material apps in combination with such libraries as [Material-UI](http://www.material-ui.com/) 8 | 9 | ## Appearance 10 | 11 | ![screen1](https://github.com/sm-react/react-material-color-picker/raw/master/doc/screen1.png) 12 | 13 | ![screen2](https://github.com/sm-react/react-material-color-picker/raw/master/doc/screen2.png) 14 | 15 | ![screen3](https://github.com/sm-react/react-material-color-picker/raw/master/doc/screen3.png) 16 | 17 | 18 | ## Install 19 | 20 | $ npm i react-material-color-picker --save 21 | 22 | ## Usage 23 | 24 | ```js 25 | import React from 'react'; 26 | import MaterialColorPicker from 'react-material-color-picker'; 27 | 28 | // in your app 29 | 37 | ``` 38 | 39 | ## Demo 40 | [![Live demo](https://img.shields.io/badge/Live%20Demo-%20Storybook-brightgreen.svg)](https://sm-react.github.io/react-material-color-picker/?selectedKind=Material%20Color%20Picker&selectedStory=default%20view&full=0&down=1&left=1&panelRight=1&downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel) 41 | 42 | ## API 43 | 44 | #### Props and Callbacks 45 | **initColor** should be color string from Goggle material color palette 46 | 47 | **style** - inline style of the root div node 48 | 49 | **submitLabel** and **resetLabel** are titles of the appropriate buttons 50 | 51 | **onSubmit** and **onReset** are callbacks wich will be invoked by clicking the appropriate buttons. It will recieve an argument with the following structure: 52 | ```js 53 | event = { 54 | type, // 'submit' || 'reset', 55 | timeStamp, // nativeEvent.timeStamp, 56 | target: { 57 | value, // currient color string, 58 | nativeEvent, // nativeEvent, 59 | name: 'MaterialColorPicker', 60 | node, // ref to root div element, 61 | ...this.props, 62 | } 63 | }; 64 | ``` 65 | 66 | 67 | ## smArtLight 68 | [![@UsulPro](https://img.shields.io/badge/github-UsulPro-blue.svg)](https://github.com/UsulPro) 69 | [![@sm-react](https://img.shields.io/badge/github-smARTLight-red.svg)](https://github.com/sm-react) 70 | 71 | -------------------------------------------------------------------------------- /doc/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sm-react/react-material-color-picker/f17f03476fcc6838f7fb6dbbc34ecd30735cce6b/doc/screen1.png -------------------------------------------------------------------------------- /doc/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sm-react/react-material-color-picker/f17f03476fcc6838f7fb6dbbc34ecd30735cce6b/doc/screen2.png -------------------------------------------------------------------------------- /doc/screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sm-react/react-material-color-picker/f17f03476fcc6838f7fb6dbbc34ecd30735cce6b/doc/screen3.png -------------------------------------------------------------------------------- /mochacfg.js: -------------------------------------------------------------------------------- 1 | require.extensions['.png'] = function(){ return null; } 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@usulpro/color-picker", 3 | "version": "1.1.4", 4 | "description": "React Material Color Picker Component", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/sm-react/react-material-color-picker.git" 8 | }, 9 | "keywords": [ 10 | "React", 11 | "Material", 12 | "Color", 13 | "Picker", 14 | "Component" 15 | ], 16 | "author": "UsulPro", 17 | "license": "MIT", 18 | "homepage": "https://github.com/sm-react/react-material-color-picker", 19 | "scripts": { 20 | "publish-storybook": ".scripts\\publish_storybook.cmd", 21 | "prepublish": ".scripts/prepublish.sh", 22 | "lint": ".scripts\\lint.cmd src", 23 | "lintfix": ".scripts\\lint.cmd src --fix", 24 | "testonly": ".scripts\\test.cmd", 25 | "test": "npm run lint && npm run testonly", 26 | "test-watch": "bash .scripts\\test-watch.sh", 27 | "storybook": "start-storybook -p 9010", 28 | "start": "start-storybook -p 9001" 29 | }, 30 | "devDependencies": { 31 | "babel-cli": "^6.5.0", 32 | "babel-core": "^6.5.0", 33 | "babel-eslint": "^6.0.2", 34 | "babel-loader": "^6.2.4", 35 | "babel-plugin-transform-runtime": "^6.5.0", 36 | "babel-polyfill": "^6.5.0", 37 | "babel-preset-es2015": "^6.5.0", 38 | "babel-preset-react": "^6.5.0", 39 | "babel-preset-stage-2": "^6.5.0", 40 | "chai": "^3.5.0", 41 | "enzyme": "^2.2.0", 42 | "eslint": "^2.7.0", 43 | "eslint-config-airbnb": "^7.0.0", 44 | "eslint-plugin-babel": "^3.2.0", 45 | "eslint-plugin-jsx-a11y": "^0.6.2", 46 | "eslint-plugin-react": "^4.3.0", 47 | "git-url-parse": "^6.0.1", 48 | "jsdom": "^8.3.1", 49 | "mocha": "^2.4.5", 50 | "react": "^16.0.0", 51 | "react-addons-test-utils": "^15.0.0", 52 | "react-dom": "^16.0.0", 53 | "sinon": "^1.17.3", 54 | "@storybook/addons": "3.2.12", 55 | "@storybook/react": "3.2.12", 56 | "@storybook/addon-knobs": "3.2.12", 57 | "@storybook/addon-info": "3.2.12" 58 | }, 59 | "peerDependencies": { 60 | "react": "^0.14.7 || ^15.0.0 || ^16.0.0" 61 | }, 62 | "dependencies": { 63 | "babel-runtime": "^6.5.0", 64 | "prop-types": "^15.6.0" 65 | }, 66 | "main": "dist/MaterialColorPicker.js", 67 | "engines": { 68 | "npm": ">=3.0.0" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/MaterialColorPicker.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Done } from './done-black'; 4 | const _colors = require('./colors'); 5 | 6 | const propTypes = { 7 | initColor: PropTypes.string, 8 | onSubmit: PropTypes.func, 9 | onSelect: PropTypes.func, 10 | onHover: PropTypes.func, 11 | onReset: PropTypes.func, 12 | style: PropTypes.object, 13 | submitLabel: PropTypes.string, 14 | resetLabel: PropTypes.string, 15 | }; 16 | 17 | const defaultProps = { 18 | initColor: '#40c4ff', 19 | onSubmit: () => {}, 20 | onSelect: () => {}, 21 | onHover: () => {}, 22 | onReset: () => {}, 23 | submitLabel: 'Submit', 24 | resetLabel: 'Reset', 25 | }; 26 | 27 | export default class MaterialColorPicker extends React.Component { 28 | constructor(props) { 29 | super(props); 30 | this.colorNames = this.colorNameList(_colors); 31 | this.toneNames = Object.keys(this.colorNames); 32 | this.rootDivRef = null; 33 | this.hoveredColor = ''; 34 | 35 | this.toneColorByName = this.toneColorByName.bind(this); 36 | this.satColorByName = this.satColorByName.bind(this); 37 | this.resetColor = this.resetColor.bind(this); 38 | this.resetHover = this.resetHover.bind(this); 39 | this.submitHover = this.submitHover.bind(this); 40 | this.makeToneSwatches = this.makeToneSwatches.bind(this); 41 | this.makeGradeSwatches = this.makeGradeSwatches.bind(this); 42 | 43 | this.initState = this.resetColor(); 44 | this.state = { 45 | ...this.initState, 46 | hoveredTone: '', 47 | hoveredSat: '', 48 | hoveredSubmit: false, 49 | }; 50 | 51 | this.selectTone = this.selectTone.bind(this); 52 | this.selectSat = this.selectSat.bind(this); 53 | this.hoverTone = this.hoverTone.bind(this); 54 | this.hoverSat = this.hoverSat.bind(this); 55 | this.hoverReset = this.hoverReset.bind(this); 56 | 57 | this.titleName = this.titleName.bind(this); 58 | this.fullNameString = this.fullNameString.bind(this); 59 | this.createEvent = this.createEvent.bind(this); 60 | 61 | this.onSubmit = this.onSubmit.bind(this); 62 | this.onReset = this.onReset.bind(this); 63 | this.onHover = this.onHover.bind(this); 64 | 65 | this.rootDiv = this.rootDiv.bind(this); 66 | } 67 | 68 | onSubmit() { 69 | return e => { 70 | const event = { 71 | type: 'submit', 72 | timeStamp: e.nativeEvent.timeStamp, 73 | eventPhase: 3, 74 | target: { 75 | value: _colors[this.fullNameString()], 76 | nativeEvent: e.nativeEvent, 77 | name: 'MaterialColorPicker', 78 | node: this.rootDivRef, 79 | ...this.props, 80 | }, 81 | persist() { 82 | e.persist(); 83 | }, 84 | }; 85 | this.props.onSubmit(event); 86 | }; 87 | } 88 | 89 | onReset() { 90 | return e => { 91 | const timeStamp = e.nativeEvent.timeStamp; 92 | const nativeEvent = e.nativeEvent; 93 | this.setState(this.initState, () => { 94 | const event = { 95 | type: 'reset', 96 | timeStamp, 97 | eventPhase: 3, 98 | target: { 99 | value: _colors[this.fullNameString()], 100 | nativeEvent, 101 | name: 'MaterialColorPicker', 102 | node: this.rootDivRef, 103 | ...this.props, 104 | }, 105 | persist() { 106 | e.persist(); 107 | }, 108 | }; 109 | this.props.onReset(event); 110 | }); 111 | }; 112 | } 113 | 114 | onHover(event) { 115 | if (event.target.value !== this.hoveredColor) { 116 | this.hoveredColor = event.target.value; 117 | this.props.onHover(event); 118 | } 119 | } 120 | 121 | findColorName(colObj, colString) { 122 | const nameList = Object.keys(colObj); 123 | const name = nameList.find(val => { 124 | return colObj[val] === colString; 125 | }); 126 | return name; 127 | } 128 | 129 | resetColor() { 130 | const initName = this.findColorName(_colors, this.props.initColor) || ''; 131 | const initTone = this.toneColorByName(initName); 132 | const initSat = this.satColorByName(initName); 133 | const state = { 134 | selectedTone: initTone || this.toneNames[0], 135 | selectedSat: initSat || '500', 136 | }; 137 | return state; 138 | } 139 | 140 | resetHover() { 141 | const initColor = this.resetColor(); 142 | this.setState({ 143 | hoveredTone: initColor.selectedTone, 144 | hoveredSat: initColor.selectedSat, 145 | }); 146 | } 147 | 148 | submitHover(flag) { 149 | return () => { 150 | this.setState({ hoveredSubmit: flag }); 151 | }; 152 | } 153 | 154 | colorNameList(colObj) { 155 | const nameList = Object.keys(colObj); 156 | const toneList = { 157 | red: nameList.filter(val => /^red/.test(val)), 158 | pink: nameList.filter(val => /^pink/.test(val)), 159 | purple: nameList.filter(val => /^purple/.test(val)), 160 | deepPurple: nameList.filter(val => /^deepPurple/.test(val)), 161 | indigo: nameList.filter(val => /^indigo/.test(val)), 162 | blue: nameList.filter(val => /^blue[A1-9]/.test(val)), 163 | lightBlue: nameList.filter(val => /^lightBlue/.test(val)), 164 | cyan: nameList.filter(val => /^cyan/.test(val)), 165 | teal: nameList.filter(val => /^teal/.test(val)), 166 | green: nameList.filter(val => /^green/.test(val)), 167 | lightGreen: nameList.filter(val => /^lightGreen/.test(val)), 168 | lime: nameList.filter(val => /^lime/.test(val)), 169 | yellow: nameList.filter(val => /^yellow/.test(val)), 170 | amber: nameList.filter(val => /^amber/.test(val)), 171 | orange: nameList.filter(val => /^orange/.test(val)), 172 | deepOrange: nameList.filter(val => /^deepOrange/.test(val)), 173 | brown: nameList.filter(val => /^brown/.test(val)), 174 | blueGrey: nameList.filter(val => /^blueGrey/.test(val)), 175 | grey: nameList.filter(val => /^grey/.test(val)), 176 | black: nameList.filter(val => /black|white|Black|White/.test(val)), 177 | }; 178 | 179 | return toneList; 180 | } 181 | 182 | makeToneSwatches(toneNames) { 183 | return toneNames.map(val => { 184 | let toneBaseName = this.baseToneByName(val); 185 | const baseColor = _colors[toneBaseName]; 186 | return ( 187 |
201 | ); 202 | }); 203 | } 204 | 205 | makeGradeSwatches(toneName) { 206 | const gradeNameList = this.colorNames[toneName]; 207 | const gradeSwatches = gradeNameList.map(val => { 208 | return ( 209 |
226 |
227 |
237 |
247 | {this.blackShortName(this.satColorByName(val))} 248 |
249 |
250 |
251 |
252 | ); 253 | }); 254 | return gradeSwatches; 255 | } 256 | 257 | borderSelTone(val, selName, hovName) { 258 | if (val === selName) { 259 | return { 260 | borderTop: '2px #ffffff solid', 261 | borderBottom: '2px #383838 solid', 262 | }; 263 | } 264 | if (val === hovName) { 265 | return { 266 | borderTop: '2px rgba(255, 255, 255, 0.46) solid', 267 | borderBottom: '2px rgba(56, 56, 56, 0.44) solid', 268 | }; 269 | } 270 | return { 271 | borderTop: '2px rgba(209, 209, 209, 0) solid', 272 | borderBottom: '2px rgba(56, 56, 56, 0) solid', 273 | }; 274 | } 275 | 276 | borderSelGrade(val, selName, hovName) { 277 | if (val === selName) { 278 | return { 279 | borderTop: '3px #d1d1d1 solid', 280 | borderBottom: '3px #383838 solid', 281 | }; 282 | } 283 | if (val === hovName) { 284 | return { 285 | borderTop: '3px rgba(255, 255, 255, 0.61) solid', 286 | borderBottom: '3px rgba(56, 56, 56, 0.5) solid', 287 | }; 288 | } 289 | return {}; 290 | } 291 | 292 | selectTone(toneName) { 293 | return e => { 294 | const event = this.createEvent(e, 'select'); 295 | this.setState({ selectedTone: toneName }, this.props.onSelect(event)); 296 | }; 297 | } 298 | 299 | selectSat(satName) { 300 | return e => { 301 | const event = this.createEvent(e, 'select'); 302 | this.setState({ selectedSat: satName }, this.props.onSelect(event)); 303 | }; 304 | } 305 | 306 | hoverTone(toneName) { 307 | return e => { 308 | const { nativeEvent, persist } = e; 309 | this.setState({ hoveredTone: toneName }, () => { 310 | const event = this.createEvent({ nativeEvent, persist }, 'hover'); 311 | this.onHover(event); 312 | }); 313 | }; 314 | } 315 | 316 | hoverSat(satName) { 317 | return e => { 318 | const { nativeEvent, persist } = e; 319 | this.setState({ hoveredSat: satName }, () => { 320 | const event = this.createEvent({ nativeEvent, persist }, 'hover'); 321 | this.onHover(event); 322 | }); 323 | }; 324 | } 325 | 326 | hoverReset() { 327 | return e => { 328 | const { nativeEvent, persist } = e; 329 | this.setState({ hoveredTone: '', hoveredSat: '' }, () => { 330 | const event = this.createEvent({ nativeEvent, persist }, 'hover'); 331 | this.onHover(event); 332 | }); 333 | }; 334 | } 335 | 336 | baseToneByName(toneName) { 337 | let toneBaseName = `${toneName}500`; 338 | if (toneName === 'black') { 339 | toneBaseName = 'lightBlack'; 340 | } 341 | return toneBaseName; 342 | } 343 | 344 | toneColorByName(colorName) { 345 | const satName = this.satColorByName(colorName); 346 | const toneName = /black|white|Black|White/.test(satName) 347 | ? 'black' 348 | : colorName.replace(satName, ''); 349 | return toneName; 350 | } 351 | 352 | satColorByName(colorName) { 353 | let satName = colorName.replace(/\D*/, ''); 354 | if (/A\d/.test(colorName)) { 355 | satName = `A${satName}`; 356 | } 357 | return satName || colorName; 358 | } 359 | 360 | blackShortName(satName) { 361 | let newName = satName; 362 | if (/Black/.test(newName)) { 363 | newName = newName.replace(/Black/, '.B'); 364 | } 365 | if (/White/.test(newName)) { 366 | newName = newName.replace(/White/, '.W'); 367 | } 368 | return newName; 369 | } 370 | 371 | numColorByName(colorName) { 372 | const satName = colorName.replace(/\D*/, ''); 373 | return satName || colorName; 374 | } 375 | 376 | bwColorByName(colorName) { 377 | const contrColor = parseInt(this.numColorByName(colorName), 10); 378 | if (contrColor) { 379 | return contrColor <= 200 ? 'black' : 'white'; 380 | } 381 | if (/black|Black/.test(colorName)) { 382 | return 'white'; 383 | } 384 | return 'black'; 385 | } 386 | 387 | fullNameString() { 388 | let toneString = this.state.hoveredTone || this.state.selectedTone; 389 | const satString = this.state.hoveredSat || this.state.selectedSat; 390 | if (toneString === 'black') { 391 | toneString = ''; 392 | } 393 | return `${toneString}${satString}`; 394 | } 395 | 396 | titleName(isBlack) { 397 | const baseColor = isBlack ? 'black' : 'white'; 398 | const greyColor = isBlack ? '#505050' : '#c1c1c1'; 399 | let toneString = this.state.hoveredTone || this.state.selectedTone; 400 | let satString = this.state.hoveredSat || this.state.selectedSat; 401 | if (toneString === 'black') { 402 | toneString = ''; 403 | } 404 | const isHovTone = 405 | !(this.state.hoveredTone === this.state.selectedTone) && this.state.hoveredTone; 406 | const isHovSat = 407 | !(this.state.hoveredSat === this.state.selectedSat) && this.state.hoveredSat; 408 | const toneColor = isHovTone ? greyColor : baseColor; 409 | const satColor = isHovSat ? greyColor : baseColor; 410 | return ( 411 |
412 | 413 | {toneString} 414 | 415 | 416 | {satString} 417 | 418 |
419 | ); 420 | } 421 | 422 | createEvent(e, type) { 423 | const event = { 424 | type, 425 | timeStamp: e.nativeEvent.timeStamp, 426 | eventPhase: 3, 427 | target: { 428 | value: _colors[this.fullNameString()], 429 | nativeEvent: e.nativeEvent, 430 | name: 'MaterialColorPicker', 431 | node: this.rootDivRef, 432 | ...this.props, 433 | }, 434 | persist() { 435 | e.persist(); 436 | }, 437 | }; 438 | return event; 439 | } 440 | 441 | rootDiv(div) { 442 | this.rootDivRef = div; 443 | } 444 | 445 | render() { 446 | return ( 447 |
457 |
465 | {this.makeToneSwatches(this.toneNames)} 466 |
467 |
479 | {this.titleName(false)} 480 | {this.titleName(true)} 481 |
482 |
488 |
496 | {this.state.hoveredSubmit ? ( 497 | 498 | ) : null} 499 |
500 | 501 |
510 | {this.makeGradeSwatches(this.state.selectedTone)} 511 |
512 |
513 |
527 |
532 | 533 | {_colors[this.fullNameString()]} 534 | 535 |
536 |
544 |
555 | {this.props.resetLabel} 556 |
557 |
568 | {this.props.submitLabel} 569 |
570 |
571 |
572 |
573 | ); 574 | } 575 | } 576 | 577 | MaterialColorPicker.propTypes = propTypes; 578 | MaterialColorPicker.defaultProps = defaultProps; 579 | MaterialColorPicker.displayName = 'MaterialColorPicker'; 580 | -------------------------------------------------------------------------------- /src/colors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var red50 = exports.red50 = '#ffebee'; 7 | var red100 = exports.red100 = '#ffcdd2'; 8 | var red200 = exports.red200 = '#ef9a9a'; 9 | var red300 = exports.red300 = '#e57373'; 10 | var red400 = exports.red400 = '#ef5350'; 11 | var red500 = exports.red500 = '#f44336'; 12 | var red600 = exports.red600 = '#e53935'; 13 | var red700 = exports.red700 = '#d32f2f'; 14 | var red800 = exports.red800 = '#c62828'; 15 | var red900 = exports.red900 = '#b71c1c'; 16 | var redA100 = exports.redA100 = '#ff8a80'; 17 | var redA200 = exports.redA200 = '#ff5252'; 18 | var redA400 = exports.redA400 = '#ff1744'; 19 | var redA700 = exports.redA700 = '#d50000'; 20 | 21 | var pink50 = exports.pink50 = '#fce4ec'; 22 | var pink100 = exports.pink100 = '#f8bbd0'; 23 | var pink200 = exports.pink200 = '#f48fb1'; 24 | var pink300 = exports.pink300 = '#f06292'; 25 | var pink400 = exports.pink400 = '#ec407a'; 26 | var pink500 = exports.pink500 = '#e91e63'; 27 | var pink600 = exports.pink600 = '#d81b60'; 28 | var pink700 = exports.pink700 = '#c2185b'; 29 | var pink800 = exports.pink800 = '#ad1457'; 30 | var pink900 = exports.pink900 = '#880e4f'; 31 | var pinkA100 = exports.pinkA100 = '#ff80ab'; 32 | var pinkA200 = exports.pinkA200 = '#ff4081'; 33 | var pinkA400 = exports.pinkA400 = '#f50057'; 34 | var pinkA700 = exports.pinkA700 = '#c51162'; 35 | 36 | var purple50 = exports.purple50 = '#f3e5f5'; 37 | var purple100 = exports.purple100 = '#e1bee7'; 38 | var purple200 = exports.purple200 = '#ce93d8'; 39 | var purple300 = exports.purple300 = '#ba68c8'; 40 | var purple400 = exports.purple400 = '#ab47bc'; 41 | var purple500 = exports.purple500 = '#9c27b0'; 42 | var purple600 = exports.purple600 = '#8e24aa'; 43 | var purple700 = exports.purple700 = '#7b1fa2'; 44 | var purple800 = exports.purple800 = '#6a1b9a'; 45 | var purple900 = exports.purple900 = '#4a148c'; 46 | var purpleA100 = exports.purpleA100 = '#ea80fc'; 47 | var purpleA200 = exports.purpleA200 = '#e040fb'; 48 | var purpleA400 = exports.purpleA400 = '#d500f9'; 49 | var purpleA700 = exports.purpleA700 = '#aa00ff'; 50 | 51 | var deepPurple50 = exports.deepPurple50 = '#ede7f6'; 52 | var deepPurple100 = exports.deepPurple100 = '#d1c4e9'; 53 | var deepPurple200 = exports.deepPurple200 = '#b39ddb'; 54 | var deepPurple300 = exports.deepPurple300 = '#9575cd'; 55 | var deepPurple400 = exports.deepPurple400 = '#7e57c2'; 56 | var deepPurple500 = exports.deepPurple500 = '#673ab7'; 57 | var deepPurple600 = exports.deepPurple600 = '#5e35b1'; 58 | var deepPurple700 = exports.deepPurple700 = '#512da8'; 59 | var deepPurple800 = exports.deepPurple800 = '#4527a0'; 60 | var deepPurple900 = exports.deepPurple900 = '#311b92'; 61 | var deepPurpleA100 = exports.deepPurpleA100 = '#b388ff'; 62 | var deepPurpleA200 = exports.deepPurpleA200 = '#7c4dff'; 63 | var deepPurpleA400 = exports.deepPurpleA400 = '#651fff'; 64 | var deepPurpleA700 = exports.deepPurpleA700 = '#6200ea'; 65 | 66 | var indigo50 = exports.indigo50 = '#e8eaf6'; 67 | var indigo100 = exports.indigo100 = '#c5cae9'; 68 | var indigo200 = exports.indigo200 = '#9fa8da'; 69 | var indigo300 = exports.indigo300 = '#7986cb'; 70 | var indigo400 = exports.indigo400 = '#5c6bc0'; 71 | var indigo500 = exports.indigo500 = '#3f51b5'; 72 | var indigo600 = exports.indigo600 = '#3949ab'; 73 | var indigo700 = exports.indigo700 = '#303f9f'; 74 | var indigo800 = exports.indigo800 = '#283593'; 75 | var indigo900 = exports.indigo900 = '#1a237e'; 76 | var indigoA100 = exports.indigoA100 = '#8c9eff'; 77 | var indigoA200 = exports.indigoA200 = '#536dfe'; 78 | var indigoA400 = exports.indigoA400 = '#3d5afe'; 79 | var indigoA700 = exports.indigoA700 = '#304ffe'; 80 | 81 | var blue50 = exports.blue50 = '#e3f2fd'; 82 | var blue100 = exports.blue100 = '#bbdefb'; 83 | var blue200 = exports.blue200 = '#90caf9'; 84 | var blue300 = exports.blue300 = '#64b5f6'; 85 | var blue400 = exports.blue400 = '#42a5f5'; 86 | var blue500 = exports.blue500 = '#2196f3'; 87 | var blue600 = exports.blue600 = '#1e88e5'; 88 | var blue700 = exports.blue700 = '#1976d2'; 89 | var blue800 = exports.blue800 = '#1565c0'; 90 | var blue900 = exports.blue900 = '#0d47a1'; 91 | var blueA100 = exports.blueA100 = '#82b1ff'; 92 | var blueA200 = exports.blueA200 = '#448aff'; 93 | var blueA400 = exports.blueA400 = '#2979ff'; 94 | var blueA700 = exports.blueA700 = '#2962ff'; 95 | 96 | var lightBlue50 = exports.lightBlue50 = '#e1f5fe'; 97 | var lightBlue100 = exports.lightBlue100 = '#b3e5fc'; 98 | var lightBlue200 = exports.lightBlue200 = '#81d4fa'; 99 | var lightBlue300 = exports.lightBlue300 = '#4fc3f7'; 100 | var lightBlue400 = exports.lightBlue400 = '#29b6f6'; 101 | var lightBlue500 = exports.lightBlue500 = '#03a9f4'; 102 | var lightBlue600 = exports.lightBlue600 = '#039be5'; 103 | var lightBlue700 = exports.lightBlue700 = '#0288d1'; 104 | var lightBlue800 = exports.lightBlue800 = '#0277bd'; 105 | var lightBlue900 = exports.lightBlue900 = '#01579b'; 106 | var lightBlueA100 = exports.lightBlueA100 = '#80d8ff'; 107 | var lightBlueA200 = exports.lightBlueA200 = '#40c4ff'; 108 | var lightBlueA400 = exports.lightBlueA400 = '#00b0ff'; 109 | var lightBlueA700 = exports.lightBlueA700 = '#0091ea'; 110 | 111 | var cyan50 = exports.cyan50 = '#e0f7fa'; 112 | var cyan100 = exports.cyan100 = '#b2ebf2'; 113 | var cyan200 = exports.cyan200 = '#80deea'; 114 | var cyan300 = exports.cyan300 = '#4dd0e1'; 115 | var cyan400 = exports.cyan400 = '#26c6da'; 116 | var cyan500 = exports.cyan500 = '#00bcd4'; 117 | var cyan600 = exports.cyan600 = '#00acc1'; 118 | var cyan700 = exports.cyan700 = '#0097a7'; 119 | var cyan800 = exports.cyan800 = '#00838f'; 120 | var cyan900 = exports.cyan900 = '#006064'; 121 | var cyanA100 = exports.cyanA100 = '#84ffff'; 122 | var cyanA200 = exports.cyanA200 = '#18ffff'; 123 | var cyanA400 = exports.cyanA400 = '#00e5ff'; 124 | var cyanA700 = exports.cyanA700 = '#00b8d4'; 125 | 126 | var teal50 = exports.teal50 = '#e0f2f1'; 127 | var teal100 = exports.teal100 = '#b2dfdb'; 128 | var teal200 = exports.teal200 = '#80cbc4'; 129 | var teal300 = exports.teal300 = '#4db6ac'; 130 | var teal400 = exports.teal400 = '#26a69a'; 131 | var teal500 = exports.teal500 = '#009688'; 132 | var teal600 = exports.teal600 = '#00897b'; 133 | var teal700 = exports.teal700 = '#00796b'; 134 | var teal800 = exports.teal800 = '#00695c'; 135 | var teal900 = exports.teal900 = '#004d40'; 136 | var tealA100 = exports.tealA100 = '#a7ffeb'; 137 | var tealA200 = exports.tealA200 = '#64ffda'; 138 | var tealA400 = exports.tealA400 = '#1de9b6'; 139 | var tealA700 = exports.tealA700 = '#00bfa5'; 140 | 141 | var green50 = exports.green50 = '#e8f5e9'; 142 | var green100 = exports.green100 = '#c8e6c9'; 143 | var green200 = exports.green200 = '#a5d6a7'; 144 | var green300 = exports.green300 = '#81c784'; 145 | var green400 = exports.green400 = '#66bb6a'; 146 | var green500 = exports.green500 = '#4caf50'; 147 | var green600 = exports.green600 = '#43a047'; 148 | var green700 = exports.green700 = '#388e3c'; 149 | var green800 = exports.green800 = '#2e7d32'; 150 | var green900 = exports.green900 = '#1b5e20'; 151 | var greenA100 = exports.greenA100 = '#b9f6ca'; 152 | var greenA200 = exports.greenA200 = '#69f0ae'; 153 | var greenA400 = exports.greenA400 = '#00e676'; 154 | var greenA700 = exports.greenA700 = '#00c853'; 155 | 156 | var lightGreen50 = exports.lightGreen50 = '#f1f8e9'; 157 | var lightGreen100 = exports.lightGreen100 = '#dcedc8'; 158 | var lightGreen200 = exports.lightGreen200 = '#c5e1a5'; 159 | var lightGreen300 = exports.lightGreen300 = '#aed581'; 160 | var lightGreen400 = exports.lightGreen400 = '#9ccc65'; 161 | var lightGreen500 = exports.lightGreen500 = '#8bc34a'; 162 | var lightGreen600 = exports.lightGreen600 = '#7cb342'; 163 | var lightGreen700 = exports.lightGreen700 = '#689f38'; 164 | var lightGreen800 = exports.lightGreen800 = '#558b2f'; 165 | var lightGreen900 = exports.lightGreen900 = '#33691e'; 166 | var lightGreenA100 = exports.lightGreenA100 = '#ccff90'; 167 | var lightGreenA200 = exports.lightGreenA200 = '#b2ff59'; 168 | var lightGreenA400 = exports.lightGreenA400 = '#76ff03'; 169 | var lightGreenA700 = exports.lightGreenA700 = '#64dd17'; 170 | 171 | var lime50 = exports.lime50 = '#f9fbe7'; 172 | var lime100 = exports.lime100 = '#f0f4c3'; 173 | var lime200 = exports.lime200 = '#e6ee9c'; 174 | var lime300 = exports.lime300 = '#dce775'; 175 | var lime400 = exports.lime400 = '#d4e157'; 176 | var lime500 = exports.lime500 = '#cddc39'; 177 | var lime600 = exports.lime600 = '#c0ca33'; 178 | var lime700 = exports.lime700 = '#afb42b'; 179 | var lime800 = exports.lime800 = '#9e9d24'; 180 | var lime900 = exports.lime900 = '#827717'; 181 | var limeA100 = exports.limeA100 = '#f4ff81'; 182 | var limeA200 = exports.limeA200 = '#eeff41'; 183 | var limeA400 = exports.limeA400 = '#c6ff00'; 184 | var limeA700 = exports.limeA700 = '#aeea00'; 185 | 186 | var yellow50 = exports.yellow50 = '#fffde7'; 187 | var yellow100 = exports.yellow100 = '#fff9c4'; 188 | var yellow200 = exports.yellow200 = '#fff59d'; 189 | var yellow300 = exports.yellow300 = '#fff176'; 190 | var yellow400 = exports.yellow400 = '#ffee58'; 191 | var yellow500 = exports.yellow500 = '#ffeb3b'; 192 | var yellow600 = exports.yellow600 = '#fdd835'; 193 | var yellow700 = exports.yellow700 = '#fbc02d'; 194 | var yellow800 = exports.yellow800 = '#f9a825'; 195 | var yellow900 = exports.yellow900 = '#f57f17'; 196 | var yellowA100 = exports.yellowA100 = '#ffff8d'; 197 | var yellowA200 = exports.yellowA200 = '#ffff00'; 198 | var yellowA400 = exports.yellowA400 = '#ffea00'; 199 | var yellowA700 = exports.yellowA700 = '#ffd600'; 200 | 201 | var amber50 = exports.amber50 = '#fff8e1'; 202 | var amber100 = exports.amber100 = '#ffecb3'; 203 | var amber200 = exports.amber200 = '#ffe082'; 204 | var amber300 = exports.amber300 = '#ffd54f'; 205 | var amber400 = exports.amber400 = '#ffca28'; 206 | var amber500 = exports.amber500 = '#ffc107'; 207 | var amber600 = exports.amber600 = '#ffb300'; 208 | var amber700 = exports.amber700 = '#ffa000'; 209 | var amber800 = exports.amber800 = '#ff8f00'; 210 | var amber900 = exports.amber900 = '#ff6f00'; 211 | var amberA100 = exports.amberA100 = '#ffe57f'; 212 | var amberA200 = exports.amberA200 = '#ffd740'; 213 | var amberA400 = exports.amberA400 = '#ffc400'; 214 | var amberA700 = exports.amberA700 = '#ffab00'; 215 | 216 | var orange50 = exports.orange50 = '#fff3e0'; 217 | var orange100 = exports.orange100 = '#ffe0b2'; 218 | var orange200 = exports.orange200 = '#ffcc80'; 219 | var orange300 = exports.orange300 = '#ffb74d'; 220 | var orange400 = exports.orange400 = '#ffa726'; 221 | var orange500 = exports.orange500 = '#ff9800'; 222 | var orange600 = exports.orange600 = '#fb8c00'; 223 | var orange700 = exports.orange700 = '#f57c00'; 224 | var orange800 = exports.orange800 = '#ef6c00'; 225 | var orange900 = exports.orange900 = '#e65100'; 226 | var orangeA100 = exports.orangeA100 = '#ffd180'; 227 | var orangeA200 = exports.orangeA200 = '#ffab40'; 228 | var orangeA400 = exports.orangeA400 = '#ff9100'; 229 | var orangeA700 = exports.orangeA700 = '#ff6d00'; 230 | 231 | var deepOrange50 = exports.deepOrange50 = '#fbe9e7'; 232 | var deepOrange100 = exports.deepOrange100 = '#ffccbc'; 233 | var deepOrange200 = exports.deepOrange200 = '#ffab91'; 234 | var deepOrange300 = exports.deepOrange300 = '#ff8a65'; 235 | var deepOrange400 = exports.deepOrange400 = '#ff7043'; 236 | var deepOrange500 = exports.deepOrange500 = '#ff5722'; 237 | var deepOrange600 = exports.deepOrange600 = '#f4511e'; 238 | var deepOrange700 = exports.deepOrange700 = '#e64a19'; 239 | var deepOrange800 = exports.deepOrange800 = '#d84315'; 240 | var deepOrange900 = exports.deepOrange900 = '#bf360c'; 241 | var deepOrangeA100 = exports.deepOrangeA100 = '#ff9e80'; 242 | var deepOrangeA200 = exports.deepOrangeA200 = '#ff6e40'; 243 | var deepOrangeA400 = exports.deepOrangeA400 = '#ff3d00'; 244 | var deepOrangeA700 = exports.deepOrangeA700 = '#dd2c00'; 245 | 246 | var brown50 = exports.brown50 = '#efebe9'; 247 | var brown100 = exports.brown100 = '#d7ccc8'; 248 | var brown200 = exports.brown200 = '#bcaaa4'; 249 | var brown300 = exports.brown300 = '#a1887f'; 250 | var brown400 = exports.brown400 = '#8d6e63'; 251 | var brown500 = exports.brown500 = '#795548'; 252 | var brown600 = exports.brown600 = '#6d4c41'; 253 | var brown700 = exports.brown700 = '#5d4037'; 254 | var brown800 = exports.brown800 = '#4e342e'; 255 | var brown900 = exports.brown900 = '#3e2723'; 256 | 257 | var blueGrey50 = exports.blueGrey50 = '#eceff1'; 258 | var blueGrey100 = exports.blueGrey100 = '#cfd8dc'; 259 | var blueGrey200 = exports.blueGrey200 = '#b0bec5'; 260 | var blueGrey300 = exports.blueGrey300 = '#90a4ae'; 261 | var blueGrey400 = exports.blueGrey400 = '#78909c'; 262 | var blueGrey500 = exports.blueGrey500 = '#607d8b'; 263 | var blueGrey600 = exports.blueGrey600 = '#546e7a'; 264 | var blueGrey700 = exports.blueGrey700 = '#455a64'; 265 | var blueGrey800 = exports.blueGrey800 = '#37474f'; 266 | var blueGrey900 = exports.blueGrey900 = '#263238'; 267 | 268 | var grey50 = exports.grey50 = '#fafafa'; 269 | var grey100 = exports.grey100 = '#f5f5f5'; 270 | var grey200 = exports.grey200 = '#eeeeee'; 271 | var grey300 = exports.grey300 = '#e0e0e0'; 272 | var grey400 = exports.grey400 = '#bdbdbd'; 273 | var grey500 = exports.grey500 = '#9e9e9e'; 274 | var grey600 = exports.grey600 = '#757575'; 275 | var grey700 = exports.grey700 = '#616161'; 276 | var grey800 = exports.grey800 = '#424242'; 277 | var grey900 = exports.grey900 = '#212121'; 278 | 279 | var black = exports.black = '#000000'; 280 | var white = exports.white = '#ffffff'; 281 | 282 | var transparent = exports.transparent = 'rgba(0, 0, 0, 0)'; 283 | var fullBlack = exports.fullBlack = 'rgba(0, 0, 0, 1)'; 284 | var darkBlack = exports.darkBlack = 'rgba(0, 0, 0, 0.87)'; 285 | var lightBlack = exports.lightBlack = 'rgba(0, 0, 0, 0.54)'; 286 | var minBlack = exports.minBlack = 'rgba(0, 0, 0, 0.26)'; 287 | var faintBlack = exports.faintBlack = 'rgba(0, 0, 0, 0.12)'; 288 | var fullWhite = exports.fullWhite = 'rgba(255, 255, 255, 1)'; 289 | var darkWhite = exports.darkWhite = 'rgba(255, 255, 255, 0.87)'; 290 | var lightWhite = exports.lightWhite = 'rgba(255, 255, 255, 0.54)'; 291 | -------------------------------------------------------------------------------- /src/done-black.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export const Done = ({ color }) => ( 5 | 12 | 13 | 14 | 15 | ); 16 | 17 | Done.propTypes = { 18 | color: PropTypes.string.isRequired, 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /src/stories/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf, action, setAddon } from '@storybook/react'; 3 | import infoAddon from '@storybook/addon-info'; 4 | import { withKnobs, text, object } from '@storybook/addon-knobs'; 5 | 6 | // import MaterialColorPicker from 'react-material-color-picker'; 7 | import MaterialColorPicker from '../MaterialColorPicker.jsx'; 8 | 9 | 10 | setAddon(infoAddon); 11 | 12 | 13 | function actionLog(title) { 14 | return (event) => { 15 | const data = { ...event }; 16 | data.target.node = 'console.log(event.target.node)'; 17 | 18 | action(`${title || ''}${data.type}: ${data.target.value}`.trim())(data); 19 | }; 20 | } 21 | 22 | storiesOf('Material Color Picker', module) 23 | .addDecorator((story) => ( 24 |
34 | {story()} 35 |
36 | )) 37 | .addDecorator(withKnobs) 38 | .add('default view', () => ( 39 | 40 |
41 | 46 |
47 | 48 | )) 49 | .add('fullwidth view', () => ( 50 | 51 |
52 | 58 |
59 | 60 | )) 61 | .add('events', () => ( 62 | 63 |
64 | 71 |
72 | 73 | )) 74 | // storiesOf('Material Color Picker', module) 75 | .addWithInfo('API', ` 76 | [![GitHub version](https://badge.fury.io/gh/sm-react%2Freact-material-color-picker.svg)](https://badge.fury.io/gh/sm-react%2Freact-material-color-picker) 77 | [![npm version](https://badge.fury.io/js/react-material-color-picker.svg)](https://badge.fury.io/js/react-material-color-picker) 78 | 79 | #### Props and Callbacks 80 | **initColor** should be color string from Goggle material color palette 81 | 82 | **style** - inline style of the root div node 83 | 84 | **submitLabel** and **resetLabel** are titles of the appropriate buttons 85 | 86 | **onSubmit** and **onReset** are callbacks wich will be invoked by clicking the 87 | appropriate buttons. It will recieve an argument with the following structure: 88 | ~~~js 89 | event = { 90 | type, // 'submit' || 'reset', 91 | timeStamp, // nativeEvent.timeStamp, 92 | target: { 93 | value, // currient color string, 94 | nativeEvent, // nativeEvent, 95 | name: 'MaterialColorPicker', 96 | node, // ref to root div element, 97 | ...this.props, 98 | } 99 | }; 100 | ~~~ 101 | 102 | [![@UsulPro](https://img.shields.io/badge/github-UsulPro-blue.svg)](https://github.com/UsulPro) 103 | [![@sm-react](https://img.shields.io/badge/github-smARTLight-red.svg)](https://github.com/sm-react) 104 | `, () => ( 105 |
106 | 114 |
115 | ), { inline: true, source: false }) 116 | .addWithInfo('try props', 117 | ` 118 | -> 119 | 120 | -> 121 | #### select the \`KNOBS\` tab to get access for props 122 | `, 123 | () => { 124 | const style = { 125 | width: 400, 126 | backgroundColor: '#c7c7c7', 127 | }; 128 | return (
129 | 137 |
); 138 | }, { inline: true, source: false, header: false }); 139 | -------------------------------------------------------------------------------- /src/tests/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow, mount } from 'enzyme'; 3 | import { expect } from 'chai'; 4 | import sinon from 'sinon'; 5 | import MaterialColorPicker from '../MaterialColorPicker.jsx'; 6 | const { describe, it } = global; 7 | 8 | describe('### ###\n\n', () => { 9 | it('should show 20 tone swatches', () => { 10 | const wrapper = shallow(); 11 | const tonewrap = wrapper.find('.material-color-picker-tone-swatches'); 12 | expect(tonewrap.children()).to.have.length(20); 13 | }); 14 | 15 | it('should show right color name /* deepOrange800 */', () => { 16 | const wrapper = shallow(); 17 | const titlewrap = wrapper.find('.material-color-picker-title'); 18 | expect(titlewrap.childAt(0).text()).to.be.equal('deepOrange800'); 19 | }); 20 | 21 | it('should show right color name /* darkBlack */', () => { 22 | const wrapper = shallow(); 23 | const titlewrap = wrapper.find('.material-color-picker-title'); 24 | expect(titlewrap.childAt(0).text()).to.be.equal('darkBlack'); 25 | }); 26 | 27 | it('should show right color in preview', () => { 28 | const initColor = 'rgba(255, 255, 255, 0.87)'; 29 | const wrapper = shallow(); 30 | const previewwrap = wrapper.find('.material-color-picker-preview'); 31 | expect(previewwrap.props().style.backgroundColor) 32 | .to.be.equal(initColor); 33 | }); 34 | 35 | it('should handle the onSubmit event', () => { 36 | const clickMe = sinon.stub(); 37 | // Here we do a JSDOM render. So, that's why we need to 38 | // wrap this with a div. 39 | const wrapper = mount( 40 |
41 | 45 |
46 | ); 47 | wrapper.find('.material-color-picker-submit').simulate('click'); 48 | expect(clickMe.callCount).to.be.equal(1); 49 | }); 50 | 51 | it('should switch colors tones', () => { 52 | const clickMe = sinon.stub(); 53 | const wrapper = mount( 54 |
55 | 59 |
60 | ); 61 | 62 | const tonesw = wrapper.find('.material-color-picker-tone-swatches'); 63 | const previewwrap = wrapper.find('.material-color-picker-preview'); 64 | const satwrap = wrapper.find('.material-color-picker-sat-swatches'); 65 | 66 | /* red */ 67 | tonesw.childAt(0).simulate('click'); 68 | expect(satwrap.children()).to.have.length(14); 69 | expect(previewwrap.props().style.backgroundColor) 70 | .to.be.equal('#ffebee'); 71 | 72 | /* indigo */ 73 | tonesw.childAt(4).simulate('click'); 74 | expect(satwrap.children()).to.have.length(14); 75 | expect(previewwrap.props().style.backgroundColor) 76 | .to.be.equal('#e8eaf6'); 77 | 78 | /* brown */ 79 | tonesw.childAt(16).simulate('click'); 80 | expect(satwrap.children()).to.have.length(10); 81 | expect(previewwrap.props().style.backgroundColor) 82 | .to.be.equal('#efebe9'); 83 | 84 | /* grey */ 85 | tonesw.childAt(18).simulate('click'); 86 | expect(satwrap.children()).to.have.length(10); 87 | expect(previewwrap.props().style.backgroundColor) 88 | .to.be.equal('#fafafa'); 89 | 90 | /* black */ 91 | tonesw.childAt(19).simulate('click'); 92 | expect(satwrap.children()).to.have.length(10); 93 | expect(previewwrap.props().style.backgroundColor) 94 | .to.be.equal(undefined); 95 | }); 96 | }); 97 | 98 | -------------------------------------------------------------------------------- /storybook.md: -------------------------------------------------------------------------------- 1 | ## Deploy 2 | Storybook deployed to: [https://sm-react.github.io/react-material-color-picker](https://sm-react.github.io/react-material-color-picker) 3 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --compilers png:./mochacfg.js --------------------------------------------------------------------------------