@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
135 lines • 4.13 kB
JavaScript
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
import React from 'react';
import classnames from 'classnames';
import { convertJsxToString, warn } from "../../shared/component-helper.js";
import StatValueContext from "./StatValueContext.js";
import { TextInternal as Text } from "./Text.js";
const trendContextValue = {
useBasisSize: true,
defaultMainWeight: null
};
function Trend(props) {
const {
value,
children,
id = null,
element: Element = 'span',
className = null,
style = null,
srLabel = null,
tone = null,
skeleton = null,
...rest
} = props;
const rawValue = typeof value !== 'undefined' ? value : getValueFromChildren(children);
const hasCustomChildren = typeof value === 'undefined' && children !== null && children !== undefined && typeof children !== 'string' && typeof children !== 'number';
const {
tone: resolvedTone,
sign,
displayValue
} = resolveTrendValue(rawValue);
const childText = hasCustomChildren ? convertJsxToString(children) : '';
const visibleText = childText || `${sign || ''}${displayValue}`;
const usedTone = tone || resolvedTone;
const srText = srLabel ? `${convertJsxToString(srLabel)}${' '}${visibleText}` : visibleText;
return React.createElement(Text, _extends({}, rest, {
id: id,
element: Element,
className: classnames(`dnb-stat dnb-stat__trend dnb-stat__trend--${usedTone}`, className),
style: style,
skeleton: skeleton,
textClassName: false
}), React.createElement(StatValueContext.Provider, {
value: trendContextValue
}, React.createElement("span", {
className: "dnb-stat__trend-content",
"aria-hidden": true
}, !hasCustomChildren && sign ? React.createElement("span", {
className: "dnb-stat__trend-sign"
}, sign) : null, React.createElement("span", {
className: "dnb-stat__trend-value"
}, hasCustomChildren ? children : displayValue))), React.createElement("span", {
className: "dnb-sr-only",
"data-text": srText
}));
}
Trend._supportsSpacingProps = true;
function getValueFromChildren(children) {
if (typeof children === 'string' || typeof children === 'number') {
return children;
}
if (React.isValidElement(children)) {
const childProps = children.props;
if (typeof (childProps === null || childProps === void 0 ? void 0 : childProps.value) === 'number' || typeof (childProps === null || childProps === void 0 ? void 0 : childProps.value) === 'string') {
return childProps.value;
}
if (typeof (childProps === null || childProps === void 0 ? void 0 : childProps.children) === 'string' || typeof (childProps === null || childProps === void 0 ? void 0 : childProps.children) === 'number') {
return childProps.children;
}
}
const text = convertJsxToString(children);
if (!text) {
warn('Stat.Trend could not resolve a value from the provided children. Falling back to "0".');
}
return text || '0';
}
function resolveTrendValue(value) {
if (typeof value === 'number') {
if (!Number.isFinite(value)) {
return {
tone: 'neutral',
sign: null,
displayValue: '\u2013'
};
}
if (value > 0) {
return {
tone: 'positive',
sign: '+',
displayValue: String(Math.abs(value))
};
}
if (value < 0) {
return {
tone: 'negative',
sign: '-',
displayValue: String(Math.abs(value))
};
}
return {
tone: 'neutral',
sign: null,
displayValue: '0'
};
}
const normalized = String(value || '');
const match = normalized.match(/^([+\-−])\s?(.*)$/);
if (!match) {
return {
tone: 'neutral',
sign: null,
displayValue: normalized || '0'
};
}
if (!match[2]) {
return {
tone: 'neutral',
sign: null,
displayValue: '0'
};
}
if (match[1] === '+') {
return {
tone: 'positive',
sign: '+',
displayValue: match[2]
};
}
return {
tone: 'negative',
sign: '-',
displayValue: match[2]
};
}
export default Trend;
//# sourceMappingURL=Trend.js.map