diff --git a/src/assets/icons/adjust.svg b/src/assets/icons/adjust.svg new file mode 100644 index 0000000..e77beff --- /dev/null +++ b/src/assets/icons/adjust.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Paper/components/Palette/index.js b/src/components/Paper/components/Palette/index.js index a5ce924..f680cd4 100644 --- a/src/components/Paper/components/Palette/index.js +++ b/src/components/Paper/components/Palette/index.js @@ -2,21 +2,25 @@ import styles from './styles.module.css'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { PALETTE_DARK, PALETTE_LIGHT } from './../../constants'; +import { isDarkColor } from './../../../../helpers'; import { useSelector } from 'react-redux'; import { memo } from 'react'; import { useState } from 'react'; import { SketchPicker } from 'react-color'; import Draggable from 'react-draggable'; import { ReactComponent as CloseIcon } from './../../../../assets/icons/close.svg'; +import { ReactComponent as AdjustIcon } from './../../../../assets/icons/adjust.svg'; import { useEffect } from 'react'; +import Tooltip from 'rc-tooltip'; function Palette(props) { const isDarkMode = useSelector((state) => state.settings.isDarkMode); const palette = isDarkMode ? PALETTE_DARK : PALETTE_LIGHT; let selectedColor = props.selectedColor; - const [paletteColor, setPaletteColor] = useState('#fff'); - const [selectingColor, setSelectingColor] = useState(false); + const [paletteColor, setPaletteColor] = useState(isDarkMode ? '#fff' : '#000'); + const [customColor, setCustomColor] = useState(false); + const [colorSelectorToolVisible, enableColorSelectorTool] = useState(false); // If the user did select some shapes, we want to check if the shapes are all // of the same color. If so, we select that color. If not, we do not select @@ -33,40 +37,44 @@ function Palette(props) { } } - // change in custom color palette menu + // Change in custom color palette menu. const handlePaletteChange = (color) => { setPaletteColor(color.hex); - } + }; - // change in custom color palette menu completed + // Change in custom color palette menu completed. const handleChangeComplete = (color) => { setPaletteColor(color.hex); props.onSelectColor(color.hex); - } + }; - // custom color selected in top palette + // Custom color selected in top palette. const handleSelectCustom = () => { - setSelectingColor(!selectingColor); + setCustomColor(true); props.onSelectColor(paletteColor); - } + }; - // non-custom color selected in top palette + // Non-custom color selected in top palette. const handleSelectColor = (color) => { - setSelectingColor(false); + setCustomColor(false); props.onSelectColor(color); - } + }; + + const handleColorSelectorTool = () => { + enableColorSelectorTool(!colorSelectorToolVisible); + }; useEffect(() => { const handleClickOutside = (event) => { const selector = document.querySelector(`.${styles['color-palette__selector']}`); if (selector && !selector.contains(event.target)) { - setSelectingColor(false); + enableColorSelectorTool(false); } - } + }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); - }, [setSelectingColor]); + }, [enableColorSelectorTool]); return (
@@ -76,43 +84,50 @@ function Palette(props) { key={`color-palette__${color.substring(1)}`} onClick={() => handleSelectColor(color)} className={classNames(styles['color-palette__color'], { - [styles['color-palette__color-active']]: color === selectedColor, + [styles['color-palette__color-active']]: color === selectedColor && !customColor, })} style={{ backgroundColor: color }} /> ))} -
-
+ + +
+ +
+
- {selectingColor && - + {colorSelectorToolVisible && ( +
-
-
+
setSelectingColor(false)} + className={classNames(styles['custom-color-container__close-btn'])} + onClick={() => enableColorSelectorTool(false)} >
-
- } + )}
); } diff --git a/src/components/Paper/components/Palette/styles.module.css b/src/components/Paper/components/Palette/styles.module.css index dae5221..4b0e37e 100644 --- a/src/components/Paper/components/Palette/styles.module.css +++ b/src/components/Paper/components/Palette/styles.module.css @@ -13,6 +13,7 @@ } .color-palette__selector { + background: #fff; cursor: default; position: fixed; top: 10rem; @@ -21,21 +22,6 @@ display: block; align-items: center; justify-content: center; - padding: 5px; - border-radius: 7px; - box-shadow: 0 0 15px 0 rgba(0, 0, 0, .2); -} - -.color-palette__selector-header { - cursor: default; - position: fixed; - top: 7rem; - left: 50%; - transform: translateX(-50%); - display: block; - align-items: center; - justify-content: center; - padding: 5px; border-radius: 7px; box-shadow: 0 0 15px 0 rgba(0, 0, 0, .2); } @@ -62,35 +48,56 @@ transform: scale(0.6); } -@media (prefers-color-scheme: dark) { - .color-palette__container { - background: #323232; - } +.color-palette__custom-color svg { + pointer-events: none; + width: 100%; + height: 100%; + transform: scale(0.7) rotate(90deg); + fill: #000; } -@media (prefers-color-scheme: light) { - .color-palette__container { - background: #fff; - border: 1px solid #d1d1d1; - } +.color-palette__custom-color--dark svg { + fill: #fff; +} + +.custom-color-container__handle { + background-color: #fff; + border-radius: 5px 5px 0 0; + display: flex; + justify-content: flex-end; + position: relative; + margin: 3px; + top: 3px; } -.close-btn svg { - fill: #fd5865; +.custom-color-container__close-btn svg { height: 100%; min-width: 2.5rem; min-height: 2.5rem; max-width: 2.5rem; max-height: 2.5rem; - padding: 3px; - background-color: #ccc; + padding: 5px; border-radius: 100%; - margin: 1px; display: flex; justify-content: space-between; } -.close-btn svg:hover { +.custom-color-container__close-btn svg:hover { cursor: pointer; - background-color: #bbb; -} \ No newline at end of file +} + +@media (prefers-color-scheme: dark) { + .color-palette__container { + background: #323232; + } +} + +@media (prefers-color-scheme: light) { + .color-palette__selector { + border: 1px solid #d1d1d1; + } + .color-palette__container { + background: #fff; + border: 1px solid #d1d1d1; + } +} diff --git a/src/helpers.js b/src/helpers.js index ae00f22..e4e7df6 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -73,3 +73,25 @@ export function isEqual(obj1, obj2) { return true; } + +/** + * Check if a color is dark or light. + * + * @param {string} hex - The hex code to check. + * @returns {boolean} True when the color is considered a dark color. + */ +export function isDarkColor(hex) { + if (hex.length === 4) { + hex = hex.replace(/#(.)(.)(.)/, '#$1$1$2$2$3$3'); + } + + // Convert hex to RGB. + let r = parseInt(hex.substring(1, 3), 16); + let g = parseInt(hex.substring(3, 5), 16); + let b = parseInt(hex.substring(5, 7), 16); + + let luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255; + + // Check if the color is dark. + return luminance < 0.5; +} diff --git a/src/index.css b/src/index.css index 2a901cc..ede8c7e 100644 --- a/src/index.css +++ b/src/index.css @@ -256,6 +256,11 @@ hr { } } +.sketch-picker { + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + @media (prefers-color-scheme: light) { hr { border-top: 1px solid #d1d1d1;