@wonderflow/react-components
Version:
UI components from Wonderflow's Wanda design system
99 lines (98 loc) • 4.18 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import tkns from '@wonderflow/tokens/platforms/web/tokens.json';
import clsx from 'clsx';
import { forwardRef, useMemo, } from 'react';
import { Skeleton, Stack, Symbol, Text, } from '../../..';
import { formatKpiValue, formatPriceRangeValues, isGreaterThan, isValueOverCap, } from '../../../utils/formatting';
import * as styles from './product-card-kpis.module.css';
export const ProductCardKpis = forwardRef(({ rating, feedbackCount, votesCount, votesRating, sentiment, nps, groups, tgw, priceMin, priceMax, currency = 'EUR', currencyDecimals = 0, users, usersCap, skus, skusCap, kpiItems = 3, kpisRowGap = 8, isLoading = false, className, style, }, forwardedRef) => {
const config = useMemo(() => ([
{
property: 'feedback-rating',
value: formatKpiValue(rating, { decimal: 2, minRange: 0, maxRange: 5 }),
icon: 'feedback-rating',
iconColor: isGreaterThan(3.99, rating) ? `hsl(${tkns.color.yellow['30']})` : undefined,
},
{
property: 'nps',
value: formatKpiValue(nps, { decimal: 0, minRange: -100, maxRange: 100 }),
icon: 'nps',
},
{
property: 'feedback-count',
value: formatKpiValue(feedbackCount),
icon: 'message',
},
{
property: 'votes-rating',
value: formatKpiValue(votesRating, { decimal: 2, minRange: 0, maxRange: 5 }),
icon: 'star',
iconColor: isGreaterThan(3.99, votesRating) ? `hsl(${tkns.color.yellow['20']})` : undefined,
},
{
property: 'votes-count',
value: formatKpiValue(votesCount),
icon: 'votes-count',
},
{
property: 'sentiment',
value: formatKpiValue(sentiment, { decimal: 2, minRange: -1, maxRange: 1 }),
icon: 'hearts-suit',
iconColor: isGreaterThan(0.5, sentiment) ? 'var(--highlight-red-foreground)' : undefined,
},
{
property: 'tgw',
value: formatKpiValue(tgw, { decimal: 2, minRange: 0 }),
icon: 'frown',
},
{
property: 'price',
value: formatPriceRangeValues(priceMin, priceMax, { currency, decimals: currencyDecimals }),
icon: 'tags',
},
{
property: 'groups',
value: formatKpiValue(groups),
icon: 'grid',
},
{
property: 'users',
value: formatKpiValue(users, { decimal: 0, minRange: 0, cap: usersCap }),
icon: 'users',
iconColor: isValueOverCap(users, usersCap) ? 'var(--highlight-red-foreground)' : undefined,
},
{
property: 'skus',
value: formatKpiValue(skus, { decimal: 0, minRange: 0, cap: skusCap }),
icon: 'rectangle-barcode',
iconColor: isValueOverCap(skus, skusCap) ? 'var(--highlight-red-foreground)' : undefined,
},
]), [
rating,
sentiment,
feedbackCount,
votesCount,
votesRating,
nps,
groups,
tgw,
priceMin,
priceMax,
currency,
currencyDecimals,
users,
usersCap,
skus,
skusCap
]);
const itemHeight = 20;
const dynamicStyle = {
'--kpis-height': `${kpiItems * itemHeight + ((kpiItems - 1) * (+kpisRowGap))}px`,
};
return (_jsx("div", { className: clsx(styles.Kpis, className), style: { ...dynamicStyle, ...style }, ref: forwardedRef, children: isLoading
? (_jsx(Stack, { hPadding: 24, children: _jsx(Skeleton, { height: "20px", width: "50%", count: kpiItems }) }))
: (_jsx(Stack, { rowGap: kpisRowGap, hPadding: 24, children: config
.filter(el => el.value)
.map(el => (_jsx(Text, { variant: "body-2", decoratorStart: _jsx(Symbol, { source: el.icon, color: el.iconColor, weight: "solid" }), decoratorSize: "small", children: _jsx("b", { children: el.value }) }, el.property))) })) }));
});
ProductCardKpis.displayName = 'ProductCardKpis';