@elliemae/ds-tabs 2.0.0-alpha.1 → 2.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/DSTabs.js +29 -107
- package/cjs/DSTabsCTX.js +30 -0
- package/cjs/DSTabsDatatestid.js +18 -0
- package/cjs/DSTabsTypes.js +2 -0
- package/cjs/config/useCrossRef.js +17 -0
- package/cjs/config/useTabs.js +51 -0
- package/cjs/defaultProps.js +27 -0
- package/cjs/{PanelContainer.js → exportsRelated/DSTab.js} +19 -28
- package/cjs/index.js +5 -5
- package/cjs/parts/carousel/Carousel.js +71 -0
- package/cjs/parts/carousel/styles.js +60 -0
- package/cjs/parts/carousel/useCarousel.js +78 -0
- package/cjs/parts/carousel/useCarouselCallbacks.js +72 -0
- package/cjs/parts/tabBar/TabBar.js +160 -0
- package/cjs/parts/tabBar/styles.js +199 -0
- package/cjs/parts/tabBar/useTabBar.js +98 -0
- package/cjs/parts/tabsContent/TabsContent.js +49 -0
- package/cjs/parts/tabsContent/styles.js +15 -0
- package/cjs/parts/tabsPanel/TabsPanels.js +77 -0
- package/cjs/parts/tabsPanel/styles.js +25 -0
- package/cjs/propTypes.js +33 -0
- package/cjs/utils/constants.js +29 -0
- package/cjs/utils/helpers.js +47 -0
- package/cjs/utils/hooks/useKeyboardNavigation.js +61 -0
- package/cjs/utils/hooks/useTabsCallbacks.js +59 -0
- package/esm/DSTabs.js +30 -108
- package/esm/DSTabsCTX.js +25 -0
- package/esm/DSTabsDatatestid.js +14 -0
- package/esm/DSTabsTypes.js +1 -0
- package/esm/config/useCrossRef.js +13 -0
- package/esm/config/useTabs.js +47 -0
- package/esm/defaultProps.js +23 -0
- package/esm/{PanelContainer.js → exportsRelated/DSTab.js} +11 -23
- package/esm/index.js +4 -3
- package/esm/parts/carousel/Carousel.js +63 -0
- package/esm/parts/carousel/styles.js +49 -0
- package/esm/parts/carousel/useCarousel.js +70 -0
- package/esm/parts/carousel/useCarouselCallbacks.js +68 -0
- package/esm/parts/tabBar/TabBar.js +151 -0
- package/esm/parts/tabBar/styles.js +185 -0
- package/esm/parts/tabBar/useTabBar.js +90 -0
- package/esm/parts/tabsContent/TabsContent.js +40 -0
- package/esm/parts/tabsContent/styles.js +7 -0
- package/esm/parts/tabsPanel/TabsPanels.js +67 -0
- package/esm/parts/tabsPanel/styles.js +17 -0
- package/esm/propTypes.js +28 -0
- package/esm/utils/constants.js +21 -0
- package/esm/utils/helpers.js +37 -0
- package/esm/utils/hooks/useKeyboardNavigation.js +57 -0
- package/esm/utils/hooks/useTabsCallbacks.js +55 -0
- package/package.json +100 -37
- package/types/DSTabs.d.ts +10 -60
- package/types/DSTabsCTX.d.ts +4 -0
- package/types/DSTabsDatatestid.d.ts +12 -0
- package/types/DSTabsTypes.d.ts +202 -0
- package/types/config/useCrossRef.d.ts +2 -0
- package/types/config/useTabs.d.ts +2 -0
- package/types/defaultProps.d.ts +2 -0
- package/types/exportsRelated/DSTab.d.ts +14 -0
- package/types/index.d.ts +4 -3
- package/types/parts/carousel/Carousel.d.ts +3 -0
- package/types/parts/carousel/styles.d.ts +9 -0
- package/types/parts/carousel/useCarousel.d.ts +2 -0
- package/types/parts/carousel/useCarouselCallbacks.d.ts +2 -0
- package/types/parts/tabBar/TabBar.d.ts +2 -0
- package/types/parts/tabBar/styles.d.ts +7 -0
- package/types/parts/tabBar/useTabBar.d.ts +2 -0
- package/types/parts/tabsContent/TabsContent.d.ts +2 -0
- package/types/parts/tabsContent/styles.d.ts +1 -0
- package/types/parts/tabsPanel/TabsPanels.d.ts +2 -0
- package/types/parts/tabsPanel/styles.d.ts +2 -0
- package/types/propTypes.d.ts +54 -0
- package/types/tests/{DSTabs.events.test.d.ts → DSTabs.callbacks.test.d.ts} +0 -0
- package/types/tests/DSTabs.func.test.d.ts +1 -0
- package/types/tests/DSTabs.keyboard.test.d.ts +1 -0
- package/types/utils/constants.d.ts +19 -0
- package/types/utils/helpers.d.ts +8 -0
- package/types/utils/hooks/useKeyboardNavigation.d.ts +2 -0
- package/types/utils/hooks/useTabsCallbacks.d.ts +2 -0
- package/cjs/Carousel.js +0 -197
- package/cjs/DSTab.js +0 -43
- package/cjs/SubTabBar.js +0 -45
- package/cjs/TabBar.js +0 -410
- package/cjs/TabTypes.js +0 -12
- package/cjs/TabsImpl.js +0 -114
- package/cjs/TabsPanels.js +0 -82
- package/cjs/package.json +0 -7
- package/cjs/useResize.js +0 -24
- package/esm/Carousel.js +0 -186
- package/esm/DSTab.js +0 -33
- package/esm/SubTabBar.js +0 -39
- package/esm/TabBar.js +0 -399
- package/esm/TabTypes.js +0 -7
- package/esm/TabsImpl.js +0 -107
- package/esm/TabsPanels.js +0 -72
- package/esm/package.json +0 -7
- package/esm/useResize.js +0 -20
- package/types/Carousel.d.ts +0 -16
- package/types/DSTab.d.ts +0 -22
- package/types/PanelContainer.d.ts +0 -20
- package/types/SubTabBar.d.ts +0 -23
- package/types/TabBar.d.ts +0 -30
- package/types/TabTypes.d.ts +0 -5
- package/types/TabsImpl.d.ts +0 -37
- package/types/TabsPanels.d.ts +0 -5
- package/types/useResize.d.ts +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const TabTypes = {
|
|
6
|
+
NORMAL: 'normal',
|
|
7
|
+
NORMAL_SMALL: 'normal_small',
|
|
8
|
+
SUBTABS: 'subtabs'
|
|
9
|
+
};
|
|
10
|
+
const TabTypesValuesAsArray = Object.values(TabTypes);
|
|
11
|
+
const MOBILE_GRADIENT_WIDTH = 24;
|
|
12
|
+
const defaultIndicatorStyles = {
|
|
13
|
+
left: '0px',
|
|
14
|
+
width: '0px',
|
|
15
|
+
backgroundWithTransparentAndWhite: '',
|
|
16
|
+
backgroundWithTransparent: ''
|
|
17
|
+
};
|
|
18
|
+
const gradientOffsetsAccordingType = {
|
|
19
|
+
normal_small: 14,
|
|
20
|
+
normal: 16,
|
|
21
|
+
subtabs: 16,
|
|
22
|
+
fixedTabsHeaders: 0
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
exports.MOBILE_GRADIENT_WIDTH = MOBILE_GRADIENT_WIDTH;
|
|
26
|
+
exports.TabTypes = TabTypes;
|
|
27
|
+
exports.TabTypesValuesAsArray = TabTypesValuesAsArray;
|
|
28
|
+
exports.defaultIndicatorStyles = defaultIndicatorStyles;
|
|
29
|
+
exports.gradientOffsetsAccordingType = gradientOffsetsAccordingType;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var constants = require('./constants.js');
|
|
6
|
+
|
|
7
|
+
const isElementVisible = (tab, tabList) => {
|
|
8
|
+
const tabDimensions = tab.getBoundingClientRect();
|
|
9
|
+
const tabListDimensions = tabList.getBoundingClientRect();
|
|
10
|
+
return tabDimensions.left <= tabListDimensions.left ? tabListDimensions.left - tabDimensions.left <= tabDimensions.width : tabDimensions.right - tabListDimensions.right <= tabDimensions.width;
|
|
11
|
+
};
|
|
12
|
+
const isElementVisibleCarousel = function (tab, tabContainer) {
|
|
13
|
+
let firstOrLastItem = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
14
|
+
|
|
15
|
+
if (tab && tabContainer) {
|
|
16
|
+
const tabDimensions = tab.getBoundingClientRect();
|
|
17
|
+
const tabContainerDimensions = tabContainer.getBoundingClientRect();
|
|
18
|
+
const offset = firstOrLastItem ? 16 : 32;
|
|
19
|
+
const tabDimensionsLeft = Math.floor(tabDimensions.left - offset);
|
|
20
|
+
const tabDimensionsRight = Math.floor(tabDimensions.right + offset);
|
|
21
|
+
const tabContainerDimensionsLeft = Math.floor(tabContainerDimensions.left);
|
|
22
|
+
const tabContainerDimensionsRight = Math.floor(tabContainerDimensions.right);
|
|
23
|
+
return tabDimensionsLeft >= tabContainerDimensionsLeft && tabDimensionsRight <= tabContainerDimensionsRight;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
28
|
+
const getVisibleDimensions = (node, referenceNode) => {
|
|
29
|
+
const nodeDimensions = node.getBoundingClientRect();
|
|
30
|
+
const referenceNodeDimensions = referenceNode.getBoundingClientRect();
|
|
31
|
+
return {
|
|
32
|
+
width: Math.min(node.clientWidth, referenceNodeDimensions.left + referenceNode.clientWidth - nodeDimensions.left, node.clientWidth - (referenceNodeDimensions.left - nodeDimensions.left)),
|
|
33
|
+
height: Math.min(node.clientHeight, referenceNodeDimensions.top + referenceNode.clientHeight - nodeDimensions.top, node.clientHeight - (referenceNodeDimensions.top - nodeDimensions.top))
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const getIndexById = (children, activeId) => children && children.findIndex(item => item.props.tabId === activeId);
|
|
37
|
+
const getIdByIndex = (children, index) => children && children[index].props.tabId || '';
|
|
38
|
+
const shouldHaveLeftGradient = scrollLeft => Math.abs(scrollLeft) > constants.MOBILE_GRADIENT_WIDTH;
|
|
39
|
+
const shouldHaveRightGradient = (scrollLeft, clientWidth, scrollWidth) => Math.abs(scrollLeft) <= scrollWidth - (clientWidth + constants.MOBILE_GRADIENT_WIDTH);
|
|
40
|
+
|
|
41
|
+
exports.getIdByIndex = getIdByIndex;
|
|
42
|
+
exports.getIndexById = getIndexById;
|
|
43
|
+
exports.getVisibleDimensions = getVisibleDimensions;
|
|
44
|
+
exports.isElementVisible = isElementVisible;
|
|
45
|
+
exports.isElementVisibleCarousel = isElementVisibleCarousel;
|
|
46
|
+
exports.shouldHaveLeftGradient = shouldHaveLeftGradient;
|
|
47
|
+
exports.shouldHaveRightGradient = shouldHaveRightGradient;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var DSTabsCTX = require('../../DSTabsCTX.js');
|
|
7
|
+
|
|
8
|
+
/* eslint-disable max-statements */
|
|
9
|
+
const useKeyboardNavigation = () => {
|
|
10
|
+
const {
|
|
11
|
+
focusableTabsRef
|
|
12
|
+
} = React.useContext(DSTabsCTX.DSTabsContext);
|
|
13
|
+
const {
|
|
14
|
+
firstSubtabInternalRef,
|
|
15
|
+
lastTabInternalRef
|
|
16
|
+
} = React.useContext(DSTabsCTX.DSTabsCrossRefContext);
|
|
17
|
+
const handleOnKeyDown = React.useCallback(e => {
|
|
18
|
+
if (e.key === 'ArrowRight' && focusableTabsRef.current) {
|
|
19
|
+
var _focusableTabsRef$cur, _focusableTabsRef$cur2;
|
|
20
|
+
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
e.stopPropagation();
|
|
23
|
+
const nextTab = focusableTabsRef.current[(focusableTabsRef === null || focusableTabsRef === void 0 ? void 0 : (_focusableTabsRef$cur = focusableTabsRef.current) === null || _focusableTabsRef$cur === void 0 ? void 0 : (_focusableTabsRef$cur2 = _focusableTabsRef$cur.indexOf) === null || _focusableTabsRef$cur2 === void 0 ? void 0 : _focusableTabsRef$cur2.call(_focusableTabsRef$cur, e.target)) + 1];
|
|
24
|
+
if (nextTab) nextTab.focus();
|
|
25
|
+
if (!nextTab) return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (e.key === 'ArrowLeft' && focusableTabsRef.current) {
|
|
29
|
+
var _focusableTabsRef$cur3, _focusableTabsRef$cur4;
|
|
30
|
+
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
e.stopPropagation();
|
|
33
|
+
const prevTab = focusableTabsRef.current[(focusableTabsRef === null || focusableTabsRef === void 0 ? void 0 : (_focusableTabsRef$cur3 = focusableTabsRef.current) === null || _focusableTabsRef$cur3 === void 0 ? void 0 : (_focusableTabsRef$cur4 = _focusableTabsRef$cur3.indexOf) === null || _focusableTabsRef$cur4 === void 0 ? void 0 : _focusableTabsRef$cur4.call(_focusableTabsRef$cur3, e.target)) - 1];
|
|
34
|
+
if (prevTab) prevTab.focus();
|
|
35
|
+
if (!prevTab) return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (e.key === 'ArrowDown') {
|
|
39
|
+
var _firstSubtabInternalR;
|
|
40
|
+
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
e.stopPropagation();
|
|
43
|
+
const canFocusCrossTabs = (firstSubtabInternalRef === null || firstSubtabInternalRef === void 0 ? void 0 : firstSubtabInternalRef.current) && (lastTabInternalRef === null || lastTabInternalRef === void 0 ? void 0 : lastTabInternalRef.current);
|
|
44
|
+
if (canFocusCrossTabs) (_firstSubtabInternalR = firstSubtabInternalRef.current) === null || _firstSubtabInternalR === void 0 ? void 0 : _firstSubtabInternalR.focus();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (e.key === 'ArrowUp') {
|
|
48
|
+
var _lastTabInternalRef$c;
|
|
49
|
+
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
e.stopPropagation();
|
|
52
|
+
const canFocusCrossTabs = (firstSubtabInternalRef === null || firstSubtabInternalRef === void 0 ? void 0 : firstSubtabInternalRef.current) && (lastTabInternalRef === null || lastTabInternalRef === void 0 ? void 0 : lastTabInternalRef.current);
|
|
53
|
+
if (canFocusCrossTabs) (_lastTabInternalRef$c = lastTabInternalRef.current) === null || _lastTabInternalRef$c === void 0 ? void 0 : _lastTabInternalRef$c.focus();
|
|
54
|
+
}
|
|
55
|
+
}, [firstSubtabInternalRef, lastTabInternalRef, focusableTabsRef]);
|
|
56
|
+
return {
|
|
57
|
+
handleOnKeyDown
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
exports.useKeyboardNavigation = useKeyboardNavigation;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var DSTabsCTX = require('../../DSTabsCTX.js');
|
|
7
|
+
|
|
8
|
+
const useTabsCallbacks = () => {
|
|
9
|
+
const {
|
|
10
|
+
setInternalActiveTab,
|
|
11
|
+
tabsListRef,
|
|
12
|
+
props: {
|
|
13
|
+
onTabChange,
|
|
14
|
+
isDSMobile,
|
|
15
|
+
allowTextSelection,
|
|
16
|
+
fixedTabsHeaders
|
|
17
|
+
}
|
|
18
|
+
} = 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
|
+
const handleOnTabChange = React.useCallback((tabId, e) => {
|
|
42
|
+
setInternalActiveTab(tabId);
|
|
43
|
+
onTabChange(tabId, e);
|
|
44
|
+
|
|
45
|
+
if (isDSMobile && !fixedTabsHeaders && e) {
|
|
46
|
+
centerTabWhenTabChangeMobile(e);
|
|
47
|
+
}
|
|
48
|
+
}, [centerTabWhenTabChangeMobile, fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab]);
|
|
49
|
+
const handleOnMouseDown = React.useCallback(e => {
|
|
50
|
+
const role = e.target.getAttribute('role');
|
|
51
|
+
if (role !== 'tabpanel' && allowTextSelection) e.stopPropagation();
|
|
52
|
+
}, [allowTextSelection]);
|
|
53
|
+
return {
|
|
54
|
+
handleOnTabChange,
|
|
55
|
+
handleOnMouseDown
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
exports.useTabsCallbacks = useTabsCallbacks;
|
package/esm/DSTabs.js
CHANGED
|
@@ -1,113 +1,35 @@
|
|
|
1
1
|
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
|
-
import 'react';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
lastTabRef: lastTabRef,
|
|
31
|
-
allowTextSelection: allowTextSelection,
|
|
32
|
-
animated: animated,
|
|
33
|
-
containerProps: containerProps,
|
|
34
|
-
enableMouseEvents: enableMouseEvents,
|
|
35
|
-
innerRef: innerRef,
|
|
36
|
-
onlyRenderActiveTab: onlyRenderActiveTab,
|
|
37
|
-
onTabChange: onTabChange,
|
|
38
|
-
tabBarExtraContent: tabBarExtraContent,
|
|
39
|
-
tabsListAriaLabel: tabsListAriaLabel,
|
|
40
|
-
type: type,
|
|
41
|
-
withCarousel: withCarousel,
|
|
42
|
-
flexibleTabsHeaders: flexibleTabsHeaders,
|
|
43
|
-
fixedTabsHeaders: fixedTabsHeaders,
|
|
44
|
-
isDSMobile: isDSMobile
|
|
45
|
-
}, void 0, tabs);
|
|
46
|
-
|
|
47
|
-
const props = {
|
|
48
|
-
/** Whether the tab transition should animate or not */
|
|
49
|
-
animated: PropTypes.bool.description('Whether the tab transition should animate or not'),
|
|
50
|
-
|
|
51
|
-
/** Enables tab transition with mouse drag events */
|
|
52
|
-
enableMouseEvents: PropTypes.bool.description('Enables tab transition with mouse drag events'),
|
|
53
|
-
|
|
54
|
-
/** Allow text selection when mouse drag events are active */
|
|
55
|
-
allowTextSelection: PropTypes.bool.description('Allow text selection when mouse drag events are active'),
|
|
56
|
-
|
|
57
|
-
/** Handler when a user clicks on a different tab */
|
|
58
|
-
onTabChange: PropTypes.func.description('Handler when a user clicks on a different tab'),
|
|
59
|
-
|
|
60
|
-
/** Tab type */
|
|
61
|
-
type: PropTypes.oneOf(['normal', 'subtabs']).description('Tab type'),
|
|
62
|
-
|
|
63
|
-
/** Extra content next to the tabs pills */
|
|
64
|
-
tabBarExtraContent: PropTypes.element.description('Extra content next to the tabs pills'),
|
|
65
|
-
|
|
66
|
-
/** Only renders the active tab in the DOM */
|
|
67
|
-
onlyRenderActiveTab: PropTypes.bool.description('Only renders the active tab in the DOM'),
|
|
68
|
-
|
|
69
|
-
/** Mobile only flexible tabs mode */
|
|
70
|
-
flexibleTabsHeaders: PropTypes.bool.description('Mobile only flexible tabs mode'),
|
|
71
|
-
|
|
72
|
-
/** Mobile only fixed tabs mode */
|
|
73
|
-
fixedTabsHeaders: PropTypes.bool.description('Mobile only fixed tabs mode'),
|
|
74
|
-
|
|
75
|
-
/** Whether or not it's a ds-tab from DSMobile tabs */
|
|
76
|
-
isDSMobile: PropTypes.bool.description("Whether or not it's a ds-tab from DSMobile tabs"),
|
|
77
|
-
|
|
78
|
-
/** Activate carousel behavior */
|
|
79
|
-
withCarousel: PropTypes.bool.description('Activate carousel behavior'),
|
|
80
|
-
|
|
81
|
-
/** The active tabId */
|
|
82
|
-
activeTab: PropTypes.string.description('The active tabId'),
|
|
83
|
-
|
|
84
|
-
/** tabs children */
|
|
85
|
-
children: PropTypes.arrayOf(PropTypes.shape({
|
|
86
|
-
type: PropTypes.instanceOf([PropTypes.instanceOf(DSTab), PropTypes.array])
|
|
87
|
-
})).isRequired.description('tabs children'),
|
|
88
|
-
|
|
89
|
-
/** Aria label for the list */
|
|
90
|
-
tabsListAriaLabel: PropTypes.string.description('Aria label for the list'),
|
|
91
|
-
|
|
92
|
-
/** Additional properties for the container */
|
|
93
|
-
containerProps: PropTypes.object.description('Additional properties for the container'),
|
|
94
|
-
|
|
95
|
-
/** REF */
|
|
96
|
-
innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
|
|
97
|
-
current: PropTypes.any
|
|
98
|
-
})]).description('REF'),
|
|
99
|
-
|
|
100
|
-
/** internal ref to handle keyboard a11y behavior */
|
|
101
|
-
firstSubtabRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
|
|
102
|
-
current: PropTypes.any
|
|
103
|
-
})]).description('internal ref to handle keyboard a11y behavior'),
|
|
104
|
-
|
|
105
|
-
/** internal ref to handle keyboard a11y behavior */
|
|
106
|
-
lastTabRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
|
|
107
|
-
current: PropTypes.any
|
|
108
|
-
})]).description('internal ref to handle keyboard a11y behavior')
|
|
2
|
+
import { describe } from 'react-desc';
|
|
3
|
+
import { tabsPropTypes } from './propTypes.js';
|
|
4
|
+
import { DSTabsContext, DSTabsCrossRefContext } from './DSTabsCTX.js';
|
|
5
|
+
import { TabsContent } from './parts/tabsContent/TabsContent.js';
|
|
6
|
+
import { useTabs } from './config/useTabs.js';
|
|
7
|
+
import { useCrossRef } from './config/useCrossRef.js';
|
|
8
|
+
import { TabTypes } from './utils/constants.js';
|
|
9
|
+
|
|
10
|
+
var _TabsContent, _TabsContent2;
|
|
11
|
+
|
|
12
|
+
const DSTabs = props => {
|
|
13
|
+
const ctx = useTabs(props);
|
|
14
|
+
const crossRefsCtx = useCrossRef();
|
|
15
|
+
const {
|
|
16
|
+
type
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
if (type === TabTypes.SUBTABS) {
|
|
20
|
+
return /*#__PURE__*/_jsx(DSTabsContext.Provider, {
|
|
21
|
+
value: ctx
|
|
22
|
+
}, void 0, _TabsContent || (_TabsContent = /*#__PURE__*/_jsx(TabsContent, {})));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return /*#__PURE__*/_jsx(DSTabsCrossRefContext.Provider, {
|
|
26
|
+
value: crossRefsCtx
|
|
27
|
+
}, void 0, /*#__PURE__*/_jsx(DSTabsContext.Provider, {
|
|
28
|
+
value: ctx
|
|
29
|
+
}, void 0, _TabsContent2 || (_TabsContent2 = /*#__PURE__*/_jsx(TabsContent, {}))));
|
|
109
30
|
};
|
|
31
|
+
|
|
110
32
|
const DSTabsWithSchema = describe(DSTabs);
|
|
111
|
-
DSTabsWithSchema.propTypes =
|
|
33
|
+
DSTabsWithSchema.propTypes = tabsPropTypes;
|
|
112
34
|
|
|
113
35
|
export { DSTabs, DSTabsWithSchema, DSTabs as default };
|
package/esm/DSTabsCTX.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createContext, createRef } from 'react';
|
|
2
|
+
import { tabsDefaultProps } from './defaultProps.js';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
5
|
+
const noop = () => {};
|
|
6
|
+
|
|
7
|
+
const defaultContext = {
|
|
8
|
+
props: tabsDefaultProps,
|
|
9
|
+
tabsRef: /*#__PURE__*/createRef(),
|
|
10
|
+
tabsListRef: /*#__PURE__*/createRef(),
|
|
11
|
+
carouselOnlyListRef: /*#__PURE__*/createRef(),
|
|
12
|
+
focusableTabsRef: /*#__PURE__*/createRef(),
|
|
13
|
+
tabsRefAsArray: /*#__PURE__*/createRef(),
|
|
14
|
+
actualActiveTabRef: /*#__PURE__*/createRef(),
|
|
15
|
+
setInternalActiveTab: noop,
|
|
16
|
+
actualActiveTab: ''
|
|
17
|
+
};
|
|
18
|
+
const defaultCrossRefsContext = {
|
|
19
|
+
lastTabInternalRef: /*#__PURE__*/createRef(),
|
|
20
|
+
firstSubtabInternalRef: /*#__PURE__*/createRef()
|
|
21
|
+
};
|
|
22
|
+
const DSTabsContext = /*#__PURE__*/createContext(defaultContext);
|
|
23
|
+
const DSTabsCrossRefContext = /*#__PURE__*/createContext(defaultCrossRefsContext);
|
|
24
|
+
|
|
25
|
+
export { DSTabsContext, DSTabsCrossRefContext };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const DSTabsDatatestid = {
|
|
2
|
+
TABS_CONTAINER: 'ds-tabs-container',
|
|
3
|
+
TAB_BUTTON: 'ds-tabs-tab-button',
|
|
4
|
+
SUBTAB_BUTTON: 'ds-tabs-subtab-button',
|
|
5
|
+
TAB_PANEL: 'ds-tabs-tab-panel',
|
|
6
|
+
SUB_TAB_LIST: 'subtabs-list',
|
|
7
|
+
TAB_LIST: 'tab-list',
|
|
8
|
+
CAROUSEL: {
|
|
9
|
+
BUTTON_RIGHT: 'chevron-right',
|
|
10
|
+
BUTTON_LEFT: 'chevron-left'
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { DSTabsDatatestid };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useRef, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
const useCrossRef = () => {
|
|
4
|
+
const firstSubtabInternalRef = useRef();
|
|
5
|
+
const lastTabInternalRef = useRef();
|
|
6
|
+
const ctx = useMemo(() => ({
|
|
7
|
+
firstSubtabInternalRef,
|
|
8
|
+
lastTabInternalRef
|
|
9
|
+
}), []);
|
|
10
|
+
return ctx;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { useCrossRef };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import 'core-js/modules/web.dom-collections.iterator.js';
|
|
2
|
+
import 'core-js/modules/esnext.async-iterator.find.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
4
|
+
import 'core-js/modules/esnext.iterator.find.js';
|
|
5
|
+
import { useRef, useState, useMemo, useEffect } from 'react';
|
|
6
|
+
import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';
|
|
7
|
+
import { tabsDefaultProps } from '../defaultProps.js';
|
|
8
|
+
|
|
9
|
+
const useTabs = props => {
|
|
10
|
+
var _children$, _children$$props;
|
|
11
|
+
|
|
12
|
+
const propsWithDefaults = useMemoMergePropsWithDefault(props, tabsDefaultProps);
|
|
13
|
+
const {
|
|
14
|
+
activeTab,
|
|
15
|
+
children
|
|
16
|
+
} = propsWithDefaults;
|
|
17
|
+
const tabsRef = useRef({});
|
|
18
|
+
const tabsRefAsArray = useRef([]);
|
|
19
|
+
const focusableTabsRef = useRef([]);
|
|
20
|
+
const carouselOnlyListRef = useRef(null);
|
|
21
|
+
const tabsListRef = useRef(null);
|
|
22
|
+
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);
|
|
24
|
+
const actualActiveTab = useMemo(() => {
|
|
25
|
+
if (activeTab !== undefined) return activeTab;
|
|
26
|
+
return internalActiveTab;
|
|
27
|
+
}, [activeTab, internalActiveTab]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
var _focusableTabsRef$cur;
|
|
30
|
+
|
|
31
|
+
actualActiveTabRef.current = (_focusableTabsRef$cur = focusableTabsRef.current.find(el => el.dataset.tabId === internalActiveTab)) !== null && _focusableTabsRef$cur !== void 0 ? _focusableTabsRef$cur : null;
|
|
32
|
+
}, [internalActiveTab]);
|
|
33
|
+
const ctx = useMemo(() => ({
|
|
34
|
+
props: propsWithDefaults,
|
|
35
|
+
tabsRef,
|
|
36
|
+
focusableTabsRef,
|
|
37
|
+
tabsListRef,
|
|
38
|
+
tabsRefAsArray,
|
|
39
|
+
setInternalActiveTab,
|
|
40
|
+
actualActiveTab,
|
|
41
|
+
actualActiveTabRef,
|
|
42
|
+
carouselOnlyListRef
|
|
43
|
+
}), [actualActiveTab, propsWithDefaults]);
|
|
44
|
+
return ctx;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { useTabs };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TabTypes } from './utils/constants.js';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
4
|
+
const noop = () => {};
|
|
5
|
+
|
|
6
|
+
const tabsDefaultProps = {
|
|
7
|
+
containerProps: {},
|
|
8
|
+
animated: true,
|
|
9
|
+
enableMouseEvents: false,
|
|
10
|
+
allowTextSelection: false,
|
|
11
|
+
onTabChange: noop,
|
|
12
|
+
tabsListAriaLabel: 'Tab list',
|
|
13
|
+
type: TabTypes.NORMAL,
|
|
14
|
+
onlyRenderActiveTab: false,
|
|
15
|
+
withCarousel: false,
|
|
16
|
+
isDSMobile: false,
|
|
17
|
+
showSelectionIndicator: true,
|
|
18
|
+
children: [],
|
|
19
|
+
fixedTabsHeaders: false,
|
|
20
|
+
showSeparator: true
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { tabsDefaultProps };
|
|
@@ -1,33 +1,21 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
4
|
+
import 'core-js/modules/esnext.async-iterator.for-each.js';
|
|
5
|
+
import 'core-js/modules/esnext.iterator.for-each.js';
|
|
1
6
|
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
2
|
-
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
|
|
3
7
|
import React from 'react';
|
|
4
|
-
import {
|
|
8
|
+
import { describe } from 'react-desc';
|
|
9
|
+
import { tabPropTypes } from '../propTypes.js';
|
|
5
10
|
import { jsx } from 'react/jsx-runtime';
|
|
6
11
|
|
|
7
|
-
const _excluded = ["children", "lastTabRef", "firstSubtabRef"];
|
|
8
|
-
|
|
9
12
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
10
13
|
|
|
11
14
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
12
|
-
const blockName = 'tabs-panels';
|
|
13
|
-
const PC = aggregatedClasses('div')(blockName, 'panel');
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
-
let {
|
|
17
|
-
children,
|
|
18
|
-
lastTabRef,
|
|
19
|
-
firstSubtabRef
|
|
20
|
-
} = _ref,
|
|
21
|
-
rest = _objectWithoutProperties(_ref, _excluded);
|
|
16
|
+
const DSTab = props => /*#__PURE__*/jsx(React.Fragment, _objectSpread({}, props));
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
firstSubtabRef,
|
|
26
|
-
lastTabRef
|
|
27
|
-
}) : c);
|
|
28
|
-
return /*#__PURE__*/jsx(PC, _objectSpread(_objectSpread({}, rest), {}, {
|
|
29
|
-
children: child
|
|
30
|
-
}));
|
|
31
|
-
};
|
|
18
|
+
const DSTabWithSchema = describe(DSTab);
|
|
19
|
+
DSTabWithSchema.propTypes = tabPropTypes;
|
|
32
20
|
|
|
33
|
-
export {
|
|
21
|
+
export { DSTab, DSTabWithSchema, DSTab as default };
|
package/esm/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { DSTab, DSTabWithSchema } from './DSTab.js';
|
|
2
|
-
export { DSTabs, DSTabsWithSchema
|
|
3
|
-
export { TabTypes
|
|
1
|
+
export { DSTab, DSTabWithSchema } from './exportsRelated/DSTab.js';
|
|
2
|
+
export { DSTabs, DSTabsWithSchema } from './DSTabs.js';
|
|
3
|
+
export { TabTypes } from './utils/constants.js';
|
|
4
|
+
export { DSTabsDatatestid } from './DSTabsDatatestid.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { DSIconSizes, DSIconColors } from '@elliemae/ds-icon';
|
|
4
|
+
import { BUTTON_TYPES } from '@elliemae/ds-button';
|
|
5
|
+
import { ChevronLeft, ChevronRight } from '@elliemae/ds-icons';
|
|
6
|
+
import { StyledCarouselWrapper, StyledCarouselButtonWrapper, StyledCarouselBtn, StyledChildrenWrap } from './styles.js';
|
|
7
|
+
import { useCarousel } from './useCarousel.js';
|
|
8
|
+
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
9
|
+
import { DSTabsDatatestid } from '../../DSTabsDatatestid.js';
|
|
10
|
+
import { jsx } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
const Carousel = _ref => {
|
|
13
|
+
let {
|
|
14
|
+
children,
|
|
15
|
+
updateIndicatorStyle
|
|
16
|
+
} = _ref;
|
|
17
|
+
const {
|
|
18
|
+
showChevrons,
|
|
19
|
+
leftButtonOnClick,
|
|
20
|
+
rightButtonOnClick,
|
|
21
|
+
handleOnClick,
|
|
22
|
+
handleOnScroll
|
|
23
|
+
} = useCarousel({
|
|
24
|
+
updateIndicatorStyle
|
|
25
|
+
});
|
|
26
|
+
const {
|
|
27
|
+
carouselOnlyListRef,
|
|
28
|
+
props: {
|
|
29
|
+
type
|
|
30
|
+
}
|
|
31
|
+
} = useContext(DSTabsContext);
|
|
32
|
+
return /*#__PURE__*/_jsx(StyledCarouselWrapper, {}, void 0, showChevrons.left && /*#__PURE__*/_jsx(StyledCarouselButtonWrapper, {
|
|
33
|
+
tabType: type
|
|
34
|
+
}, void 0, /*#__PURE__*/_jsx(StyledCarouselBtn, {
|
|
35
|
+
size: "s",
|
|
36
|
+
onClick: leftButtonOnClick,
|
|
37
|
+
tabIndex: -1,
|
|
38
|
+
"data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_LEFT,
|
|
39
|
+
buttonType: BUTTON_TYPES.ICON
|
|
40
|
+
}, void 0, /*#__PURE__*/_jsx(ChevronLeft, {
|
|
41
|
+
size: DSIconSizes.S,
|
|
42
|
+
color: DSIconColors.PRIMARY
|
|
43
|
+
}))), showChevrons.right && /*#__PURE__*/_jsx(StyledCarouselButtonWrapper, {
|
|
44
|
+
tabType: type,
|
|
45
|
+
right: showChevrons.right
|
|
46
|
+
}, void 0, /*#__PURE__*/_jsx(StyledCarouselBtn, {
|
|
47
|
+
size: "s",
|
|
48
|
+
onClick: rightButtonOnClick,
|
|
49
|
+
tabIndex: -1,
|
|
50
|
+
"data-testid": DSTabsDatatestid.CAROUSEL.BUTTON_RIGHT,
|
|
51
|
+
buttonType: BUTTON_TYPES.ICON
|
|
52
|
+
}, void 0, /*#__PURE__*/_jsx(ChevronRight, {
|
|
53
|
+
size: DSIconSizes.S,
|
|
54
|
+
color: DSIconColors.PRIMARY
|
|
55
|
+
}))), /*#__PURE__*/jsx(StyledChildrenWrap, {
|
|
56
|
+
ref: carouselOnlyListRef,
|
|
57
|
+
onClick: handleOnClick,
|
|
58
|
+
onScroll: handleOnScroll,
|
|
59
|
+
children: children
|
|
60
|
+
}));
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export { Carousel };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { DSButtonV2 } from '@elliemae/ds-button';
|
|
3
|
+
import { TabTypes } from '../../utils/constants.js';
|
|
4
|
+
|
|
5
|
+
const StyledCarouselBtn = /*#__PURE__*/styled(DSButtonV2).withConfig({
|
|
6
|
+
componentId: "sc-prv5a7-0"
|
|
7
|
+
})(["margin:0;min-width:", ";width:", ";&:hover:not(:disabled){background-color:transparent;}background-color:transparent;border-radius:0px;"], _ref => {
|
|
8
|
+
let {
|
|
9
|
+
theme
|
|
10
|
+
} = _ref;
|
|
11
|
+
return theme.space.xs;
|
|
12
|
+
}, _ref2 => {
|
|
13
|
+
let {
|
|
14
|
+
theme
|
|
15
|
+
} = _ref2;
|
|
16
|
+
return theme.space.xs;
|
|
17
|
+
});
|
|
18
|
+
const StyledCarouselWrapper = /*#__PURE__*/styled.span.withConfig({
|
|
19
|
+
componentId: "sc-prv5a7-1"
|
|
20
|
+
})(["position:relative;width:100%;display:flex;"]);
|
|
21
|
+
const StyledChildrenWrap = /*#__PURE__*/styled.div.withConfig({
|
|
22
|
+
componentId: "sc-prv5a7-2"
|
|
23
|
+
})(["display:flex;flex-wrap:nowrap;flex:1;overflow-x:hidden;"]);
|
|
24
|
+
const StyledCarouselButtonWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
25
|
+
componentId: "sc-prv5a7-3"
|
|
26
|
+
})(["max-width:16px;position:absolute;z-index:200;", " width:16px;height:", ";padding-top:", ";background-color:white;", ";"], _ref3 => {
|
|
27
|
+
let {
|
|
28
|
+
right
|
|
29
|
+
} = _ref3;
|
|
30
|
+
return right ? 'right: 0;' : "left: 0;";
|
|
31
|
+
}, _ref4 => {
|
|
32
|
+
let {
|
|
33
|
+
tabType
|
|
34
|
+
} = _ref4;
|
|
35
|
+
return tabType === TabTypes.NORMAL ? '32px' : '22px';
|
|
36
|
+
}, _ref5 => {
|
|
37
|
+
let {
|
|
38
|
+
tabType
|
|
39
|
+
} = _ref5;
|
|
40
|
+
return tabType === TabTypes.NORMAL ? '5px' : '0px';
|
|
41
|
+
}, _ref6 => {
|
|
42
|
+
let {
|
|
43
|
+
theme,
|
|
44
|
+
tabType
|
|
45
|
+
} = _ref6;
|
|
46
|
+
return tabType === TabTypes.NORMAL ? "\n border-bottom: 1px solid ".concat(theme.colors.neutral[200], ";") : "";
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export { StyledCarouselBtn, StyledCarouselButtonWrapper, StyledCarouselWrapper, StyledChildrenWrap };
|