UNPKG

chayns-components

Version:

A set of beautiful React components for developing chayns® applications.

429 lines (423 loc) 15.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _clsx = _interopRequireDefault(require("clsx")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _Bubble = _interopRequireDefault(require("../../react-chayns-bubble/component/Bubble")); var _color = require("../../utils/color"); var _is = require("../../utils/is"); var _ColorArea = _interopRequireDefault(require("./colorArea/ColorArea")); var _ColorInput = _interopRequireDefault(require("./colorInput/ColorInput")); require("./ColorPicker.css"); var _HueSlider = _interopRequireDefault(require("./hueSlider/HueSlider")); var _TransparencySlider = _interopRequireDefault(require("./transparencySlider/TransparencySlider")); var _isDescendant = _interopRequireDefault(require("../../utils/isDescendant")); var _ColorSelection = _interopRequireDefault(require("./colorSelection/ColorSelection")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * @component */ const getHsvColor = color => { if ((0, _is.isString)(color)) { // HEX(A) return (0, _color.hexStringToHsv)(color); } if (color.r !== undefined) { // RGB(A) (0-255) return (0, _color.rgbToHsv)(color); } if (color.h !== undefined) { // HSV(A) return color; } return { h: 0, s: 0, v: 0, a: 1 }; }; /** * Lets a user choose a color for text, shapes, marking tools, and other * elements. */ const ColorPicker = /*#__PURE__*/(0, _react.forwardRef)((_ref, reference) => { let { defaultColorModel, transparency = false, onChangeEnd, input = false, color, onBlur, inline = false, children, removeParentSpace = false, parent, onChange, style, className, bubblePosition = _Bubble.default.position.BOTTOM_CENTER, bubbleClassName, bubbleStyle, showAllColorModels = false, customColorsArray, showCustomColors = false, showGlobalColors = false, onCreateCustomColor, onRemoveCustomColor } = _ref; // references const bubbleRef = (0, _react.useRef)(null); const bubbleContentRef = (0, _react.useRef)(null); const linkRef = (0, _react.useRef)(null); const childrenRef = (0, _react.useRef)(null); // state const [colorState, setColor] = (0, _react.useState)(getHsvColor(color)); const [coordinates, setCoordinates] = (0, _react.useState)({ x: 0, y: 0 }); const [colorModel, setColorModel] = (0, _react.useState)(defaultColorModel !== null && defaultColorModel !== void 0 ? defaultColorModel : transparency ? ColorPicker.colorModels.RGB : ColorPicker.colorModels.HEX); const [customColorsState, setCustomColorsState] = (0, _react.useState)(customColorsArray ? customColorsArray.map(c => getHsvColor(c)) : []); (0, _react.useEffect)(() => { if (customColorsArray) { setCustomColorsState(customColorsArray.map(c => getHsvColor(c))); } else { setCustomColorsState([]); } }, [customColorsArray]); // effects (lifecycle methods) (0, _react.useEffect)(() => { setColor(getHsvColor(color)); }, [color]); const closeBubble = (0, _react.useCallback)(async event => { // Hide bubble and remove event listeners if click was outside of the bubble if (event.type === 'blur' || !(event.target === bubbleContentRef.current || (0, _isDescendant.default)(bubbleContentRef.current, event.target))) { document.removeEventListener('click', closeBubble); window.removeEventListener('blur', closeBubble); if (bubbleRef.current) { bubbleRef.current.hide(); } if (onBlur) { onBlur(color); } if (chayns.env.isApp || chayns.env.isMyChaynsApp) { chayns.allowRefreshScroll(); } } }, [color, onBlur]); const openBubble = (0, _react.useCallback)(async () => { if (inline) { return; } const ref = children ? childrenRef : linkRef; const rect = ref.current.getBoundingClientRect(); let newX = rect.left + rect.width / 2; let newY = rect.bottom + (chayns.env.isApp ? (await chayns.getWindowMetrics()).pageYOffset : 0); if (removeParentSpace) { const parentRect = (parent || document.getElementsByClassName('tapp')[0] || document.body).getBoundingClientRect(); newX -= parentRect.left; newY -= parentRect.top; } setCoordinates({ x: newX, y: newY }); bubbleRef.current.show(); // Add event listeners to hide the bubble document.addEventListener('click', closeBubble, { capture: true }); // window.addEventListener('blur', closeBubble); if (chayns.env.isApp || chayns.env.isMyChaynsApp) { chayns.disallowRefreshScroll(); } }, [inline, children, removeParentSpace, closeBubble, parent]); const onChangeCallback = (0, _react.useCallback)(newColor => { setColor(newColor); if (onChange) { onChange(newColor); } }, [setColor, onChange]); const onCreateCustomColorCallback = (0, _react.useCallback)(newColor => { if (onCreateCustomColor) { onCreateCustomColor(newColor); } }, [onCreateCustomColor]); const onRemoveCustomColorCallback = (0, _react.useCallback)(newColor => { if (onRemoveCustomColor) { onRemoveCustomColor(newColor); } }, [onRemoveCustomColor]); const onColorModelToggle = (0, _react.useCallback)(() => { setColorModel((colorModel + 1) % Object.keys(ColorPicker.colorModels).length); }, [setColorModel, colorModel]); const rgb255 = (0, _color.hsvToRgb)(colorState); (0, _react.useImperativeHandle)(reference, () => ({ show: openBubble })); if (inline) { return /*#__PURE__*/_react.default.createElement("div", { className: (0, _clsx.default)('cc__color-picker', className), style: { width: '322px', ...style }, onClick: openBubble, key: "div", ref: childrenRef }, /*#__PURE__*/_react.default.createElement("div", { ref: bubbleContentRef, className: "cc__color-picker__bubble-content" }, /*#__PURE__*/_react.default.createElement(_ColorArea.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd }), /*#__PURE__*/_react.default.createElement("div", { style: { padding: '0 11px' } }, /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', flexDirection: 'row' } }, /*#__PURE__*/_react.default.createElement("div", { style: {}, className: transparency ? 'cc__color-picker__slider-container__with-transparency' : 'cc__color-picker__slider-container__without-transparency' }, /*#__PURE__*/_react.default.createElement(_HueSlider.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd, showTooltip: false }), transparency && /*#__PURE__*/_react.default.createElement(_TransparencySlider.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd })), transparency && /*#__PURE__*/_react.default.createElement("div", { className: "cc__color-picker__color-square", style: { backgroundColor: (0, _color.hsvToHexString)(colorState) } }))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_ColorSelection.default, { customColorsArray: customColorsState, showCustomColors: showCustomColors, showGlobalColors: showGlobalColors, color: colorState, onChange: c => { onChangeCallback(c); onChangeEnd === null || onChangeEnd === void 0 ? void 0 : onChangeEnd(c); }, onCreateCustomColor: onCreateCustomColorCallback, onRemoveCustomColor: onRemoveCustomColorCallback }), input && /*#__PURE__*/_react.default.createElement(_ColorInput.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd, onModelToggle: onColorModelToggle, colorModel: colorModel, transparency: transparency, showAllColorModels: showAllColorModels })))); } return [/*#__PURE__*/_react.default.createElement("div", { className: (0, _clsx.default)('cc__color-picker', className), style: style, onClick: openBubble, key: "div", ref: childrenRef }, children || [/*#__PURE__*/_react.default.createElement("div", { key: "circle", className: "cc__color-picker__color-circle", style: { backgroundColor: (0, _color.rgbToRgbString)(rgb255, true) } }), /*#__PURE__*/_react.default.createElement("div", { key: "link", className: "cc__color-picker__color-link chayns__color--headline chayns__border-color--headline", ref: linkRef }, colorModel === ColorPicker.colorModels.RGB ? (0, _color.rgbToRgbString)(rgb255, transparency) : (0, _color.rgbToHexString)(rgb255, transparency))]), /*#__PURE__*/_react.default.createElement(_Bubble.default, { ref: bubbleRef, coordinates: coordinates, position: bubblePosition, parent: parent, className: bubbleClassName, style: { width: '322px', ...bubbleStyle }, key: "bubble" }, /*#__PURE__*/_react.default.createElement("div", { ref: bubbleContentRef, className: "cc__color-picker__bubble-content" }, /*#__PURE__*/_react.default.createElement(_ColorArea.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd }), /*#__PURE__*/_react.default.createElement("div", { style: { padding: '0 11px' } }, /*#__PURE__*/_react.default.createElement("div", { style: { display: 'flex', flexDirection: 'row' } }, /*#__PURE__*/_react.default.createElement("div", { style: {}, className: transparency ? 'cc__color-picker__slider-container__with-transparency' : 'cc__color-picker__slider-container__without-transparency' }, /*#__PURE__*/_react.default.createElement(_HueSlider.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd, showTooltip: false }), transparency && /*#__PURE__*/_react.default.createElement(_TransparencySlider.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd })), transparency && /*#__PURE__*/_react.default.createElement("div", { className: "cc__color-picker__color-square", style: { backgroundColor: (0, _color.hsvToHexString)(colorState) } }))), /*#__PURE__*/_react.default.createElement("div", { style: { marginBottom: '5px' } }, /*#__PURE__*/_react.default.createElement(_ColorSelection.default, { customColorsArray: customColorsState, showCustomColors: showCustomColors, showGlobalColors: showGlobalColors, color: colorState, onChange: c => { onChangeCallback(c); onChangeEnd === null || onChangeEnd === void 0 ? void 0 : onChangeEnd(c); }, onCreateCustomColor: onCreateCustomColorCallback, onRemoveCustomColor: onRemoveCustomColorCallback }), input && /*#__PURE__*/_react.default.createElement(_ColorInput.default, { color: colorState, onChange: onChangeCallback, onChangeEnd: onChangeEnd, onModelToggle: onColorModelToggle, colorModel: colorModel, transparency: transparency, showAllColorModels: showAllColorModels }))))]; }); const colorPropType = _propTypes.default.oneOfType([_propTypes.default.string.isRequired, _propTypes.default.shape({ r: _propTypes.default.number.isRequired, g: _propTypes.default.number.isRequired, b: _propTypes.default.number.isRequired, a: _propTypes.default.number }).isRequired, _propTypes.default.shape({ h: _propTypes.default.number.isRequired, s: _propTypes.default.number.isRequired, v: _propTypes.default.number.isRequired, a: _propTypes.default.number }).isRequired]); ColorPicker.propTypes = { /** * Display the color picker without a bubble. */ inline: _propTypes.default.bool, /** * The current color. Either a HEX-string, an HSV(A)- or RGB(A)-object. */ color: colorPropType.isRequired, /** * The bubble position. The possible values are listed under the * `Bubble`-component. */ bubblePosition: _propTypes.default.number, /** * Will be called when changing the color. */ onChange: _propTypes.default.func, /** * Will be called after the color was changed. */ onChangeEnd: _propTypes.default.func, /** * Will be called when the picker loses focus. */ onBlur: _propTypes.default.func, /** * Wether the picker should show a transparency slider. */ transparency: _propTypes.default.bool, /** * The parent node the bubble should be rendered into. */ parent: typeof Element !== 'undefined' ? _propTypes.default.instanceOf(Element) : () => {}, /** * The classname that will be set on the children wrapper. */ className: _propTypes.default.string, /** * A React style object that will be assigned to the children wrapper * element. */ style: _propTypes.default.objectOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])), /** * A classname string that will be applied to the Bubble component. */ bubbleClassName: _propTypes.default.string, /** * A React style object that will be applied to the Bubble component. */ bubbleStyle: _propTypes.default.objectOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])), /** * Displays an input to type in the color. */ input: _propTypes.default.bool, /** * The color model that is used by default. */ defaultColorModel: _propTypes.default.number, /** * Children // TODO */ children: _propTypes.default.node, /** * Removes space from the parent to the page borders from the tooltip * position. This is only needed if the parent is padded from the page and * has a relative positioning. */ removeParentSpace: _propTypes.default.bool, /** * Shows all color models */ showAllColorModels: _propTypes.default.bool, /** * An array of custom selectable colors */ customColorsArray: _propTypes.default.arrayOf(colorPropType), /** * Shows custom colors */ showCustomColors: _propTypes.default.bool, /** * Shows global colors */ showGlobalColors: _propTypes.default.bool, /** * Will be called when a custom color is added */ onCreateCustomColor: _propTypes.default.func, /** * Will be called when a custom color is removed */ onRemoveCustomColor: _propTypes.default.func }; ColorPicker.colorModels = { HEX: 0, RGB: 1 }; ColorPicker.displayName = 'ColorPicker'; var _default = ColorPicker; exports.default = _default; //# sourceMappingURL=ColorPicker.js.map