mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-28 05:05:48 +08:00
style: optimize ColorPicker code (#42329)
* style: optimize ColorPicker code * style: optimize ColorPicker code * test
This commit is contained in:
parent
828db96962
commit
d3093c9096
@ -31,22 +31,11 @@ const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
|
||||
/>
|
||||
)}
|
||||
{panel}
|
||||
<ColorInput
|
||||
value={color}
|
||||
onChange={(value) => onChange?.(value)}
|
||||
prefixCls={prefixCls}
|
||||
{...injectProps}
|
||||
/>
|
||||
|
||||
<ColorInput value={color} onChange={onChange} prefixCls={prefixCls} {...injectProps} />
|
||||
{Array.isArray(presets) && (
|
||||
<>
|
||||
<Divider className={`${colorPickerPanelPrefixCls}-divider`} />
|
||||
<ColorPresets
|
||||
value={color}
|
||||
presets={presets}
|
||||
onChange={(value) => onChange?.(value)}
|
||||
prefixCls={prefixCls}
|
||||
/>
|
||||
<ColorPresets value={color} presets={presets} prefixCls={prefixCls} onChange={onChange} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@ -60,4 +49,9 @@ const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
ColorPickerPanel.displayName = 'ColorPickerPanel';
|
||||
}
|
||||
|
||||
export default ColorPickerPanel;
|
||||
|
@ -12,7 +12,7 @@ interface ColorAlphaInputProps extends Pick<ColorPickerBaseProps, 'prefixCls'> {
|
||||
|
||||
const ColorAlphaInput: FC<ColorAlphaInputProps> = ({ prefixCls, value, onChange }) => {
|
||||
const colorAlphaInputPrefixCls = `${prefixCls}-alpha-input`;
|
||||
const [alphaValue, setAlphaValue] = useState(generateColor(value || '#000'));
|
||||
const [alphaValue, setAlphaValue] = useState<Color>(generateColor(value || '#000'));
|
||||
|
||||
// Update step value
|
||||
useEffect(() => {
|
||||
|
@ -18,7 +18,7 @@ const ColorClear: FC<ColorClearProps> = ({ prefixCls, value, onChange }) => {
|
||||
onChange?.(genColor);
|
||||
}
|
||||
};
|
||||
|
||||
return <div className={`${prefixCls}-clear`} onClick={handleClick} />;
|
||||
};
|
||||
|
||||
export default ColorClear;
|
||||
|
@ -14,7 +14,7 @@ interface ColorHsbInputProps extends Pick<ColorPickerBaseProps, 'prefixCls'> {
|
||||
|
||||
const ColorHsbInput: FC<ColorHsbInputProps> = ({ prefixCls, value, onChange }) => {
|
||||
const colorHsbInputPrefixCls = `${prefixCls}-hsb-input`;
|
||||
const [hsbValue, setHsbValue] = useState(generateColor(value || '#000'));
|
||||
const [hsbValue, setHsbValue] = useState<Color>(generateColor(value || '#000'));
|
||||
|
||||
// Update step value
|
||||
useEffect(() => {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import type { FC } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import Select from '../../select';
|
||||
import type { Color } from '../color';
|
||||
import type { ColorPickerBaseProps } from '../interface';
|
||||
import { ColorFormat } from '../interface';
|
||||
import type { Color } from '../color';
|
||||
import ColorAlphaInput from './ColorAlphaInput';
|
||||
import ColorHexInput from './ColorHexInput';
|
||||
import ColorHsbInput from './ColorHsbInput';
|
||||
@ -16,8 +16,13 @@ interface ColorInputProps
|
||||
onChange?: (value: Color) => void;
|
||||
}
|
||||
|
||||
const selectOptions = [ColorFormat.hex, ColorFormat.hsb, ColorFormat.rgb].map((format) => ({
|
||||
value: format,
|
||||
label: format.toLocaleUpperCase(),
|
||||
}));
|
||||
|
||||
const ColorInput: FC<ColorInputProps> = (props) => {
|
||||
const { prefixCls, format, onFormatChange, value, onChange } = props;
|
||||
const { prefixCls, format, value, onFormatChange, onChange } = props;
|
||||
const [colorFormat, setColorFormat] = useMergedState('hex', {
|
||||
value: format,
|
||||
onChange: onFormatChange,
|
||||
@ -29,17 +34,18 @@ const ColorInput: FC<ColorInputProps> = (props) => {
|
||||
setColorFormat(newFormat);
|
||||
};
|
||||
|
||||
const steppersRender = () => {
|
||||
const steppersNode = useMemo<React.ReactNode>(() => {
|
||||
const inputProps = { value, prefixCls, onChange };
|
||||
switch (colorFormat) {
|
||||
case ColorFormat.hsb:
|
||||
return <ColorHsbInput value={value} onChange={onChange} prefixCls={prefixCls} />;
|
||||
return <ColorHsbInput {...inputProps} />;
|
||||
case ColorFormat.rgb:
|
||||
return <ColorRgbInput value={value} onChange={onChange} prefixCls={prefixCls} />;
|
||||
return <ColorRgbInput {...inputProps} />;
|
||||
case ColorFormat.hex:
|
||||
default:
|
||||
return <ColorHexInput value={value} onChange={onChange} prefixCls={prefixCls} />;
|
||||
return <ColorHexInput {...inputProps} />;
|
||||
}
|
||||
};
|
||||
}, [colorFormat, prefixCls, value, onChange]);
|
||||
|
||||
return (
|
||||
<div className={`${colorInputPrefixCls}-container`}>
|
||||
@ -52,24 +58,12 @@ const ColorInput: FC<ColorInputProps> = (props) => {
|
||||
onChange={handleFormatChange}
|
||||
className={`${prefixCls}-format-select`}
|
||||
size="small"
|
||||
options={[
|
||||
{
|
||||
label: ColorFormat.hex.toLocaleUpperCase(),
|
||||
value: ColorFormat.hex,
|
||||
},
|
||||
{
|
||||
label: ColorFormat.hsb.toLocaleUpperCase(),
|
||||
value: ColorFormat.hsb,
|
||||
},
|
||||
{
|
||||
label: ColorFormat.rgb.toLocaleUpperCase(),
|
||||
value: ColorFormat.rgb,
|
||||
},
|
||||
]}
|
||||
options={selectOptions}
|
||||
/>
|
||||
<div className={colorInputPrefixCls}>{steppersRender()}</div>
|
||||
<div className={colorInputPrefixCls}>{steppersNode}</div>
|
||||
<ColorAlphaInput prefixCls={prefixCls} value={value} onChange={onChange} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ColorInput;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { ColorBlock } from '@rc-component/color-picker';
|
||||
import classNames from 'classnames';
|
||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import type { FC } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { ColorBlock } from '@rc-component/color-picker';
|
||||
import Collapse from '../../collapse';
|
||||
import { useLocale } from '../../locale';
|
||||
import type { Color } from '../color';
|
||||
@ -39,7 +39,7 @@ const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color,
|
||||
});
|
||||
const colorPresetsPrefixCls = `${prefixCls}-presets`;
|
||||
|
||||
const activeKey = useMemo(
|
||||
const activeKeys = useMemo<string[]>(
|
||||
() => presetsValue.map((preset) => `panel-${preset.label}`),
|
||||
[presetsValue],
|
||||
);
|
||||
@ -50,14 +50,14 @@ const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color,
|
||||
|
||||
return (
|
||||
<div className={colorPresetsPrefixCls}>
|
||||
<Collapse defaultActiveKey={activeKey} ghost>
|
||||
<Collapse defaultActiveKey={activeKeys} ghost>
|
||||
{presetsValue.map((preset) => (
|
||||
<Panel
|
||||
header={<div className={`${colorPresetsPrefixCls}-label`}>{preset?.label}</div>}
|
||||
key={`panel-${preset?.label}`}
|
||||
>
|
||||
<div className={`${colorPresetsPrefixCls}-items`}>
|
||||
{Array.isArray(preset?.colors) && preset?.colors.length ? (
|
||||
{Array.isArray(preset?.colors) && preset.colors?.length > 0 ? (
|
||||
preset.colors.map((presetColor: Color) => (
|
||||
<ColorBlock
|
||||
key={`preset-${presetColor.toHexString()}`}
|
||||
@ -81,4 +81,5 @@ const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color,
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ColorPresets;
|
||||
|
@ -13,7 +13,7 @@ interface ColorRgbInputProps extends Pick<ColorPickerBaseProps, 'prefixCls'> {
|
||||
|
||||
const ColorRgbInput: FC<ColorRgbInputProps> = ({ prefixCls, value, onChange }) => {
|
||||
const colorRgbInputPrefixCls = `${prefixCls}-rgb-input`;
|
||||
const [rgbValue, setRgbValue] = useState(generateColor(value || '#000'));
|
||||
const [rgbValue, setRgbValue] = useState<Color>(generateColor(value || '#000'));
|
||||
|
||||
// Update step value
|
||||
useEffect(() => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ColorBlock } from '@rc-component/color-picker';
|
||||
import classNames from 'classnames';
|
||||
import type { CSSProperties, MouseEventHandler } from 'react';
|
||||
import React, { forwardRef, useMemo } from 'react';
|
||||
import { ColorBlock } from '@rc-component/color-picker';
|
||||
import type { ColorPickerBaseProps } from '../interface';
|
||||
import ColorClear from './ColorClear';
|
||||
|
||||
@ -20,14 +20,14 @@ const ColorTrigger = forwardRef<HTMLDivElement, colorTriggerProps>((props, ref)
|
||||
const { color, prefixCls, open, clearColor, disabled, className, ...rest } = props;
|
||||
const colorTriggerPrefixCls = `${prefixCls}-trigger`;
|
||||
|
||||
const containerRender = useMemo(
|
||||
const containerNode = useMemo<React.ReactNode>(
|
||||
() =>
|
||||
clearColor ? (
|
||||
<ColorClear prefixCls={prefixCls} />
|
||||
) : (
|
||||
<ColorBlock color={color.toRgbString()} prefixCls={prefixCls} />
|
||||
<ColorBlock prefixCls={prefixCls} color={color.toRgbString()} />
|
||||
),
|
||||
[color, clearColor],
|
||||
[color, clearColor, prefixCls],
|
||||
);
|
||||
|
||||
return (
|
||||
@ -39,8 +39,9 @@ const ColorTrigger = forwardRef<HTMLDivElement, colorTriggerProps>((props, ref)
|
||||
})}
|
||||
{...rest}
|
||||
>
|
||||
{containerRender}
|
||||
{containerNode}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default ColorTrigger;
|
||||
|
@ -2,19 +2,16 @@ import { useEffect, useState } from 'react';
|
||||
import type { Color } from '../color';
|
||||
import { generateColor } from '../util';
|
||||
|
||||
function hasValue(value: Color | string | undefined) {
|
||||
function hasValue(value?: Color | string) {
|
||||
return value !== undefined;
|
||||
}
|
||||
|
||||
const useColorState = (
|
||||
defaultStateValue: Color | string,
|
||||
option: {
|
||||
defaultValue?: Color | string;
|
||||
value?: Color | string;
|
||||
},
|
||||
): [Color, React.Dispatch<React.SetStateAction<Color>>] => {
|
||||
option: { defaultValue?: Color | string; value?: Color | string },
|
||||
): readonly [Color, React.Dispatch<React.SetStateAction<Color>>] => {
|
||||
const { defaultValue, value } = option;
|
||||
const [colorValue, setColorValue] = useState(() => {
|
||||
const [colorValue, setColorValue] = useState<Color>(() => {
|
||||
let mergeState: string | Color | undefined;
|
||||
if (hasValue(value)) {
|
||||
mergeState = value;
|
||||
@ -32,7 +29,7 @@ const useColorState = (
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
return [colorValue, setColorValue];
|
||||
return [colorValue, setColorValue] as const;
|
||||
};
|
||||
|
||||
export default useColorState;
|
||||
|
@ -8,7 +8,10 @@ export enum ColorFormat {
|
||||
hsb = 'hsb',
|
||||
}
|
||||
|
||||
export type PresetsItem = { label: ReactNode; colors: Array<string | Color> };
|
||||
export interface PresetsItem {
|
||||
label: ReactNode;
|
||||
colors: (string | Color)[];
|
||||
}
|
||||
|
||||
export interface ColorPickerBaseProps {
|
||||
color?: Color;
|
||||
|
Loading…
Reference in New Issue
Block a user