@elliemae/ds-tabs 2.0.0-rc.1 → 2.0.0-rc.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/cjs/DSTabs.js +27 -108
  2. package/cjs/DSTabsCTX.js +30 -0
  3. package/cjs/DSTabsDatatestid.js +18 -0
  4. package/cjs/DSTabsTypes.js +2 -0
  5. package/cjs/config/useCrossRef.js +17 -0
  6. package/cjs/config/useTabs.js +51 -0
  7. package/cjs/defaultProps.js +27 -0
  8. package/cjs/{PanelContainer.js → exportsRelated/DSTab.js} +14 -30
  9. package/cjs/index.js +5 -5
  10. package/cjs/parts/carousel/Carousel.js +71 -0
  11. package/cjs/parts/carousel/styles.js +60 -0
  12. package/cjs/parts/carousel/useCarousel.js +91 -0
  13. package/cjs/parts/carousel/useCarouselCallbacks.js +72 -0
  14. package/cjs/parts/tabBar/TabBar.js +160 -0
  15. package/cjs/parts/tabBar/styles.js +199 -0
  16. package/cjs/parts/tabBar/useTabBar.js +98 -0
  17. package/cjs/parts/tabsContent/TabsContent.js +49 -0
  18. package/cjs/parts/tabsContent/styles.js +15 -0
  19. package/cjs/parts/tabsPanel/TabsPanels.js +77 -0
  20. package/cjs/parts/tabsPanel/styles.js +30 -0
  21. package/cjs/propTypes.js +33 -0
  22. package/cjs/utils/constants.js +29 -0
  23. package/cjs/utils/helpers.js +47 -0
  24. package/cjs/utils/hooks/useKeyboardNavigation.js +61 -0
  25. package/cjs/{useResize.js → utils/hooks/useResize.js} +8 -4
  26. package/cjs/utils/hooks/useTabsCallbacks.js +59 -0
  27. package/esm/DSTabs.js +29 -110
  28. package/esm/DSTabsCTX.js +25 -0
  29. package/esm/DSTabsDatatestid.js +14 -0
  30. package/esm/DSTabsTypes.js +1 -0
  31. package/esm/config/useCrossRef.js +13 -0
  32. package/esm/config/useTabs.js +47 -0
  33. package/esm/defaultProps.js +23 -0
  34. package/esm/{PanelContainer.js → exportsRelated/DSTab.js} +7 -26
  35. package/esm/index.js +4 -3
  36. package/esm/parts/carousel/Carousel.js +63 -0
  37. package/esm/parts/carousel/styles.js +49 -0
  38. package/esm/parts/carousel/useCarousel.js +87 -0
  39. package/esm/parts/carousel/useCarouselCallbacks.js +68 -0
  40. package/esm/parts/tabBar/TabBar.js +151 -0
  41. package/esm/parts/tabBar/styles.js +185 -0
  42. package/esm/parts/tabBar/useTabBar.js +90 -0
  43. package/esm/parts/tabsContent/TabsContent.js +40 -0
  44. package/esm/parts/tabsContent/styles.js +7 -0
  45. package/esm/parts/tabsPanel/TabsPanels.js +67 -0
  46. package/esm/parts/tabsPanel/styles.js +22 -0
  47. package/esm/propTypes.js +28 -0
  48. package/esm/utils/constants.js +21 -0
  49. package/esm/utils/helpers.js +37 -0
  50. package/esm/utils/hooks/useKeyboardNavigation.js +57 -0
  51. package/esm/{useResize.js → utils/hooks/useResize.js} +9 -5
  52. package/esm/utils/hooks/useTabsCallbacks.js +55 -0
  53. package/package.json +103 -36
  54. package/types/DSTabs.d.ts +10 -60
  55. package/types/DSTabsCTX.d.ts +4 -0
  56. package/types/DSTabsDatatestid.d.ts +12 -0
  57. package/types/DSTabsTypes.d.ts +202 -0
  58. package/types/config/useCrossRef.d.ts +2 -0
  59. package/types/config/useTabs.d.ts +2 -0
  60. package/types/defaultProps.d.ts +2 -0
  61. package/types/exportsRelated/DSTab.d.ts +14 -0
  62. package/types/index.d.ts +4 -3
  63. package/types/parts/carousel/Carousel.d.ts +3 -0
  64. package/types/parts/carousel/styles.d.ts +9 -0
  65. package/types/parts/carousel/useCarousel.d.ts +2 -0
  66. package/types/parts/carousel/useCarouselCallbacks.d.ts +2 -0
  67. package/types/parts/tabBar/TabBar.d.ts +2 -0
  68. package/types/parts/tabBar/styles.d.ts +7 -0
  69. package/types/parts/tabBar/useTabBar.d.ts +2 -0
  70. package/types/parts/tabsContent/TabsContent.d.ts +2 -0
  71. package/types/parts/tabsContent/styles.d.ts +1 -0
  72. package/types/parts/tabsPanel/TabsPanels.d.ts +2 -0
  73. package/types/parts/tabsPanel/styles.d.ts +2 -0
  74. package/types/propTypes.d.ts +54 -0
  75. package/types/tests/{DSTabs.events.test.d.ts → DSTabs.callbacks.test.d.ts} +0 -0
  76. package/types/tests/DSTabs.func.test.d.ts +1 -0
  77. package/types/tests/DSTabs.keyboard.test.d.ts +1 -0
  78. package/types/utils/constants.d.ts +19 -0
  79. package/types/utils/helpers.d.ts +8 -0
  80. package/types/utils/hooks/useKeyboardNavigation.d.ts +2 -0
  81. package/types/utils/hooks/useResize.d.ts +2 -0
  82. package/types/utils/hooks/useTabsCallbacks.d.ts +2 -0
  83. package/cjs/Carousel.js +0 -205
  84. package/cjs/DSTab.js +0 -46
  85. package/cjs/SubTabBar.js +0 -54
  86. package/cjs/TabBar.js +0 -421
  87. package/cjs/TabTypes.js +0 -15
  88. package/cjs/TabsImpl.js +0 -120
  89. package/cjs/TabsPanels.js +0 -85
  90. package/esm/Carousel.js +0 -196
  91. package/esm/DSTab.js +0 -36
  92. package/esm/SubTabBar.js +0 -48
  93. package/esm/TabBar.js +0 -410
  94. package/esm/TabTypes.js +0 -10
  95. package/esm/TabsImpl.js +0 -113
  96. package/esm/TabsPanels.js +0 -75
  97. package/types/Carousel.d.ts +0 -16
  98. package/types/DSTab.d.ts +0 -22
  99. package/types/PanelContainer.d.ts +0 -20
  100. package/types/SubTabBar.d.ts +0 -23
  101. package/types/TabBar.d.ts +0 -30
  102. package/types/TabTypes.d.ts +0 -5
  103. package/types/TabsImpl.d.ts +0 -37
  104. package/types/TabsPanels.d.ts +0 -5
  105. package/types/useResize.d.ts +0 -1
