@elliemae/ds-tabs 2.0.0-rc.9 → 2.0.2

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 (106) 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/exportsRelated/DSTab.js +32 -0
  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 +78 -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 +25 -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/utils/hooks/useTabsCallbacks.js +59 -0
  26. package/esm/DSTabs.js +29 -110
  27. package/esm/DSTabsCTX.js +25 -0
  28. package/esm/DSTabsDatatestid.js +14 -0
  29. package/esm/DSTabsTypes.js +1 -0
  30. package/esm/config/useCrossRef.js +13 -0
  31. package/esm/config/useTabs.js +47 -0
  32. package/esm/defaultProps.js +23 -0
  33. package/esm/exportsRelated/DSTab.js +21 -0
  34. package/esm/index.js +4 -3
  35. package/esm/parts/carousel/Carousel.js +63 -0
  36. package/esm/parts/carousel/styles.js +49 -0
  37. package/esm/parts/carousel/useCarousel.js +70 -0
  38. package/esm/parts/carousel/useCarouselCallbacks.js +68 -0
  39. package/esm/parts/tabBar/TabBar.js +151 -0
  40. package/esm/parts/tabBar/styles.js +185 -0
  41. package/esm/parts/tabBar/useTabBar.js +90 -0
  42. package/esm/parts/tabsContent/TabsContent.js +40 -0
  43. package/esm/parts/tabsContent/styles.js +7 -0
  44. package/esm/parts/tabsPanel/TabsPanels.js +67 -0
  45. package/esm/parts/tabsPanel/styles.js +17 -0
  46. package/esm/propTypes.js +28 -0
  47. package/esm/utils/constants.js +21 -0
  48. package/esm/utils/helpers.js +37 -0
  49. package/esm/utils/hooks/useKeyboardNavigation.js +57 -0
  50. package/esm/utils/hooks/useTabsCallbacks.js +55 -0
  51. package/package.json +91 -35
  52. package/types/DSTabs.d.ts +6 -165
  53. package/types/DSTabsCTX.d.ts +4 -0
  54. package/types/DSTabsDatatestid.d.ts +12 -0
  55. package/types/DSTabsTypes.d.ts +202 -0
  56. package/types/config/useCrossRef.d.ts +2 -0
  57. package/types/config/useTabs.d.ts +2 -0
  58. package/types/defaultProps.d.ts +2 -0
  59. package/types/exportsRelated/DSTab.d.ts +14 -0
  60. package/types/index.d.ts +4 -3
  61. package/types/parts/carousel/Carousel.d.ts +3 -0
  62. package/types/parts/carousel/styles.d.ts +9 -0
  63. package/types/parts/carousel/useCarousel.d.ts +2 -0
  64. package/types/parts/carousel/useCarouselCallbacks.d.ts +2 -0
  65. package/types/parts/tabBar/TabBar.d.ts +2 -0
  66. package/types/parts/tabBar/styles.d.ts +7 -0
  67. package/types/parts/tabBar/useTabBar.d.ts +2 -0
  68. package/types/parts/tabsContent/TabsContent.d.ts +2 -0
  69. package/types/parts/tabsContent/styles.d.ts +1 -0
  70. package/types/parts/tabsPanel/TabsPanels.d.ts +2 -0
  71. package/types/parts/tabsPanel/styles.d.ts +2 -0
  72. package/types/propTypes.d.ts +54 -0
  73. package/types/tests/{DSTabs.events.test.d.ts → DSTabs.callbacks.test.d.ts} +0 -0
  74. package/types/tests/DSTabs.func.test.d.ts +1 -0
  75. package/types/tests/DSTabs.keyboard.test.d.ts +1 -0
  76. package/types/utils/constants.d.ts +19 -0
  77. package/types/utils/helpers.d.ts +8 -0
  78. package/types/utils/hooks/useKeyboardNavigation.d.ts +2 -0
  79. package/types/utils/hooks/useTabsCallbacks.d.ts +2 -0
  80. package/cjs/Carousel.js +0 -205
  81. package/cjs/DSTab.js +0 -46
  82. package/cjs/PanelContainer.js +0 -48
  83. package/cjs/SubTabBar.js +0 -54
  84. package/cjs/TabBar.js +0 -421
  85. package/cjs/TabTypes.js +0 -15
  86. package/cjs/TabsImpl.js +0 -120
  87. package/cjs/TabsPanels.js +0 -85
  88. package/cjs/useResize.js +0 -24
  89. package/esm/Carousel.js +0 -196
  90. package/esm/DSTab.js +0 -36
  91. package/esm/PanelContainer.js +0 -40
  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/esm/useResize.js +0 -20
  98. package/types/Carousel.d.ts +0 -16
  99. package/types/DSTab.d.ts +0 -51
  100. package/types/PanelContainer.d.ts +0 -20
  101. package/types/SubTabBar.d.ts +0 -23
  102. package/types/TabBar.d.ts +0 -30
  103. package/types/TabTypes.d.ts +0 -5
  104. package/types/TabsImpl.d.ts +0 -37
  105. package/types/TabsPanels.d.ts +0 -5
  106. package/types/useResize.d.ts +0 -1
