@elliemae/ds-tabs 2.0.3 → 2.0.7

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.
@@ -11,12 +11,9 @@ var dsPropsHelpers = require('@elliemae/ds-props-helpers');
11
11
  var defaultProps = require('../defaultProps.js');
12
12
 
13
13
  const useTabs = props => {
14
- var _children$, _children$$props;
15
-
16
14
  const propsWithDefaults = dsPropsHelpers.useMemoMergePropsWithDefault(props, defaultProps.tabsDefaultProps);
17
15
  const {
18
- activeTab,
19
- children
16
+ activeTab
20
17
  } = propsWithDefaults;
21
18
  const tabsRef = React.useRef({});
22
19
  const tabsRefAsArray = React.useRef([]);
@@ -24,7 +21,7 @@ const useTabs = props => {
24
21
  const carouselOnlyListRef = React.useRef(null);
25
22
  const tabsListRef = React.useRef(null);
26
23
  const actualActiveTabRef = React.useRef(null);
27
- const [internalActiveTab, setInternalActiveTab] = React.useState(children === null || children === void 0 ? void 0 : (_children$ = children[0]) === null || _children$ === void 0 ? void 0 : (_children$$props = _children$.props) === null || _children$$props === void 0 ? void 0 : _children$$props.tabId);
24
+ const [internalActiveTab, setInternalActiveTab] = React.useState('');
28
25
  const actualActiveTab = React.useMemo(() => {
29
26
  if (activeTab !== undefined) return activeTab;
30
27
  return internalActiveTab;
@@ -32,8 +29,14 @@ const useTabs = props => {
32
29
  React.useEffect(() => {
33
30
  var _focusableTabsRef$cur;
34
31
 
35
- actualActiveTabRef.current = (_focusableTabsRef$cur = focusableTabsRef.current.find(el => el.dataset.tabId === internalActiveTab)) !== null && _focusableTabsRef$cur !== void 0 ? _focusableTabsRef$cur : null;
36
- }, [internalActiveTab]);
32
+ actualActiveTabRef.current = (_focusableTabsRef$cur = focusableTabsRef.current.find(el => el.dataset.tabId === actualActiveTab)) !== null && _focusableTabsRef$cur !== void 0 ? _focusableTabsRef$cur : null;
33
+ }, [actualActiveTab]);
34
+ React.useEffect(() => {
35
+ if (activeTab === undefined) {
36
+ const firstAvailableTab = focusableTabsRef.current.find(el => el.ariaDisabled !== 'true');
37
+ setInternalActiveTab((firstAvailableTab === null || firstAvailableTab === void 0 ? void 0 : firstAvailableTab.dataset.tabId) || '');
38
+ }
39
+ }, [activeTab]);
37
40
  const ctx = React.useMemo(() => ({
38
41
  props: propsWithDefaults,
39
42
  tabsRef,
@@ -46,8 +46,7 @@ const Carousel = _ref => {
46
46
  "data-testid": DSTabsDatatestid.DSTabsDatatestid.CAROUSEL.BUTTON_LEFT,
47
47
  buttonType: dsButton.BUTTON_TYPES.ICON
48
48
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsIcons.ChevronLeft, {
49
- size: dsIcon.DSIconSizes.S,
50
- color: dsIcon.DSIconColors.PRIMARY
49
+ size: dsIcon.DSIconSizes.S
51
50
  }))), showChevrons.right && /*#__PURE__*/_jsx__default["default"](styles.StyledCarouselButtonWrapper, {
52
51
  tabType: type,
53
52
  right: showChevrons.right
@@ -58,8 +57,7 @@ const Carousel = _ref => {
58
57
  "data-testid": DSTabsDatatestid.DSTabsDatatestid.CAROUSEL.BUTTON_RIGHT,
59
58
  buttonType: dsButton.BUTTON_TYPES.ICON
60
59
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsIcons.ChevronRight, {
61
- size: dsIcon.DSIconSizes.S,
62
- color: dsIcon.DSIconColors.PRIMARY
60
+ size: dsIcon.DSIconSizes.S
63
61
  }))), /*#__PURE__*/jsxRuntime.jsx(styles.StyledChildrenWrap, {
64
62
  ref: carouselOnlyListRef,
65
63
  onClick: handleOnClick,
@@ -12,7 +12,7 @@ var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);
12
12
 
13
13
  const StyledCarouselBtn = /*#__PURE__*/styled__default["default"](dsButton.DSButtonV2).withConfig({
14
14
  componentId: "sc-prv5a7-0"
15
- })(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;"], _ref => {
15
+ })(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;& .em-ds-icon svg{fill:", ";}"], _ref => {
16
16
  let {
17
17
  theme
18
18
  } = _ref;
@@ -22,6 +22,11 @@ const StyledCarouselBtn = /*#__PURE__*/styled__default["default"](dsButton.DSBut
22
22
  theme
23
23
  } = _ref2;
24
24
  return theme.space.xs;
25
+ }, _ref3 => {
26
+ let {
27
+ theme
28
+ } = _ref3;
29
+ return theme.colors.brand[600];
25
30
  });
26
31
  const StyledCarouselWrapper = /*#__PURE__*/styled__default["default"].span.withConfig({
27
32
  componentId: "sc-prv5a7-1"
@@ -31,27 +36,27 @@ const StyledChildrenWrap = /*#__PURE__*/styled__default["default"].div.withConfi
31
36
  })(["display:flex;flex-wrap:nowrap;flex:1;overflow-x:hidden;"]);
32
37
  const StyledCarouselButtonWrapper = /*#__PURE__*/styled__default["default"].div.withConfig({
33
38
  componentId: "sc-prv5a7-3"
34
- })(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background-color:white;", ";"], _ref3 => {
39
+ })(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background:white;", ";"], _ref4 => {
35
40
  let {
36
41
  right
37
- } = _ref3;
42
+ } = _ref4;
38
43
  return right ? 'right: 0;' : "left: 0;";
39
- }, _ref4 => {
44
+ }, _ref5 => {
40
45
  let {
41
46
  tabType
42
- } = _ref4;
47
+ } = _ref5;
43
48
  return tabType === constants.TabTypes.NORMAL ? '32px' : '22px';
44
- }, _ref5 => {
49
+ }, _ref6 => {
45
50
  let {
46
51
  tabType
47
- } = _ref5;
52
+ } = _ref6;
48
53
  return tabType === constants.TabTypes.NORMAL ? '5px' : '0px';
