@elliemae/ds-tabs 2.0.6 → 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.
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
2
|
import { useContext } from 'react';
|
|
3
|
-
import { DSIconSizes
|
|
3
|
+
import { DSIconSizes } from '@elliemae/ds-icon';
|
|
4
4
|
import { BUTTON_TYPES } from '@elliemae/ds-button';
|
|
5
5
|
import { ChevronLeft, ChevronRight } from '@elliemae/ds-icons';
|
|
6
6
|
import { StyledCarouselWrapper, StyledCarouselButtonWrapper, StyledCarouselBtn, StyledChildrenWrap } from './styles.js';
|
|
@@ -38,8 +38,7 @@ const Carousel = _ref => {
|
|
|
38
38
|
"data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_LEFT,
|
|
39
39
|
buttonType: BUTTON_TYPES.ICON
|
|
40
40
|
}, void 0, /*#__PURE__*/_jsx(ChevronLeft, {
|
|
41
|
-
size: DSIconSizes.S
|
|
42
|
-
color: DSIconColors.PRIMARY
|
|
41
|
+
size: DSIconSizes.S
|
|
43
42
|
}))), showChevrons.right && /*#__PURE__*/_jsx(StyledCarouselButtonWrapper, {
|
|
44
43
|
tabType: type,
|
|
45
44
|
right: showChevrons.right
|
|
@@ -50,8 +49,7 @@ const Carousel = _ref => {
|
|
|
50
49
|
"data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_RIGHT,
|
|
51
50
|
buttonType: BUTTON_TYPES.ICON
|
|
52
51
|
}, void 0, /*#__PURE__*/_jsx(ChevronRight, {
|
|
53
|
-
size: DSIconSizes.S
|
|
54
|
-
color: DSIconColors.PRIMARY
|
|
52
|
+
size: DSIconSizes.S
|
|
55
53
|
}))), /*#__PURE__*/jsx(StyledChildrenWrap, {
|
|
56
54
|
ref: carouselOnlyListRef,
|
|
57
55
|
onClick: handleOnClick,
|
|
@@ -4,7 +4,7 @@ import { TabTypes } from '../../utils/constants.js';
|
|
|
4
4
|
|
|
5
5
|
const StyledCarouselBtn = /*#__PURE__*/styled(DSButtonV2).withConfig({
|
|
6
6
|
componentId: "sc-prv5a7-0"
|
|
7
|
-
})(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;"], _ref => {
|
|
7
|
+
})(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;& .em-ds-icon svg{fill:", ";}"], _ref => {
|
|
8
8
|
let {
|
|
9
9
|
theme
|
|
10
10
|
} = _ref;
|
|
@@ -14,6 +14,11 @@ const StyledCarouselBtn = /*#__PURE__*/styled(DSButtonV2).withConfig({
|
|
|
14
14
|
theme
|
|
15
15
|
} = _ref2;
|
|
16
16
|
return theme.space.xs;
|
|
17
|
+
}, _ref3 => {
|
|
18
|
+
let {
|
|
19
|
+
theme
|
|
20
|
+
} = _ref3;
|
|
21
|
+
return theme.colors.brand[600];
|
|
17
22
|
});
|
|
18
23
|
const StyledCarouselWrapper = /*#__PURE__*/styled.span.withConfig({
|
|
19
24
|
componentId: "sc-prv5a7-1"
|
|
@@ -23,27 +28,27 @@ const StyledChildrenWrap = /*#__PURE__*/styled.div.withConfig({
|
|
|
23
28
|
})(["display:flex;flex-wrap:nowrap;flex:1;overflow-x:hidden;"]);
|
|
24
29
|
const StyledCarouselButtonWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
25
30
|
componentId: "sc-prv5a7-3"
|
|
26
|
-
})(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background
|
|
31
|
+
})(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background:white;", ";"], _ref4 => {
|
|
27
32
|
let {
|
|
28
33
|
right
|
|
29
|
-
} =
|
|
34
|
+
} = _ref4;
|
|
30
35
|
return right ? 'right: 0;' : "left: 0;";
|
|
31
|
-
},
|
|
36
|
+
}, _ref5 => {
|
|
32
37
|
let {
|
|
33
38
|
tabType
|
|
34
|
-
} =
|
|
39
|
+
} = _ref5;
|
|
35
40
|
return tabType === TabTypes.NORMAL ? '32px' : '22px';
|
|
36
|
-
},
|
|
41
|
+
}, _ref6 => {
|
|
37
42
|
let {
|
|
38
43
|
tabType
|
|
39
|
-
} =
|
|
44
|
+
} = _ref6;
|
|
40
45
|
return tabType === TabTypes.NORMAL ? '5px' : '0px';
|
|
41
|
-
},
|
|
46
|
+
}, _ref7 => {
|
|
42
47
|
let {
|
|
43
48
|
theme,
|
|
44
49
|
tabType
|
|
45
|
-
} =
|
|
46
|
-
return tabType === TabTypes.NORMAL ? "\n
|
|
50
|
+
} = _ref7;
|
|
51
|
+
return tabType === 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 ") : "";
|
|
47
52
|
});
|
|
48
53
|
|
|
49
54
|
export { StyledCarouselBtn, StyledCarouselButtonWrapper, StyledCarouselWrapper, StyledChildrenWrap };
|
|
@@ -7,6 +7,7 @@ import { useTabBar } from './useTabBar.js';
|
|
|
7
7
|
import { StyledTabButton, StyledRequiredMark, StyledSubTabsList, StyledTabList, StyledTabWrapper, StyledSelectionIndicator } from './styles.js';
|
|
8
8
|
import { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';
|
|
9
9
|
import { useKeyboardNavigation } from '../../utils/hooks/useKeyboardNavigation.js';
|
|
10
|
+
import { centerTab } from '../../utils/helpers.js';
|
|
10
11
|
import { TabTypes } from '../../utils/constants.js';
|
|
11
12
|
import { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';
|
|
12
13
|
import { DSTabsDatatestid } from '../../DSTabsDatatestid.js';
|
|
@@ -19,6 +20,7 @@ const TabBar = () => {
|
|
|
19
20
|
focusableTabsRef,
|
|
20
21
|
tabsListRef,
|
|
21
22
|
tabsRefAsArray,
|
|
23
|
+
carouselOnlyListRef,
|
|
22
24
|
actualActiveTab,
|
|
23
25
|
props: {
|
|
24
26
|
type,
|
|
@@ -61,21 +63,21 @@ const TabBar = () => {
|
|
|
61
63
|
if (!disabled) availableTabIndexes.push(index);
|
|
62
64
|
return /*#__PURE__*/jsxs(StyledTabButton, {
|
|
63
65
|
role: "tab",
|
|
64
|
-
ref:
|
|
65
|
-
if (tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
|
|
66
|
-
tabsRefAsArray.current[index] =
|
|
67
|
-
if (!disabled && !focusableTabsRef.current.includes(
|
|
68
|
-
tabsRef.current[index] =
|
|
66
|
+
ref: tabButtonRef => {
|
|
67
|
+
if (tabButtonRef && tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
|
|
68
|
+
tabsRefAsArray.current[index] = tabButtonRef;
|
|
69
|
+
if (!disabled && !focusableTabsRef.current.includes(tabButtonRef)) focusableTabsRef.current.push(tabButtonRef);
|
|
70
|
+
tabsRef.current[index] = tabButtonRef;
|
|
69
71
|
|
|
70
72
|
if (type === TabTypes.SUBTABS && firstSubtabInternalRef && index === availableTabIndexes[0]) {
|
|
71
|
-
firstSubtabInternalRef.current =
|
|
73
|
+
firstSubtabInternalRef.current = tabButtonRef;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
if (type !== TabTypes.SUBTABS && index === availableTabIndexes[availableTabIndexes.length - 1]) {
|
|
75
|
-
lastTabInternalRef.current =
|
|
77
|
+
lastTabInternalRef.current = tabButtonRef;
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
if (ref) ref.current =
|
|
80
|
+
if (ref) ref.current = tabButtonRef;
|
|
79
81
|
}
|
|
80
82
|
},
|
|
81
83
|
type: "button",
|
|
@@ -104,6 +106,12 @@ const TabBar = () => {
|
|
|
104
106
|
|
|
105
107
|
if (onClick && !disabled) onClick(tabId, e);
|
|
106
108
|
},
|
|
109
|
+
onFocus: e => {
|
|
110
|
+
if (withCarousel) centerTab({
|
|
111
|
+
e,
|
|
112
|
+
listRef: carouselOnlyListRef
|
|
113
|
+
});
|
|
114
|
+
},
|
|
107
115
|
onKeyDown: e => {
|
|
108
116
|
if (e.key === 'Enter') e.stopPropagation();
|
|
109
117
|
if (!disabled) handleOnKeyDown(e);
|
|
@@ -113,7 +121,7 @@ const TabBar = () => {
|
|
|
113
121
|
children: [title, required && (_StyledRequiredMark || (_StyledRequiredMark = /*#__PURE__*/_jsx(StyledRequiredMark, {}, void 0, "\u25CF")))]
|
|
114
122
|
}, tabId);
|
|
115
123
|
});
|
|
116
|
-
}, [tabs, actualActiveTab, isDSMobile, fixedTabsHeaders, type, withCarousel, showSeparator, tabsRefAsArray, focusableTabsRef, tabsRef, firstSubtabInternalRef, lastTabInternalRef, handleOnTabChange, updateIndicatorStyle, handleOnKeyDown]);
|
|
124
|
+
}, [tabs, actualActiveTab, isDSMobile, fixedTabsHeaders, type, withCarousel, showSeparator, tabsRefAsArray, focusableTabsRef, tabsRef, firstSubtabInternalRef, lastTabInternalRef, handleOnTabChange, updateIndicatorStyle, carouselOnlyListRef, handleOnKeyDown]);
|
|
117
125
|
|
|
118
126
|
if (type === TabTypes.SUBTABS && !isDSMobile) {
|
|
119
127
|
return /*#__PURE__*/jsx(StyledSubTabsList, {
|
|
@@ -11,7 +11,7 @@ const StyledSelectionIndicator = /*#__PURE__*/styled.div.withConfig({
|
|
|
11
11
|
tabType,
|
|
12
12
|
isDSMobile
|
|
13
13
|
} = _ref;
|
|
14
|
-
if (isDSMobile) return "
|
|
14
|
+
if (isDSMobile) return "35px";
|
|
15
15
|
if (tabType === TabTypes.NORMAL_SMALL) return "15px";
|
|
16
16
|
return "25px";
|
|
17
17
|
}, _ref2 => {
|
|
@@ -43,135 +43,136 @@ const mobileGradientsSettings = css(_templateObject || (_templateObject = _tagge
|
|
|
43
43
|
});
|
|
44
44
|
const StyledTabWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
45
45
|
componentId: "sc-3hla56-1"
|
|
46
|
-
})(["display:flex;flex:1;flex-wrap:nowrap;", ""], _ref5 => {
|
|
46
|
+
})(["display:flex;flex:1;flex-wrap:nowrap;", " ", ""], _ref5 => {
|
|
47
47
|
let {
|
|
48
48
|
fixedTabsHeaders,
|
|
49
49
|
isDSMobile
|
|
50
50
|
} = _ref5;
|
|
51
51
|
return !fixedTabsHeaders && isDSMobile ? '' : 'overflow-x: hidden;';
|
|
52
|
+
}, _ref6 => {
|
|
53
|
+
let {
|
|
54
|
+
theme,
|
|
55
|
+
isDSMobile
|
|
56
|
+
} = _ref6;
|
|
57
|
+
return isDSMobile ? "border-bottom: 1px solid ".concat(theme.colors.brand[300], ";") : "";
|
|
52
58
|
});
|
|
53
59
|
const StyledTabButton = /*#__PURE__*/styled.button.withConfig({
|
|
54
60
|
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:", ";", " ", " ", " ", " ", " ", " ", ""],
|
|
61
|
+
})(["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 => {
|
|
56
62
|
let {
|
|
57
63
|
tabType
|
|
58
|
-
} =
|
|
64
|
+
} = _ref7;
|
|
59
65
|
return tabType === TabTypes.SUBTABS ? "capitalize" : "uppercase";
|
|
60
|
-
},
|
|
66
|
+
}, _ref8 => {
|
|
61
67
|
let {
|
|
62
68
|
fixedTabsHeaders,
|
|
63
69
|
isDSMobile
|
|
64
|
-
} =
|
|
70
|
+
} = _ref8;
|
|
65
71
|
if (fixedTabsHeaders) return '0px';
|
|
66
72
|
if (!fixedTabsHeaders && isDSMobile) return '14px';
|
|
67
73
|
return '16px';
|
|
68
|
-
},
|
|
74
|
+
}, _ref9 => {
|
|
69
75
|
let {
|
|
70
76
|
fixedTabsHeaders,
|
|
71
77
|
isDSMobile
|
|
72
|
-
} =
|
|
78
|
+
} = _ref9;
|
|
73
79
|
if (fixedTabsHeaders) return '0px';
|
|
74
80
|
if (!fixedTabsHeaders && isDSMobile) return '14px';
|
|
75
81
|
return '16px';
|
|
76
|
-
},
|
|
82
|
+
}, _ref10 => {
|
|
77
83
|
let {
|
|
78
84
|
theme
|
|
79
|
-
} =
|
|
85
|
+
} = _ref10;
|
|
80
86
|
return theme.colors.neutral[700];
|
|
81
|
-
}, onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'),
|
|
87
|
+
}, onlySafariAndFirefox('-webkit-text-stroke: 0.4px transparent;'), _ref11 => {
|
|
82
88
|
let {
|
|
83
89
|
tabType
|
|
84
|
-
} = _ref10;
|
|
85
|
-
return tabType === TabTypes.NORMAL ? "height: 32px;" : "height: 22px;";
|
|
86
|
-
}, _ref11 => {
|
|
87
|
-
let {
|
|
88
|
-
theme,
|
|
89
|
-
isActive,
|
|
90
|
-
disabled
|
|
91
90
|
} = _ref11;
|
|
92
|
-
return
|
|
91
|
+
return tabType === TabTypes.NORMAL ? "height: 32px;" : "height: 22px;";
|
|
93
92
|
}, _ref12 => {
|
|
94
93
|
let {
|
|
95
94
|
theme,
|
|
95
|
+
isActive,
|
|
96
96
|
disabled
|
|
97
97
|
} = _ref12;
|
|
98
|
-
return disabled ? "\n
|
|
98
|
+
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 ";
|
|
99
99
|
}, _ref13 => {
|
|
100
100
|
let {
|
|
101
101
|
theme,
|
|
102
|
-
|
|
102
|
+
disabled
|
|
103
103
|
} = _ref13;
|
|
104
|
-
return
|
|
104
|
+
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 ");
|
|
105
105
|
}, _ref14 => {
|
|
106
106
|
let {
|
|
107
107
|
theme,
|
|
108
108
|
showSeparator,
|
|
109
109
|
tabType
|
|
110
110
|
} = _ref14;
|
|
111
|
-
return showSeparator ? "\n &:not(:last-of-type):before\n {\n content: \"\";\n position: absolute;\n width: 1px;\n right: -
|
|
111
|
+
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 === TabTypes.SUBTABS ? "10px" : "16px", ";\n background: ").concat(theme.colors.neutral[400], ";\n }") : "";
|
|
112
112
|
}, _ref15 => {
|
|
113
|
+
let {
|
|
114
|
+
theme,
|
|
115
|
+
isDSMobile,
|
|
116
|
+
tabType,
|
|
117
|
+
isActive
|
|
118
|
+
} = _ref15;
|
|
119
|
+
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 !== 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 ") : "";
|
|
120
|
+
}, _ref16 => {
|
|
113
121
|
let {
|
|
114
122
|
theme,
|
|
115
123
|
isActive,
|
|
116
124
|
disabled,
|
|
117
125
|
isDSMobile
|
|
118
|
-
} =
|
|
126
|
+
} = _ref16;
|
|
119
127
|
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
128
|
});
|
|
121
129
|
const StyledSubTabsList = /*#__PURE__*/styled.div.withConfig({
|
|
122
130
|
componentId: "sc-3hla56-3"
|
|
123
|
-
})(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""],
|
|
131
|
+
})(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", ""], _ref17 => {
|
|
124
132
|
let {
|
|
125
133
|
withCarousel
|
|
126
|
-
} =
|
|
134
|
+
} = _ref17;
|
|
127
135
|
return withCarousel ? 'max-width: 100%;' : '';
|
|
128
136
|
});
|
|
129
137
|
const StyledTabList = /*#__PURE__*/styled.div.withConfig({
|
|
130
138
|
componentId: "sc-3hla56-4"
|
|
131
|
-
})(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", " ", " ", "{padding-bottom:0;padding-top:0;}", " ", " ", " ", "{", "}
|
|
139
|
+
})(["position:relative;display:flex;flex-wrap:nowrap;flex:1;width:100%;", " ", " ", "{padding-bottom:0;padding-top:0;}", " ", " ", " ", "{", "}", "{background:", ";}"], _ref18 => {
|
|
132
140
|
let {
|
|
133
141
|
withCarousel,
|
|
134
142
|
isDSMobile
|
|
135
|
-
} =
|
|
143
|
+
} = _ref18;
|
|
136
144
|
return withCarousel && !isDSMobile ? "max-width: 100%;" : '';
|
|
137
|
-
},
|
|
145
|
+
}, _ref19 => {
|
|
138
146
|
let {
|
|
139
147
|
theme,
|
|
140
148
|
isDSMobile,
|
|
141
149
|
tabType
|
|
142
|
-
} =
|
|
143
|
-
return tabType !== TabTypes.NORMAL_SMALL ? "\n &:after {\n content: '';\n position: absolute;\n width: 100%;\n height:
|
|
144
|
-
}, StyledTabButton,
|
|
150
|
+
} = _ref19;
|
|
151
|
+
return tabType !== 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 ") : "";
|
|
152
|
+
}, StyledTabButton, _ref20 => {
|
|
145
153
|
let {
|
|
146
154
|
theme,
|
|
147
155
|
isDSMobile
|
|
148
|
-
} =
|
|
149
|
-
return isDSMobile ? "
|
|
150
|
-
}, mobileGradientsSettings,
|
|
156
|
+
} = _ref20;
|
|
157
|
+
return isDSMobile ? "\n \n background: ".concat(theme.colors.brand[200], ";") : "";
|
|
158
|
+
}, mobileGradientsSettings, _ref21 => {
|
|
151
159
|
let {
|
|
152
160
|
isDSMobile,
|
|
153
161
|
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
162
|
} = _ref21;
|
|
160
|
-
return "\n
|
|
163
|
+
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 }")) : "";
|
|
161
164
|
}, StyledSelectionIndicator, _ref22 => {
|
|
162
165
|
let {
|
|
163
|
-
|
|
164
|
-
indicatorStyle,
|
|
165
|
-
isDSMobile
|
|
166
|
+
indicatorStyle
|
|
166
167
|
} = _ref22;
|
|
167
|
-
return
|
|
168
|
+
return "\n width: ".concat(indicatorStyle.width, ";\n left: ").concat(indicatorStyle.left, ";\n ");
|
|
168
169
|
}, StyledSelectionIndicator, _ref23 => {
|
|
169
170
|
let {
|
|
170
171
|
theme,
|
|
171
172
|
indicatorStyle,
|
|
172
173
|
isDSMobile
|
|
173
174
|
} = _ref23;
|
|
174
|
-
return !isDSMobile ? indicatorStyle.
|
|
175
|
+
return !isDSMobile ? indicatorStyle.backgroundWithTransparent : theme.colors.brand[600];
|
|
175
176
|
});
|
|
176
177
|
const StyledRequiredMark = /*#__PURE__*/styled.span.withConfig({
|
|
177
178
|
componentId: "sc-3hla56-5"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import 'core-js/modules/web.dom-collections.iterator.js';
|
|
2
|
-
import { useContext, useState, useCallback,
|
|
2
|
+
import { useContext, useState, useCallback, useLayoutEffect } from 'react';
|
|
3
3
|
import useResizeObserver from '@react-hook/resize-observer';
|
|
4
4
|
import { isElementVisible, shouldHaveLeftGradient, shouldHaveRightGradient } from '../../utils/helpers.js';
|
|
5
5
|
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
@@ -33,12 +33,10 @@ const useTabBar = () => {
|
|
|
33
33
|
// behavior that adds scroll to the tabList
|
|
34
34
|
|
|
35
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
36
|
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
37
|
return {
|
|
39
38
|
left: "".concat(position, "px"),
|
|
40
39
|
width: "".concat(tabClientWidth, "px"),
|
|
41
|
-
backgroundWithTransparentAndWhite,
|
|
42
40
|
backgroundWithTransparent
|
|
43
41
|
};
|
|
44
42
|
}
|
|
@@ -60,15 +58,6 @@ const useTabBar = () => {
|
|
|
60
58
|
});
|
|
61
59
|
}
|
|
62
60
|
}, [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
61
|
useLayoutEffect(() => {
|
|
73
62
|
if (showSelectionIndicator) {
|
|
74
63
|
updateIndicatorStyle();
|
|
@@ -77,7 +66,7 @@ const useTabBar = () => {
|
|
|
77
66
|
if (isDSMobile && !fixedTabsHeaders) {
|
|
78
67
|
updateMobileGradients();
|
|
79
68
|
}
|
|
80
|
-
}, [updateMobileGradients, showSelectionIndicator, updateIndicatorStyle, isDSMobile, fixedTabsHeaders]);
|
|
69
|
+
}, [updateMobileGradients, showSelectionIndicator, updateIndicatorStyle, isDSMobile, fixedTabsHeaders, actualActiveTab]);
|
|
81
70
|
return {
|
|
82
71
|
updateIndicatorStyle,
|
|
83
72
|
setIndicatorStyle,
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
|
+
import 'core-js/modules/esnext.async-iterator.constructor.js';
|
|
3
|
+
import 'core-js/modules/esnext.async-iterator.to-array.js';
|
|
4
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.to-array.js';
|
|
6
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
7
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
2
8
|
import 'core-js/modules/esnext.async-iterator.map.js';
|
|
3
9
|
import 'core-js/modules/esnext.iterator.map.js';
|
|
4
10
|
import React, { useContext, useCallback, useMemo } from 'react';
|
|
5
11
|
import SwipeableViews from 'react-swipeable-views';
|
|
6
|
-
import { getIdByIndex, getIndexById } from '../../utils/helpers.js';
|
|
7
12
|
import { StyledPanelContainer } from './styles.js';
|
|
8
13
|
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
9
14
|
import { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';
|
|
@@ -25,18 +30,38 @@ const TabsPanels = () => {
|
|
|
25
30
|
handleOnTabChange,
|
|
26
31
|
handleOnMouseDown
|
|
27
32
|
} = useTabsCallbacks();
|
|
28
|
-
const handleOnChangeIndex = useCallback(index => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
const handleOnChangeIndex = useCallback((index, indexLatest) => {
|
|
34
|
+
if (!focusableTabsRef.current) return;
|
|
35
|
+
const offset = index - indexLatest;
|
|
36
|
+
|
|
37
|
+
if (focusableTabsRef.current) {
|
|
38
|
+
var _focusableTabsRef$cur, _focusableTabsRef$cur2, _focusableTabsRef$cur3, _focusableTabsRef$cur4;
|
|
39
|
+
|
|
40
|
+
const currentIndexFocusable = (_focusableTabsRef$cur = focusableTabsRef.current) === null || _focusableTabsRef$cur === void 0 ? void 0 : _focusableTabsRef$cur.findIndex(el => el.dataset.tabId === actualActiveTab);
|
|
41
|
+
const newFocusableIndex = currentIndexFocusable >= 0 ? currentIndexFocusable + offset : -1;
|
|
42
|
+
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;
|
|
43
|
+
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
|
|
44
|
+
// by clicking we are manually forcing to center the tab
|
|
45
|
+
|
|
46
|
+
focusableTabsRef.current[newFocusableIndex].click();
|
|
47
|
+
}
|
|
48
|
+
}, [actualActiveTab, focusableTabsRef, handleOnTabChange]);
|
|
49
|
+
const firstSlideToShow = useMemo(() => {
|
|
50
|
+
const childrenArray = React.Children.toArray(tabs);
|
|
51
|
+
const index = childrenArray.filter(tab => tab.props.disabled !== true).findIndex(tab => tab.props.tabId === actualActiveTab);
|
|
52
|
+
if (index === -1) return 0;
|
|
53
|
+
return index;
|
|
54
|
+
}, [actualActiveTab, tabs]);
|
|
32
55
|
const panels = useMemo(() => React.Children.map(tabs, tab => {
|
|
33
56
|
const {
|
|
34
57
|
tabId: panelId = '',
|
|
35
58
|
style,
|
|
36
|
-
children: content
|
|
59
|
+
children: content,
|
|
60
|
+
disabled
|
|
37
61
|
} = tab.props;
|
|
38
62
|
const isActive = actualActiveTab === panelId;
|
|
39
63
|
const shouldRender = !onlyRenderActiveTab || isActive;
|
|
64
|
+
if (disabled) return null;
|
|
40
65
|
return shouldRender && /*#__PURE__*/_jsx(StyledPanelContainer, {
|
|
41
66
|
id: panelId,
|
|
42
67
|
"aria-labelledby": "".concat(panelId, "-label"),
|
|
@@ -54,7 +79,7 @@ const TabsPanels = () => {
|
|
|
54
79
|
if (animated) {
|
|
55
80
|
return /*#__PURE__*/_jsx(SwipeableViews, {
|
|
56
81
|
enableMouseEvents: enableMouseEvents,
|
|
57
|
-
index:
|
|
82
|
+
index: firstSlideToShow,
|
|
58
83
|
onChangeIndex: handleOnChangeIndex
|
|
59
84
|
}, void 0, panels);
|
|
60
85
|
}
|
package/esm/utils/constants.js
CHANGED
package/esm/utils/helpers.js
CHANGED
|
@@ -21,6 +21,33 @@ const isElementVisibleCarousel = function (tab, tabContainer) {
|
|
|
21
21
|
|
|
22
22
|
return false;
|
|
23
23
|
};
|
|
24
|
+
const centerTab = _ref => {
|
|
25
|
+
let {
|
|
26
|
+
e,
|
|
27
|
+
listRef
|
|
28
|
+
} = _ref;
|
|
29
|
+
|
|
30
|
+
if (listRef.current) {
|
|
31
|
+
const {
|
|
32
|
+
offsetLeft
|
|
33
|
+
} = e === null || e === void 0 ? void 0 : e.target;
|
|
34
|
+
const {
|
|
35
|
+
width: tabWidth
|
|
36
|
+
} = (e === null || e === void 0 ? void 0 : e.target).getBoundingClientRect();
|
|
37
|
+
const {
|
|
38
|
+
width: listWidth
|
|
39
|
+
} = listRef.current.getBoundingClientRect();
|
|
40
|
+
const extraSideSpace = listWidth - tabWidth;
|
|
41
|
+
const leftOffsetToCenter = extraSideSpace > 0 ? extraSideSpace / 2 : 0;
|
|
42
|
+
const centeredLeftOffset = offsetLeft > leftOffsetToCenter ? offsetLeft - leftOffsetToCenter : 0;
|
|
43
|
+
listRef.current.scrollTo({
|
|
44
|
+
top: 0,
|
|
45
|
+
left: centeredLeftOffset,
|
|
46
|
+
behavior: 'smooth'
|
|
47
|
+
});
|
|
48
|
+
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
24
51
|
const getVisibleDimensions = (node, referenceNode) => {
|
|
25
52
|
const nodeDimensions = node.getBoundingClientRect();
|
|
26
53
|
const referenceNodeDimensions = referenceNode.getBoundingClientRect();
|
|
@@ -29,9 +56,7 @@ const getVisibleDimensions = (node, referenceNode) => {
|
|
|
29
56
|
height: Math.min(node.clientHeight, referenceNodeDimensions.top + referenceNode.clientHeight - nodeDimensions.top, node.clientHeight - (referenceNodeDimensions.top - nodeDimensions.top))
|
|
30
57
|
};
|
|
31
58
|
};
|
|
32
|
-
const getIndexById = (children, activeId) => children && children.findIndex(item => item.props.tabId === activeId);
|
|
33
|
-
const getIdByIndex = (children, index) => children && children[index].props.tabId || '';
|
|
34
59
|
const shouldHaveLeftGradient = scrollLeft => Math.abs(scrollLeft) > MOBILE_GRADIENT_WIDTH;
|
|
35
60
|
const shouldHaveRightGradient = (scrollLeft, clientWidth, scrollWidth) => Math.abs(scrollLeft) <= scrollWidth - (clientWidth + MOBILE_GRADIENT_WIDTH);
|
|
36
61
|
|
|
37
|
-
export {
|
|
62
|
+
export { centerTab, getVisibleDimensions, isElementVisible, isElementVisibleCarousel, shouldHaveLeftGradient, shouldHaveRightGradient };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useContext, useCallback } from 'react';
|
|
2
|
+
import { centerTab } from '../helpers.js';
|
|
2
3
|
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
3
4
|
|
|
4
5
|
const useTabsCallbacks = () => {
|
|
@@ -12,36 +13,17 @@ const useTabsCallbacks = () => {
|
|
|
12
13
|
fixedTabsHeaders
|
|
13
14
|
}
|
|
14
15
|
} = useContext(DSTabsContext);
|
|
15
|
-
const centerTabWhenTabChangeMobile = useCallback(e => {
|
|
16
|
-
if (tabsListRef.current) {
|
|
17
|
-
const {
|
|
18
|
-
offsetLeft
|
|
19
|
-
} = e === null || e === void 0 ? void 0 : e.target;
|
|
20
|
-
const {
|
|
21
|
-
width: tabWidth
|
|
22
|
-
} = (e === null || e === void 0 ? void 0 : e.target).getBoundingClientRect();
|
|
23
|
-
const {
|
|
24
|
-
width: listWidth
|
|
25
|
-
} = tabsListRef.current.getBoundingClientRect();
|
|
26
|
-
const extraSideSpace = listWidth - tabWidth;
|
|
27
|
-
const leftOffsetToCenter = extraSideSpace > 0 ? extraSideSpace / 2 : 0;
|
|
28
|
-
const centeredLeftOffset = offsetLeft > leftOffsetToCenter ? offsetLeft - leftOffsetToCenter : 0;
|
|
29
|
-
tabsListRef.current.scrollTo({
|
|
30
|
-
top: 0,
|
|
31
|
-
left: centeredLeftOffset,
|
|
32
|
-
behavior: 'smooth'
|
|
33
|
-
});
|
|
34
|
-
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
35
|
-
}
|
|
36
|
-
}, [tabsListRef]);
|
|
37
16
|
const handleOnTabChange = useCallback((tabId, e) => {
|
|
38
17
|
setInternalActiveTab(tabId);
|
|
39
18
|
onTabChange(tabId, e);
|
|
40
19
|
|
|
41
20
|
if (isDSMobile && !fixedTabsHeaders && e) {
|
|
42
|
-
|
|
21
|
+
centerTab({
|
|
22
|
+
e,
|
|
23
|
+
listRef: tabsListRef
|
|
24
|
+
});
|
|
43
25
|
}
|
|
44
|
-
}, [
|
|
26
|
+
}, [fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab, tabsListRef]);
|
|
45
27
|
const handleOnMouseDown = useCallback(e => {
|
|
46
28
|
const role = e.target.getAttribute('role');
|
|
47
29
|
if (role !== 'tabpanel' && allowTextSelection) e.stopPropagation();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-tabs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Tabs",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -128,11 +128,11 @@
|
|
|
128
128
|
"build": "node ../../scripts/build/build.js"
|
|
129
129
|
},
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"@elliemae/ds-button": "2.0.
|
|
132
|
-
"@elliemae/ds-icon": "2.0.
|
|
133
|
-
"@elliemae/ds-icons": "2.0.
|
|
134
|
-
"@elliemae/ds-props-helpers": "2.0.
|
|
135
|
-
"@elliemae/ds-system": "2.0.
|
|
131
|
+
"@elliemae/ds-button": "2.0.7",
|
|
132
|
+
"@elliemae/ds-icon": "2.0.7",
|
|
133
|
+
"@elliemae/ds-icons": "2.0.7",
|
|
134
|
+
"@elliemae/ds-props-helpers": "2.0.7",
|
|
135
|
+
"@elliemae/ds-system": "2.0.7",
|
|
136
136
|
"@react-hook/resize-observer": "~1.2.5",
|
|
137
137
|
"prop-types": "~15.7.2",
|
|
138
138
|
"react-desc": "~4.1.3",
|
package/types/DSTabsTypes.d.ts
CHANGED
|
@@ -124,7 +124,6 @@ export interface MobileGradientsT {
|
|
|
124
124
|
export interface IndicatorStyleT {
|
|
125
125
|
left: string;
|
|
126
126
|
width: string;
|
|
127
|
-
backgroundWithTransparentAndWhite: string;
|
|
128
127
|
backgroundWithTransparent: string;
|
|
129
128
|
}
|
|
130
129
|
export interface UseCarouselReturnTypeT {
|
|
@@ -163,6 +162,10 @@ export interface VisibleDimensionsT {
|
|
|
163
162
|
width: number;
|
|
164
163
|
height: number;
|
|
165
164
|
}
|
|
165
|
+
export interface CenterTabPropsT {
|
|
166
|
+
e?: React.MouseEvent | React.FocusEvent;
|
|
167
|
+
listRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
168
|
+
}
|
|
166
169
|
export interface StyledTabWrapperPropsT {
|
|
167
170
|
isDSMobile: boolean;
|
|
168
171
|
fixedTabsHeaders: boolean;
|
|
@@ -8,7 +8,6 @@ export declare const MOBILE_GRADIENT_WIDTH = 24;
|
|
|
8
8
|
export declare const defaultIndicatorStyles: {
|
|
9
9
|
left: string;
|
|
10
10
|
width: string;
|
|
11
|
-
backgroundWithTransparentAndWhite: string;
|
|
12
11
|
backgroundWithTransparent: string;
|
|
13
12
|
};
|
|
14
13
|
export declare const gradientOffsetsAccordingType: {
|
package/types/utils/helpers.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CenterTabPropsT, VisibleDimensionsT } from '../DSTabsTypes';
|
|
2
2
|
export declare const isElementVisible: (tab: HTMLElement, tabList: HTMLElement) => boolean;
|
|
3
3
|
export declare const isElementVisibleCarousel: (tab: HTMLElement | null, tabContainer: HTMLDivElement | null, firstOrLastItem?: boolean) => boolean;
|
|
4
|
+
export declare const centerTab: ({ e, listRef }: CenterTabPropsT) => void;
|
|
4
5
|
export declare const getVisibleDimensions: (node: HTMLElement, referenceNode: HTMLElement) => VisibleDimensionsT;
|
|
5
|
-
export declare const getIndexById: (children: React.ReactElement<DSTabPropsWithDefaultT>[], activeId?: string | undefined) => number;
|
|
6
|
-
export declare const getIdByIndex: (children: React.ReactElement<DSTabPropsWithDefaultT>[], index: number) => string;
|
|
7
6
|
export declare const shouldHaveLeftGradient: (scrollLeft: number) => boolean;
|
|
8
7
|
export declare const shouldHaveRightGradient: (scrollLeft: number, clientWidth: number, scrollWidth: number) => boolean;
|