UNPKG

react-tinted

Version:

A react wrapper for the Tinted color harmony wheel

347 lines (300 loc) 10.2 kB
import React, { useContext, useRef, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import chroma from 'chroma-js'; import { TintedWheel as TintedWheel$1, TintedPalette as TintedPalette$1 } from 'tinted'; export { colorModes } from 'tinted'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function createCommonjsModule(fn, basedir, module) { return module = { path: basedir, exports: {}, require: function (path, base) { return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); } }, fn(module, module.exports), module.exports; } function commonjsRequire () { throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); } var classnames = createCommonjsModule(function (module) { /*! Copyright (c) 2017 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg) && arg.length) { var inner = classNames.apply(null, arg); if (inner) { classes.push(inner); } } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if ( module.exports) { classNames.default = classNames; module.exports = classNames; } else { window.classNames = classNames; } }()); }); var WheelContext = /*#__PURE__*/React.createContext(null); function useWheel() { return useContext(WheelContext); } function TintedWheel(props) { var children = props.children, className = props.className, colorCount = props.colorCount, customColors = props.customColors, radius = props.radius, markerWidth = props.markerWidth, markerOutlineWidth = props.markerOutlineWidth, margin = props.margin, defaultSlice = props.defaultSlice, initRoot = props.initRoot, mode = props.mode, colorWheelImage = props.colorWheelImage, onColorsChanged = props.onColorsChanged, rest = _objectWithoutProperties(props, ["children", "className", "colorCount", "customColors", "radius", "markerWidth", "markerOutlineWidth", "margin", "defaultSlice", "initRoot", "mode", "colorWheelImage", "onColorsChanged"]); var rootElRef = useRef(); var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), wheel = _useState2[0], setWheel = _useState2[1]; useEffect(function () { var defaultMargin = markerWidth / 2 + markerOutlineWidth; var finalMargin = typeof margin === 'number' ? margin : defaultMargin; var wheel = new TintedWheel$1({ container: rootElRef.current, radius: radius, markerWidth: markerWidth, markerOutlineWidth: markerOutlineWidth, margin: finalMargin, defaultSlice: defaultSlice, initRoot: initRoot, initMode: mode, colorWheelImage: colorWheelImage }); setWheel(wheel); }, []); useEffect(function () { if (!wheel) return; wheel.setMode(mode); }, [wheel, mode]); useEffect(function () { if (!wheel || !onColorsChanged) return; wheel.dispatch.on('update-end.reactWheel', function () { var colorData = wheel._getVisibleMarkers().data(); var hexColors = colorData.map(function (d) { return chroma(d.color).hex(); }); onColorsChanged(hexColors, mode, wheel); }); return function () { wheel.dispatch.on('update-end.reactWheel', null); }; }, [wheel, onColorsChanged]); useEffect(function () { if (!wheel) return; var userData = customColors || colorCount; wheel.bindData(userData); }, [wheel, colorCount, customColors]); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("svg", _extends({}, rest, { ref: rootElRef, className: classnames('tinted-wheel', className) })), /*#__PURE__*/React.createElement(WheelContext.Provider, { value: wheel }, children)); } TintedWheel.propTypes = { colorCount: PropTypes.number, customColors: PropTypes.array, radius: PropTypes.number, markerWidth: PropTypes.number, markerOutlineWidth: PropTypes.number, margin: PropTypes.number, defaultSlice: PropTypes.number, initRoot: PropTypes.string, mode: PropTypes.oneOf(Object.values(TintedWheel$1.MODES)), colorWheelImage: PropTypes.string, onColorsChanged: PropTypes.func }; TintedWheel.defaultProps = { colorCount: 5, radius: 100, markerWidth: 25, markerOutlineWidth: 1, defaultSlice: 20, initRoot: 'red', mode: TintedWheel$1.MODES.ANALOGOUS, colorWheelImage: 'https://zposten.github.io/tinted/wheel.png' }; function TintedPalette(props) { var children = props.children, className = props.className, rest = _objectWithoutProperties(props, ["children", "className"]); var wheel = useWheel(); var rootElRef = useRef(); var paletteRef = useRef(); var _useState = useState([]), _useState2 = _slicedToArray(_useState, 2), hexColors = _useState2[0], setHexColors = _useState2[1]; useEffect(function () { if (!wheel) return; var palette = new TintedPalette$1({ container: rootElRef.current, colorWheel: wheel }); wheel.dispatch.on('bind-data.reactPalette', function (data) { palette.render(data, wheel); }); wheel.dispatch.on('markers-updated.reactPalette', function () { palette.onColorValuesChanged(wheel.currentMode); }); wheel.dispatch.on('update-end.reactPalette', function () { var colorData = wheel._getVisibleMarkers().data(); var hexColors = colorData.map(function (d) { return chroma(d.color).hex(); }); setHexColors(hexColors); }); return function () { wheel.dispatch.on('bind-data.reactPalette', null); wheel.dispatch.on('markers-updated.reactPalette', null); wheel.dispatch.on('update-end.reactPalette', null); }; }, [wheel]); useEffect(function () { if (wheel) return; paletteRef.current; }); // Throw an error if multiple child elements are passed React.Children.only(children); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", _extends({}, rest, { ref: rootElRef, className: classnames('tinted-palette', className) })), children && /*#__PURE__*/React.createElement("div", { className: "tinted-palette-for-each-color" }, // Duplicate the children once for each color hexColors.map(function (hexColor, i) { var order = markerDistance(i); var clonedChild = /*#__PURE__*/React.cloneElement(children, { hexColor: hexColor, order: order }); return /*#__PURE__*/React.createElement(React.Fragment, { key: "".concat(hexColor, "-").concat(i) }, clonedChild); }))); } // Stolen from tinted/src/util.js function markerDistance(i) { return Math.ceil(i / 2) * Math.pow(-1, i + 1); } export { TintedPalette, TintedWheel, useWheel }; //# sourceMappingURL=index.js.map