From 22ae75e950214eb8e0dedb6ac28b57687e0a411b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Thu, 24 Aug 2023 20:12:27 +0800 Subject: [PATCH] chore: merge conic logic, auto fallback (#254) * chore: fallback of liner * chore: update direction * chore: update demo * chore: fallback of old bro --- docs/examples/gap.tsx | 12 --- docs/examples/gradient-circle.tsx | 19 +--- src/Circle/ColorGradient.tsx | 26 ----- src/Circle/PtgCircle.tsx | 64 ++++++++----- src/Circle/index.tsx | 10 +- src/Circle/util.ts | 6 +- src/interface.ts | 4 +- tests/__snapshots__/conic.spec.tsx.snap | 12 ++- tests/__snapshots__/index.spec.js.snap | 122 ++++++++++++------------ 9 files changed, 115 insertions(+), 160 deletions(-) delete mode 100644 src/Circle/ColorGradient.tsx diff --git a/docs/examples/gap.tsx b/docs/examples/gap.tsx index 239b1b6..dc6e318 100644 --- a/docs/examples/gap.tsx +++ b/docs/examples/gap.tsx @@ -109,18 +109,6 @@ class Example extends React.Component { gapDegree={70} strokeWidth={6} strokeColor={{ - '0%': 'red', - '100%': 'blue', - }} - /> - -
- { />
-

Circle With Success Percent {65}%

-
- -
-

Circle colors

; -} - -export default function ColorGradient(props: ColorGradientProps) { - const { gradientId, gradient } = props; - - return ( - - - {Object.keys(gradient) - .sort((a, b) => stripPercentToNumber(a) - stripPercentToNumber(b)) - .map((key, index) => ( - - ))} - - - ); -} diff --git a/src/Circle/PtgCircle.tsx b/src/Circle/PtgCircle.tsx index e13fb4a..04d2da6 100644 --- a/src/Circle/PtgCircle.tsx +++ b/src/Circle/PtgCircle.tsx @@ -1,6 +1,32 @@ import * as React from 'react'; import type { ProgressProps } from '..'; -import type { StrokeColorType } from '../interface'; +import type { StrokeColorObject } from '../interface'; + +interface BlockProps { + bg: string; + children?: React.ReactNode; +} + +const Block = ({ bg, children }: BlockProps) => ( +
+ {children} +
+); + +function getPtgColors(color: Record, scale: number) { + return Object.keys(color).map((key) => { + const parsedKey = parseFloat(key); + const ptgKey = `${Math.floor(parsedKey * scale)}%`; + + return `${color[key]} ${ptgKey}`; + }); +} export interface ColorGradientProps { prefixCls: string; @@ -11,8 +37,7 @@ export interface ColorGradientProps { strokeLinecap: ProgressProps['strokeLinecap']; strokeWidth: ProgressProps['strokeWidth']; size: number; - color: StrokeColorType; - conic: boolean; + color: string | StrokeColorObject; gapDegree: number; } @@ -27,19 +52,12 @@ const PtgCircle = React.forwardRef((props, strokeLinecap, strokeWidth, size, - conic, gapDegree, } = props; const isGradient = color && typeof color === 'object'; - const stroke = React.useMemo(() => { - if (conic) { - return '#FFF'; - } - - return isGradient ? `url(#${gradientId})` : undefined; - }, [gradientId, isGradient, conic]); + const stroke = isGradient ? `#FFF` : undefined; // ========================== Circle ========================== const halfSize = size / 2; @@ -60,36 +78,30 @@ const PtgCircle = React.forwardRef((props, ); // ========================== Render ========================== - if (!conic) { + if (!isGradient) { return circleNode; } const maskId = `${gradientId}-conic`; - const conicColorKeys = Object.keys(color).filter((key) => key !== 'conic'); const fromDeg = gapDegree ? `${180 + gapDegree / 2}deg` : '0deg'; - const conicColors = conicColorKeys.map((key) => { - const parsedKey = parseFloat(key); - const ptgKey = `${gapDegree ? Math.floor((parsedKey * (360 - gapDegree)) / 360) : parsedKey}%`; - - return `${color[key]} ${ptgKey}`; - }); + const conicColors = getPtgColors(color, (360 - gapDegree) / 360); + const linearColors = getPtgColors(color, 1); const conicColorBg = `conic-gradient(from ${fromDeg}, ${conicColors.join(', ')})`; + const linearColorBg = `linear-gradient(to ${gapDegree ? 'bottom' : 'top'}, ${linearColors.join( + ', ', + )})`; return ( <> {circleNode} -
+ + + ); diff --git a/src/Circle/index.tsx b/src/Circle/index.tsx index 20714f5..94aa047 100644 --- a/src/Circle/index.tsx +++ b/src/Circle/index.tsx @@ -3,9 +3,8 @@ import classNames from 'classnames'; import { defaultProps, useTransitionDuration } from '../common'; import type { ProgressProps } from '../interface'; import useId from '../hooks/useId'; -import ColorGradient from './ColorGradient'; import PtgCircle from './PtgCircle'; -import { VIEW_BOX_SIZE, getCircleStyle, isConicColor } from './util'; +import { VIEW_BOX_SIZE, getCircleStyle } from './util'; function toArray(value: T | T[]): T[] { const mergedValue = value ?? []; @@ -50,7 +49,7 @@ const Circle: React.FC = (props) => { string, string >; - const isConicGradient = isConicColor(gradient); + const isConicGradient = gradient && typeof gradient === 'object'; const mergedStrokeLinecap = isConicGradient ? 'butt' : strokeLinecap; const circleStyle = getCircleStyle( @@ -98,7 +97,6 @@ const Circle: React.FC = (props) => { style={circleStyleForStack} strokeLinecap={mergedStrokeLinecap} strokeWidth={strokeWidth} - conic={isConicGradient} gapDegree={gapDegree} ref={(elem) => { // https://reactjs.org/docs/refs-and-the-dom.html#callback-refs @@ -169,10 +167,6 @@ const Circle: React.FC = (props) => { role="presentation" {...restProps} > - {/* Line Gradient */} - {gradient && !isConicGradient && ( - - )} {!stepCount && ( > & { - conic?: boolean; -}; +export type StrokeColorObject = Record; export type BaseStrokeColorType = string | StrokeColorObject; diff --git a/tests/__snapshots__/conic.spec.tsx.snap b/tests/__snapshots__/conic.spec.tsx.snap index 70d7abc..b708d4d 100644 --- a/tests/__snapshots__/conic.spec.tsx.snap +++ b/tests/__snapshots__/conic.spec.tsx.snap @@ -41,7 +41,11 @@ exports[`Circle.conic gapDegree 1`] = ` >
+ > +
+
@@ -88,7 +92,11 @@ exports[`Circle.conic should work 1`] = ` >
+ > +
+
diff --git a/tests/__snapshots__/index.spec.js.snap b/tests/__snapshots__/index.spec.js.snap index 93fcf70..6d96e51 100644 --- a/tests/__snapshots__/index.spec.js.snap +++ b/tests/__snapshots__/index.spec.js.snap @@ -89,90 +89,92 @@ exports[`Progress Circle should gradient works and circles have different gradie role="presentation" viewBox="0 0 100 100" > - - - - - - - + + + + +
+
+
+ - - - - - - - + + + + +
+
+
+
`;