From 518cef6273be596d0170d07a66e9e5277d21aec9 Mon Sep 17 00:00:00 2001 From: bbsqq <1491812683@qq.com> Date: Thu, 21 Nov 2024 17:22:25 +0800 Subject: [PATCH] feat(text): fit antd darkAlgorithm --- src/Text/VisText.tsx | 8 +- src/Text/config.tsx | 28 +++--- src/Text/constants.ts | 9 -- src/Text/demos/common.tsx | 97 +++++++++++-------- .../mini-charts/hooks/getElementFontSize.ts | 2 +- src/Text/mini-charts/hooks/useSvgWrapper.tsx | 2 +- src/Text/mini-charts/line/SingleLineChart.tsx | 9 +- src/Text/mini-charts/line/useLineCompute.ts | 2 +- src/Text/mini-charts/proportion/index.tsx | 10 +- src/Text/theme.ts | 24 +++++ src/Text/utils/getThemeColor.ts | 32 ++++++ src/Text/utils/index.ts | 2 + src/Text/utils/useAntdDarkAlgorithm.ts | 14 +++ 13 files changed, 159 insertions(+), 80 deletions(-) delete mode 100644 src/Text/constants.ts create mode 100644 src/Text/theme.ts create mode 100644 src/Text/utils/getThemeColor.ts create mode 100644 src/Text/utils/index.ts create mode 100644 src/Text/utils/useAntdDarkAlgorithm.ts diff --git a/src/Text/VisText.tsx b/src/Text/VisText.tsx index b985cc0..67fa0a0 100644 --- a/src/Text/VisText.tsx +++ b/src/Text/VisText.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { useComponentGlobalConfig } from '../ConfigProvider/hooks'; import { type TextConfig, STATICS_KEY } from './config'; import type { VisTextProps } from './types'; +import { getThemeColor, useAntdDarkAlgorithm } from './utils'; const { Text } = Typography; @@ -20,9 +21,13 @@ function renderPrefixSuffix( const VisText = (props: VisTextProps) => { const { children, className, style, type, origin } = props; + + const isDark = useAntdDarkAlgorithm(); const textConfig = useComponentGlobalConfig('VisText'); + const encoding = type ? textConfig?.[type] : {}; const staticsConfig = textConfig?.[STATICS_KEY]; + return ( // TODO @羽熙 暂时简单处理 tooltip 直接显示 origin,后续可以根据 origin 类型分类处理 @@ -32,8 +37,9 @@ const VisText = (props: VisTextProps) => { // antd Text 组件写死了 14px,在段落定义了 font-size 的情况下,显示很突兀,这里不设置,跟随上级容器字体大小改变。 // TODO @羽熙 之后看能否通过 antd ConfigProvider 统一配置 fontSize: 'unset', + color: getThemeColor({ type, color: encoding?.color, theme: isDark ? 'dark' : 'light' }), ...style, - ...pick(encoding, ['color', 'backgroundColor', 'fontWeight']), + ...pick(encoding, ['backgroundColor', 'fontWeight']), }} > {renderPrefixSuffix(encoding?.prefix, staticsConfig, props)} diff --git a/src/Text/config.tsx b/src/Text/config.tsx index d801872..9a8438c 100644 --- a/src/Text/config.tsx +++ b/src/Text/config.tsx @@ -1,7 +1,7 @@ import type { CSSProperties } from 'react'; -import { TEXT_THEME } from './constants'; import { ArrowDown, ArrowUp } from './custom-icons'; import { ProportionChart, SingleLineChart } from './mini-charts'; +import { TEXT_THEME } from './theme'; import type { VisTextProps } from './types'; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -56,49 +56,49 @@ export const DEFAULT_VIS_TEXT_CONFIG: TextConfig = { 'mini-chart:line': SingleLineChart, }, metric_name: { - color: TEXT_THEME.black88, + color: TEXT_THEME.light.default88Color, fontWeight: 500, }, metric_value: { - color: TEXT_THEME.primaryColor, + color: TEXT_THEME.light.primaryColor, }, other_metric_value: { - color: TEXT_THEME.black65, + color: TEXT_THEME.light.default65Color, }, delta_value: { - color: TEXT_THEME.black65, + color: TEXT_THEME.light.default65Color, }, ratio_value: { - color: TEXT_THEME.black65, + color: TEXT_THEME.light.default65Color, }, delta_value_pos: { - color: TEXT_THEME.posColor, + color: TEXT_THEME.light.posColor, prefix: '+', }, delta_value_neg: { - color: TEXT_THEME.negColor, + color: TEXT_THEME.light.negColor, prefix: '-', }, ratio_value_pos: { - color: TEXT_THEME.posColor, + color: TEXT_THEME.light.posColor, prefix: 'icon:arrow-up', }, ratio_value_neg: { - color: TEXT_THEME.negColor, + color: TEXT_THEME.light.negColor, prefix: 'icon:arrow-down', }, contribute_ratio: { - color: TEXT_THEME.statisticsInsightColor, + color: TEXT_THEME.light.conclusionColor, }, trend_desc: { - color: TEXT_THEME.statisticsInsightColor, + color: TEXT_THEME.light.conclusionColor, suffix: 'mini-chart:line', }, dim_value: { - color: TEXT_THEME.black88, + color: TEXT_THEME.light.default88Color, }, time_desc: { - color: TEXT_THEME.black88, + color: TEXT_THEME.light.default88Color, }, proportion: { suffix: 'mini-chart:proportion', diff --git a/src/Text/constants.ts b/src/Text/constants.ts deleted file mode 100644 index ed7cd4f..0000000 --- a/src/Text/constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const TEXT_THEME = { - fontSizeBase: 14, - primaryColor: '#1677FF', - black88: 'rgba(0, 0, 0, 0.88)', - black65: 'rgba(0, 0, 0, 0.65)', - posColor: '#FA541C', - negColor: '#13A8A8', - statisticsInsightColor: '#1F0352', -}; diff --git a/src/Text/demos/common.tsx b/src/Text/demos/common.tsx index 847b714..f13638a 100644 --- a/src/Text/demos/common.tsx +++ b/src/Text/demos/common.tsx @@ -1,50 +1,61 @@ import { VisText } from '@antv/gpt-vis'; -import { Descriptions, Space } from 'antd'; +import { ConfigProvider, Descriptions, Space, theme } from 'antd'; +import { usePrefersColor } from 'dumi'; import React from 'react'; export default () => { + // dumi 文档当前的主题色 + const [color] = usePrefersColor(); return ( - - - DAU - - - - 90.1w - - - - 30% - - - - 100.33 - 100.33 - - - - - 30% - 30% - - - - 20% - - - - 趋势上涨 - - - - 杭州 - - - 2021-10-11 - - - 30% - - + // 适配 antd 主题。待整体文档 demo 都适配主题后可以删除 + // https://github.com/antvis/GPT-Vis/pull/24 + + + + DAU + + + + 90.1w + + + + 30% + + + + 100.33 + 100.33 + + + + + 30% + 30% + + + + 20% + + + + 趋势上涨 + + + + 杭州 + + + 2021-10-11 + + + 30% + + + ); }; diff --git a/src/Text/mini-charts/hooks/getElementFontSize.ts b/src/Text/mini-charts/hooks/getElementFontSize.ts index 0de1a02..abf1b82 100644 --- a/src/Text/mini-charts/hooks/getElementFontSize.ts +++ b/src/Text/mini-charts/hooks/getElementFontSize.ts @@ -1,4 +1,4 @@ -import { TEXT_THEME } from '../../constants'; +import { TEXT_THEME } from '../../theme'; function getStyle(ele: Element, style: string): string | undefined { return window.getComputedStyle diff --git a/src/Text/mini-charts/hooks/useSvgWrapper.tsx b/src/Text/mini-charts/hooks/useSvgWrapper.tsx index fa0f0a9..c1e03d2 100644 --- a/src/Text/mini-charts/hooks/useSvgWrapper.tsx +++ b/src/Text/mini-charts/hooks/useSvgWrapper.tsx @@ -1,6 +1,6 @@ import type { PropsWithChildren } from 'react'; import React, { useLayoutEffect, useRef, useState } from 'react'; -import { TEXT_THEME } from '../../constants'; +import { TEXT_THEME } from '../../theme'; import { getElementFontSize } from './getElementFontSize'; type SvgProps = PropsWithChildren>; diff --git a/src/Text/mini-charts/line/SingleLineChart.tsx b/src/Text/mini-charts/line/SingleLineChart.tsx index bc68edf..0e89c36 100644 --- a/src/Text/mini-charts/line/SingleLineChart.tsx +++ b/src/Text/mini-charts/line/SingleLineChart.tsx @@ -1,13 +1,12 @@ import { isArray, isString, size } from 'lodash'; import React, { useMemo } from 'react'; +import { TEXT_THEME } from '../../theme'; import type { VisTextProps } from '../../types'; import { useSvgWrapper } from '../hooks'; import { useLineCompute } from './useLineCompute'; const LINEAR_FILL_COLOR_ID = 'wsc-line-fill'; -const LINE_STROKE_COLOR = '#5B8FF9'; - function getLineChartData(origin: any) { if (isArray(origin)) return origin; if (isString(origin)) { @@ -29,11 +28,13 @@ export const SingleLineChart: React.FC = ({ origin }) => { - + - {linePath && } + {linePath && ( + + )} {polygonPath && } ) diff --git a/src/Text/mini-charts/line/useLineCompute.ts b/src/Text/mini-charts/line/useLineCompute.ts index f52efa2..bd7590a 100644 --- a/src/Text/mini-charts/line/useLineCompute.ts +++ b/src/Text/mini-charts/line/useLineCompute.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { TEXT_THEME } from '../../constants'; +import { TEXT_THEME } from '../../theme'; import type { Scale } from './scaleLinear'; import { scaleLinear } from './scaleLinear'; diff --git a/src/Text/mini-charts/proportion/index.tsx b/src/Text/mini-charts/proportion/index.tsx index a471936..c3555d0 100644 --- a/src/Text/mini-charts/proportion/index.tsx +++ b/src/Text/mini-charts/proportion/index.tsx @@ -1,12 +1,10 @@ import { isNaN, isString, toNumber } from 'lodash'; import React, { useMemo } from 'react'; +import { TEXT_THEME } from '../../theme'; import type { VisTextProps } from '../../types'; import { useSvgWrapper } from '../hooks/useSvgWrapper'; import { getArcPath } from './getArcPath'; -const SHADOW_COLOR = '#CDDDFD'; -const FILL_COLOR = '#3471F9'; - function getProportionNumber( children: string | string[], // markdown 中传入的 children 文本为 string[] origin?: any, @@ -38,11 +36,11 @@ export const ProportionChart: React.FC = ({ origin, children }) => return ( data && ( - + {data >= 1 ? ( - + ) : ( - + )} ) diff --git a/src/Text/theme.ts b/src/Text/theme.ts new file mode 100644 index 0000000..f6a7d6d --- /dev/null +++ b/src/Text/theme.ts @@ -0,0 +1,24 @@ +export const TEXT_THEME = { + fontSizeBase: 14, + chart: { + proportionShadowColor: '#CDDDFD', + proportionFillColor: '#3471F9', + lineStrokeColor: '#5B8FF9', + }, + light: { + primaryColor: '#1677FF', + default88Color: 'rgba(0, 0, 0, 0.88)', + default65Color: 'rgba(0, 0, 0, 0.65)', + posColor: '#FA541C', + negColor: '#13A8A8', + conclusionColor: '#1F0352', + }, + dark: { + primaryColor: '#4B91FF', + default88Color: 'rgba(255, 255, 255, 0.88)', + default65Color: 'rgba(255, 255, 255, 0.65)', + posColor: '#FA541C', + negColor: '#13A8A8', + conclusionColor: '#D8C3F3', + }, +}; diff --git a/src/Text/utils/getThemeColor.ts b/src/Text/utils/getThemeColor.ts new file mode 100644 index 0000000..f15502f --- /dev/null +++ b/src/Text/utils/getThemeColor.ts @@ -0,0 +1,32 @@ +import { findKey, get } from 'lodash'; +import { DEFAULT_VIS_TEXT_CONFIG } from '../config'; +import { TEXT_THEME } from '../theme'; + +/** + * 自动适配暗黑模式 + * @params type 类型 + * @params color 当前颜色 + * @params theme 当前主题 + */ +export const getThemeColor = ({ + type, + color, + theme, +}: { + type?: string; + color: string | undefined; + theme: 'dark' | 'light'; +}) => { + // 仅暗黑主题才处理 + if (type && color && theme === 'dark') { + const defaultLightColor = get(DEFAULT_VIS_TEXT_CONFIG, [type, 'color']); + // 仅当前颜色为默认的浅色主题时才处理 + if (color === defaultLightColor) { + // 找到浅色主题的 token + const token = findKey(TEXT_THEME.light, (i) => i === color); + // 返回暗黑主题的对应 token 的颜色 + if (token) return TEXT_THEME.dark[token as keyof typeof TEXT_THEME.dark]; + } + } + return color; +}; diff --git a/src/Text/utils/index.ts b/src/Text/utils/index.ts new file mode 100644 index 0000000..27bfa2e --- /dev/null +++ b/src/Text/utils/index.ts @@ -0,0 +1,2 @@ +export * from './getThemeColor'; +export * from './useAntdDarkAlgorithm'; diff --git a/src/Text/utils/useAntdDarkAlgorithm.ts b/src/Text/utils/useAntdDarkAlgorithm.ts new file mode 100644 index 0000000..06252e3 --- /dev/null +++ b/src/Text/utils/useAntdDarkAlgorithm.ts @@ -0,0 +1,14 @@ +import { ConfigProvider, theme as antdTheme } from 'antd'; +import { isArray } from 'lodash'; +import { useContext } from 'react'; + +const { darkAlgorithm } = antdTheme; + +/** 判断是否运用了 antd dark algorithm */ +export const useAntdDarkAlgorithm = () => { + const config = useContext(ConfigProvider.ConfigContext); + const currentAlgorithm = config.theme?.algorithm; + + if (isArray(currentAlgorithm) && currentAlgorithm.includes(darkAlgorithm)) return true; + return currentAlgorithm === darkAlgorithm; +};