UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

307 lines (295 loc) 15 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import React__default, { useState, useEffect, useCallback, useMemo, isValidElement, cloneElement } from 'react'; import '../../../node_modules/recharts/es6/index.js'; import { animate } from 'framer-motion'; import '../utils/index.js'; import '../CommonChartComponents/index.js'; import { componentId } from '../CommonChartComponents/tokens.js'; import { componentIds } from './componentIds.js'; import { useLineChartContext, LineChartContext } from './LineChartContext.js'; import getIn from '../../../utils/lodashButBetter/get.js'; import '../../../utils/makeAnalyticsAttribute/index.js'; import '../../../utils/metaAttribute/index.js'; import '../../BladeProvider/index.js'; import '../../Box/BaseBox/index.js'; import '../../../utils/isValidAllowedChildren/index.js'; import '../../../utils/assignWithoutSideEffects/index.js'; import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import useTheme from '../../BladeProvider/useTheme.js'; import useChartsColorTheme from '../utils/useColorTheme.js'; import { Line as Line$1 } from '../../../node_modules/recharts/es6/cartesian/Line.js'; import { assignWithoutSideEffects } from '../../../utils/assignWithoutSideEffects/assignWithoutSideEffects.js'; import { getComponentId } from '../../../utils/isValidAllowedChildren/isValidAllowedChildren.js'; import { assignDataColorMapping } from '../utils/assignDataColorMapping/assignDataColorMapping.js'; import { CommonChartComponentsContext } from '../CommonChartComponents/CommonChartComponentsContext.js'; import { BaseBox } from '../../Box/BaseBox/BaseBox.web.js'; import { metaAttribute } from '../../../utils/metaAttribute/metaAttribute.web.js'; import { makeAnalyticsAttribute } from '../../../utils/makeAnalyticsAttribute/makeAnalyticsAttribute.js'; import { ResponsiveContainer } from '../../../node_modules/recharts/es6/component/ResponsiveContainer.js'; import { LineChart } from '../../../node_modules/recharts/es6/chart/LineChart.js'; var _excluded = ["color", "strokeStyle", "type", "dot", "activeDot", "showLegend", "_index", "_colorTheme", "_totalLines", "hide", "dataKey"], _excluded2 = ["children", "colorTheme", "testID", "data"]; function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var Line = function Line(_ref) { var color = _ref.color, _ref$strokeStyle = _ref.strokeStyle, strokeStyle = _ref$strokeStyle === void 0 ? 'solid' : _ref$strokeStyle, _ref$type = _ref.type, type = _ref$type === void 0 ? 'monotone' : _ref$type, _ref$dot = _ref.dot, dot = _ref$dot === void 0 ? false : _ref$dot, _ref$activeDot = _ref.activeDot, activeDot = _ref$activeDot === void 0 ? true : _ref$activeDot, _ref$showLegend = _ref.showLegend, showLegend = _ref$showLegend === void 0 ? true : _ref$showLegend, _index = _ref._index, _colorTheme = _ref._colorTheme, _totalLines = _ref._totalLines, hide = _ref.hide, dataKey = _ref.dataKey, props = _objectWithoutProperties(_ref, _excluded); var _useTheme = useTheme(), theme = _useTheme.theme; var _useLineChartContext = useLineChartContext(), hoveredDataKey = _useLineChartContext.hoveredDataKey, setHoveredDataKey = _useLineChartContext.setHoveredDataKey; var themeColors = useChartsColorTheme({ colorTheme: _colorTheme, chartName: 'line', chartDataIndicators: _totalLines }); var isOtherLineHovered = hoveredDataKey !== null && hoveredDataKey !== dataKey; var colorToken = getIn(theme.colors, color !== null && color !== void 0 ? color : themeColors[_index !== null && _index !== void 0 ? _index : 0]); var strokeDasharray = strokeStyle === 'dashed' ? '5 5' : strokeStyle === 'dotted' ? '2 2' : undefined; var isLineDotted = strokeStyle === 'dashed'; var animationBegin = isLineDotted ? theme.motion.delay.gentle + theme.motion.duration.xgentle : theme.motion.delay.gentle; var animationDuration = theme.motion.duration.xgentle; // Animated opacity using framer-motion var targetOpacity = isOtherLineHovered ? 0.2 : 1; var _useState = useState(targetOpacity), _useState2 = _slicedToArray(_useState, 2), animatedOpacity = _useState2[0], setAnimatedOpacity = _useState2[1]; useEffect(function () { var controls = animate(animatedOpacity, targetOpacity, { duration: 0.5, ease: 'easeInOut', onUpdate: function onUpdate(latest) { return setAnimatedOpacity(latest); } }); return function () { return controls.stop(); }; }, [targetOpacity]); var updateHoveredDataKey = useCallback(function (key) { if (!hide) { setHoveredDataKey === null || setHoveredDataKey === void 0 || setHoveredDataKey(key); } }, [hide, setHoveredDataKey]); var handleMouseEnter = useCallback(function () { updateHoveredDataKey(dataKey); }, [dataKey, updateHoveredDataKey]); var handleMouseLeave = useCallback(function () { updateHoveredDataKey(null); }, [updateHoveredDataKey]); // activeDot config with hover handlers var activeDotConfig = useMemo(function () { return activeDot ? { onMouseEnter: function onMouseEnter() { return updateHoveredDataKey(dataKey); }, onMouseLeave: function onMouseLeave() { return updateHoveredDataKey(null); } } : false; }, [activeDot, dataKey, updateHoveredDataKey]); return /*#__PURE__*/jsxs(Fragment, { children: [/*#__PURE__*/jsx(Line$1, { type: "monotone", dataKey: dataKey, stroke: "transparent", strokeWidth: 15, dot: false, activeDot: false, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, connectNulls: true, legendType: "none", tooltipType: "none", hide: hide }, "line-".concat(dataKey, "-background")), /*#__PURE__*/jsx(Line$1, _objectSpread({ stroke: colorToken, strokeWidth: 1.5, strokeDasharray: strokeDasharray, type: type, dataKey: dataKey, activeDot: isOtherLineHovered ? false : activeDotConfig, dot: dot, legendType: showLegend ? 'line' : 'none', animationBegin: animationBegin, animationDuration: animationDuration, strokeLinecap: "round", strokeLinejoin: "round", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, hide: hide // Animated opacity using framer-motion , strokeOpacity: animatedOpacity, isAnimationActive: true }, props), "line-".concat(dataKey, "-main"))] }); }; var ChartLine = /*#__PURE__*/assignWithoutSideEffects(Line, { componentId: componentIds.ChartLine }); // Main components var ChartLineWrapper = function ChartLineWrapper(_ref2) { var children = _ref2.children, _ref2$colorTheme = _ref2.colorTheme, colorTheme = _ref2$colorTheme === void 0 ? 'categorical' : _ref2$colorTheme, testID = _ref2.testID, data = _ref2.data, restProps = _objectWithoutProperties(_ref2, _excluded2); var themeColors = useChartsColorTheme({ colorTheme: colorTheme, chartName: 'line' }); // State to track which line is currently hovered var _useState3 = useState(null), _useState4 = _slicedToArray(_useState3, 2), hoveredDataKey = _useState4[0], setHoveredDataKey = _useState4[1]; var _useState5 = useState(undefined), _useState6 = _slicedToArray(_useState5, 2), selectedDataKeys = _useState6[0], setSelectedDataKeys = _useState6[1]; /** * We need to check child of CharLineWrapper. if they have any custom color we store that. * We need these mapping because colors of tooltip & legend is determine based on this * recharts do provide a color but it is hex code and we need blade color token . */ var _useMemo = useMemo(function () { var childrenArray = React__default.Children.toArray(children); var dataColorMapping = {}; // Count ChartLine components var totalLines = childrenArray.filter(function (child) { return /*#__PURE__*/isValidElement(child) && getComponentId(child) === componentIds.ChartLine; }).length; // Find ChartXAxis and extract secondaryDataKey var secondaryDataKey; var _iterator = _createForOfIteratorHelper(childrenArray), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var child = _step.value; if (/*#__PURE__*/React__default.isValidElement(child) && getComponentId(child) === componentId.chartXAxis) { var _child$props3; secondaryDataKey = (_child$props3 = child.props) === null || _child$props3 === void 0 ? void 0 : _child$props3.secondaryDataKey; break; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var LineChartIndex = 0; var lineChartModifiedChildrens = React__default.Children.map(children, function (child) { if (/*#__PURE__*/isValidElement(child) && getComponentId(child) === componentIds.ChartLine) { var _child$props, _child$props2; var childColor = child === null || child === void 0 || (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.color; var dataKey = child === null || child === void 0 || (_child$props2 = child.props) === null || _child$props2 === void 0 ? void 0 : _child$props2.dataKey; if (dataKey) { /** * if we have custom color given by user we use that other wise we just * assign theme colors to the dataColorMapping, in `assignDataColorMapping` */ dataColorMapping[dataKey] = { colorToken: childColor, isCustomColor: Boolean(childColor) }; } // Pass hide prop based on whether this line's dataKey is NOT in selectedDataKeys // If selectedDataKeys is undefined, show all lines (default behavior) return /*#__PURE__*/cloneElement(child, { _index: LineChartIndex++, _colorTheme: colorTheme, _totalLines: totalLines, hide: selectedDataKeys ? !selectedDataKeys.includes(dataKey) : false }); } return child; }); assignDataColorMapping(dataColorMapping, themeColors); return { dataColorMapping: dataColorMapping, lineChartModifiedChildrens: lineChartModifiedChildrens, totalLines: totalLines, secondaryDataKey: secondaryDataKey }; }, [children, colorTheme, themeColors, selectedDataKeys]), dataColorMapping = _useMemo.dataColorMapping, lineChartModifiedChildrens = _useMemo.lineChartModifiedChildrens, secondaryDataKey = _useMemo.secondaryDataKey; // Build secondary label map internally from ChartXAxis's secondaryDataKey prop var secondaryLabelMap = useMemo(function () { if (!secondaryDataKey || !data) return undefined; var map = {}; data.forEach(function (item, index) { map[index] = item[secondaryDataKey]; }); return map; }, [data, secondaryDataKey]); // Memoize context values to prevent unnecessary re-renders of consumers var lineChartContextValue = useMemo(function () { return { hoveredDataKey: hoveredDataKey, setHoveredDataKey: setHoveredDataKey }; }, [hoveredDataKey]); var commonChartContextValue = useMemo(function () { return { chartName: 'line', dataColorMapping: dataColorMapping, selectedDataKeys: selectedDataKeys, setSelectedDataKeys: setSelectedDataKeys, secondaryLabelMap: secondaryLabelMap, dataLength: data === null || data === void 0 ? void 0 : data.length }; }, [dataColorMapping, selectedDataKeys, secondaryLabelMap, data === null || data === void 0 ? void 0 : data.length]); return /*#__PURE__*/jsx(LineChartContext.Provider, { value: lineChartContextValue, children: /*#__PURE__*/jsx(CommonChartComponentsContext.Provider, { value: commonChartContextValue, children: /*#__PURE__*/jsx(BaseBox, _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, metaAttribute({ name: 'line-chart', testID: testID })), makeAnalyticsAttribute(restProps)), {}, { width: "100%", height: "100%" }, restProps), {}, { children: /*#__PURE__*/jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /*#__PURE__*/jsx(LineChart, { data: data, onMouseLeave: function onMouseLeave() { return setHoveredDataKey(null); }, children: lineChartModifiedChildrens }) }) })) }) }); }; export { ChartLine, ChartLineWrapper }; //# sourceMappingURL=LineChart.web.js.map