UNPKG

react-color-palette-picker

Version:

React Color Picker Component written in typescript.

434 lines (410 loc) 23.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var colorConverter = require('@wilfredlopez/color-converter'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var classes = {"saturationCursor":"saturation-module_saturationCursor__3gE-Q","saturation":"saturation-module_saturation__aaXjp"}; function selectClass(classes) { var output = ''; //ONLY ACCEPTING ONE SelectorClasss var el = classes[0]; for (var key in el) { if (el[key]) { output += key; } } //IF ACCEPTING MORE THAN ONE SelectorClasss // for (let i = 0; i < classes.length; i++) { // const el = classes[i] // for (let key in el) { // if (el[key]) { // output += key // } // } // } return output; } var getCoordinatesByColor = colorConverter.canvasUtils.getCoordinatesByColor, moveAt = colorConverter.canvasUtils.moveAt, getColorByCoordinates = colorConverter.canvasUtils.getColorByCoordinates; var Saturation = function (_a) { var _b, _c; var canvasClass = _a.canvasClass, saturationCursorClass = _a.saturationCursorClass, containerClass = _a.containerClass, width = _a.width, height = _a.height, color = _a.color, setColor = _a.setColor; var paletteRef = React.useRef(null); var cursorPosition = React.useMemo(function () { var _a = getCoordinatesByColor(color.toColorObject(), width, height), x = _a[0], y = _a[1]; return { x: x, y: y }; }, [color, width, height]); React.useEffect(function () { var drawPalette = function () { if (paletteRef.current) { var ctx = paletteRef.current.getContext("2d"); if (ctx) { var saturation = ctx.createLinearGradient(0, height / 2, width, height / 2); saturation.addColorStop(0, "white"); var hsl = color.hslObject; saturation.addColorStop(1, "hsl(" + hsl.hue + ", 100%, 50%)"); ctx.fillStyle = saturation; ctx.fillRect(0, 0, width, height); var brightness = ctx.createLinearGradient(width / 2, 0, width / 2, height); brightness.addColorStop(0, "transparent"); brightness.addColorStop(1, "black"); ctx.fillStyle = brightness; ctx.fillRect(0, 0, width, height); } } }; if (paletteRef.current) drawPalette(); }, [width, height, color]); var moveCursor = React.useCallback(function (x, y, shiftX, shiftY) { var _a = moveAt({ value: x, shift: shiftX, min: 0, max: width }, { value: y, shift: shiftY, min: 0, max: height }), newX = _a[0], newY = _a[1]; if (newX > width) { newX = width; } if (newY > height) { newY = height; } if (newY === height && newX === width) { return; } var hue = color.hslObject.hue; var newColor = getColorByCoordinates(hue, newX, newY, width, height); setColor(new colorConverter.ColorConverter(newColor.hex, color.alpha, color.type, color.weight)); }, [color, height, width, setColor]); var onMouseDown = React.useCallback(function (e) { var _a; if (paletteRef.current) { if (e.button !== 0) return; (_a = document.getSelection()) === null || _a === void 0 ? void 0 : _a.empty(); var _b = paletteRef.current.getBoundingClientRect(), shiftX_1 = _b.left, shiftY_1 = _b.top; moveCursor(e.clientX, e.clientY, shiftX_1, shiftY_1); var mouseMove_1 = function (e) { if (e.button !== 0) return; if (paletteRef.current) { var _a = paletteRef.current.getBoundingClientRect(), left = _a.left, top_1 = _a.top; shiftX_1 = left; shiftY_1 = top_1; } moveCursor(e.clientX, e.clientY, shiftX_1, shiftY_1); }; var mouseUp_1 = function () { document.removeEventListener("mousemove", mouseMove_1, false); document.removeEventListener("mouseup", mouseUp_1, false); }; document.addEventListener("mousemove", mouseMove_1, false); document.addEventListener("mouseup", mouseUp_1, false); } }, [moveCursor]); var onTouchStart = React.useCallback(function (e) { var _a; if (paletteRef.current) { if (e.touches.length === 0) return; (_a = document.getSelection()) === null || _a === void 0 ? void 0 : _a.empty(); var _b = paletteRef.current.getBoundingClientRect(), shiftX_2 = _b.left, shiftY_2 = _b.top; var x = e.touches[0].pageX; var y = e.touches[0].pageY; moveCursor(x, y, shiftX_2, shiftY_2); var toucheMove_1 = function (e) { if (e.touches.length === 0) return; moveCursor(e.touches[0].pageX, e.touches[0].pageY, shiftX_2, shiftY_2); }; var mouseUp_2 = function () { document.removeEventListener('touchmove', toucheMove_1, false); document.removeEventListener('touchend', mouseUp_2, false); }; document.addEventListener("touchmove", toucheMove_1, false); document.addEventListener("touchend", mouseUp_2, false); } }, [moveCursor]); return (React__default['default'].createElement("div", { className: selectClass([(_b = {}, _b[classes.saturation] = !containerClass, _b[containerClass || ""] = !!containerClass, _b)]) }, React__default['default'].createElement("canvas", { className: canvasClass, ref: paletteRef, width: width, height: height, onTouchStart: onTouchStart, onMouseDown: onMouseDown }), React__default['default'].createElement("div", { className: selectClass([(_c = {}, _c[classes.saturationCursor] = !saturationCursorClass, _c[saturationCursorClass || ""] = !!saturationCursorClass, _c)]), style: { left: cursorPosition.x, top: cursorPosition.y, backgroundColor: color.hexString() } }))); }; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var classes$1 = {"hueBar":"huebar-module_hueBar__2ncjI","hueBarCursor":"huebar-module_hueBarCursor__1rF_Z"}; var getCoordinatesByHue = colorConverter.canvasUtils.getCoordinatesByHue, moveAt$1 = colorConverter.canvasUtils.moveAt, getHueByCoordinates = colorConverter.canvasUtils.getHueByCoordinates, changeHue = colorConverter.canvasUtils.changeHue; var toColorObject = colorConverter.canvasUtils.toColorObject; var HueBar = function (_a) { var _b, _c; var width = _a.width, color = _a.color, setColor = _a.setColor, containerClass = _a.containerClass, cursorClass = _a.cursorClass; var hueBarRef = React.useRef(null); var cursorPosition = React.useMemo(function () { var x = getCoordinatesByHue(color.hsbObject.hue, width); return x; }, [color, width]); var moveCursor = React.useCallback(function (x, shiftX) { var newX = moveAt$1({ value: x, shift: shiftX, min: 0, max: width, })[0]; try { var newHue = getHueByCoordinates(newX, width); var up = toColorObject('hsb', __assign(__assign({}, color.hsbObject), { hue: newHue })); var c = changeHue(up, newHue); setColor(new colorConverter.ColorConverter(c.hex)); } catch (error) { } }, [color, setColor, width]); var onMouseDown = React.useCallback(function (e) { var _a; if (hueBarRef.current) { if (e.button !== 0) return; (_a = document.getSelection()) === null || _a === void 0 ? void 0 : _a.empty(); var shiftX_1 = hueBarRef.current.getBoundingClientRect().left; moveCursor(e.clientX, shiftX_1); var mouseMove_1 = function (e) { moveCursor(e.clientX, shiftX_1); }; var mouseUp_1 = function () { document.removeEventListener("mousemove", mouseMove_1, false); document.removeEventListener("mouseup", mouseUp_1, false); }; document.addEventListener("mousemove", mouseMove_1, false); document.addEventListener("mouseup", mouseUp_1, false); } }, [moveCursor]); var onTouchStart = React.useCallback(function (e) { var _a; if (hueBarRef.current) { if (e.touches.length === 0) return; (_a = document.getSelection()) === null || _a === void 0 ? void 0 : _a.empty(); var shiftX_2 = hueBarRef.current.getBoundingClientRect().left; var x = e.touches[0].pageX; // const y = e.touches[0].pageY moveCursor(x, shiftX_2); var mouseMove_2 = function (e) { if (e.touches.length > 0) moveCursor(e.touches[0].pageX, shiftX_2); }; var mouseUp_2 = function () { document.removeEventListener('touchmove', mouseMove_2, false); document.removeEventListener('touchend', mouseUp_2, false); }; document.addEventListener("touchmove", mouseMove_2, false); document.addEventListener("touchend", mouseUp_2, false); } }, [moveCursor]); return (React__default['default'].createElement("div", { className: selectClass([ (_b = {}, _b[classes$1.hueBar] = !containerClass, _b[containerClass || ""] = true, _b) ]), ref: hueBarRef, style: { width: width, position: 'relative', backgroundImage: 'linear-gradient( to right, rgb(255, 0, 0), rgb(255, 255, 0), rgb(0, 255, 0), rgb(0, 255, 255), rgb(0, 0, 255), rgb(255, 0, 255), rgb(255, 0, 0) )' }, onMouseDown: onMouseDown, onTouchStart: onTouchStart }, React__default['default'].createElement("div", { className: selectClass([ (_c = {}, _c[classes$1.hueBarCursor] = !cursorClass, _c[cursorClass || ""] = true, _c) ]), style: { left: cursorPosition, backgroundColor: "hsl(" + color.hslObject.hue + ", 100%, 50%)" } }))); }; var classes$2 = {"dropdown":"dropdown-module_dropdown__W_0XV","dropdownTrigger":"dropdown-module_dropdownTrigger__1noD7","dropdownMenu":"dropdown-module_dropdownMenu__3Y6yC","dropdownMenuModel":"dropdown-module_dropdownMenuModel__3HMup"}; var models = ["hex", "rgb"]; //["hex", "rgb", "hsb"] var ColorModelsDropDown = function (_a) { var model = _a.model, setModel = _a.setModel; var dropDownRef = React.useRef(null); var _b = React.useState(false), isExpanded = _b[0], setIsExpanded = _b[1]; React.useEffect(function () { var onClickOutside = function () { if (isExpanded) setIsExpanded(false); }; document.addEventListener("click", onClickOutside, false); return function () { document.removeEventListener("click", onClickOutside, false); }; }, [isExpanded]); var onTriggerClick = React.useCallback(function () { setIsExpanded(!isExpanded); }, [isExpanded]); var onModelClick = React.useCallback(function (model) { setModel(model); }, [setModel]); return (React__default['default'].createElement("div", { className: classes$2.dropdown, ref: dropDownRef }, React__default['default'].createElement("div", { className: classes$2.dropdownTrigger, onClick: onTriggerClick }, model.toUpperCase()), React__default['default'].createElement("div", { className: classes$2.dropdownMenu, "aria-expanded": isExpanded }, models.map(function (model) { return (React__default['default'].createElement("div", { className: classes$2.dropdownMenuModel, key: model, onClick: function () { return onModelClick(model); } }, model.toUpperCase())); })))); }; var HexInput = function (_a) { var className = _a.className, color = _a.color, value = _a.value, onBlur = _a.onBlur, onChange = _a.onChange, onFocus = _a.onFocus; return (React__default['default'].createElement("input", { className: className, style: { backgroundColor: "" + color.hexString(), color: "" + color.getContrast().hexString(), }, type: "text", value: value, onFocus: onFocus, onChange: onChange, onBlur: onBlur })); }; var RBGOrHsbInput = function (_a) { var className = _a.className, color = _a.color, onChange = _a.onChange, colorModel = _a.colorModel; var sharedStyles = React.useMemo(function () { return ({ backgroundColor: "" + color.hexString(), color: "" + color.getContrast(), }); }, [color]); return (React__default['default'].createElement(React__default['default'].Fragment, null, React__default['default'].createElement("input", { className: className, id: colorModel === "rgb" ? "red" : "hue", style: sharedStyles, type: "number", value: (colorModel === "rgb" ? color.rgbObject.red : color.hsbObject.hue).toFixed(), onChange: onChange }), React__default['default'].createElement("input", { className: className, id: colorModel === "rgb" ? "green" : "saturation", style: sharedStyles, type: "number", value: (colorModel === "rgb" ? color.rgbObject.green : color.hsbObject.saturation).toFixed(), onChange: onChange }), React__default['default'].createElement("input", { className: className, id: colorModel === "rgb" ? "blue" : "brightness", style: sharedStyles, type: "number", value: (colorModel === "rgb" ? color.rgbObject.blue : color.hsbObject.brightness).toFixed(), onChange: onChange }))); }; var classes$3 = {"fields":"fields-module_fields__gwSOK","fieldsInput":"fields-module_fieldsInput__6_zA6"}; var isValidHex = colorConverter.canvasUtils.isValidHex, toColorObject$1 = colorConverter.canvasUtils.toColorObject, isValidRgb = colorConverter.canvasUtils.isValidRgb, isValidHsb = colorConverter.canvasUtils.isValidHsb; var Fields = function (_a) { var _b; var color = _a.color, setColor = _a.setColor, containerClass = _a.containerClass, inputClass = _a.inputClass; var _c = React.useState(color.hexString()), value = _c[0], setValue = _c[1]; var _d = React.useState(false), inputted = _d[0], setInputted = _d[1]; var _e = React.useState("hex"), colorModel = _e[0], setColorModel = _e[1]; var currentInputClass = React.useMemo(function () { var _a; return selectClass([ (_a = {}, _a[classes$3.fieldsInput] = !inputClass, _a[inputClass || ""] = true, _a) ]); }, [inputClass]); React.useEffect(function () { if (!inputted) { setValue(color.hexString()); } }, [inputted, color]); var onFocus = React.useCallback(function () { setInputted(true); }, []); var onBlur = React.useCallback(function () { setInputted(false); }, []); var onChange = React.useCallback(function (e) { var targetId = e.target.id; var newValue = e.target.value; if (colorModel === "hex") { if (isValidHex(newValue)) { // const updated = new ColorConverter(newValue) setColor(new colorConverter.ColorConverter(newValue)); // setValue(updated) } } else if (colorModel === "rgb") { if (isValidRgb(newValue)) { var red = targetId === "red" ? Number(newValue) : color.rgb[0]; var green = targetId === "green" ? Number(newValue) : color.rgb[1]; var blue = targetId === "blue" ? Number(newValue) : color.rgb[2]; var updated = new colorConverter.ColorConverter(toColorObject$1("rgb", { red: red, green: green, blue: blue }).hex); setColor(updated); // setValue(updated) } } else if (colorModel === "hsb") { if (targetId === "hue") { if (isValidHsb(true, newValue)) { var hue = Number(newValue); var hsb = __assign(__assign({}, color.hsbObject), { hue: hue }); var newCol = toColorObject$1("hsb", hsb); setColor(new colorConverter.ColorConverter(newCol.hex)); // setValue(new ColorConverter(newCol.hex)) } } else { if (isValidHsb(false, newValue)) { var saturation = targetId === "saturation" ? Number(newValue) : color.hsbObject.saturation; var brightness = targetId === "brightness" ? Number(newValue) : color.hsbObject.brightness; var hsb = __assign(__assign({}, color.hsbObject), { saturation: saturation, brightness: brightness }); setColor(new colorConverter.ColorConverter(toColorObject$1("hsb", hsb).hex)); } } } }, [color, colorModel, setColor]); return (React__default['default'].createElement("div", { className: selectClass([ (_b = {}, _b[classes$3.fields] = !containerClass, _b[containerClass || ""] = true, _b) ]) }, React__default['default'].createElement(ColorModelsDropDown, { model: colorModel, setModel: setColorModel }), colorModel === "hex" ? (React__default['default'].createElement(HexInput, { className: currentInputClass, value: value, color: color, onBlur: onBlur, onChange: onChange, onFocus: onFocus })) : (React__default['default'].createElement(RBGOrHsbInput, { className: currentInputClass, colorModel: colorModel, color: color, onChange: onChange })))); }; var classes$4 = {"colorPicker":"colorPicker-module_colorPicker__2IVpp","colorPickerBody":"colorPicker-module_colorPickerBody__11QkT"}; function parseColor(colorToParse) { if (colorToParse instanceof colorConverter.ColorConverter) { return colorToParse.hexString(); } var parsed = colorConverter.parse(colorToParse || '#3d7c7d'); if (!parsed) return '#3d7c7d'; var com = new colorConverter.ColorConverter(); if (parsed.type === "rgb") { // [this.rgb, this.alpha] = [[r, g, b], a] com.rgb = parsed.values; com.alpha = parsed.alpha; } else { com.alpha = parsed.alpha; com.rgb = colorConverter.convert.hsl.rgb(parsed.values).map(Math.round); } return com.hexString(); } var ReactColorPicker = function (_a) { var _b, _c; var _d, _e, _f, _g, _h, _j, _k; var _l = _a.width, width = _l === void 0 ? 400 : _l, _m = _a.height, height = _m === void 0 ? width : _m, color = _a.color, onChange = _a.onChange, hideControls = _a.hideControls, _o = _a.pickerClasses, pickerClasses = _o === void 0 ? {} : _o; var parsedColor = React.useMemo(function () { return parseColor(color); }, [color]); var _p = React.useState(new colorConverter.ColorConverter(parsedColor)), selectedColor = _p[0], setSelectedColor = _p[1]; function handleChange(color) { setSelectedColor(color); if (typeof onChange === 'function') { onChange(color.hexString(), color); } } return (React__default['default'].createElement("div", { className: selectClass([(_b = {}, _b[classes$4.colorPicker] = !pickerClasses.container, _b[pickerClasses.container || ""] = true, _b)]) }, React__default['default'].createElement(Saturation, { canvasClass: ((_d = pickerClasses.saturation) === null || _d === void 0 ? void 0 : _d.canvas) || "", containerClass: ((_e = pickerClasses.saturation) === null || _e === void 0 ? void 0 : _e.container) || "", saturationCursorClass: ((_f = pickerClasses.saturation) === null || _f === void 0 ? void 0 : _f.saturationCursor) || "", width: width, height: height, color: selectedColor, setColor: handleChange }), React__default['default'].createElement(HueBar, { containerClass: (_g = pickerClasses.hueBar) === null || _g === void 0 ? void 0 : _g.container, cursorClass: (_h = pickerClasses.hueBar) === null || _h === void 0 ? void 0 : _h.cursorClass, width: width, color: selectedColor, setColor: handleChange }), hideControls ? null : React__default['default'].createElement("div", { className: selectClass([ (_c = {}, _c[classes$4.colorPickerBody] = !pickerClasses.controlsContainer, _c[pickerClasses.controlsContainer || ""] = true, _c) ]), style: { width: width + 'px', } }, React__default['default'].createElement(Fields, { containerClass: (_j = pickerClasses.fields) === null || _j === void 0 ? void 0 : _j.container, inputClass: (_k = pickerClasses.fields) === null || _k === void 0 ? void 0 : _k.inputs, color: selectedColor, setColor: handleChange })))); }; function joinClass(classes) { return classes.join(' '); } exports.ReactColorPicker = ReactColorPicker; exports.joinClass = joinClass; exports.selectClass = selectClass; //# sourceMappingURL=index.js.map