@@ -0,0 +1,63 @@
1
+ import _jsx from '@babel/runtime/helpers/esm/jsx';
2
+ import { useContext } from 'react';
3
+ import { DSIconSizes, DSIconColors } from '@elliemae/ds-icon';
4
+ import { BUTTON_TYPES } from '@elliemae/ds-button';
5
+ import { ChevronLeft, ChevronRight } from '@elliemae/ds-icons';
6
+ import { StyledCarouselWrapper, StyledCarouselButtonWrapper, StyledCarouselBtn, StyledChildrenWrap } from './styles.js';
7
+ import { useCarousel } from './useCarousel.js';
8
+ import { DSTabsContext } from '../../DSTabsCTX.js';
9
+ import { DSTabsDatatestid } from '../../DSTabsDatatestid.js';
10
+ import { jsx } from 'react/jsx-runtime';
11
+
12
+ const Carousel = _ref => {
13
+ let {
14
+ children,
15
+ updateIndicatorStyle
16
+ } = _ref;
17
+ const {
18
+ showChevrons,
19
+ leftButtonOnClick,
20
+ rightButtonOnClick,
21
+ handleOnClick,
22
+ handleOnScroll
23
+ } = useCarousel({
24
+ updateIndicatorStyle
25
+ });
26
+ const {
27
+ carouselOnlyListRef,
28
+ props: {
29
+ type
30
+ }
31
+ } = useContext(DSTabsContext);
32
+ return /*#__PURE__*/_jsx(StyledCarouselWrapper, {}, void 0, showChevrons.left && /*#__PURE__*/_jsx(StyledCarouselButtonWrapper, {
33
+ tabType: type
34
+ }, void 0, /*#__PURE__*/_jsx(StyledCarouselBtn, {
35
+ size: "s",
36
+ onClick: leftButtonOnClick,
37
+ tabIndex: -1,
38
+ "data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_LEFT,
39
+ buttonType: BUTTON_TYPES.ICON
40
+ }, void 0, /*#__PURE__*/_jsx(ChevronLeft, {
41
+ size: DSIconSizes.S,
42
+ color: DSIconColors.PRIMARY
43
+ }))), showChevrons.right && /*#__PURE__*/_jsx(StyledCarouselButtonWrapper, {
44
+ tabType: type,
45
+ right: showChevrons.right
46
+ }, void 0, /*#__PURE__*/_jsx(StyledCarouselBtn, {
47
+ size: "s",
48
+ onClick: rightButtonOnClick,
49
+ tabIndex: -1,
50
+ "data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_RIGHT,
51
+ buttonType: BUTTON_TYPES.ICON
52
+ }, void 0, /*#__PURE__*/_jsx(ChevronRight, {
53
+ size: DSIconSizes.S,
54
+ color: DSIconColors.PRIMARY
55
+ }))), /*#__PURE__*/jsx(StyledChildrenWrap, {
56
+ ref: carouselOnlyListRef,
57
+ onClick: handleOnClick,
58
+ onScroll: handleOnScroll,
59
+ children: children
60
+ }));
61
+ };
62
+
63
+ export { Carousel };
@@ -0,0 +1,49 @@
1
+ import styled from 'styled-components';
2
+ import { DSButtonV2 } from '@elliemae/ds-button';
3
+ import { TabTypes } from '../../utils/constants.js';
4
+
5
+ const StyledCarouselBtn = /*#__PURE__*/styled(DSButtonV2).withConfig({
6
+ componentId: "sc-prv5a7-0"
7
+ })(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;"], _ref => {
8
+ let {
9
+ theme
10
+ } = _ref;
11
+ return theme.space.xs;
12
+ }, _ref2 => {
13
+ let {
14
+ theme
15
+ } = _ref2;
16
+ return theme.space.xs;
17
+ });
18
+ const StyledCarouselWrapper = /*#__PURE__*/styled.span.withConfig({
19
+ componentId: "sc-prv5a7-1"
20
+ })(["position:relative;width:100%;display:flex;"]);
21
+ const StyledChildrenWrap = /*#__PURE__*/styled.div.withConfig({
22
+ componentId: "sc-prv5a7-2"
23
+ })(["display:flex;flex-wrap:nowrap;flex:1;overflow-x:hidden;"]);
24
+ const StyledCarouselButtonWrapper = /*#__PURE__*/styled.div.withConfig({
25
+ componentId: "sc-prv5a7-3"
26
+ })(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background-color:white;", ";"], _ref3 => {
27
+ let {
28
+ right
29
+ } = _ref3;
30
+ return right ? 'right: 0;' : "left: 0;";
31
+ }, _ref4 => {
32
+ let {
33
+ tabType
34
+ } = _ref4;
35
+ return tabType === TabTypes.NORMAL ? '32px' : '22px';
36
+ }, _ref5 => {
37
+ let {
38
+ tabType
39
+ } = _ref5;
40
+ return tabType === TabTypes.NORMAL ? '5px' : '0px';
41
+ }, _ref6 => {
42
+ let {
43
+ theme,
44
+ tabType
45
+ } = _ref6;
46
+ return tabType === TabTypes.NORMAL ? "\n border-bottom: 1px solid ".concat(theme.colors.neutral[200], ";") : "";
47
+ });
48
+
49
+ export { StyledCarouselBtn, StyledCarouselButtonWrapper, StyledCarouselWrapper, StyledChildrenWrap };
@@ -0,0 +1,87 @@
1
+ import 'core-js/modules/web.dom-collections.iterator.js';
2
+ import 'core-js/modules/esnext.async-iterator.reduce.js';
3
+ import 'core-js/modules/esnext.iterator.constructor.js';
4
+ import 'core-js/modules/esnext.iterator.reduce.js';
5
+ import { useContext, useState, useCallback, useEffect } from 'react';
6
+ import { DSTabsContext } from '../../DSTabsCTX.js';
7
+ import { isElementVisibleCarousel } from '../../utils/helpers.js';
8
+ import { useResize } from '../../utils/hooks/useResize.js';
9
+ import { useCarouselCallbacks } from './useCarouselCallbacks.js';
10
+
11
+ const useCarousel = _ref => {
12
+ var _carouselOnlyListRef$, _carouselOnlyListRef$2, _carouselOnlyListRef$3;
13
+
14
+ let {
15
+ updateIndicatorStyle
16
+ } = _ref;
17
+ const {
18
+ carouselOnlyListRef
19
+ } = useContext(DSTabsContext);
20
+ const carouselListScrollLeft = carouselOnlyListRef === null || carouselOnlyListRef === void 0 ? void 0 : (_carouselOnlyListRef$ = carouselOnlyListRef.current) === null || _carouselOnlyListRef$ === void 0 ? void 0 : _carouselOnlyListRef$.scrollLeft;
21
+ const carouselListClientWidth = carouselOnlyListRef === null || carouselOnlyListRef === void 0 ? void 0 : (_carouselOnlyListRef$2 = carouselOnlyListRef.current) === null || _carouselOnlyListRef$2 === void 0 ? void 0 : _carouselOnlyListRef$2.clientWidth;
22
+ const carouselListScrollWidth = carouselOnlyListRef === null || carouselOnlyListRef === void 0 ? void 0 : (_carouselOnlyListRef$3 = carouselOnlyListRef.current) === null || _carouselOnlyListRef$3 === void 0 ? void 0 : _carouselOnlyListRef$3.scrollWidth;
23
+ const [showChevrons, setShowChevrons] = useState({
24
+ right: false,
25
+ left: false
26
+ });
27
+ const {
28
+ tabsRefAsArray
29
+ } = useContext(DSTabsContext);
30
+ const shouldShowLeft = useCallback(() => {
31
+ if (typeof carouselListScrollLeft === 'number') return carouselListScrollLeft > 0;
32
+ return false;
33
+ }, [carouselListScrollLeft]);
34
+ const shouldShowRight = useCallback(() => {
35
+ if (typeof carouselListScrollLeft === 'number' && typeof carouselListClientWidth === 'number' && typeof carouselListScrollWidth === 'number') return carouselListScrollLeft < carouselListScrollWidth - carouselListClientWidth;
36
+ return false;
37
+ }, [carouselListClientWidth, carouselListScrollLeft, carouselListScrollWidth]);
38
+ const recalcChevrons = useCallback(() => {
39
+ setShowChevrons({
40
+ right: shouldShowRight(),
41
+ left: shouldShowLeft()
42
+ });
43
+ }, [shouldShowLeft, shouldShowRight]);
44
+ const getVisibleItemsOffset = useCallback(() => {
45
+ if (tabsRefAsArray.current) {
46
+ const scroll = tabsRefAsArray.current.reduce((acc, c) => {
47
+ if (isElementVisibleCarousel(c, carouselOnlyListRef.current)) {
48
+ const styles = window.getComputedStyle(c);
49
+ const width = c.clientWidth;
50
+ const margin = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
51
+ return acc + (width + margin);
52
+ }
53
+
54
+ return acc;
55
+ }, 0);
56
+ return scroll - 16;
57
+ }
58
+
59
+ return 0;
60
+ }, [tabsRefAsArray, carouselOnlyListRef]);
61
+ useEffect(() => {
62
+ recalcChevrons(); // this can cause optimization problems but for now it's good enough
63
+ }, [recalcChevrons]);
64
+ useResize({
65
+ ref: carouselOnlyListRef,
66
+ callback: recalcChevrons
67
+ });
68
+ const {
69
+ leftButtonOnClick,
70
+ rightButtonOnClick,
71
+ handleOnClick,
72
+ handleOnScroll
73
+ } = useCarouselCallbacks({
74
+ getVisibleItemsOffset,
75
+ recalcChevrons,
76
+ updateIndicatorStyle
77
+ });
78
+ return {
79
+ showChevrons,
80
+ leftButtonOnClick,
81
+ rightButtonOnClick,
82
+ handleOnClick,
83
+ handleOnScroll
84
+ };
85
+ };
86
+
87
+ export { useCarousel };
@@ -0,0 +1,68 @@
1
+ import { useContext, useCallback } from 'react';
2
+ import { isElementVisibleCarousel } from '../../utils/helpers.js';
3
+ import { DSTabsContext } from '../../DSTabsCTX.js';
4
+
5
+ /* eslint-disable max-statements */
6
+ const useCarouselCallbacks = _ref => {
7
+ let {
8
+ getVisibleItemsOffset,
9
+ updateIndicatorStyle,
10
+ recalcChevrons
11
+ } = _ref;
12
+ const {
13
+ focusableTabsRef,
14
+ carouselOnlyListRef
15
+ } = useContext(DSTabsContext);
16
+ const rightButtonOnClick = useCallback(() => {
17
+ if (carouselOnlyListRef.current) {
18
+ carouselOnlyListRef.current.scrollLeft += getVisibleItemsOffset();
19
+ }
20
+ }, [getVisibleItemsOffset, carouselOnlyListRef]);
21
+ const leftButtonOnClick = useCallback(() => {
22
+ if (carouselOnlyListRef.current) {
23
+ carouselOnlyListRef.current.scrollLeft -= getVisibleItemsOffset();
24
+ }
25
+ }, [getVisibleItemsOffset, carouselOnlyListRef]);
26
+ const handleOnScroll = useCallback(() => {
27
+ recalcChevrons();
28
+ if (updateIndicatorStyle) updateIndicatorStyle();
29
+ }, [recalcChevrons, updateIndicatorStyle]);
30
+ const handleOnClick = useCallback(_ref2 => {
31
+ let {
32
+ target
33
+ } = _ref2;
34
+
35
+ if (focusableTabsRef.current && target.getAttribute('role') === 'tab') {
36
+ const tabList = carouselOnlyListRef.current;
37
+ const tabButton = target;
38
+ const tabButtonDimensions = tabButton.getBoundingClientRect();
39
+ const tabListDimensions = tabList === null || tabList === void 0 ? void 0 : tabList.getBoundingClientRect();
40
+ const tabButtonIndex = tabButton.dataset.index;
41
+ const lastItemIndex = focusableTabsRef.current.length.toString();
42
+ const magicNumber = 34;
43
+ const firstOrLastItem = tabButtonIndex === '0' || tabButtonIndex === lastItemIndex;
44
+
45
+ if (!isElementVisibleCarousel(tabButton, tabList, firstOrLastItem) && tabListDimensions && carouselOnlyListRef.current) {
46
+ const containerWidth = tabListDimensions.width;
47
+ const halfContainer = containerWidth / 2;
48
+ const elementScrollPosition = tabButtonDimensions.left - tabListDimensions.left;
49
+ const positionInContainer = elementScrollPosition % containerWidth;
50
+ const width = tabButton.offsetWidth + magicNumber;
51
+
52
+ if (positionInContainer > halfContainer) {
53
+ carouselOnlyListRef.current.scrollLeft += width + positionInContainer - containerWidth;
54
+ } else {
55
+ carouselOnlyListRef.current.scrollLeft += positionInContainer - magicNumber;
56
+ }
57
+ }
58
+ }
59
+ }, [focusableTabsRef, carouselOnlyListRef]);
60
+ return {
61
+ handleOnClick,
62
+ rightButtonOnClick,
63
+ leftButtonOnClick,
64
+ handleOnScroll
65
+ };
66
+ };
67
+
68
+ export { useCarouselCallbacks };
@@ -0,0 +1,151 @@
1
+ import _jsx from '@babel/runtime/helpers/esm/jsx';
2
+ import 'core-js/modules/esnext.async-iterator.map.js';
3
+ import 'core-js/modules/esnext.iterator.map.js';
4
+ import React, { useContext, useMemo } from 'react';
5
+ import { Carousel } from '../carousel/Carousel.js';
6
+ import { useTabBar } from './useTabBar.js';
7
+ import { StyledTabButton, StyledRequiredMark, StyledSubTabsList, StyledTabList, StyledTabWrapper, StyledSelectionIndicator } from './styles.js';
8
+ import { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';
9
+ import { useKeyboardNavigation } from '../../utils/hooks/useKeyboardNavigation.js';
10
+ import { TabTypes } from '../../utils/constants.js';
11
+ import { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';
12
+ import { DSTabsDatatestid } from '../../DSTabsDatatestid.js';
13
+ import { jsxs, jsx } from 'react/jsx-runtime';
14
+
15
+ var _StyledRequiredMark;
16
+ const TabBar = () => {
17
+ const {
18
+ tabsRef,
19
+ focusableTabsRef,
20
+ tabsListRef,
21
+ tabsRefAsArray,
22
+ actualActiveTab,
23
+ props: {
24
+ type,
25
+ fixedTabsHeaders,
26
+ withCarousel,
27
+ isDSMobile,
28
+ showSeparator,
29
+ children: tabs
30
+ }
31
+ } = useContext(DSTabsContext);
32
+ const {
33
+ lastTabInternalRef,
34
+ firstSubtabInternalRef
35
+ } = useContext(DSTabsCrossRefContext);
36
+ const {
37
+ handleOnTabChange
38
+ } = useTabsCallbacks();
39
+ const {
40
+ handleOnKeyDown
41
+ } = useKeyboardNavigation();
42
+ const {
43
+ indicatorStyle,
44
+ mobileGradients,
45
+ updateMobileGradients,
46
+ updateIndicatorStyle
47
+ } = useTabBar();
48
+ const renderTabs = useMemo(() => {
49
+ const availableTabIndexes = [];
50
+ return React.Children.map(tabs, (tab, index) => {
51
+ const {
52
+ tabId = '',
53
+ title = '',
54
+ style,
55
+ required = false,
56
+ disabled = false,
57
+ ref,
58
+ onClick,
59
+ onKeyDown
60
+ } = tab.props;
61
+ if (!disabled) availableTabIndexes.push(index);
62
+ return /*#__PURE__*/jsxs(StyledTabButton, {
63
+ role: "tab",
64
+ ref: t => {
65
+ if (tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
66
+ tabsRefAsArray.current[index] = t;
67
+ if (!disabled && !focusableTabsRef.current.includes(t)) focusableTabsRef.current.push(t);
68
+ tabsRef.current[index] = t;
69
+
70
+ if (type === TabTypes.SUBTABS && firstSubtabInternalRef && index === availableTabIndexes[0]) {
71
+ firstSubtabInternalRef.current = t;
72
+ }
73
+
74
+ if (type === TabTypes.NORMAL && index === availableTabIndexes[availableTabIndexes.length - 1]) {
75
+ lastTabInternalRef.current = t;
76
+ }
77
+
78
+ if (ref) ref.current = t;
79
+ }
80
+ },
81
+ type: "button",
82
+ "aria-controls": tabId,
83
+ "aria-selected": actualActiveTab === tabId,
84
+ "aria-disabled": disabled,
85
+ "aria-labelledby": "".concat(tabId, "-label"),
86
+ isDSMobile: isDSMobile,
87
+ fixedTabsHeaders: fixedTabsHeaders,
88
+ tabType: type,
89
+ title: title,
90
+ "data-required": required,
91
+ "data-tab-id": tabId,
92
+ "data-index": index,
93
+ withCarousel: withCarousel,
94
+ isActive: actualActiveTab === tabId,
95
+ disabled: disabled,
96
+ showSeparator: showSeparator && type !== TabTypes.NORMAL,
97
+ "data-testid": type === TabTypes.NORMAL ? DSTabsDatatestid.TAB_BUTTON : DSTabsDatatestid.SUBTAB_BUTTON,
98
+ id: "".concat(tabId, "-label"),
99
+ onClick: e => {
100
+ if (!disabled) {
101
+ handleOnTabChange(tabId, e);
102
+ updateIndicatorStyle();
103
+ }
104
+
105
+ if (onClick && !disabled) onClick(tabId, e);
106
+ },
107
+ onKeyDown: e => {
108
+ if (e.key === 'Enter') e.stopPropagation();
109
+ if (!disabled) handleOnKeyDown(e);
110
+ if (onKeyDown && !disabled) onKeyDown(e);
111
+ },
112
+ style: style,
113
+ children: [title, required && (_StyledRequiredMark || (_StyledRequiredMark = /*#__PURE__*/_jsx(StyledRequiredMark, {}, void 0, "\u25CF")))]
114
+ }, tabId);
115
+ });
116
+ }, [tabs, actualActiveTab, isDSMobile, fixedTabsHeaders, type, withCarousel, showSeparator, tabsRefAsArray, focusableTabsRef, tabsRef, firstSubtabInternalRef, lastTabInternalRef, handleOnTabChange, updateIndicatorStyle, handleOnKeyDown]);
117
+
118
+ if (type === TabTypes.SUBTABS && !isDSMobile) {
119
+ return /*#__PURE__*/jsx(StyledSubTabsList, {
120
+ withCarousel: withCarousel,
121
+ "data-testid": DSTabsDatatestid.SUB_TAB_LIST,
122
+ ref: tabsListRef,
123
+ role: "tablist",
124
+ children: withCarousel ? /*#__PURE__*/_jsx(Carousel, {}, void 0, renderTabs) : renderTabs
125
+ });
126
+ }
127
+
128
+ return /*#__PURE__*/jsxs(StyledTabList, {
129
+ withCarousel: withCarousel,
130
+ ref: tabsListRef,
131
+ role: "tablist",
132
+ "data-testid": DSTabsDatatestid.TAB_LIST,
133
+ isDSMobile: isDSMobile,
134
+ fixedTabsHeaders: fixedTabsHeaders,
135
+ mobileGradients: mobileGradients,
136
+ onScroll: updateMobileGradients,
137
+ indicatorStyle: indicatorStyle,
138
+ tabType: type,
139
+ children: [/*#__PURE__*/_jsx(StyledTabWrapper, {
140
+ isDSMobile: isDSMobile,
141
+ fixedTabsHeaders: fixedTabsHeaders
142
+ }, void 0, !isDSMobile && withCarousel ? /*#__PURE__*/_jsx(Carousel, {
143
+ updateIndicatorStyle: updateIndicatorStyle
144
+ }, void 0, renderTabs) : renderTabs), /*#__PURE__*/_jsx(StyledSelectionIndicator, {
145
+ isDSMobile: isDSMobile,
146
+ tabType: type
147
+ })]
148
+ });
149
+ };
150
+
151
+ export { TabBar };
@@ -0,0 +1,185 @@
1
+ import _taggedTemplateLiteral from '@babel/runtime/helpers/esm/taggedTemplateLiteral';
2
+ import styled from 'styled-components';
3
+ import { css, onlySafariAndFirefox, safariAndFirefoxBold } from '@elliemae/ds-system';
4
+ import { TabTypes } from '../../utils/constants.js';
5
+
6
+ var _templateObject;
7
+ const StyledSelectionIndicator = /*#__PURE__*/styled.div.withConfig({
8
+ componentId: "sc-3hla56-0"
9
+ })(["position:absolute;height:3px;top:", ";margin-top:", ";pointer-events:none;transition:200ms cubic-bezier(0.36,0,1,1);z-index:10;", ""], _ref => {
10
+ let {
11
+ tabType,
12
+ isDSMobile
13
+ } = _ref;
14
+ if (isDSMobile) return "34px";
15
+ if (tabType === TabTypes.NORMAL_SMALL) return "15px";
16
+ return "25px";
17
+ }, _ref2 => {
18
+ let {
19
+ theme
20
+ } = _ref2;
21
+ return theme.space.xxxs;
22
+ }, _ref3 => {
23
+ let {
24
+ isDSMobile
25
+ } = _ref3;
26
+ return isDSMobile ? " \n margin-left: 0;\n margin-top: 3px;\n " : "";
27
+ });
28
+ const mobileGradientsSettings = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n"])), _ref4 => {
29
+ let {
30
+ theme,
31
+ mobileGradients,
32
+ isDSMobile,
33
+ fixedTabsHeaders
34
+ } = _ref4;
35
+
36
+ if (isDSMobile && !fixedTabsHeaders) {
37
+ if (mobileGradients.right && mobileGradients.left) return "background: linear-gradient(90deg, rgba(238,238,238,0) 0%, ".concat(theme.colors.brand[200], " 20%, ").concat(theme.colors.brand[200], " 80%, rgba(238,238,238,0) 100%);");
38
+ if (mobileGradients.right) return "background: linear-gradient(90deg, ".concat(theme.colors.brand[200], " 0%, ").concat(theme.colors.brand[200], " 80%, rgba(238,238,238,0) 100%);");
39
+ if (mobileGradients.left) return "background: linear-gradient(90deg, rgba(238,238,238,0) 0%, ".concat(theme.colors.brand[200], " 20%, ").concat(theme.colors.brand[200], " 100%);");
40
+ }
41
+
42
+ return "";
43
+ });
44
+ const StyledTabWrapper = /*#__PURE__*/styled.div.withConfig({
45
+ componentId: "sc-3hla56-1"
46
+ })(["display:flex;flex:1;flex-wrap:nowrap;", ""], _ref5 => {
47
+ let {
48
+ fixedTabsHeaders,
49
+ isDSMobile
50
+ } = _ref5;
51
+ return !fixedTabsHeaders && isDSMobile ? '' : 'overflow-x: hidden;';
52
+ });
53
+ const StyledTabButton = /*#__PURE__*/styled.button.withConfig({
54
+ componentId: "sc-3hla56-2"
55
+ })(["position:relative;background-color:transparent;border:none;cursor:pointer;transition:100ms cubic-bezier(0,0,0.42,1);text-transform:", ";letter-spacing:0px;white-space:nowrap;padding:2px 0;margin-right:", ";margin-left:", ";color:", ";", " ", " ", " ", " ", " ", " ", ""], _ref6 => {
56
+ let {
57
+ tabType
58
+ } = _ref6;
59
+ return tabType === TabTypes.NORMAL ? "uppercase" : "capitalize";
60
+ }, _ref7 => {
61
+ let {
62
+ fixedTabsHeaders,
63
+ isDSMobile
64
+ } = _ref7;
65
+ if (fixedTabsHeaders) return '0px';
66
+ if (!fixedTabsHeaders && isDSMobile) return '14px';
67
+ return '16px';
68
+ }, _ref8 => {
69
+ let {
70
+ fixedTabsHeaders,
71
+ isDSMobile
72
+ } = _ref8;
73
+ if (fixedTabsHeaders) return '0px';
74
+ if (!fixedTabsHeaders && isDSMobile) return '14px';
75
+ return '16px';
76
+ }, _ref9 => {
77
+ let {
78
+ theme
79
+ } = _ref9;
80
+ return theme.colors.neutral[700];
81
+ }, onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), _ref10 => {
82
+ let {
83
+ tabType
84
+ } = _ref10;
85
+ return tabType === TabTypes.NORMAL ? "height: 32px;" : "height: 22px;";
86
+ }, _ref11 => {
87
+ let {
88
+ theme,
89
+ isActive,
90
+ disabled
91
+ } = _ref11;
92
+ return isActive && !disabled ? "\n font-weight: ".concat(theme.fontWeights.semibold, ";\n ").concat(safariAndFirefoxBold("#353C46"), "\n\n &:hover {\n ").concat(safariAndFirefoxBold("#1E79C2"), "\n }\n \n ") : "\n \n ";
93
+ }, _ref12 => {
94
+ let {
95
+ theme,
96
+ disabled
97
+ } = _ref12;
98
+ return disabled ? "\n color: ".concat(theme.colors.neutral[500], ";\n cursor: not-allowed;\n ") : "\n &:hover {\n color: ".concat(theme.colors.brand[600], ";\n }\n ");
99
+ }, _ref13 => {
100
+ let {
101
+ theme,
102
+ isDSMobile
103
+ } = _ref13;
104
+ return !isDSMobile ? "\n &:focus {\n outline: none;\n &:after {\n position: absolute;\n content: '';\n top: 0;\n left: -16px;\n width: calc(100% + 32px);\n height: 100%;\n z-index: 5;\n border-radius: 2px;\n border: 2px solid ".concat(theme.colors.brand[600], ";\n }\n }\n \n ") : "";
105
+ }, _ref14 => {
106
+ let {
107
+ theme,
108
+ showSeparator,
109
+ tabType
110
+ } = _ref14;
111
+ return showSeparator ? "\n &:not(:last-of-type):before\n {\n content: \"\";\n position: absolute;\n width: 1px;\n right: -17px;\n top: 50%;\n transform: translateY(-50%);\n height: ".concat(tabType === TabTypes.NORMAL_SMALL ? "10px" : "16px", ";\n background-color: ").concat(theme.colors.neutral[400], ";\n }") : "";
112
+ }, _ref15 => {
113
+ let {
114
+ theme,
115
+ isActive,
116
+ disabled,
117
+ isDSMobile
118
+ } = _ref15;
119
+ return isDSMobile ? "\n height: 40px;\n color: ".concat(theme.colors.brand[600], ";\n font-weight: ").concat(theme.fontWeights.regular, ";\n padding: 0;\n font-size: 13px;\n line-height: 1.3;\n ").concat(onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), " \n\n &:focus {\n font-weight: ").concat(theme.fontWeights.regular, ";\n font-size: 13px;\n ").concat(safariAndFirefoxBold('#006AA9'), "\n }\n\n ").concat(isActive ? "\n font-weight: ".concat(theme.fontWeights.regular, ";\n font-size: 13px;\n ").concat(safariAndFirefoxBold('#006AA9'), "\n ") : "", "\n\n ").concat(isActive && !disabled ? "\n font-size: 13px;\n color: ".concat(theme.colors.brand[700], ";\n line-height: 1.3;\n font-weight: ").concat(theme.fontWeights.regular, ";\n -webkit-font-smoothing: subpixel-antialiased; \n -webkit-text-stroke: 0.4px ").concat(theme.colors.brand[700], ";") : "", "\n\n ").concat(!disabled ? "\n &:hover,\n &:focus {\n outline: none;\n color: ".concat(theme.colors.brand[700], ";\n ").concat(safariAndFirefoxBold('#006AA9'), "\n }") : "", "\n\n ") : "";
120
+ });
121
+ const StyledSubTabsList = /*#__PURE__*/styled.div.withConfig({
122
+ componentId: "sc-3hla56-3"
123
+ })(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""], _ref16 => {
124
+ let {
125
+ withCarousel
126
+ } = _ref16;
127
+ return withCarousel ? 'max-width: 100%;' : '';
128
+ });
129
+ const StyledTabList = /*#__PURE__*/styled.div.withConfig({
130
+ componentId: "sc-3hla56-4"
131
+ })(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", " ", " ", "{padding-bottom:0;padding-top:0;}", " ", " ", " ", "{", "}&:not(:focus-within){", "{background:", ";}}&:focus-within{", "{background:", "}"], _ref17 => {
132
+ let {
133
+ withCarousel,
134
+ isDSMobile
135
+ } = _ref17;
136
+ return withCarousel && !isDSMobile ? "max-width: 100%;" : '';
137
+ }, _ref18 => {
138
+ let {
139
+ theme,
140
+ isDSMobile,
141
+ tabType
142
+ } = _ref18;
143
+ return tabType !== TabTypes.NORMAL_SMALL ? "\n &:after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: ".concat(isDSMobile ? theme.colors.brand[200] : theme.colors.neutral[200], ";\n pointer-events: none;\n }\n ") : "";
144
+ }, StyledTabButton, _ref19 => {
145
+ let {
146
+ theme,
147
+ isDSMobile
148
+ } = _ref19;
149
+ return isDSMobile ? "border-bottom: 1px solid ".concat(theme.colors.brand[300], ";\n background: ").concat(theme.colors.brand[200], ";") : "";
150
+ }, mobileGradientsSettings, _ref20 => {
151
+ let {
152
+ isDSMobile,
153
+ fixedTabsHeaders
154
+ } = _ref20;
155
+ return isDSMobile ? "\n ".concat(!fixedTabsHeaders ? "\n z-index: 0;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n &::-webkit-scrollbar {\n display: none;\n }" : "\n display: flex;\n ".concat(StyledTabButton, " {\n flex: 1;\n overflow-x: hidden;\n }")) : "";
156
+ }, StyledSelectionIndicator, _ref21 => {
157
+ let {
158
+ indicatorStyle
159
+ } = _ref21;
160
+ return "\n width: ".concat(indicatorStyle.width, ";\n left: ").concat(indicatorStyle.left, ";\n ");
161
+ }, StyledSelectionIndicator, _ref22 => {
162
+ let {
163
+ theme,
164
+ indicatorStyle,
165
+ isDSMobile
166
+ } = _ref22;
167
+ return !isDSMobile ? indicatorStyle.backgroundWithTransparent : theme.colors.brand[600];
168
+ }, StyledSelectionIndicator, _ref23 => {
169
+ let {
170
+ theme,
171
+ indicatorStyle,
172
+ isDSMobile
173
+ } = _ref23;
174
+ return !isDSMobile ? indicatorStyle.backgroundWithTransparentAndWhite : theme.colors.brand[600];
175
+ });
176
+ const StyledRequiredMark = /*#__PURE__*/styled.span.withConfig({
177
+ componentId: "sc-3hla56-5"
178
+ })(["color:", ";font-size:6px;margin-left:2px;position:absolute;top:5px;"], _ref24 => {
179
+ let {
180
+ theme
181
+ } = _ref24;
182
+ return theme.colors.danger[900];
183
+ });
184
+
185
+ export { StyledRequiredMark, StyledSelectionIndicator, StyledSubTabsList, StyledTabButton, StyledTabList, StyledTabWrapper };