49
- }, _ref6 => {
54
+ }, _ref7 => {
50
55
  let {
51
56
  theme,
52
57
  tabType
53
- } = _ref6;
54
- return tabType === constants.TabTypes.NORMAL ? "\n border-bottom: 1px solid ".concat(theme.colors.neutral[200], ";") : "";
58
+ } = _ref7;
59
+ return tabType === constants.TabTypes.NORMAL ? "\n background: linear-gradient(to bottom, white 0px, white 30px, ".concat(theme.colors.neutral[400], " 30px, ").concat(theme.colors.neutral[400], " 31px, white 31px , white 32px );\n ") : "";
55
60
  });
56
61
 
57
62
  exports.StyledCarouselBtn = StyledCarouselBtn;
@@ -11,6 +11,7 @@ var useTabBar = require('./useTabBar.js');
11
11
  var styles = require('./styles.js');
12
12
  var DSTabsCTX = require('../../DSTabsCTX.js');
13
13
  var useKeyboardNavigation = require('../../utils/hooks/useKeyboardNavigation.js');
14
+ var helpers = require('../../utils/helpers.js');
14
15
  var constants = require('../../utils/constants.js');
15
16
  var useTabsCallbacks = require('../../utils/hooks/useTabsCallbacks.js');
16
17
  var DSTabsDatatestid = require('../../DSTabsDatatestid.js');