@@ -0,0 +1,70 @@
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 } from 'react';
6
+ import useResizeObserver from '@react-hook/resize-observer';
7
+ import { DSTabsContext } from '../../DSTabsCTX.js';
8
+ import { isElementVisibleCarousel } from '../../utils/helpers.js';
9
+ import { useCarouselCallbacks } from './useCarouselCallbacks.js';
10
+
11
+ const useCarousel = _ref => {
12
+ let {
13
+ updateIndicatorStyle
14
+ } = _ref;
15
+ const {
16
+ carouselOnlyListRef
17
+ } = useContext(DSTabsContext);
18
+ const [showChevrons, setShowChevrons] = useState({
19
+ right: false,
20
+ left: false
21
+ });
22
+ const {
23
+ tabsRefAsArray
24
+ } = useContext(DSTabsContext);
25
+ const shouldShowLeft = useCallback(() => carouselOnlyListRef.current ? carouselOnlyListRef.current.scrollLeft > 0 : false, [carouselOnlyListRef]);
26
+ const shouldShowRight = useCallback(() => carouselOnlyListRef.current ? carouselOnlyListRef.current.scrollLeft < carouselOnlyListRef.current.scrollWidth - carouselOnlyListRef.current.clientWidth : false, [carouselOnlyListRef]);
27
+ const recalcChevrons = useCallback(() => {
28
+ setShowChevrons({
29
+ right: shouldShowRight(),
30
+ left: shouldShowLeft()
31
+ });
32
+ }, [shouldShowLeft, shouldShowRight]);
33
+ const getVisibleItemsOffset = useCallback(() => {
34
+ if (tabsRefAsArray.current) {
35
+ const scroll = tabsRefAsArray.current.reduce((acc, c) => {
36
+ if (isElementVisibleCarousel(c, carouselOnlyListRef.current)) {
37
+ const styles = window.getComputedStyle(c);
38
+ const width = c.clientWidth;
39
+ const margin = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
40
+ return acc + (width + margin);
41
+ }
42
+
43
+ return acc;
44
+ }, 0);
45
+ return scroll - 16;
46
+ }
47
+
48
+ return 0;
49
+ }, [tabsRefAsArray, carouselOnlyListRef]);
50
+ useResizeObserver(carouselOnlyListRef, recalcChevrons);
51
+ const {
52
+ leftButtonOnClick,
53
+ rightButtonOnClick,
54
+ handleOnClick,
55
+ handleOnScroll
56
+ } = useCarouselCallbacks({
57
+ getVisibleItemsOffset,
58
+ recalcChevrons,
59
+ updateIndicatorStyle
60
+ });
61
+ return {
62
+ showChevrons,
63
+ leftButtonOnClick,
64
+ rightButtonOnClick,
65
+ handleOnClick,
66
+ handleOnScroll
67
+ };
68
+ };
69
+
70
+ 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.SUBTABS && 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.SUBTABS ? "capitalize" : "uppercase";
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 };
@@ -0,0 +1,90 @@
1
+ import 'core-js/modules/web.dom-collections.iterator.js';
2
+ import { useContext, useState, useCallback, useEffect, useLayoutEffect } from 'react';
3
+ import useResizeObserver from '@react-hook/resize-observer';
4
+ import { isElementVisible, shouldHaveLeftGradient, shouldHaveRightGradient } from '../../utils/helpers.js';
5
+ import { DSTabsContext } from '../../DSTabsCTX.js';
6
+ import { defaultIndicatorStyles } from '../../utils/constants.js';
7
+
8
+ const useTabBar = () => {
9
+ const {
10
+ actualActiveTab,
11
+ actualActiveTabRef,
12
+ tabsListRef,
13
+ props: {
14
+ showSelectionIndicator,
15
+ isDSMobile,
16
+ fixedTabsHeaders
17
+ }
18
+ } = useContext(DSTabsContext);
19
+ const [mobileGradients, setMobileGradients] = useState({
20
+ left: false,
21
+ right: false
22
+ });
23
+ const [indicatorStyle, setIndicatorStyle] = useState(defaultIndicatorStyles);
24
+ const getIndicatorStyles = useCallback(() => {
25
+ if (tabsListRef.current) {
26
+ const tabList = tabsListRef.current;
27
+ const activeTabButton = actualActiveTabRef.current;
28
+ if (!activeTabButton || !isElementVisible(activeTabButton, tabList)) return defaultIndicatorStyles; // The missingMargins are to make the selection indicator white marks work properly in desktop, we need
29
+ // the full width of the tab button with margins.
30
+
31
+ const missingMargins = isDSMobile ? 0 : 16;
32
+ const tabClientWidth = isDSMobile && !fixedTabsHeaders ? activeTabButton.clientWidth : activeTabButton.clientWidth + missingMargins * 2; // The reason why we use the tabList.scrollLeft is due to the centerOnTabChange (only in Mobile and FlexibleTabs)
33
+ // behavior that adds scroll to the tabList
34
+
35
+ const position = isDSMobile && !fixedTabsHeaders ? activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left + tabList.scrollLeft : activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left - missingMargins;
36
+ const backgroundWithTransparentAndWhite = "linear-gradient(to right, transparent 0px, transparent 12px, white 12px, white 16px, #1E79C2 16px, #1E79C2 ".concat(tabClientWidth - 16, "px,white ").concat(tabClientWidth - 16, "px,white ").concat(tabClientWidth - 12, "px,transparent ").concat(tabClientWidth - 12, "px,transparent ").concat(tabClientWidth, "px )");
37
+ const backgroundWithTransparent = "linear-gradient(to right, transparent 0px, transparent 16px, #1E79C2 16px, #1E79C2 ".concat(tabClientWidth - 16, "px,transparent ").concat(tabClientWidth - 16, "px,transparent ").concat(tabClientWidth, "px )");
38
+ return {
39
+ left: "".concat(position, "px"),
40
+ width: "".concat(tabClientWidth, "px"),
41
+ backgroundWithTransparentAndWhite,
42
+ backgroundWithTransparent
43
+ };
44
+ }
45
+
46
+ return defaultIndicatorStyles;
47
+ }, [actualActiveTabRef, fixedTabsHeaders, isDSMobile, tabsListRef]);
48
+ const updateIndicatorStyle = useCallback(() => setTimeout(() => setIndicatorStyle(getIndicatorStyles()), 100), [getIndicatorStyles, setIndicatorStyle]);
49
+ useResizeObserver(tabsListRef, updateIndicatorStyle);
50
+ const updateMobileGradients = useCallback(() => {
51
+ if (tabsListRef.current && isDSMobile && !fixedTabsHeaders) {
52
+ const {
53
+ scrollLeft,
54
+ scrollWidth,
55
+ clientWidth
56
+ } = tabsListRef.current;
57
+ setMobileGradients({
58
+ left: shouldHaveLeftGradient(scrollLeft),
59
+ right: shouldHaveRightGradient(scrollLeft, clientWidth, scrollWidth)
60
+ });
61
+ }
62
+ }, [fixedTabsHeaders, isDSMobile, tabsListRef]);
63
+ useEffect(() => {
64
+ if (showSelectionIndicator) {
65
+ updateIndicatorStyle();
66
+ }
67
+
68
+ if (isDSMobile && !fixedTabsHeaders) {
69
+ updateMobileGradients();
70
+ }
71
+ }, [updateIndicatorStyle, showSelectionIndicator, actualActiveTab, updateMobileGradients, isDSMobile, fixedTabsHeaders]);
72
+ useLayoutEffect(() => {
73
+ if (showSelectionIndicator) {
74
+ updateIndicatorStyle();
75
+ }
76
+
77
+ if (isDSMobile && !fixedTabsHeaders) {
78
+ updateMobileGradients();
79
+ }
80
+ }, [updateMobileGradients, showSelectionIndicator, updateIndicatorStyle, isDSMobile, fixedTabsHeaders]);
81
+ return {
82
+ updateIndicatorStyle,
83
+ setIndicatorStyle,
84
+ indicatorStyle,
85
+ mobileGradients,
86
+ updateMobileGradients
87
+ };
88
+ };
89
+
90
+ export { useTabBar };
@@ -0,0 +1,40 @@
1
+ import 'core-js/modules/esnext.async-iterator.filter.js';
2
+ import 'core-js/modules/esnext.iterator.constructor.js';
3
+ import 'core-js/modules/esnext.iterator.filter.js';
4
+ import 'core-js/modules/esnext.async-iterator.for-each.js';
5
+ import 'core-js/modules/esnext.iterator.for-each.js';
6
+ import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
7
+ import _jsx from '@babel/runtime/helpers/esm/jsx';
8
+ import { useContext } from 'react';
9
+ import { TabsPanels } from '../tabsPanel/TabsPanels.js';
10
+ import { TabBar } from '../tabBar/TabBar.js';
11
+ import { StyledTabBarContainer } from './styles.js';
12
+ import { DSTabsContext } from '../../DSTabsCTX.js';
13
+ import { DSTabsDatatestid } from '../../DSTabsDatatestid.js';
14
+ import { jsxs } from 'react/jsx-runtime';
15
+
16
+ var _TabBar, _TabsPanels;
17
+
18
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19
+
20
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
21
+ const TabsContent = () => {
22
+ const {
23
+ props: {
24
+ containerProps,
25
+ innerRef,
26
+ tabsListAriaLabel,
27
+ tabBarExtraContent
28
+ }
29
+ } = useContext(DSTabsContext);
30
+ return /*#__PURE__*/jsxs("div", _objectSpread(_objectSpread({}, containerProps), {}, {
31
+ ref: innerRef,
32
+ "data-testid": DSTabsDatatestid.TABS_CONTAINER,
33
+ children: [/*#__PURE__*/_jsx(StyledTabBarContainer, {
34
+ "aria-label": tabsListAriaLabel,
35
+ role: "tablist"
36
+ }, void 0, _TabBar || (_TabBar = /*#__PURE__*/_jsx(TabBar, {})), tabBarExtraContent), _TabsPanels || (_TabsPanels = /*#__PURE__*/_jsx(TabsPanels, {}))]
37
+ }));
38
+ };
39
+
40
+ export { TabsContent };
@@ -0,0 +1,7 @@
1
+ import styled from 'styled-components';
2
+
3
+ const StyledTabBarContainer = /*#__PURE__*/styled.div.withConfig({
4
+ componentId: "sc-vm3k1y-0"
5
+ })(["display:flex;overflow-x:hidden;"]);
6
+
7
+ export { StyledTabBarContainer };