UNPKG

react-email-builder

Version:
126 lines (125 loc) 4.48 kB
import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { HexColorPicker } from 'react-colorful'; import { getPresetColors } from './preset'; import { getCss } from '../../utils'; export function ColorPalette({ color: propColor, onChange, onSelect }) { const css = useCss(); const color = (propColor || '#000000').toUpperCase(); return (React.createElement("div", { className: css.root }, React.createElement("div", { className: css.colors }, getPresetColors().map((val) => (React.createElement("div", { key: val, className: clsx(css.color, { [css.active]: val === color }), onClick: () => { onChange(val); onSelect?.(); } }, React.createElement("div", { style: { backgroundColor: val } }))))), React.createElement(Input, { color: color, onChange: onChange }), React.createElement(HexColorPicker, { color: color, onChange: onChange, style: { width: '100%', height: 150 } }))); } function useCss() { return getCss('ColorPalette', (ns) => ({ root: ns(), colors: ns('colors'), color: ns('color'), active: ns('active'), form: ns('form'), mode: ns('mode'), input: ns('input'), selected: ns('selected'), preview: ns('preview') })); } function Input({ color, onChange }) { const [mode, setMode] = useState('hex'); const [focused, setFocused] = useState(false); const [input, setInput] = useState(''); const css = useCss(); useEffect(() => { if (!focused) { if (color) { setInput(mode === 'hex' ? color.toUpperCase() : hex2rgb(color)); } else { setInput(''); } } }, [mode, focused, color]); return (React.createElement("div", { className: css.form }, React.createElement("div", { className: css.mode }, React.createElement("div", { className: mode === 'hex' ? css.selected : '', onClick: () => { setMode('hex'); } }, "HEX"), React.createElement("div", { className: mode === 'rgb' ? css.selected : '', onClick: () => { setMode('rgb'); } }, "RGB")), React.createElement("div", { className: css.input }, React.createElement("input", { placeholder: "\u8BF7\u8F93\u5165", value: input, onFocus: () => { setFocused(true); }, onBlur: () => { setFocused(false); }, onChange: (e) => { const value = e.target.value; const newColor = parseColor(value); setInput(value); if (newColor) { onChange(newColor); } } })), React.createElement("div", { className: css.preview }, React.createElement("div", { style: { backgroundColor: color } })))); } function parseColor(color) { const val = color .trim() .replace(/rgba?/i, '') .replace(/[^0-9a-fA-F,.\s%]/g, ''); const arr = val.split(/[\s,]+/); let result; if (arr.length > 1 || val.includes('%')) { const hex = (s) => { let n = 0; if (s) { if (s.endsWith('%')) { n = Math.round(((+s.slice(0, -1) || 0) * 255) / 100); } else { n = Math.round(+s || 0); } } if (n < 0) { n = 0; } if (n > 255) { n = 255; } const h = n.toString(16); return h.length < 2 ? '0' + h : h; }; result = '#' + hex(arr[0]) + hex(arr[1]) + hex(arr[2]); } else { if (val.length === 3) { const [r, g, b] = val.split(''); result = '#' + r + r + g + g + b + b; } else if (val.length === 6) { result = '#' + val; } } return result?.toUpperCase(); } function hex2rgb(color) { const hex = parseColor(color); if (hex) { const num = (s) => parseInt(s, 16) || 0; return ('rgb(' + num(hex.slice(1, 3)) + ', ' + num(hex.slice(3, 5)) + ', ' + num(hex.slice(5)) + ')'); } return 'rgb(0, 0, 0)'; }