@@ -28,6 +29,7 @@ const TabBar = () => {
28
29
  focusableTabsRef,
29
30
  tabsListRef,
30
31
  tabsRefAsArray,
32
+ carouselOnlyListRef,
31
33
  actualActiveTab,
32
34
  props: {
33
35
  type,
@@ -70,21 +72,21 @@ const TabBar = () => {
70
72
  if (!disabled) availableTabIndexes.push(index);
71
73
  return /*#__PURE__*/jsxRuntime.jsxs(styles.StyledTabButton, {
72
74
  role: "tab",
73
- ref: t => {
74
- if (tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
75
- tabsRefAsArray.current[index] = t;
76
- if (!disabled && !focusableTabsRef.current.includes(t)) focusableTabsRef.current.push(t);
77
- tabsRef.current[index] = t;
75
+ ref: tabButtonRef => {
76
+ if (tabButtonRef && tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
77
+ tabsRefAsArray.current[index] = tabButtonRef;
78
+ if (!disabled && !focusableTabsRef.current.includes(tabButtonRef)) focusableTabsRef.current.push(tabButtonRef);
79
+ tabsRef.current[index] = tabButtonRef;
78
80
 
79
81
  if (type === constants.TabTypes.SUBTABS && firstSubtabInternalRef && index === availableTabIndexes[0]) {
80
- firstSubtabInternalRef.current = t;
82
+ firstSubtabInternalRef.current = tabButtonRef;
81
83
  }
82
84
 
83
85
  if (type !== constants.TabTypes.SUBTABS && index === availableTabIndexes[availableTabIndexes.length - 1]) {
84
- lastTabInternalRef.current = t;
86
+ lastTabInternalRef.current = tabButtonRef;
85
87
  }
86
88
 
87
- if (ref) ref.current = t;
89
+ if (ref) ref.current = tabButtonRef;
88
90
  }
89
91
  },
90
92
  type: "button",
@@ -113,6 +115,12 @@ const TabBar = () => {
113
115
 
114
116
  if (onClick && !disabled) onClick(tabId, e);
115
117
  },
118
+ onFocus: e => {
119
+ if (withCarousel) helpers.centerTab({
120
+ e,
121
+ listRef: carouselOnlyListRef
122
+ });
123
+ },
116
124
  onKeyDown: e => {
117
125
  if (e.key === 'Enter') e.stopPropagation();
118
126
  if (!disabled) handleOnKeyDown(e);
@@ -122,7 +130,7 @@ const TabBar = () => {
122
130
  children: [title, required && (_StyledRequiredMark || (_StyledRequiredMark = /*#__PURE__*/_jsx__default["default"](styles.StyledRequiredMark, {}, void 0, "\u25CF")))]
123
131
  }, tabId);
124
132
  });
125
- }, [tabs, actualActiveTab, isDSMobile, fixedTabsHeaders, type, withCarousel, showSeparator, tabsRefAsArray, focusableTabsRef, tabsRef, firstSubtabInternalRef, lastTabInternalRef, handleOnTabChange, updateIndicatorStyle, handleOnKeyDown]);
133
+ }, [tabs, actualActiveTab, isDSMobile, fixedTabsHeaders, type, withCarousel, showSeparator, tabsRefAsArray, focusableTabsRef, tabsRef, firstSubtabInternalRef, lastTabInternalRef, handleOnTabChange, updateIndicatorStyle, carouselOnlyListRef, handleOnKeyDown]);
126
134
 
127
135
  if (type === constants.TabTypes.SUBTABS && !isDSMobile) {
128
136
  return /*#__PURE__*/jsxRuntime.jsx(styles.StyledSubTabsList, {
@@ -20,7 +20,7 @@ const StyledSelectionIndicator = /*#__PURE__*/styled__default["default"].div.wit
20
20
  tabType,
21
21
  isDSMobile
22
22
  } = _ref;
23
- if (isDSMobile) return "34px";
23
+ if (isDSMobile) return "35px";
24
24
  if (tabType === constants.TabTypes.NORMAL_SMALL) return "15px";
25
25
  return "25px";
26
26
  }, _ref2 => {
@@ -52,135 +52,136 @@ const mobileGradientsSettings = dsSystem.css(_templateObject || (_templateObject
52
52
  });
53
53
  const StyledTabWrapper = /*#__PURE__*/styled__default["default"].div.withConfig({
54
54
  componentId: "sc-3hla56-1"
55
- })(["display:flex;flex:1;flex-wrap:nowrap;", ""], _ref5 => {
55
+ })(["display:flex;flex:1;flex-wrap:nowrap;", " ", ""], _ref5 => {
56
56
  let {
57
57
  fixedTabsHeaders,
58
58
  isDSMobile
59
59
  } = _ref5;
60
60
  return !fixedTabsHeaders && isDSMobile ? '' : 'overflow-x: hidden;';
61
+ }, _ref6 => {
62
+ let {
63
+ theme,
64
+ isDSMobile
65
+ } = _ref6;
66
+ return isDSMobile ? "border-bottom: 1px solid ".concat(theme.colors.brand[300], ";") : "";
61
67
  });
62
68
  const StyledTabButton = /*#__PURE__*/styled__default["default"].button.withConfig({
63
69
  componentId: "sc-3hla56-2"
64
- })(["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 => {
70
+ })(["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:", ";", " ", " ", " ", " ", " ", " ", ""], _ref7 => {
65
71
  let {
66
72
  tabType
67
- } = _ref6;
73
+ } = _ref7;
68
74
  return tabType === constants.TabTypes.SUBTABS ? "capitalize" : "uppercase";
69
- }, _ref7 => {
75
+ }, _ref8 => {
70
76
  let {
71
77
  fixedTabsHeaders,
72
78
  isDSMobile
73
- } = _ref7;
79
+ } = _ref8;
74
80
  if (fixedTabsHeaders) return '0px';
75
81
  if (!fixedTabsHeaders && isDSMobile) return '14px';
76
82
  return '16px';
77
- }, _ref8 => {
83
+ }, _ref9 => {
78
84
  let {
79
85
  fixedTabsHeaders,
80
86
  isDSMobile
81
- } = _ref8;
87
+ } = _ref9;
82
88
  if (fixedTabsHeaders) return '0px';
83
89
  if (!fixedTabsHeaders && isDSMobile) return '14px';
84
90
  return '16px';
85
- }, _ref9 => {
91
+ }, _ref10 => {
86
92
  let {
87
93
  theme
88
- } = _ref9;
94
+ } = _ref10;
89
95
  return theme.colors.neutral[700];
90
- }, dsSystem.onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), _ref10 => {
96
+ }, dsSystem.onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), _ref11 => {
91
97
  let {
92
98
  tabType
93
- } = _ref10;
94
- return tabType === constants.TabTypes.NORMAL ? "height: 32px;" : "height: 22px;";
95
- }, _ref11 => {
96
- let {
97
- theme,
98
- isActive,
99
- disabled
100
99
  } = _ref11;
101
- return isActive && !disabled ? "\n font-weight: ".concat(theme.fontWeights.semibold, ";\n ").concat(dsSystem.safariAndFirefoxBold("#353C46"), "\n\n &:hover {\n ").concat(dsSystem.safariAndFirefoxBold("#1E79C2"), "\n }\n \n ") : "\n \n ";
100
+ return tabType === constants.TabTypes.NORMAL ? "height: 32px;" : "height: 22px;";
102
101
  }, _ref12 => {
103
102
  let {
104
103
  theme,
104
+ isActive,
105
105
  disabled
106
106
  } = _ref12;
107
- 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 ");
107
+ return isActive && !disabled ? "\n font-weight: ".concat(theme.fontWeights.semibold, ";\n ").concat(dsSystem.safariAndFirefoxBold("#353C46"), "\n\n &:hover {\n ").concat(dsSystem.safariAndFirefoxBold("#1E79C2"), "\n }\n \n ") : "\n \n ";
108
108
  }, _ref13 => {
109
109
  let {
110
110
  theme,
111
- isDSMobile
111
+ disabled
112
112
  } = _ref13;
113
- 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 ") : "";
113
+ 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 ");
114
114
  }, _ref14 => {
115
115
  let {
116
116
  theme,
117
117
  showSeparator,
118
118
  tabType
119
119
  } = _ref14;
120
- 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 === constants.TabTypes.NORMAL_SMALL ? "10px" : "16px", ";\n background-color: ").concat(theme.colors.neutral[400], ";\n }") : "";
120
+ return showSeparator ? "\n &:not(:last-of-type):before\n {\n content: \"\";\n position: absolute;\n width: 1px;\n right: -16px;\n top: 50%;\n transform: translateY(-50%);\n height: ".concat(tabType === constants.TabTypes.SUBTABS ? "10px" : "16px", ";\n background: ").concat(theme.colors.neutral[400], ";\n }") : "";
121
121
  }, _ref15 => {
122
+ let {
123
+ theme,
124
+ isDSMobile,
125
+ tabType,
126
+ isActive
127
+ } = _ref15;
128
+ 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[700], ";\n }\n\n ").concat(tabType !== constants.TabTypes.SUBTABS && isActive ? "\n &:before {\n position: absolute;\n content: '';\n left: -16px;\n right: 0;\n top: calc(100% - 2px);\n transform: none;\n width: calc(100% + 32px);\n height: 2px;\n z-index: 10;\n background: linear-gradient(to right, transparent 0px, transparent 12px, white 12px, white 16px, transparent 16px,transparent calc(100% - 16px), white calc(100% - 16px), white calc(100% - 12px), transparent calc(100% - 12px), transparent 100%);\n }\n " : "", "\n }\n \n ") : "";
129
+ }, _ref16 => {
122
130
  let {
123
131
  theme,
124
132
  isActive,
125
133
  disabled,
126
134
  isDSMobile
127
- } = _ref15;
135
+ } = _ref16;
128
136
  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(dsSystem.onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), " \n\n &:focus {\n font-weight: ").concat(theme.fontWeights.regular, ";\n font-size: 13px;\n ").concat(dsSystem.safariAndFirefoxBold('#006AA9'), "\n }\n\n ").concat(isActive ? "\n font-weight: ".concat(theme.fontWeights.regular, ";\n font-size: 13px;\n ").concat(dsSystem.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(dsSystem.safariAndFirefoxBold('#006AA9'), "\n }") : "", "\n\n ") : "";
129
137
  });
