React自定义色块组件-颜色选择器
2020-12-17
功能:
- 点击色块,弹出颜色选择器,自定义色块颜色,在回调中处理外部业务。
- 点击除色块和选择器的区域,自动关闭选择器。
封装色块组件,便于任意处使用。
<ColorBlock color={color} onChange={onChange} />
缺省宽高属性: width={40} height={40}
import React, { useState, useEffect } from "react";
import { SketchPicker } from "react-color";
export default function ColorBlock(props) {
// 默认选择器宽度
const defaultPickerWidth = 220;
// 默认选择器高度
const defaultPickerHeight = 300;
// 色块容器样式
const containerStyle = {
display: "inline-block",
width: props.width || 40,
height: props.height || 40,
position: "relative"
};
// 颜色选择器显隐控制
const [picker, setPicker] = useState(false);
// 颜色选择器自定义位置
const [pickerPos, setPickerPos] = useState({
left: containerStyle.width,
top: 0
});
// 处理点击任意外部区域关闭颜色选择器
useEffect(() => {
document.addEventListener("click", hidePicker);
return () => {
document.removeEventListener("click", hidePicker);
};
});
// 色块样式
const blockStyle = {
backgroundColor: props.color,
width: "100%",
height: "100%"
};
// 颜色选择器样式
const pickerStyle = {
backgroundColor: "white",
position: "absolute",
left: pickerPos.left,
top: pickerPos.top,
display: picker ? "block" : "none"
};
// 点击色块
const onClickBlock = (e) => {
const clientX = e.clientX;
const clientY = e.clientY;
const width = window.innerWidth;
const height = window.innerHeight;
let left = 0;
let top = 0;
// 此处仅作参考,可依据实际情况,计算颜色选择器出现的合理位置
if (width - clientX < containerStyle.width + defaultPickerWidth) {
left = -defaultPickerWidth;
} else {
left = containerStyle.width;
}
if (height - clientY < defaultPickerHeight) {
top = height - clientY - defaultPickerHeight;
} else {
top = 0;
}
setPickerPos({ left, top });
doPrevent(e);
setPicker(true);
};
// 阻止进一步冒泡
const doPrevent = (e) => {
e.nativeEvent.stopImmediatePropagation();
};
// 隐藏颜色选择器
const hidePicker = (e) => {
setPicker(false);
};
return (
<>
<div style={containerStyle}>
<div style={blockStyle} onClick={onClickBlock}></div>
<div style={pickerStyle} onClick={doPrevent}>
<SketchPicker
width={defaultPickerWidth}
color={props.color}
onChange={props.onChange}
/>
</div>
</div>
</>
);
}
颜色选择器:
https://casesandberg.github.io/react-color/
在线Demo: