@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,67 @@
|
|
|
1
|
+
import _jsx from '@babel/runtime/helpers/esm/jsx';
|
|
2
|
+
import 'core-js/modules/esnext.async-iterator.map.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.map.js';
|
|
4
|
+
import React, { useContext, useCallback, useMemo } from 'react';
|
|
5
|
+
import SwipeableViews from 'react-swipeable-views';
|
|
6
|
+
import { getIdByIndex, getIndexById } from '../../utils/helpers.js';
|
|
7
|
+
import { StyledPanelContainer } from './styles.js';
|
|
8
|
+
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
9
|
+
import { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';
|
|
10
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
const TabsPanels = () => {
|
|
13
|
+
const {
|
|
14
|
+
actualActiveTab,
|
|
15
|
+
focusableTabsRef,
|
|
16
|
+
props: {
|
|
17
|
+
animated,
|
|
18
|
+
enableMouseEvents,
|
|
19
|
+
onlyRenderActiveTab,
|
|
20
|
+
children: tabs,
|
|
21
|
+
isDSMobile
|
|
22
|
+
}
|
|
23
|
+
} = useContext(DSTabsContext);
|
|
24
|
+
const {
|
|
25
|
+
handleOnTabChange,
|
|
26
|
+
handleOnMouseDown
|
|
27
|
+
} = useTabsCallbacks();
|
|
28
|
+
const handleOnChangeIndex = useCallback(index => {
|
|
29
|
+
handleOnTabChange(getIdByIndex(tabs, index));
|
|
30
|
+
if (focusableTabsRef.current) focusableTabsRef.current[index].click();
|
|
31
|
+
}, [focusableTabsRef, handleOnTabChange, tabs]);
|
|
32
|
+
const panels = useMemo(() => React.Children.map(tabs, tab => {
|
|
33
|
+
const {
|
|
34
|
+
tabId: panelId = '',
|
|
35
|
+
style,
|
|
36
|
+
children: content
|
|
37
|
+
} = tab.props;
|
|
38
|
+
const isActive = actualActiveTab === panelId;
|
|
39
|
+
const shouldRender = !onlyRenderActiveTab || isActive;
|
|
40
|
+
return shouldRender && /*#__PURE__*/_jsx(StyledPanelContainer, {
|
|
41
|
+
id: panelId,
|
|
42
|
+
"aria-labelledby": "".concat(panelId, "-label"),
|
|
43
|
+
"aria-hidden": !isActive,
|
|
44
|
+
"data-panel-id": panelId,
|
|
45
|
+
"data-testid": "ds-tabs-tab-panel",
|
|
46
|
+
hidden: !isActive,
|
|
47
|
+
onMouseDown: handleOnMouseDown,
|
|
48
|
+
role: "tabpanel",
|
|
49
|
+
style: style,
|
|
50
|
+
isDSMobile: isDSMobile
|
|
51
|
+
}, panelId, content);
|
|
52
|
+
}), [actualActiveTab, handleOnMouseDown, isDSMobile, onlyRenderActiveTab, tabs]);
|
|
53
|
+
|
|
54
|
+
if (animated) {
|
|
55
|
+
return /*#__PURE__*/_jsx(SwipeableViews, {
|
|
56
|
+
enableMouseEvents: enableMouseEvents,
|
|
57
|
+
index: getIndexById(tabs, actualActiveTab),
|
|
58
|
+
onChangeIndex: handleOnChangeIndex
|
|
59
|
+
}, void 0, panels);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return /*#__PURE__*/jsx(Fragment, {
|
|
63
|
+
children: panels
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { TabsPanels };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
|
|
3
|
+
const StyledPanelContainer = /*#__PURE__*/styled.div.withConfig({
|
|
4
|
+
componentId: "sc-oxw5jq-0"
|
|
5
|
+
})(["padding-top:8px;&:focus{outline:none;}", " ", ""], _ref => {
|
|
6
|
+
let {
|
|
7
|
+
hidden
|
|
8
|
+
} = _ref;
|
|
9
|
+
return hidden ? 'visibility: hidden;' : '';
|
|
10
|
+
}, _ref2 => {
|
|
11
|
+
let {
|
|
12
|
+
isDSMobile
|
|
13
|
+
} = _ref2;
|
|
14
|
+
return isDSMobile ? "padding-top: 0;" : "";
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { StyledPanelContainer };
|
package/esm/propTypes.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PropTypes } from 'react-desc';
|
|
2
|
+
import { TabTypesValuesAsArray } from './utils/constants.js';
|
|
3
|
+
|
|
4
|
+
const tabPropTypes = {
|
|
5
|
+
tabId: PropTypes.string.description('Unique Tab id.').defaultValue(''),
|
|
6
|
+
title: PropTypes.string.description('Tab title.').defaultValue(''),
|
|
7
|
+
required: PropTypes.bool.description('Show a required mark next to the title.').defaultValue(false),
|
|
8
|
+
disabled: PropTypes.bool.description('Disables Tab.').defaultValue(false)
|
|
9
|
+
};
|
|
10
|
+
const tabsPropTypes = {
|
|
11
|
+
animated: PropTypes.bool.description('Whether the Tab transition should animate or not.').defaultValue(true),
|
|
12
|
+
enableMouseEvents: PropTypes.bool.description('Enables Tab transition with mouse drag events.').defaultValue(false),
|
|
13
|
+
allowTextSelection: PropTypes.bool.description('Allows text selection when mouse drag events are active.').defaultValue(false),
|
|
14
|
+
onTabChange: PropTypes.func.description('Handler when a user clicks on a different Tab.').defaultValue('() => {}'),
|
|
15
|
+
type: PropTypes.oneOf(TabTypesValuesAsArray).description('Tab type.').defaultValue(TabTypesValuesAsArray[0]),
|
|
16
|
+
tabBarExtraContent: PropTypes.element.description('Extra content next to the Tab Bar.').defaultValue(undefined),
|
|
17
|
+
onlyRenderActiveTab: PropTypes.bool.description('Only renders the active Tab in the DOM.').defaultValue(false),
|
|
18
|
+
withCarousel: PropTypes.bool.description('Activate carousel behavior.').defaultValue(false),
|
|
19
|
+
activeTab: PropTypes.string.description('Passing a value makes DSTabs a controlled component.').defaultValue('First DSTab children.'),
|
|
20
|
+
children: PropTypes.node.description('Use DSTab component as children.').isRequired,
|
|
21
|
+
tabsListAriaLabel: PropTypes.string.description('Aria label for the list.').defaultValue('Tab list.'),
|
|
22
|
+
containerProps: PropTypes.object.description('Additional properties for the container.').defaultValue({}),
|
|
23
|
+
innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
|
|
24
|
+
current: PropTypes.any
|
|
25
|
+
})]).description('Ref to the container.').defaultValue(undefined)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { tabPropTypes, tabsPropTypes };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const TabTypes = {
|
|
2
|
+
NORMAL: 'normal',
|
|
3
|
+
NORMAL_SMALL: 'normal_small',
|
|
4
|
+
SUBTABS: 'subtabs'
|
|
5
|
+
};
|
|
6
|
+
const TabTypesValuesAsArray = Object.values(TabTypes);
|
|
7
|
+
const MOBILE_GRADIENT_WIDTH = 24;
|
|
8
|
+
const defaultIndicatorStyles = {
|
|
9
|
+
left: '0px',
|
|
10
|
+
width: '0px',
|
|
11
|
+
backgroundWithTransparentAndWhite: '',
|
|
12
|
+
backgroundWithTransparent: ''
|
|
13
|
+
};
|
|
14
|
+
const gradientOffsetsAccordingType = {
|
|
15
|
+
normal_small: 14,
|
|
16
|
+
normal: 16,
|
|
17
|
+
subtabs: 16,
|
|
18
|
+
fixedTabsHeaders: 0
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { MOBILE_GRADIENT_WIDTH, TabTypes, TabTypesValuesAsArray, defaultIndicatorStyles, gradientOffsetsAccordingType };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { MOBILE_GRADIENT_WIDTH } from './constants.js';
|
|
2
|
+
|
|
3
|
+
const isElementVisible = (tab, tabList) => {
|
|
4
|
+
const tabDimensions = tab.getBoundingClientRect();
|
|
5
|
+
const tabListDimensions = tabList.getBoundingClientRect();
|
|
6
|
+
return tabDimensions.left <= tabListDimensions.left ? tabListDimensions.left - tabDimensions.left <= tabDimensions.width : tabDimensions.right - tabListDimensions.right <= tabDimensions.width;
|
|
7
|
+
};
|
|
8
|
+
const isElementVisibleCarousel = function (tab, tabContainer) {
|
|
9
|
+
let firstOrLastItem = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
10
|
+
|
|
11
|
+
if (tab && tabContainer) {
|
|
12
|
+
const tabDimensions = tab.getBoundingClientRect();
|
|
13
|
+
const tabContainerDimensions = tabContainer.getBoundingClientRect();
|
|
14
|
+
const offset = firstOrLastItem ? 16 : 32;
|
|
15
|
+
const tabDimensionsLeft = Math.floor(tabDimensions.left - offset);
|
|
16
|
+
const tabDimensionsRight = Math.floor(tabDimensions.right + offset);
|
|
17
|
+
const tabContainerDimensionsLeft = Math.floor(tabContainerDimensions.left);
|
|
18
|
+
const tabContainerDimensionsRight = Math.floor(tabContainerDimensions.right);
|
|
19
|
+
return tabDimensionsLeft >= tabContainerDimensionsLeft && tabDimensionsRight <= tabContainerDimensionsRight;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
const getVisibleDimensions = (node, referenceNode) => {
|
|
25
|
+
const nodeDimensions = node.getBoundingClientRect();
|
|
26
|
+
const referenceNodeDimensions = referenceNode.getBoundingClientRect();
|
|
27
|
+
return {
|
|
28
|
+
width: Math.min(node.clientWidth, referenceNodeDimensions.left + referenceNode.clientWidth - nodeDimensions.left, node.clientWidth - (referenceNodeDimensions.left - nodeDimensions.left)),
|
|
29
|
+
height: Math.min(node.clientHeight, referenceNodeDimensions.top + referenceNode.clientHeight - nodeDimensions.top, node.clientHeight - (referenceNodeDimensions.top - nodeDimensions.top))
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const getIndexById = (children, activeId) => children && children.findIndex(item => item.props.tabId === activeId);
|
|
33
|
+
const getIdByIndex = (children, index) => children && children[index].props.tabId || '';
|
|
34
|
+
const shouldHaveLeftGradient = scrollLeft => Math.abs(scrollLeft) > MOBILE_GRADIENT_WIDTH;
|
|
35
|
+
const shouldHaveRightGradient = (scrollLeft, clientWidth, scrollWidth) => Math.abs(scrollLeft) <= scrollWidth - (clientWidth + MOBILE_GRADIENT_WIDTH);
|
|
36
|
+
|
|
37
|
+
export { getIdByIndex, getIndexById, getVisibleDimensions, isElementVisible, isElementVisibleCarousel, shouldHaveLeftGradient, shouldHaveRightGradient };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useContext, useCallback } from 'react';
|
|
2
|
+
import { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable max-statements */
|
|
5
|
+
const useKeyboardNavigation = () => {
|
|
6
|
+
const {
|
|
7
|
+
focusableTabsRef
|
|
8
|
+
} = useContext(DSTabsContext);
|
|
9
|
+
const {
|
|
10
|
+
firstSubtabInternalRef,
|
|
11
|
+
lastTabInternalRef
|
|
12
|
+
} = useContext(DSTabsCrossRefContext);
|
|
13
|
+
const handleOnKeyDown = useCallback(e => {
|
|
14
|
+
if (e.key === 'ArrowRight' && focusableTabsRef.current) {
|
|
15
|
+
var _focusableTabsRef$cur, _focusableTabsRef$cur2;
|
|
16
|
+
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
e.stopPropagation();
|
|
19
|
+
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];
|
|
20
|
+
if (nextTab) nextTab.focus();
|
|
21
|
+
if (!nextTab) return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (e.key === 'ArrowLeft' && focusableTabsRef.current) {
|
|
25
|
+
var _focusableTabsRef$cur3, _focusableTabsRef$cur4;
|
|
26
|
+
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
e.stopPropagation();
|
|
29
|
+
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];
|
|
30
|
+
if (prevTab) prevTab.focus();
|
|
31
|
+
if (!prevTab) return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (e.key === 'ArrowDown') {
|
|
35
|
+
var _firstSubtabInternalR;
|
|
36
|
+
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
e.stopPropagation();
|
|
39
|
+
const canFocusCrossTabs = (firstSubtabInternalRef === null || firstSubtabInternalRef === void 0 ? void 0 : firstSubtabInternalRef.current) && (lastTabInternalRef === null || lastTabInternalRef === void 0 ? void 0 : lastTabInternalRef.current);
|
|
40
|
+
if (canFocusCrossTabs) (_firstSubtabInternalR = firstSubtabInternalRef.current) === null || _firstSubtabInternalR === void 0 ? void 0 : _firstSubtabInternalR.focus();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (e.key === 'ArrowUp') {
|
|
44
|
+
var _lastTabInternalRef$c;
|
|
45
|
+
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
const canFocusCrossTabs = (firstSubtabInternalRef === null || firstSubtabInternalRef === void 0 ? void 0 : firstSubtabInternalRef.current) && (lastTabInternalRef === null || lastTabInternalRef === void 0 ? void 0 : lastTabInternalRef.current);
|
|
49
|
+
if (canFocusCrossTabs) (_lastTabInternalRef$c = lastTabInternalRef.current) === null || _lastTabInternalRef$c === void 0 ? void 0 : _lastTabInternalRef$c.focus();
|
|
50
|
+
}
|
|
51
|
+
}, [firstSubtabInternalRef, lastTabInternalRef, focusableTabsRef]);
|
|
52
|
+
return {
|
|
53
|
+
handleOnKeyDown
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export { useKeyboardNavigation };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useContext, useCallback } from 'react';
|
|
2
|
+
import { DSTabsContext } from '../../DSTabsCTX.js';
|
|
3
|
+
|
|
4
|
+
const useTabsCallbacks = () => {
|
|
5
|
+
const {
|
|
6
|
+
setInternalActiveTab,
|
|
7
|
+
tabsListRef,
|
|
8
|
+
props: {
|
|
9
|
+
onTabChange,
|
|
10
|
+
isDSMobile,
|
|
11
|
+
allowTextSelection,
|
|
12
|
+
fixedTabsHeaders
|
|
13
|
+
}
|
|
14
|
+
} = 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
|
+
const handleOnTabChange = useCallback((tabId, e) => {
|
|
38
|
+
setInternalActiveTab(tabId);
|
|
39
|
+
onTabChange(tabId, e);
|
|
40
|
+
|
|
41
|
+
if (isDSMobile && !fixedTabsHeaders && e) {
|
|
42
|
+
centerTabWhenTabChangeMobile(e);
|
|
43
|
+
}
|
|
44
|
+
}, [centerTabWhenTabChangeMobile, fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab]);
|
|
45
|
+
const handleOnMouseDown = useCallback(e => {
|
|
46
|
+
const role = e.target.getAttribute('role');
|
|
47
|
+
if (role !== 'tabpanel' && allowTextSelection) e.stopPropagation();
|
|
48
|
+
}, [allowTextSelection]);
|
|
49
|
+
return {
|
|
50
|
+
handleOnTabChange,
|
|
51
|
+
handleOnMouseDown
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { useTabsCallbacks };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-tabs",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Tabs",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -11,45 +11,101 @@
|
|
|
11
11
|
"import": "./esm/index.js",
|
|
12
12
|
"require": "./cjs/index.js"
|
|
13
13
|
},
|
|
14
|
-
"./
|
|
15
|
-
"import": "./esm/
|
|
16
|
-
"require": "./cjs/
|
|
14
|
+
"./utils/hooks/useTabsCallbacks": {
|
|
15
|
+
"import": "./esm/utils/hooks/useTabsCallbacks.js",
|
|
16
|
+
"require": "./cjs/utils/hooks/useTabsCallbacks.js"
|
|
17
17
|
},
|
|
18
|
-
"./
|
|
19
|
-
"import": "./esm/
|
|
20
|
-
"require": "./cjs/
|
|
18
|
+
"./utils/hooks/useKeyboardNavigation": {
|
|
19
|
+
"import": "./esm/utils/hooks/useKeyboardNavigation.js",
|
|
20
|
+
"require": "./cjs/utils/hooks/useKeyboardNavigation.js"
|
|
21
21
|
},
|
|
22
|
-
"./
|
|
23
|
-
"import": "./esm/
|
|
24
|
-
"require": "./cjs/
|
|
22
|
+
"./utils/helpers": {
|
|
23
|
+
"import": "./esm/utils/helpers.js",
|
|
24
|
+
"require": "./cjs/utils/helpers.js"
|
|
25
25
|
},
|
|
26
|
-
"./
|
|
27
|
-
"import": "./esm/
|
|
28
|
-
"require": "./cjs/
|
|
26
|
+
"./utils/constants": {
|
|
27
|
+
"import": "./esm/utils/constants.js",
|
|
28
|
+
"require": "./cjs/utils/constants.js"
|
|
29
29
|
},
|
|
30
|
-
"./
|
|
31
|
-
"import": "./esm/
|
|
32
|
-
"require": "./cjs/
|
|
30
|
+
"./propTypes": {
|
|
31
|
+
"import": "./esm/propTypes.js",
|
|
32
|
+
"require": "./cjs/propTypes.js"
|
|
33
33
|
},
|
|
34
|
-
"./
|
|
35
|
-
"import": "./esm/
|
|
36
|
-
"require": "./cjs/
|
|
34
|
+
"./parts/tabsPanel/TabsPanels": {
|
|
35
|
+
"import": "./esm/parts/tabsPanel/TabsPanels.js",
|
|
36
|
+
"require": "./cjs/parts/tabsPanel/TabsPanels.js"
|
|
37
37
|
},
|
|
38
|
-
"./
|
|
39
|
-
"import": "./esm/
|
|
40
|
-
"require": "./cjs/
|
|
38
|
+
"./parts/tabsPanel/styles": {
|
|
39
|
+
"import": "./esm/parts/tabsPanel/styles.js",
|
|
40
|
+
"require": "./cjs/parts/tabsPanel/styles.js"
|
|
41
|
+
},
|
|
42
|
+
"./parts/tabsContent/TabsContent": {
|
|
43
|
+
"import": "./esm/parts/tabsContent/TabsContent.js",
|
|
44
|
+
"require": "./cjs/parts/tabsContent/TabsContent.js"
|
|
45
|
+
},
|
|
46
|
+
"./parts/tabsContent/styles": {
|
|
47
|
+
"import": "./esm/parts/tabsContent/styles.js",
|
|
48
|
+
"require": "./cjs/parts/tabsContent/styles.js"
|
|
49
|
+
},
|
|
50
|
+
"./parts/tabBar/useTabBar": {
|
|
51
|
+
"import": "./esm/parts/tabBar/useTabBar.js",
|
|
52
|
+
"require": "./cjs/parts/tabBar/useTabBar.js"
|
|
53
|
+
},
|
|
54
|
+
"./parts/tabBar/TabBar": {
|
|
55
|
+
"import": "./esm/parts/tabBar/TabBar.js",
|
|
56
|
+
"require": "./cjs/parts/tabBar/TabBar.js"
|
|
57
|
+
},
|
|
58
|
+
"./parts/tabBar/styles": {
|
|
59
|
+
"import": "./esm/parts/tabBar/styles.js",
|
|
60
|
+
"require": "./cjs/parts/tabBar/styles.js"
|
|
61
|
+
},
|
|
62
|
+
"./parts/carousel/useCarouselCallbacks": {
|
|
63
|
+
"import": "./esm/parts/carousel/useCarouselCallbacks.js",
|
|
64
|
+
"require": "./cjs/parts/carousel/useCarouselCallbacks.js"
|
|
65
|
+
},
|
|
66
|
+
"./parts/carousel/useCarousel": {
|
|
67
|
+
"import": "./esm/parts/carousel/useCarousel.js",
|
|
68
|
+
"require": "./cjs/parts/carousel/useCarousel.js"
|
|
69
|
+
},
|
|
70
|
+
"./parts/carousel/styles": {
|
|
71
|
+
"import": "./esm/parts/carousel/styles.js",
|
|
72
|
+
"require": "./cjs/parts/carousel/styles.js"
|
|
73
|
+
},
|
|
74
|
+
"./parts/carousel/Carousel": {
|
|
75
|
+
"import": "./esm/parts/carousel/Carousel.js",
|
|
76
|
+
"require": "./cjs/parts/carousel/Carousel.js"
|
|
77
|
+
},
|
|
78
|
+
"./exportsRelated/DSTab": {
|
|
79
|
+
"import": "./esm/exportsRelated/DSTab.js",
|
|
80
|
+
"require": "./cjs/exportsRelated/DSTab.js"
|
|
81
|
+
},
|
|
82
|
+
"./DSTabsTypes": {
|
|
83
|
+
"import": "./esm/DSTabsTypes.js",
|
|
84
|
+
"require": "./cjs/DSTabsTypes.js"
|
|
85
|
+
},
|
|
86
|
+
"./DSTabsDatatestid": {
|
|
87
|
+
"import": "./esm/DSTabsDatatestid.js",
|
|
88
|
+
"require": "./cjs/DSTabsDatatestid.js"
|
|
89
|
+
},
|
|
90
|
+
"./DSTabsCTX": {
|
|
91
|
+
"import": "./esm/DSTabsCTX.js",
|
|
92
|
+
"require": "./cjs/DSTabsCTX.js"
|
|
41
93
|
},
|
|
42
94
|
"./DSTabs": {
|
|
43
95
|
"import": "./esm/DSTabs.js",
|
|
44
96
|
"require": "./cjs/DSTabs.js"
|
|
45
97
|
},
|
|
46
|
-
"./
|
|
47
|
-
"import": "./esm/
|
|
48
|
-
"require": "./cjs/
|
|
98
|
+
"./defaultProps": {
|
|
99
|
+
"import": "./esm/defaultProps.js",
|
|
100
|
+
"require": "./cjs/defaultProps.js"
|
|
101
|
+
},
|
|
102
|
+
"./config/useTabs": {
|
|
103
|
+
"import": "./esm/config/useTabs.js",
|
|
104
|
+
"require": "./cjs/config/useTabs.js"
|
|
49
105
|
},
|
|
50
|
-
"./
|
|
51
|
-
"import": "./esm/
|
|
52
|
-
"require": "./cjs/
|
|
106
|
+
"./config/useCrossRef": {
|
|
107
|
+
"import": "./esm/config/useCrossRef.js",
|
|
108
|
+
"require": "./cjs/config/useCrossRef.js"
|
|
53
109
|
}
|
|
54
110
|
},
|
|
55
111
|
"sideEffects": [
|
|
@@ -72,20 +128,27 @@
|
|
|
72
128
|
"build": "node ../../scripts/build/build.js"
|
|
73
129
|
},
|
|
74
130
|
"dependencies": {
|
|
75
|
-
"@elliemae/ds-button": "2.0.0-alpha.
|
|
76
|
-
"@elliemae/ds-
|
|
77
|
-
"@elliemae/ds-
|
|
78
|
-
"@elliemae/ds-
|
|
79
|
-
"
|
|
131
|
+
"@elliemae/ds-button": "2.0.0-alpha.13",
|
|
132
|
+
"@elliemae/ds-icon": "2.0.0-alpha.13",
|
|
133
|
+
"@elliemae/ds-icons": "2.0.0-alpha.13",
|
|
134
|
+
"@elliemae/ds-props-helpers": "2.0.0-alpha.13",
|
|
135
|
+
"@elliemae/ds-system": "2.0.0-alpha.13",
|
|
136
|
+
"@react-hook/resize-observer": "~1.2.5",
|
|
80
137
|
"prop-types": "~15.7.2",
|
|
81
|
-
"react-desc": "
|
|
82
|
-
"react-swipeable-views": "~0.13.9"
|
|
83
|
-
|
|
138
|
+
"react-desc": "~4.1.3",
|
|
139
|
+
"react-swipeable-views": "~0.13.9"
|
|
140
|
+
},
|
|
141
|
+
"devDependencies": {
|
|
142
|
+
"@testing-library/jest-dom": "~5.15.0",
|
|
143
|
+
"@testing-library/react": "~12.1.2",
|
|
144
|
+
"@testing-library/user-event": "~13.5.0",
|
|
145
|
+
"styled-components": "~5.3.3"
|
|
84
146
|
},
|
|
85
147
|
"peerDependencies": {
|
|
86
148
|
"lodash": "^4.17.21",
|
|
87
149
|
"react": "^17.0.2",
|
|
88
|
-
"react-dom": "^17.0.2"
|
|
150
|
+
"react-dom": "^17.0.2",
|
|
151
|
+
"styled-components": "^5.3.3"
|
|
89
152
|
},
|
|
90
153
|
"publishConfig": {
|
|
91
154
|
"access": "public",
|
package/types/DSTabs.d.ts
CHANGED
|
@@ -1,64 +1,14 @@
|
|
|
1
|
-
/// <reference
|
|
1
|
+
/// <reference path="../../../../shared/typings/react-desc.d.ts" />
|
|
2
|
+
import type { WeakValidationMap } from 'react';
|
|
3
|
+
import type { DSTabsPropsT } from './DSTabsTypes';
|
|
2
4
|
declare const DSTabs: {
|
|
3
|
-
(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
tabsListAriaLabel?: string | undefined;
|
|
11
|
-
type?: string | undefined;
|
|
12
|
-
tabBarExtraContent?: undefined;
|
|
13
|
-
children: any;
|
|
14
|
-
onlyRenderActiveTab?: boolean | undefined;
|
|
15
|
-
activeTab: any;
|
|
16
|
-
withCarousel?: boolean | undefined;
|
|
17
|
-
firstSubtabRef: any;
|
|
18
|
-
lastTabRef: any;
|
|
19
|
-
flexibleTabsHeaders: any;
|
|
20
|
-
fixedTabsHeaders: any;
|
|
21
|
-
isDSMobile?: boolean | undefined;
|
|
22
|
-
}): JSX.Element;
|
|
23
|
-
propTypes: {
|
|
24
|
-
/** Whether the tab transition should animate or not */
|
|
25
|
-
animated: any;
|
|
26
|
-
/** Enables tab transition with mouse drag events */
|
|
27
|
-
enableMouseEvents: any;
|
|
28
|
-
/** Allow text selection when mouse drag events are active */
|
|
29
|
-
allowTextSelection: any;
|
|
30
|
-
/** Handler when a user clicks on a different tab */
|
|
31
|
-
onTabChange: any;
|
|
32
|
-
/** Tab type */
|
|
33
|
-
type: any;
|
|
34
|
-
/** Extra content next to the tabs pills */
|
|
35
|
-
tabBarExtraContent: any;
|
|
36
|
-
/** Only renders the active tab in the DOM */
|
|
37
|
-
onlyRenderActiveTab: any;
|
|
38
|
-
/** Mobile only flexible tabs mode */
|
|
39
|
-
flexibleTabsHeaders: any;
|
|
40
|
-
/** Mobile only fixed tabs mode */
|
|
41
|
-
fixedTabsHeaders: any;
|
|
42
|
-
/** Whether or not it's a ds-tab from DSMobile tabs */
|
|
43
|
-
isDSMobile: any;
|
|
44
|
-
/** Activate carousel behavior */
|
|
45
|
-
withCarousel: any;
|
|
46
|
-
/** The active tabId */
|
|
47
|
-
activeTab: any;
|
|
48
|
-
/** tabs children */
|
|
49
|
-
children: any;
|
|
50
|
-
/** Aria label for the list */
|
|
51
|
-
tabsListAriaLabel: any;
|
|
52
|
-
/** Additional properties for the container */
|
|
53
|
-
containerProps: any;
|
|
54
|
-
/** REF */
|
|
55
|
-
innerRef: any;
|
|
56
|
-
/** internal ref to handle keyboard a11y behavior */
|
|
57
|
-
firstSubtabRef: any;
|
|
58
|
-
/** internal ref to handle keyboard a11y behavior */
|
|
59
|
-
lastTabRef: any;
|
|
60
|
-
};
|
|
5
|
+
(props: DSTabsPropsT): JSX.Element;
|
|
6
|
+
propTypes: WeakValidationMap<unknown>;
|
|
7
|
+
};
|
|
8
|
+
declare const DSTabsWithSchema: {
|
|
9
|
+
(props?: DSTabsPropsT | undefined): JSX.Element;
|
|
10
|
+
propTypes: unknown;
|
|
11
|
+
toTypescript: () => import("react-desc").TypescriptSchema;
|
|
61
12
|
};
|
|
62
|
-
declare const DSTabsWithSchema: any;
|
|
63
13
|
export { DSTabs, DSTabsWithSchema };
|
|
64
14
|
export default DSTabs;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { DSTabsUseCrossRefContextT, DSTabsUseTabsContextT } from './DSTabsTypes';
|
|
3
|
+
export declare const DSTabsContext: import("react").Context<DSTabsUseTabsContextT>;
|
|
4
|
+
export declare const DSTabsCrossRefContext: import("react").Context<DSTabsUseCrossRefContextT>;
|