UNPKG

mobile-more

Version:

基于 antd-mobile v5 扩展移动端 UI 组件

273 lines (264 loc) 10.8 kB
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _extends from "@babel/runtime/helpers/esm/extends"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import React, { useMemo } from 'react'; import { isBoolean, isString, round } from 'ut2'; import classNames from 'classnames'; import { useControllableValue } from 'rc-hooks'; import { Popover } from 'antd-mobile'; import tinycolor from 'tinycolor2'; import { Chrome, ChromeInputType as BizColorPickerChromeInputType, color as handleColor, validHex } from '@uiw/react-color'; import { prefixClass } from "../../config"; import "./index.css"; var prefixCls = "".concat(prefixClass, "-color-picker"); var triggerPrefixCls = "".concat(prefixCls, "-trigger"); var colorBlockPrefixCls = "".concat(prefixCls, "-color-block"); var TRANSPARENT_VALUE = '#00000000'; var TRANSPARENT_TEXT = 'transparent'; var EMPTY_VALUE = TRANSPARENT_VALUE; var EMPTY_TEXT = 'none'; var COLOR_FORMAT_MAP = { rgb: 'rgb', hex: 'hex', hsl: 'hsl' }; /**颜色值或对象 */ /**颜色格式 */ var INPUT_TYPE_MAP = { rgb: BizColorPickerChromeInputType.RGBA, hex: BizColorPickerChromeInputType.HEXA, hsl: BizColorPickerChromeInputType.HSLA }; /** * 将颜色转换为十六进制文本格式。 * * @param str 颜色字符串 * @returns 十六进制文本格式的颜色字符串 */ function toHex8String(str) { return validHex(str) ? str : tinycolor(str).toHex8String(); // 使用 tinycolor 可以处理颜色名称 } /** * 将颜色转换为颜色对象。 * * @param value 颜色值或对象 * @returns 颜色对象 */ function wrapColor(value) { if (!value) { return handleColor(EMPTY_VALUE); } else if (isString(value)) { var hex8 = value.toLowerCase() === TRANSPARENT_TEXT ? TRANSPARENT_VALUE : toHex8String(value); return handleColor(hex8); } return value; } /** * 将颜色转换为十六进制文本格式。 * * @param color 颜色值或对象 * @returns 十六进制文本格式的颜色字符串 * @example * colorToHexString('red'); // '#ff0000' * colorToHexString('rgb(230, 0, 0)'); // '#e60000' * colorToHexString('rgba(230, 0, 0, 0.5)'); // '#e6000080' * colorToHexString({ hex: '#e60000', hexa: '#e60000ff', hsva: { ..., a: 1 }, ... }) // '#e60000' * colorToHexString({ hex: '#e60000', hexa: '#e6000080', hsva: { ..., a: 0.5 }, ... }) // '#e6000080' */ function colorToHexString(color) { var colorRet = wrapColor(color); return round(colorRet.rgba.a, 2) === 1 ? colorRet.hex : colorRet.hexa; } /** * 将颜色转换为 rgb 字符串格式。 * * 如果透明度不为 1 ,则在 rgb 字符串格式的颜色字符串后添加透明度值。 * * @param color 颜色值或对象 * @returns rgb 字符串格式的颜色字符串 * @example * colorToRgbString('red'); // 'rgb(255, 0, 0)' * colorToRgbString('#e60000'); // 'rgb(230, 0, 0)' * colorToRgbString('#e6000080'); // 'rgb(230, 0, 0, 0.5)' * colorToRgbString({ hex: '#e60000', hexa: '#e60000ff', hsva: { ..., a: 1 }, ... }) // 'rgb(230, 0, 0)' * colorToRgbString({ hex: '#e60000', hexa: '#e6000080', hsva: { ..., a: 0.5 }, ... }) // 'rgba(230, 0, 0, 0.5)' */ function colorToRgbString(color) { var colorRet = wrapColor(color); var rgbString = round(colorRet.rgb.r) + ', ' + round(colorRet.rgb.g) + ', ' + round(colorRet.rgb.b); var roundA = round(colorRet.rgba.a, 2); return roundA === 1 ? 'rgb(' + rgbString + ')' : 'rgba(' + rgbString + ', ' + roundA + ')'; } /** * 将颜色转换为 hsl 字符串格式。 * * 如果透明度不为 1 ,则在 hsl 字符串格式的颜色字符串后添加透明度值。 * * @param color 颜色值或对象 * @returns hsl 字符串格式的颜色字符串 * @example * colorToHslString('red'); // 'hsl(0, 100%, 50%)' * colorToHslString('#e60000'); // 'hsl(0, 100%, 45%)' * colorToHslString('#e6000080'); // 'hsla(0, 100%, 45%, 0.5)' * colorToHslString({ hex: '#e60000', hexa: '#e60000ff', hsva: { ..., a: 1 }, ... }) // 'hsl(0, 100%, 45%)' * colorToHslString({ hex: '#e60000', hexa: '#e6000080', hsva: { ..., a: 0.5 }, ... }) // 'hsla(0, 100%, 45%, 0.5)' */ function colorToHslString(color) { var colorRet = wrapColor(color); var hslString = round(colorRet.hsl.h) + ', ' + round(colorRet.hsl.s) + '%, ' + round(colorRet.hsl.l) + '%'; var roundA = round(colorRet.hsla.a, 2); return roundA === 1 ? 'hsl(' + hslString + ')' : 'hsla(' + hslString + ', ' + roundA + ')'; } /** * 将颜色转换为文本格式。 * * @param color 颜色值或对象 * @param options 选项,选填。 * @param options.format 颜色格式。可选`hex``rgb``hsl`,默认`hex`。 * @param options.emptyText 空值文本。默认`none`。 * @param options.transparentText 透明文本。默认`transparent`。 * @returns 文本 * @example * * // Falsy 值,返回 emptyText * toText(); // 'none' * toText(''); // 'none' * toText('', { emptyText: '未选择' }); // '未选择' * * // 'transparent' 返回 transparentText * toText('transparent'); // 'transparent' * toText('transparent', { transparentText: '透明' }); // '透明' * * // 颜色值为字符串或对象 * toText('red'); // '#ff0000' * toText('red', { format: 'hsl' }); // 'hsl(0, 100%, 50%)' * toText('#e6000080', { format: 'hsl' }); // 'hsla(0, 100%, 45%, 0.5)' * * const color1 = { hex: '#e60000', hexa: '#e60000ff', hsva: { ..., a: 1 }, ... }; * toText(color1); // '#e60000' * toText(color1, { format: 'rgb' }); // 'rgb(230, 0, 0)' * toText(color1, { format: 'hsl' }); // 'hsl(0, 100%, 45%)' * * const color2 = { hex: '#e60000', hexa: '#e6000080', hsva: { ..., a: 0.5 }, ... }; * toText(color2); // '#e6000080' * toText(color2, { format: 'rgb' }); // 'rgba(230, 0, 0, 0.5)' * toText(color2, { format: 'hsl' }); // 'hsla(0, 100%, 45%, 0.5)' */ function toText(value) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _options$format = options.format, format = _options$format === void 0 ? COLOR_FORMAT_MAP.hex : _options$format, _options$emptyText = options.emptyText, emptyText = _options$emptyText === void 0 ? EMPTY_TEXT : _options$emptyText, _options$transparentT = options.transparentText, transparentText = _options$transparentT === void 0 ? TRANSPARENT_TEXT : _options$transparentT; if (!value) { return emptyText; } if (isString(value) && value.toLowerCase() === TRANSPARENT_TEXT) { return transparentText; } if (format === COLOR_FORMAT_MAP.rgb) { return colorToRgbString(value); } if (format === COLOR_FORMAT_MAP.hsl) { return colorToHslString(value); } return colorToHexString(value); } var BizColorPicker = function BizColorPicker(props) { var _props$format = props.format, format = _props$format === void 0 ? COLOR_FORMAT_MAP.hex : _props$format, showText = props.showText, readOnly = props.readOnly, disabled = props.disabled, children = props.children, _props$emptyText = props.emptyText, emptyText = _props$emptyText === void 0 ? EMPTY_TEXT : _props$emptyText, _props$transparentTex = props.transparentText, transparentText = _props$transparentTex === void 0 ? TRANSPARENT_TEXT : _props$transparentTex, className = props.className, style = props.style, _props$placement = props.placement, placement = _props$placement === void 0 ? 'bottom-start' : _props$placement, popoverProps = props.popoverProps, showAlpha = props.showAlpha, chromeProps = props.chromeProps; var _useControllableValue = useControllableValue(props), _useControllableValue2 = _slicedToArray(_useControllableValue, 2), value = _useControllableValue2[0], setValue = _useControllableValue2[1]; var _useControllableValue3 = useControllableValue(props, { valuePropName: 'visible', defaultValue: false, defaultValuePropName: 'defaultVisible', trigger: 'onVisibleChange' }), _useControllableValue4 = _slicedToArray(_useControllableValue3, 2), visible = _useControllableValue4[0], setVisible = _useControllableValue4[1]; var _useMemo = useMemo(function () { var colorRet = wrapColor(value); var valueIsTransparent = isString(value) && value.toLowerCase() === TRANSPARENT_TEXT; return { colorResult: colorRet, colorValue: valueIsTransparent || !value ? _objectSpread(_objectSpread({}, colorRet.hsva), {}, { a: 1 }) : colorRet.hsva, colorBlock: colorToRgbString(colorRet) }; }, [value]), colorResult = _useMemo.colorResult, colorValue = _useMemo.colorValue, colorBlock = _useMemo.colorBlock; return /*#__PURE__*/React.createElement(Popover, _extends({ content: /*#__PURE__*/React.createElement(Chrome, _extends({ showAlpha: showAlpha, inputType: INPUT_TYPE_MAP[format] }, chromeProps, { style: _objectSpread({ '--github-border': 'none', '--github-box-shadow': 'none' }, chromeProps === null || chromeProps === void 0 ? void 0 : chromeProps.style), color: colorValue, onChange: function onChange(v) { setValue(v, colorToRgbString(v)); }, showTriangle: false })), trigger: "click", placement: placement, destroyOnHide: true, className: classNames(prefixCls, popoverProps === null || popoverProps === void 0 ? void 0 : popoverProps.className) }, popoverProps, { visible: visible, onVisibleChange: function onVisibleChange(v) { if (!disabled && !readOnly) { setVisible(v); } } }), children || /*#__PURE__*/React.createElement("div", { className: classNames("".concat(triggerPrefixCls), _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(triggerPrefixCls, "-active"), visible), "".concat(triggerPrefixCls, "-disabled"), disabled), "".concat(triggerPrefixCls, "-read"), readOnly), "".concat(triggerPrefixCls, "-empty"), !value), className), style: style }, /*#__PURE__*/React.createElement("div", { className: "".concat(colorBlockPrefixCls) }, /*#__PURE__*/React.createElement("div", { className: "".concat(colorBlockPrefixCls, "-inner"), style: { background: colorBlock } })), showText && /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-text") }, isBoolean(showText) ? toText(value, { format: format, emptyText: emptyText, transparentText: transparentText }) : showText(colorResult, value)))); }; BizColorPicker.color = wrapColor; BizColorPicker.colorToHexString = colorToHexString; BizColorPicker.colorToRgbString = colorToRgbString; BizColorPicker.colorToHslString = colorToHslString; BizColorPicker.toText = toText; export default BizColorPicker;