130
138
  const StyledSubTabsList = /*#__PURE__*/styled__default["default"].div.withConfig({
131
139
  componentId: "sc-3hla56-3"
132
- })(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""], _ref16 => {
140
+ })(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""], _ref17 => {
133
141
  let {
134
142
  withCarousel
135
- } = _ref16;
143
+ } = _ref17;
136
144
  return withCarousel ? 'max-width: 100%;' : '';
137
145
  });
138
146
  const StyledTabList = /*#__PURE__*/styled__default["default"].div.withConfig({
139
147
  componentId: "sc-3hla56-4"
140
- })(["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 => {
148
+ })(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", " ", " ", "{padding-bottom:0;padding-top:0;}", " ", " ", " ", "{", "}", "{background:", ";}"], _ref18 => {
141
149
  let {
142
150
  withCarousel,
143
151
  isDSMobile
144
- } = _ref17;
152
+ } = _ref18;
145
153
  return withCarousel && !isDSMobile ? "max-width: 100%;" : '';
146
- }, _ref18 => {
154
+ }, _ref19 => {
147
155
  let {
148
156
  theme,
149
157
  isDSMobile,
150
158
  tabType
151
- } = _ref18;
152
- return tabType !== constants.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 ") : "";
153
- }, StyledTabButton, _ref19 => {
159
+ } = _ref19;
160
+ return tabType !== constants.TabTypes.NORMAL_SMALL && !isDSMobile ? "\n &:after {\n content: '';\n position: absolute;\n width: 100%;\n height: 1px;\n box-shadow: 0px 0px 0px 1px ".concat(theme.colors.neutral[400], ";\n pointer-events: none;\n bottom: 0px;\n }\n ") : "";
161
+ }, StyledTabButton, _ref20 => {
154
162
  let {
155
163
  theme,
156
164
  isDSMobile
157
- } = _ref19;
158
- return isDSMobile ? "border-bottom: 1px solid ".concat(theme.colors.brand[300], ";\n background: ").concat(theme.colors.brand[200], ";") : "";
159
- }, mobileGradientsSettings, _ref20 => {
165
+ } = _ref20;
166
+ return isDSMobile ? "\n \n background: ".concat(theme.colors.brand[200], ";") : "";
167
+ }, mobileGradientsSettings, _ref21 => {
160
168
  let {
161
169
  isDSMobile,
162
170
  fixedTabsHeaders
163
- } = _ref20;
164
- 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 }")) : "";
165
- }, StyledSelectionIndicator, _ref21 => {
166
- let {
167
- indicatorStyle
168
171
  } = _ref21;
169
- return "\n width: ".concat(indicatorStyle.width, ";\n left: ").concat(indicatorStyle.left, ";\n ");
172
+ 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 }")) : "";
170
173
  }, StyledSelectionIndicator, _ref22 => {
171
174
  let {
172
- theme,
173
- indicatorStyle,
174
- isDSMobile
175
+ indicatorStyle
175
176
  } = _ref22;
176
- return !isDSMobile ? indicatorStyle.backgroundWithTransparent : theme.colors.brand[600];
177
+ return "\n width: ".concat(indicatorStyle.width, ";\n left: ").concat(indicatorStyle.left, ";\n ");
177
178
  }, StyledSelectionIndicator, _ref23 => {
178
179
  let {
179
180
  theme,
180
181
  indicatorStyle,
181
182
  isDSMobile
182
183
  } = _ref23;
183
- return !isDSMobile ? indicatorStyle.backgroundWithTransparentAndWhite : theme.colors.brand[600];
184
+ return !isDSMobile ? indicatorStyle.backgroundWithTransparent : theme.colors.brand[600];
184
185
  });
