@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
153 lines (151 loc) • 6.49 kB
JavaScript
'use client';
import iconDown from '@ui5/webcomponents-icons/dist/down.js';
import iconUp from '@ui5/webcomponents-icons/dist/up.js';
import { useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
import { clsx } from 'clsx';
import { cloneElement, forwardRef, useId } from 'react';
import { DeviationIndicator } from '../../enums/DeviationIndicator.js';
import { ValueColor } from '../../enums/ValueColor.js';
import { ARIA_DESC_CARD_HEADER, NUMERICCONTENT_DEVIATION_DOWN, NUMERICCONTENT_DEVIATION_UP, SEMANTIC_COLOR_CRITICAL, SEMANTIC_COLOR_ERROR, SEMANTIC_COLOR_GOOD, SEMANTIC_COLOR_NEUTRAL } from '../../i18n/i18n-defaults.js';
import { flattenFragments } from '../../internal/utils.js';
import { Icon } from '../../webComponents/Icon/index.js';
import { classNames, content } from './AnalyticalCardHeader.module.css.js';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const semanticColorMap = new Map([[ValueColor.Neutral, SEMANTIC_COLOR_NEUTRAL], [ValueColor.Good, SEMANTIC_COLOR_GOOD], [ValueColor.Critical, SEMANTIC_COLOR_CRITICAL], [ValueColor.Error, SEMANTIC_COLOR_ERROR]]);
const deviationMap = new Map([[DeviationIndicator.Up, NUMERICCONTENT_DEVIATION_UP], [DeviationIndicator.Down, NUMERICCONTENT_DEVIATION_DOWN]]);
/**
* The `AnalyticalCardHeader` is a KPI header, enabling the AnalyticalCard representation. If this header is used, the `Card` should only receive a chart as content and no footer area.
*
* __Note:__ This component should only be used as header for the `Card` component.
*/
export const AnalyticalCardHeader = /*#__PURE__*/forwardRef((props, ref) => {
const {
titleText,
titleTextLevel = 3,
subtitleText,
value,
scale,
state = ValueColor.None,
onClick,
className,
description,
status,
unitOfMeasurement,
trend = DeviationIndicator.None,
style,
children,
id,
...rest
} = props;
useStylesheet(content, AnalyticalCardHeader.displayName);
const headerClasses = clsx(classNames.cardHeader, onClick && classNames.cardHeaderClickable, className);
const valueAndUnitClasses = clsx(classNames.mainIndicator, state === ValueColor.Good && classNames.good, state === ValueColor.Error && classNames.error, state === ValueColor.Critical && classNames.critical, state === ValueColor.Neutral && classNames.neutral);
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
const uniqueHeaderId = useId();
const headerId = id ?? uniqueHeaderId;
const sideIndicators = flattenFragments(children);
const sideIndicatorIds = sideIndicators.map((child, idx) => {
return child.props?.id ?? `${headerId}-indicator${idx}`;
});
let kpiAriaLabel = `${value ?? ''}${scale ?? ''}\n`;
if (trend && trend !== DeviationIndicator.None) {
kpiAriaLabel += i18nBundle.getText(deviationMap.get(trend) ?? '');
kpiAriaLabel += '\n';
}
if (state && state !== ValueColor.None) {
kpiAriaLabel += i18nBundle.getText(semanticColorMap.get(state) ?? '');
}
let cardLabelledBy = `${headerId}-title`;
if (subtitleText) {
cardLabelledBy += ` ${headerId}-subtitle`;
}
if (unitOfMeasurement) {
cardLabelledBy += ` ${headerId}-unitOfMeasurement`;
}
cardLabelledBy += ` ${headerId}-mainIndicator`;
for (const sideIndicatorId of sideIndicatorIds) {
cardLabelledBy += ` ${sideIndicatorId}`;
}
if (description) {
cardLabelledBy += ` ${headerId}-description`;
}
return /*#__PURE__*/_jsx("div", {
ref: ref,
className: headerClasses,
style: style,
id: headerId,
"data-sap-ui-fastnavgroup": "true",
tabIndex: 0,
role: "group",
"aria-roledescription": i18nBundle.getText(ARIA_DESC_CARD_HEADER),
"aria-labelledby": cardLabelledBy,
slot: "header",
...rest,
onClick: onClick,
children: /*#__PURE__*/_jsxs("div", {
children: [/*#__PURE__*/_jsxs("div", {
className: classNames.headerTitles,
children: [/*#__PURE__*/_jsxs("div", {
className: classNames.headerFirstLine,
children: [/*#__PURE__*/_jsx("span", {
role: "heading",
"aria-level": titleTextLevel,
className: classNames.headerText,
id: `${headerId}-title`,
children: titleText
}), status && /*#__PURE__*/_jsx("span", {
className: classNames.status,
children: status
})]
}), (subtitleText || unitOfMeasurement) && /*#__PURE__*/_jsxs("div", {
className: classNames.headerSecondLine,
children: [/*#__PURE__*/_jsx("span", {
id: `${headerId}-subtitle`,
children: subtitleText
}), unitOfMeasurement && /*#__PURE__*/_jsx("span", {
id: `${headerId}-unitOfMeasurement`,
className: classNames.unitOfMeasurement,
children: unitOfMeasurement
})]
})]
}), /*#__PURE__*/_jsxs("div", {
className: classNames.kpiContent,
children: [/*#__PURE__*/_jsxs("div", {
className: valueAndUnitClasses,
id: `${headerId}-mainIndicator`,
"aria-label": kpiAriaLabel.trim(),
title: kpiAriaLabel.trim(),
role: "img",
"data-component-name": "AnalyticalCardHeaderNumericContent",
children: [/*#__PURE__*/_jsx("span", {
className: classNames.value,
children: value
}), /*#__PURE__*/_jsxs("div", {
className: classNames.indicatorAndUnit,
children: [trend !== DeviationIndicator.None && /*#__PURE__*/_jsx(Icon, {
className: clsx(classNames.indicator),
name: trend === DeviationIndicator.Up ? iconUp : iconDown
}), /*#__PURE__*/_jsx("div", {
className: classNames.unit,
children: scale
})]
})]
}), /*#__PURE__*/_jsx("div", {
className: classNames.indicatorGap
}), /*#__PURE__*/_jsx("div", {
className: classNames.sideIndicators,
children: sideIndicators.map((sideIndicator, index) => {
return /*#__PURE__*/cloneElement(sideIndicator, {
id: sideIndicator.props.id ?? `${headerId}-indicator${index}`
});
})
})]
}), description && /*#__PURE__*/_jsx("span", {
id: `${headerId}-description`,
className: classNames.description,
children: description
})]
})
});
});
AnalyticalCardHeader.displayName = 'AnalyticalCardHeader';