* move colors in ui-toolkit/config * fixing tests and add stories * fixing some tests and edit story * update sparkline story * rename story templates for sparkline * use tailwind colors and rename to *.spec.tsx * use tailwind only * remove test.tsx * Update libs/tailwindcss-config/src/theme.js Co-authored-by: Matthew Russell <mattrussell36@gmail.com> * remove gray from tailwind and use black/40 and white/40 for strokeCurrent Co-authored-by: madalinaraicu <“madalina@raygroup.uk”> Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
99 lines
2.6 KiB
TypeScript
99 lines
2.6 KiB
TypeScript
/**
|
|
* A component that will display a number, and when it is updated will use animation to
|
|
* highlight the direction of change. This defaults to red for downwards, and green for
|
|
* upwards.
|
|
*
|
|
* @author Matt <matt@vega.xyz>
|
|
* @author Edd <edd@vega.xyz>
|
|
* @author John <john.walley@mulberryhousesoftware.com>
|
|
*/
|
|
|
|
import { memo, useRef, useEffect } from 'react';
|
|
import { theme } from '@vegaprotocol/tailwindcss-config';
|
|
import { splitAt } from '../format';
|
|
|
|
const FLASH_DURATION = 800; // Duration of flash animation in milliseconds
|
|
|
|
export interface FlashCellProps {
|
|
/**
|
|
* The string representation of value. It can be formatted in bespoke ways,
|
|
* so we can't simply convert value
|
|
*/
|
|
children: string;
|
|
/** The numeric representation of 'children' */
|
|
value: number;
|
|
}
|
|
|
|
/**
|
|
* Given two strings, finds the index first character that has changed in string 2
|
|
*
|
|
* Used by <FlashCell /> to highlight substrings to highlight the portion of a number that has changed
|
|
* From: https://stackoverflow.com/questions/32858626/detect-position-of-first-difference-in-2-strings
|
|
*
|
|
* @param a String to diff
|
|
* @param b Second string to diff
|
|
* @return number Index of first different character, or -1
|
|
*/
|
|
export function findFirstDiffPos(a: string, b: string): number {
|
|
let i = 0;
|
|
if (a === b) return -1;
|
|
if (!a || !b) return -1;
|
|
|
|
while (a[i] === b[i]) i++;
|
|
return i;
|
|
}
|
|
|
|
/**
|
|
* Get value from previous render
|
|
*/
|
|
function usePrevious<T>(value: T): T | undefined {
|
|
const ref = useRef<T | undefined>();
|
|
|
|
useEffect(() => {
|
|
ref.current = value;
|
|
}, [value]);
|
|
|
|
return ref.current;
|
|
}
|
|
|
|
export const FlashCell = memo(({ children, value }: FlashCellProps) => {
|
|
const ref = useRef<HTMLSpanElement | null>(null);
|
|
const previousLabel = usePrevious(children);
|
|
const previousValue = usePrevious(value);
|
|
|
|
const indexOfChange = previousLabel
|
|
? findFirstDiffPos(previousLabel, children)
|
|
: 0;
|
|
|
|
const splitText = splitAt(indexOfChange)(children);
|
|
|
|
if (indexOfChange !== -1 && previousValue !== undefined) {
|
|
if (value < previousValue) {
|
|
ref.current?.animate(
|
|
[
|
|
{ color: theme.colors.pink },
|
|
{ color: theme.colors.pink, offset: 0.8 },
|
|
{ color: 'inherit' },
|
|
],
|
|
FLASH_DURATION
|
|
);
|
|
} else if (value > previousValue) {
|
|
ref.current?.animate(
|
|
[
|
|
{ color: theme.colors.green.vega },
|
|
{ color: theme.colors.green.vega, offset: 0.8 },
|
|
{ color: 'inherit' },
|
|
],
|
|
FLASH_DURATION
|
|
);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<span data-testid="flash-cell">
|
|
{splitText[0]}
|
|
<span ref={ref}>{splitText[1]}</span>
|
|
</span>
|
|
);
|
|
});
|