UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

143 lines (139 loc) 6.37 kB
import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import React__default from 'react'; import ReactDOM from 'react-dom'; import { TabNavContext } from './TabNavContext.js'; import { TabNavIndicator } from './TabNavIndicator.web.js'; import { useResize } from '../../../utils/useResize.js'; import '../../Box/BaseBox/index.js'; import '../../Box/styledProps/index.js'; import '../../../utils/metaAttribute/index.js'; import '../../../utils/makeAnalyticsAttribute/index.js'; import { jsx, jsxs } from 'react/jsx-runtime'; import { BaseBox } from '../../Box/BaseBox/BaseBox.web.js'; import { metaAttribute } from '../../../utils/metaAttribute/metaAttribute.web.js'; import { MetaConstants } from '../../../utils/metaAttribute/metaConstants.js'; import { makeAnalyticsAttribute } from '../../../utils/makeAnalyticsAttribute/makeAnalyticsAttribute.js'; import { getStyledProps } from '../../Box/styledProps/getStyledProps.js'; var _excluded = ["children"], _excluded2 = ["children", "items"]; 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 TabNavItems = function TabNavItems(_ref) { var children = _ref.children, rest = _objectWithoutProperties(_ref, _excluded); return /*#__PURE__*/jsx(BaseBox, _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, rest), {}, { display: "flex", width: "100%", gap: "spacing.0", position: "relative", left: "-1px" }, metaAttribute({ name: MetaConstants.TabNavItems })), makeAnalyticsAttribute(rest)), {}, { children: React__default.Children.map(children, function (child, index) { return /*#__PURE__*/React__default.cloneElement(child, { __isInsideTabNavItems: true, __index: index }); }) })); }; var TabNav = function TabNav(_ref2) { var children = _ref2.children, items = _ref2.items, rest = _objectWithoutProperties(_ref2, _excluded2); var ref = React__default.useRef(null); var itemsRowRef = React__default.useRef(null); var _React$useState = React__default.useState(items), _React$useState2 = _slicedToArray(_React$useState, 2), controlledItems = _React$useState2[0], setControlledItems = _React$useState2[1]; var overflowingItems = controlledItems.filter(function (item) { var _item$isAlwaysOverflo; return (_item$isAlwaysOverflo = item.isAlwaysOverflowing) !== null && _item$isAlwaysOverflo !== void 0 ? _item$isAlwaysOverflo : item.isOverflowing; }); var _items = controlledItems.filter(function (item) { return !item.isAlwaysOverflowing && !item.isOverflowing; }); // We need to memoize this callback otherwise it will cause infinite re-renders // Because the ResizeObserver callback will be a new reference on every render // and it will trigger a re-render var resizeCallback = React__default.useCallback(function (resizeInfo) { var target = resizeInfo.target; var updateItems = function updateItems() { setControlledItems(function (items) { return items.map(function (item, index) { // never overflow the first item if (index === 0) return _objectSpread(_objectSpread({}, item), {}, { isOverflowing: false }); // add padding to the offsetX to account the "More" menu's width changing due to the selection state (eg: More:ProdctName) // Currently, hardcoding this to 150, we can make this dynamic too but that's causing layout thrashing // because first we need to calculate the width of the "More" menu and then update the items var padding = 150; var offset = item.offsetX + padding - target.getBoundingClientRect().left; if (offset > target.offsetWidth) { return _objectSpread(_objectSpread({}, item), {}, { isOverflowing: true }); } else { return _objectSpread(_objectSpread({}, item), {}, { isOverflowing: false }); } }); }); }; // https://github.com/webpack/webpack/issues/14814 var flushSync = ReactDOM['flushSync'.toString()]; // Using flushSync to avoid layout thrashing, // this will force React to flush all pending updates and only then update the DOM if (flushSync !== undefined) { flushSync(updateItems); } else { updateItems(); } }, []); useResize(ref, resizeCallback); return /*#__PURE__*/jsx(TabNavContext.Provider, { value: { containerRef: ref, controlledItems: controlledItems, setControlledItems: setControlledItems }, children: /*#__PURE__*/jsx(BaseBox, _objectSpread(_objectSpread(_objectSpread(_objectSpread({ as: "nav", display: "flex", width: "100%", alignItems: "center", alignSelf: "center", position: "relative" }, getStyledProps(rest)), makeAnalyticsAttribute(rest)), metaAttribute({ name: MetaConstants.TabNav })), {}, { ref: ref, children: /*#__PURE__*/jsx(BaseBox, { display: "flex", width: "100%", position: "relative", children: /*#__PURE__*/jsxs(BaseBox, { ref: itemsRowRef, display: "flex", flexDirection: "row", width: "max-content", position: "relative", children: [children({ items: _items, overflowingItems: overflowingItems }), /*#__PURE__*/jsx(TabNavIndicator, { containerRef: itemsRowRef })] }) }) })) }); }; export { TabNav, TabNavItems }; //# sourceMappingURL=TabNav.web.js.map