fix: ColorPicker UI in Dark Mode (#42827)

* fix: fix ui in dark mode

* test: add test case
This commit is contained in:
红果汁 2023-06-05 16:23:03 +08:00 committed by GitHub
parent 89d23faa3f
commit a0d8fcb23a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 13 deletions

View File

@ -4,6 +4,8 @@ import React, { useMemo, useState } from 'react';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { waitFakeTimer } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
import theme from '../../theme';
import ColorPicker from '../ColorPicker';
import type { Color } from '../color';
@ -299,4 +301,22 @@ describe('ColorPicker', () => {
await waitFakeTimer();
expect(container.querySelector('.ant-popover-hidden')).toBeTruthy();
});
it('Should work at dark mode', async () => {
const { container } = render(
<ConfigProvider theme={{ algorithm: theme.darkAlgorithm }}>
<ColorPicker
open
presets={[
{
label: 'test',
colors: ['#0000001A'],
},
]}
/>
</ConfigProvider>,
);
expect(container.querySelector('.ant-color-picker-presets-color-bright')).toBeFalsy();
});
});

View File

@ -1,10 +1,11 @@
import { ColorBlock } from '@rc-component/color-picker';
import { ColorBlock, Color as RcColor } 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 Collapse from '../../collapse';
import { useLocale } from '../../locale';
import theme from '../../theme';
import type { Color } from '../color';
import type { ColorPickerBaseProps, PresetsItem } from '../interface';
import { generateColor } from '../util';
@ -23,16 +24,21 @@ const genPresetColor = (list: PresetsItem[]) =>
return value;
});
const isBright = (value: Color) => {
const isBright = (value: Color, bgColorToken: string) => {
const { r, g, b, a } = value.toRgb();
const hsv = new RcColor(value.toRgbString()).onBackground(bgColorToken).toHsv();
if (a <= 0.5) {
return true;
// Adapted to dark mode
return hsv.v > 0.5;
}
return r * 0.299 + g * 0.587 + b * 0.114 > 192;
};
const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color, onChange }) => {
const [locale] = useLocale('ColorPicker');
const {
token: { colorBgElevated },
} = theme.useToken();
const [presetsValue] = useMergedState(genPresetColor(presets), {
value: genPresetColor(presets),
postState: genPresetColor,
@ -66,7 +72,10 @@ const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color,
className={classNames(`${colorPresetsPrefixCls}-color`, {
[`${colorPresetsPrefixCls}-color-checked`]:
presetColor.toHexString() === color?.toHexString(),
[`${colorPresetsPrefixCls}-color-bright`]: isBright(presetColor),
[`${colorPresetsPrefixCls}-color-bright`]: isBright(
presetColor,
colorBgElevated,
),
})}
onClick={() => handleClick(presetColor)}
/>

View File

@ -1,13 +1,11 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { ColorPickerToken } from './index';
const TRANSPARENT_DOT_COLOR = '#EEE';
/**
* @private Internal usage only
*/
export const getTransBg = (size: string): CSSObject => ({
backgroundImage: `conic-gradient(${TRANSPARENT_DOT_COLOR} 0 25%, transparent 0 50%, ${TRANSPARENT_DOT_COLOR} 0 75%, transparent 0)`,
export const getTransBg = (size: string, colorFill: string): CSSObject => ({
backgroundImage: `conic-gradient(${colorFill} 0 25%, transparent 0 50%, ${colorFill} 0 75%, transparent 0)`,
backgroundSize: `${size} ${size}`,
});
@ -21,7 +19,7 @@ const genColorBlockStyle = (token: ColorPickerToken, size: number): CSSObject =>
width: size,
height: size,
boxShadow: colorPickerInsetShadow,
...getTransBg('50%'),
...getTransBg('50%', token.colorFillSecondary),
[`${componentCls}-color-block-inner`]: {
width: '100%',
height: '100%',

View File

@ -58,7 +58,7 @@ const genPickerStyle: GenerateStyle<ColorPickerToken, CSSObject> = (token) => {
borderRadius: colorPickerSliderHeight / 2,
boxShadow: colorPickerInsetShadow,
},
'&-alpha': getTransBg(`${colorPickerSliderHeight}px`),
'&-alpha': getTransBg(`${colorPickerSliderHeight}px`, token.colorFillSecondary),
marginBottom: marginSM,
},

View File

@ -16,7 +16,6 @@ const genPresetsStyle: GenerateStyle<ColorPickerToken, CSSObject> = (token) => {
borderRadius,
colorFill,
colorWhite,
colorTextTertiary,
marginXXS,
paddingXS,
} = token;
@ -74,7 +73,7 @@ const genPresetsStyle: GenerateStyle<ColorPickerToken, CSSObject> = (token) => {
boxSizing: 'border-box',
position: 'absolute',
top: '50%',
insetInlineStart: '21.5%',
insetInlineStart: '22.5%',
display: 'table',
width: (colorPickerPresetColorSize / 13) * 5,
height: (colorPickerPresetColorSize / 13) * 8,
@ -96,7 +95,7 @@ const genPresetsStyle: GenerateStyle<ColorPickerToken, CSSObject> = (token) => {
},
[`&${componentCls}-presets-color-bright`]: {
'&::after': {
borderColor: colorTextTertiary,
borderColor: 'rgba(0, 0, 0, 0.45)',
},
},
},