185
186
  const StyledRequiredMark = /*#__PURE__*/styled__default["default"].span.withConfig({
186
187
  componentId: "sc-3hla56-5"
@@ -41,12 +41,10 @@ const useTabBar = () => {
41
41
  // behavior that adds scroll to the tabList
42
42
 
43
43
  const position = isDSMobile && !fixedTabsHeaders ? activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left + tabList.scrollLeft : activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left - missingMargins;
44
- 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 )");
45
44
  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 )");
46
45
  return {
47
46
  left: "".concat(position, "px"),
48
47
  width: "".concat(tabClientWidth, "px"),
49
- backgroundWithTransparentAndWhite,
50
48
  backgroundWithTransparent
51
49
  };
52
50
  }
@@ -68,15 +66,6 @@ const useTabBar = () => {
68
66
  });
69
67
  }
70
68
  }, [fixedTabsHeaders, isDSMobile, tabsListRef]);
71
- React.useEffect(() => {
72
- if (showSelectionIndicator) {
73
- updateIndicatorStyle();
74
- }
75
-
76
- if (isDSMobile && !fixedTabsHeaders) {
77
- updateMobileGradients();
78
- }
79
- }, [updateIndicatorStyle, showSelectionIndicator, actualActiveTab, updateMobileGradients, isDSMobile, fixedTabsHeaders]);
80
69
  React.useLayoutEffect(() => {
81
70
  if (showSelectionIndicator) {
82
71
  updateIndicatorStyle();
@@ -85,7 +74,7 @@ const useTabBar = () => {
85
74
  if (isDSMobile && !fixedTabsHeaders) {
86
75
  updateMobileGradients();
87
76
  }
88
- }, [updateMobileGradients, showSelectionIndicator, updateIndicatorStyle, isDSMobile, fixedTabsHeaders]);
77
+ }, [updateMobileGradients, showSelectionIndicator, updateIndicatorStyle, isDSMobile, fixedTabsHeaders, actualActiveTab]);
89
78
  return {
90
79
  updateIndicatorStyle,
91
80
  setIndicatorStyle,
@@ -3,11 +3,16 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _jsx = require('@babel/runtime/helpers/jsx');
6
+ require('core-js/modules/esnext.async-iterator.constructor.js');
7
+ require('core-js/modules/esnext.async-iterator.to-array.js');
8
+ require('core-js/modules/esnext.iterator.constructor.js');
9
+ require('core-js/modules/esnext.iterator.to-array.js');
10
+ require('core-js/modules/esnext.async-iterator.filter.js');
11
+ require('core-js/modules/esnext.iterator.filter.js');
6
12
  require('core-js/modules/esnext.async-iterator.map.js');
7
13
  require('core-js/modules/esnext.iterator.map.js');
8
14
  var React = require('react');
9
15
  var SwipeableViews = require('react-swipeable-views');
10
- var helpers = require('../../utils/helpers.js');
11
16
  var styles = require('./styles.js');
12
17
  var DSTabsCTX = require('../../DSTabsCTX.js');
13
18
  var useTabsCallbacks = require('../../utils/hooks/useTabsCallbacks.js');
@@ -35,18 +40,38 @@ const TabsPanels = () => {
35
40
  handleOnTabChange,
36
41
  handleOnMouseDown
37
42
  } = useTabsCallbacks.useTabsCallbacks();
38
- const handleOnChangeIndex = React.useCallback(index => {
39
- handleOnTabChange(helpers.getIdByIndex(tabs, index));
40
- if (focusableTabsRef.current) focusableTabsRef.current[index].click();
41
- }, [focusableTabsRef, handleOnTabChange, tabs]);
43
+ const handleOnChangeIndex = React.useCallback((index, indexLatest) => {
44
+ if (!focusableTabsRef.current) return;
45
+ const offset = index - indexLatest;
46
+
47
+ if (focusableTabsRef.current) {
48
+ var _focusableTabsRef$cur, _focusableTabsRef$cur2, _focusableTabsRef$cur3, _focusableTabsRef$cur4;
49
+
50
+ const currentIndexFocusable = (_focusableTabsRef$cur = focusableTabsRef.current) === null || _focusableTabsRef$cur === void 0 ? void 0 : _focusableTabsRef$cur.findIndex(el => el.dataset.tabId === actualActiveTab);
51
+ const newFocusableIndex = currentIndexFocusable >= 0 ? currentIndexFocusable + offset : -1;
52
+ if (newFocusableIndex < 0 || newFocusableIndex > ((_focusableTabsRef$cur2 = focusableTabsRef.current) === null || _focusableTabsRef$cur2 === void 0 ? void 0 : _focusableTabsRef$cur2.length) || !((_focusableTabsRef$cur3 = focusableTabsRef.current) !== null && _focusableTabsRef$cur3 !== void 0 && _focusableTabsRef$cur3[newFocusableIndex])) return;
53
+ handleOnTabChange((_focusableTabsRef$cur4 = focusableTabsRef.current[newFocusableIndex].dataset) === null || _focusableTabsRef$cur4 === void 0 ? void 0 : _focusableTabsRef$cur4.tabId); // swiping does not trigger centerTab function inside handleOnTabChange because there is no event
54
+ // by clicking we are manually forcing to center the tab
55
+
56
+ focusableTabsRef.current[newFocusableIndex].click();
57
+ }
58
+ }, [actualActiveTab, focusableTabsRef, handleOnTabChange]);
59
+ const firstSlideToShow = React.useMemo(() => {
60
+ const childrenArray = React__default["default"].Children.toArray(tabs);
61
+ const index = childrenArray.filter(tab => tab.props.disabled !== true).findIndex(tab => tab.props.tabId === actualActiveTab);
62
+ if (index === -1) return 0;
63
+ return index;
64
+ }, [actualActiveTab, tabs]);
42
65
  const panels = React.useMemo(() => React__default["default"].Children.map(tabs, tab => {
43
66
  const {
44
67
  tabId: panelId = '',
45
68
  style,
46
- children: content
69
+ children: content,
70
+ disabled
47
71
  } = tab.props;
48
72
  const isActive = actualActiveTab === panelId;
49
73
  const shouldRender = !onlyRenderActiveTab || isActive;
74
+ if (disabled) return null;
50
75
  return shouldRender && /*#__PURE__*/_jsx__default["default"](styles.StyledPanelContainer, {
51
76
  id: panelId,
52
77
  "aria-labelledby": "".concat(panelId, "-label"),
@@ -64,7 +89,7 @@ const TabsPanels = () => {
64
89
  if (animated) {
65
90
  return /*#__PURE__*/_jsx__default["default"](SwipeableViews__default["default"], {
66
91
  enableMouseEvents: enableMouseEvents,
67
- index: helpers.getIndexById(tabs, actualActiveTab),
92
+ index: firstSlideToShow,
68
93
  onChangeIndex: handleOnChangeIndex
69
94
  }, void 0, panels);
70
95
  }
@@ -12,7 +12,6 @@ const MOBILE_GRADIENT_WIDTH = 24;
12
12
  const defaultIndicatorStyles = {
13
13
  left: '0px',
14
14
  width: '0px',
15
- backgroundWithTransparentAndWhite: '',
16
15
  backgroundWithTransparent: ''
17
16
  };
18
17
  const gradientOffsetsAccordingType = {
@@ -25,6 +25,33 @@ const isElementVisibleCarousel = function (tab, tabContainer) {
25
25
 
26
26
  return false;
27
27
  };
28
+ const centerTab = _ref => {
29
+ let {
30
+ e,
31
+ listRef
32
+ } = _ref;
33
+
34
+ if (listRef.current) {
35
+ const {
36
+ offsetLeft
37
+ } = e === null || e === void 0 ? void 0 : e.target;
38
+ const {
39
+ width: tabWidth
40
+ } = (e === null || e === void 0 ? void 0 : e.target).getBoundingClientRect();
41
+ const {
42
+ width: listWidth
43
+ } = listRef.current.getBoundingClientRect();
44
+ const extraSideSpace = listWidth - tabWidth;
45
+ const leftOffsetToCenter = extraSideSpace > 0 ? extraSideSpace / 2 : 0;
46
+ const centeredLeftOffset = offsetLeft > leftOffsetToCenter ? offsetLeft - leftOffsetToCenter : 0;
47
+ listRef.current.scrollTo({
48
+ top: 0,
49
+ left: centeredLeftOffset,
50
+ behavior: 'smooth'
51
+ });
52
+ e === null || e === void 0 ? void 0 : e.preventDefault();
53
+ }
54
+ };
28
55
  const getVisibleDimensions = (node, referenceNode) => {
29
56
  const nodeDimensions = node.getBoundingClientRect();
30
57
  const referenceNodeDimensions = referenceNode.getBoundingClientRect();
@@ -33,13 +60,10 @@ const getVisibleDimensions = (node, referenceNode) => {
33
60
  height: Math.min(node.clientHeight, referenceNodeDimensions.top + referenceNode.clientHeight - nodeDimensions.top, node.clientHeight - (referenceNodeDimensions.top - nodeDimensions.top))
34
61
  };
35
62
  };
36
- const getIndexById = (children, activeId) => children && children.findIndex(item => item.props.tabId === activeId);
37
- const getIdByIndex = (children, index) => children && children[index].props.tabId || '';
38
63
  const shouldHaveLeftGradient = scrollLeft => Math.abs(scrollLeft) > constants.MOBILE_GRADIENT_WIDTH;
39
64
  const shouldHaveRightGradient = (scrollLeft, clientWidth, scrollWidth) => Math.abs(scrollLeft) <= scrollWidth - (clientWidth + constants.MOBILE_GRADIENT_WIDTH);
40
65
 
41
- exports.getIdByIndex = getIdByIndex;
42
- exports.getIndexById = getIndexById;
66
+ exports.centerTab = centerTab;
43
67
  exports.getVisibleDimensions = getVisibleDimensions;
44
68
  exports.isElementVisible = isElementVisible;
45
69
  exports.isElementVisibleCarousel = isElementVisibleCarousel;
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
+ var helpers = require('../helpers.js');
6
7
  var DSTabsCTX = require('../../DSTabsCTX.js');
7
8
 
8
9
  const useTabsCallbacks = () => {
@@ -16,36 +17,17 @@ const useTabsCallbacks = () => {
16
17
  fixedTabsHeaders
17
18
  }
18
19
  } = React.useContext(DSTabsCTX.DSTabsContext);
19
- const centerTabWhenTabChangeMobile = React.useCallback(e => {
20
- if (tabsListRef.current) {
21
- const {
22
- offsetLeft
23
- } = e === null || e === void 0 ? void 0 : e.target;
24
- const {
25
- width: tabWidth
26
- } = (e === null || e === void 0 ? void 0 : e.target).getBoundingClientRect();
27
- const {
28
- width: listWidth
29
- } = tabsListRef.current.getBoundingClientRect();
30
- const extraSideSpace = listWidth - tabWidth;
31
- const leftOffsetToCenter = extraSideSpace > 0 ? extraSideSpace / 2 : 0;
32
- const centeredLeftOffset = offsetLeft > leftOffsetToCenter ? offsetLeft - leftOffsetToCenter : 0;
33
- tabsListRef.current.scrollTo({
34
- top: 0,
35
- left: centeredLeftOffset,
36
- behavior: 'smooth'
37
- });
38
- e === null || e === void 0 ? void 0 : e.preventDefault();
39
- }
40
- }, [tabsListRef]);
41
20
  const handleOnTabChange = React.useCallback((tabId, e) => {
42
21
  setInternalActiveTab(tabId);
43
22
  onTabChange(tabId, e);
44
23
 
45
24
  if (isDSMobile && !fixedTabsHeaders && e) {
46
- centerTabWhenTabChangeMobile(e);
25
+ helpers.centerTab({
26
+ e,
27
+ listRef: tabsListRef
28
+ });
47
29
  }
48
- }, [centerTabWhenTabChangeMobile, fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab]);
30
+ }, [fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab, tabsListRef]);
49
31
  const handleOnMouseDown = React.useCallback(e => {
50
32
  const role = e.target.getAttribute('role');
51
33
  if (role !== 'tabpanel' && allowTextSelection) e.stopPropagation();
@@ -7,12 +7,9 @@ import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';
7
7
  import { tabsDefaultProps } from '../defaultProps.js';
8
8
 
9
9
  const useTabs = props => {
10
- var _children$, _children$$props;
11
-
12
10
  const propsWithDefaults = useMemoMergePropsWithDefault(props, tabsDefaultProps);
13
11
  const {
14
- activeTab,
15
- children
12
+ activeTab
16
13
  } = propsWithDefaults;
17
14
  const tabsRef = useRef({});
18
15
  const tabsRefAsArray = useRef([]);
@@ -20,7 +17,7 @@ const useTabs = props => {
20
17
  const carouselOnlyListRef = useRef(null);
21
18
  const tabsListRef = useRef(null);
22
19
  const actualActiveTabRef = useRef(null);
23
- const [internalActiveTab, setInternalActiveTab] = useState(children === null || children === void 0 ? void 0 : (_children$ = children[0]) === null || _children$ === void 0 ? void 0 : (_children$$props = _children$.props) === null || _children$$props === void 0 ? void 0 : _children$$props.tabId);
20
+ const [internalActiveTab, setInternalActiveTab] = useState('');
24
21
  const actualActiveTab = useMemo(() => {
25
22
  if (activeTab !== undefined) return activeTab;
26
23
  return internalActiveTab;
@@ -28,8 +25,14 @@ const useTabs = props => {
28
25
  useEffect(() => {
29
26
  var _focusableTabsRef$cur;
30
27
 
31
- actualActiveTabRef.current = (_focusableTabsRef$cur = focusableTabsRef.current.find(el => el.dataset.tabId === internalActiveTab)) !== null && _focusableTabsRef$cur !== void 0 ? _focusableTabsRef$cur : null;
32
- }, [internalActiveTab]);
28
+ actualActiveTabRef.current = (_focusableTabsRef$cur = focusableTabsRef.current.find(el => el.dataset.tabId === actualActiveTab)) !== null && _focusableTabsRef$cur !== void 0 ? _focusableTabsRef$cur : null;
29
+ }, [actualActiveTab]);
30
+ useEffect(() => {
31
+ if (activeTab === undefined) {
32
+ const firstAvailableTab = focusableTabsRef.current.find(el => el.ariaDisabled !== 'true');
33
+ setInternalActiveTab((firstAvailableTab === null || firstAvailableTab === void 0 ? void 0 : firstAvailableTab.dataset.tabId) || '');
34
+ }
35
+ }, [activeTab]);
33
36
  const ctx = useMemo(() => ({
34
37
  props: propsWithDefaults,
35
38
  tabsRef,