@elliemae/ds-tabs 2.0.4 → 2.0.8
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.
- package/cjs/config/useTabs.js +10 -7
- package/cjs/parts/carousel/Carousel.js +2 -4
- package/cjs/parts/carousel/styles.js +15 -10
- package/cjs/parts/tabBar/TabBar.js +17 -9
- package/cjs/parts/tabBar/styles.js +47 -46
- package/cjs/parts/tabBar/useTabBar.js +1 -12
- package/cjs/parts/tabsPanel/TabsPanels.js +32 -7
- package/cjs/utils/constants.js +0 -1
- package/cjs/utils/helpers.js +28 -4
- package/cjs/utils/hooks/useTabsCallbacks.js +6 -24
- package/esm/config/useTabs.js +10 -7
- package/esm/parts/carousel/Carousel.js +3 -5
- package/esm/parts/carousel/styles.js +15 -10
- package/esm/parts/tabBar/TabBar.js +17 -9
- package/esm/parts/tabBar/styles.js +47 -46
- package/esm/parts/tabBar/useTabBar.js +2 -13
- package/esm/parts/tabsPanel/TabsPanels.js +32 -7
- package/esm/utils/constants.js +0 -1
- package/esm/utils/helpers.js +28 -3
- package/esm/utils/hooks/useTabsCallbacks.js +6 -24
- package/package.json +6 -6
- package/types/DSTabsTypes.d.ts +4 -1
- package/types/utils/constants.d.ts +0 -1
- package/types/utils/helpers.d.ts +2 -3
package/cjs/config/useTabs.js
CHANGED
|
@@ -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(
|
|
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 ===
|
|
36
|
-
}, [
|
|
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
|
|
39
|
+
})(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background:white;", ";"], _ref4 => {
|
|
35
40
|
let {
|
|
36
41
|
right
|
|
37
|
-
} =
|
|
42
|
+
} = _ref4;
|
|
38
43
|
return right ? 'right: 0;' : "left: 0;";
|
|
39
|
-
},
|
|
44
|
+
}, _ref5 => {
|
|
40
45
|
let {
|
|
41
46
|
tabType
|
|
42
|
-
} =
|
|
47
|
+
} = _ref5;
|
|
43
48
|
return tabType === constants.TabTypes.NORMAL ? '32px' : '22px';
|
|
44
|
-
},
|
|
49
|
+
}, _ref6 => {
|
|
45
50
|
let {
|
|
46
51
|
tabType
|
|
47
|
-
} =
|
|
52
|
+
} = _ref6;
|
|
48
53
|
return tabType === constants.TabTypes.NORMAL ? '5px' : '0px';
|
|
49
|
-
},
|
|
54
|
+
}, _ref7 => {
|
|
50
55
|
let {
|
|
51
56
|
theme,
|
|
52
57
|
tabType
|
|
53
|
-
} =
|
|
54
|
-
return tabType === constants.TabTypes.NORMAL ? "\n
|
|
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:
|
|
74
|
-
if (tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
|
|
75
|
-
tabsRefAsArray.current[index] =
|
|
76
|
-
if (!disabled && !focusableTabsRef.current.includes(
|
|
77
|
-
tabsRef.current[index] =
|
|
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 =
|
|
82
|
+
firstSubtabInternalRef.current = tabButtonRef;
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
if (type !== constants.TabTypes.SUBTABS && index === availableTabIndexes[availableTabIndexes.length - 1]) {
|
|
84
|
-
lastTabInternalRef.current =
|
|
86
|
+
lastTabInternalRef.current = tabButtonRef;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
if (ref) ref.current =
|
|
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 "
|
|
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:", ";", " ", " ", " ", " ", " ", " ", ""],
|
|
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
|
-
} =
|
|
73
|
+
} = _ref7;
|
|
68
74
|
return tabType === constants.TabTypes.SUBTABS ? "capitalize" : "uppercase";
|
|
69
|
-
},
|
|
75
|
+
}, _ref8 => {
|
|
70
76
|
let {
|
|
71
77
|
fixedTabsHeaders,
|
|
72
78
|
isDSMobile
|
|
73
|
-
} =
|
|
79
|
+
} = _ref8;
|
|
74
80
|
if (fixedTabsHeaders) return '0px';
|
|
75
81
|
if (!fixedTabsHeaders && isDSMobile) return '14px';
|
|
76
82
|
return '16px';
|
|
77
|
-
},
|
|
83
|
+
}, _ref9 => {
|
|
78
84
|
let {
|
|
79
85
|
fixedTabsHeaders,
|
|
80
86
|
isDSMobile
|
|
81
|
-
} =
|
|
87
|
+
} = _ref9;
|
|
82
88
|
if (fixedTabsHeaders) return '0px';
|
|
83
89
|
if (!fixedTabsHeaders && isDSMobile) return '14px';
|
|
84
90
|
return '16px';
|
|
85
|
-
},
|
|
91
|
+
}, _ref10 => {
|
|
86
92
|
let {
|
|
87
93
|
theme
|
|
88
|
-
} =
|
|
94
|
+
} = _ref10;
|
|
89
95
|
return theme.colors.neutral[700];
|
|
90
|
-
}, dsSystem.onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'),
|
|
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
|
|
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
|
|
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
|
-
|
|
111
|
+
disabled
|
|
112
112
|
} = _ref13;
|
|
113
|
-
return
|
|
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: -
|
|
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
|
-
} =
|
|
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%;", ""],
|
|
140
|
+
})(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""], _ref17 => {
|
|
133
141
|
let {
|
|
134
142
|
withCarousel
|
|
135
|
-
} =
|
|
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;}", " ", " ", " ", "{", "}
|
|
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
|
-
} =
|
|
152
|
+
} = _ref18;
|
|
145
153
|
return withCarousel && !isDSMobile ? "max-width: 100%;" : '';
|
|
146
|
-
},
|
|
154
|
+
}, _ref19 => {
|
|
147
155
|
let {
|
|
148
156
|
theme,
|
|
149
157
|
isDSMobile,
|
|
150
158
|
tabType
|
|
151
|
-
} =
|
|
152
|
-
return tabType !== constants.TabTypes.NORMAL_SMALL ? "\n &:after {\n content: '';\n position: absolute;\n width: 100%;\n height:
|
|
153
|
-
}, StyledTabButton,
|
|
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
|
-
} =
|
|
158
|
-
return isDSMobile ? "
|
|
159
|
-
}, mobileGradientsSettings,
|
|
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
|
|
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
|
-
|
|
173
|
-
indicatorStyle,
|
|
174
|
-
isDSMobile
|
|
175
|
+
indicatorStyle
|
|
175
176
|
} = _ref22;
|
|
176
|
-
return
|
|
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.
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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:
|
|
92
|
+
index: firstSlideToShow,
|
|
68
93
|
onChangeIndex: handleOnChangeIndex
|
|
69
94
|
}, void 0, panels);
|
|
70
95
|
}
|
package/cjs/utils/constants.js
CHANGED
package/cjs/utils/helpers.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
25
|
+
helpers.centerTab({
|
|
26
|
+
e,
|
|
27
|
+
listRef: tabsListRef
|
|
28
|
+
});
|
|
47
29
|
}
|
|
48
|
-
}, [
|
|
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();
|
package/esm/config/useTabs.js
CHANGED
|
@@ -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(
|
|
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 ===
|
|
32
|
-
}, [
|
|
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,
|