@elliemae/ds-tabs 3.55.0-next.11 → 3.55.0-next.12
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.
|
@@ -33,14 +33,13 @@ __export(TabsPanels_exports, {
|
|
|
33
33
|
module.exports = __toCommonJS(TabsPanels_exports);
|
|
34
34
|
var React = __toESM(require("react"));
|
|
35
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
-
var import_react = require("react");
|
|
37
|
-
var import_react2 = __toESM(require("react"));
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
38
37
|
var import_ds_swipe_card = require("@elliemae/ds-swipe-card");
|
|
39
38
|
var import_styles = require("./styles.js");
|
|
40
39
|
var import_DSTabsCTX = require("../../DSTabsCTX.js");
|
|
41
40
|
const CardRender = (props) => {
|
|
42
41
|
const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;
|
|
43
|
-
return /* @__PURE__ */ (0,
|
|
42
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
44
43
|
import_styles.StyledPanelContainer,
|
|
45
44
|
{
|
|
46
45
|
id: tabId,
|
|
@@ -50,9 +49,8 @@ const CardRender = (props) => {
|
|
|
50
49
|
hide,
|
|
51
50
|
style,
|
|
52
51
|
role,
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
content
|
|
52
|
+
children: content
|
|
53
|
+
}
|
|
56
54
|
);
|
|
57
55
|
};
|
|
58
56
|
const TabsPanels = () => {
|
|
@@ -61,8 +59,8 @@ const TabsPanels = () => {
|
|
|
61
59
|
focusableTabsRef,
|
|
62
60
|
props: { onlyRenderActiveTab, children: tabs, isDSMobile, tabPanelsProps, animated },
|
|
63
61
|
globalClickHandler
|
|
64
|
-
} = (0,
|
|
65
|
-
const handleOnChangeIndex = (0,
|
|
62
|
+
} = (0, import_react.useContext)(import_DSTabsCTX.DSTabsContext);
|
|
63
|
+
const handleOnChangeIndex = (0, import_react.useCallback)(
|
|
66
64
|
(index, indexLatest) => {
|
|
67
65
|
if (!focusableTabsRef.current) return;
|
|
68
66
|
const offset = index - indexLatest;
|
|
@@ -81,11 +79,13 @@ const TabsPanels = () => {
|
|
|
81
79
|
},
|
|
82
80
|
[actualActiveTab, focusableTabsRef, globalClickHandler]
|
|
83
81
|
);
|
|
84
|
-
const panels = (0,
|
|
85
|
-
const mapResult =
|
|
82
|
+
const panels = (0, import_react.useMemo)(() => {
|
|
83
|
+
const mapResult = import_react.default.Children.map(tabs, (tab, index) => {
|
|
86
84
|
const { tabId: panelId = "", style, children: content, disabled, applyAriaDisabled } = tab.props;
|
|
87
85
|
const isActive = actualActiveTab === panelId;
|
|
88
86
|
const shouldRender = !onlyRenderActiveTab || isActive;
|
|
87
|
+
const getOwnerProps = () => tab.props;
|
|
88
|
+
const getOwnerPropsArguments = () => ({ panelId });
|
|
89
89
|
const baseDescriptor = {
|
|
90
90
|
index,
|
|
91
91
|
tabId: panelId,
|
|
@@ -102,7 +102,9 @@ const TabsPanels = () => {
|
|
|
102
102
|
"data-testid": "ds-tabs-tab-panel",
|
|
103
103
|
hide: !isActive,
|
|
104
104
|
onClick: (event) => globalClickHandler({ event, target: "panel" }),
|
|
105
|
-
role: "tabpanel"
|
|
105
|
+
role: "tabpanel",
|
|
106
|
+
getOwnerProps,
|
|
107
|
+
getOwnerPropsArguments
|
|
106
108
|
};
|
|
107
109
|
return baseDescriptor;
|
|
108
110
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/parts/tabsPanel/TabsPanels.tsx", "../../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable arrow-body-style */\n/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\nimport React, { useMemo, useContext, useCallback } from 'react';\nimport { DSSwipeCard } from '@elliemae/ds-swipe-card';\nimport type { DSSwipeCardT } from '@elliemae/ds-swipe-card/src/react-desc-prop-types.js';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n/**\n * Describes the data needed to render a single Tab panel slide.\n */\ninterface PanelDescriptor extends Record<string, unknown> {\n index: number;\n tabId: string;\n isActive: boolean;\n isDSMobile: boolean;\n content: React.ReactNode;\n style: React.CSSProperties;\n tabPanelsProps?: GlobalAttributesT<HTMLDivElement>;\n 'aria-hidden': boolean;\n 'data-panel-id': string;\n 'data-testid': string;\n hide: boolean;\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void;\n role: 'tabpanel';\n}\n\n/**\n * Responsible for rendering a single slide using the provided panel descriptor.\n * Receives a `dsIndex` prop from DSSwipeCard which indicates the slide position.\n */\nconst CardRender: React.ComponentType<DSSwipeCardT.CardRenderProps<PanelDescriptor>> = (props) => {\n const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;\n // We pass through all attributes, including accessibility and dataset attributes.\n return (\n <StyledPanelContainer\n id={tabId}\n {...tabPanelsProps}\n {...rest}\n // Styled component specific props\n isDSMobile={isDSMobile}\n hide={hide}\n style={style}\n role={role}\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["/* eslint-disable arrow-body-style */\n/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\nimport React, { useMemo, useContext, useCallback } from 'react';\nimport { DSSwipeCard } from '@elliemae/ds-swipe-card';\nimport type { DSSwipeCardT } from '@elliemae/ds-swipe-card/src/react-desc-prop-types.js';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n/**\n * Describes the data needed to render a single Tab panel slide.\n */\ninterface PanelDescriptor extends Record<string, unknown> {\n index: number;\n tabId: string;\n isActive: boolean;\n isDSMobile: boolean;\n content: React.ReactNode;\n style: React.CSSProperties;\n tabPanelsProps?: GlobalAttributesT<HTMLDivElement>;\n 'aria-hidden': boolean;\n 'data-panel-id': string;\n 'data-testid': string;\n hide: boolean;\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void;\n role: 'tabpanel';\n}\n\n/**\n * Responsible for rendering a single slide using the provided panel descriptor.\n * Receives a `dsIndex` prop from DSSwipeCard which indicates the slide position.\n */\nconst CardRender: React.ComponentType<DSSwipeCardT.CardRenderProps<PanelDescriptor>> = (props) => {\n const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;\n // We pass through all attributes, including accessibility and dataset attributes.\n return (\n <StyledPanelContainer\n id={tabId}\n {...tabPanelsProps}\n {...rest}\n // Styled component specific props\n isDSMobile={isDSMobile}\n hide={hide}\n style={style}\n role={role}\n >\n {content}\n </StyledPanelContainer>\n );\n};\n\nexport const TabsPanels = (): JSX.Element => {\n const {\n actualActiveTab,\n focusableTabsRef,\n props: { onlyRenderActiveTab, children: tabs, isDSMobile, tabPanelsProps, animated },\n globalClickHandler,\n } = useContext(DSTabsContext);\n\n /** [PUI-15772] - Tabs Pre Refactor\n * Handler for swipe gestures and tab index changes. It:\n * 1. Calculates the offset between current and new tab index\n * 2. Finds the new focusable tab based on the offset\n * 3. Updates the active tab and forces a click event\n * 4. May cause unnecessary rerenders due to forced click events\n */\n const handleOnChangeIndex = useCallback(\n (index: number, indexLatest: number) => {\n if (!focusableTabsRef.current) return;\n\n const offset = index - indexLatest;\n\n if (focusableTabsRef.current) {\n const currentIndexFocusable = focusableTabsRef.current?.findIndex((el) => el.dataset.tabId === actualActiveTab);\n\n const newFocusableIndex = currentIndexFocusable >= 0 ? currentIndexFocusable + offset : -1;\n\n if (\n newFocusableIndex < 0 ||\n newFocusableIndex > focusableTabsRef.current?.length ||\n !focusableTabsRef.current?.[newFocusableIndex]\n )\n return;\n globalClickHandler({\n event: { type: 'click' } as React.MouseEvent<HTMLDivElement>,\n target: 'swipeableViews',\n tabId: focusableTabsRef.current[newFocusableIndex].dataset.tabId,\n });\n\n // swiping does not trigger centerTab function inside handleOnTabChange because there is no event\n // by clicking we are manually forcing to center the tab\n\n focusableTabsRef.current[newFocusableIndex].click();\n }\n },\n [actualActiveTab, focusableTabsRef, globalClickHandler],\n );\n\n const panels: PanelDescriptor[] = useMemo(() => {\n // this component is based on React.children, swipeable views want an index in the array, not a tabId\n // two bad patterns relying on each others results in:\n // - because of react.children,\n // to guarantee predictability in finding the index based on tabId we should never return \"null\" which is not part of React.Children.toArray\n //\n // when not using swipeable views, we don't need to find the index based on tabId\n // so even if we return null the variable\n // indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull\n // (which will be calculating the wrong index)\n // will have no impact on the rendering\n // https://react.dev/reference/react/Children#children-toarray-caveats\n // Caveats\n // Empty nodes (null, undefined, and Booleans) will be omitted in the returned array.\n //\n // So, long story short,\n // 1 - do not remove next line, keep the <div /> instead of null when \"animated\"\n // 2 - NEVER EVER BUILD API BASED ON REACT.CHILDREN (if you are writing code post 2022 and you are not working on a legacy codebase)\n // To preserve indices for swipe behavior, we return a fully-typed placeholder panel\n // instead of null when a panel should not be rendered. This keeps array length stable.\n const mapResult = React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>, index: number) => {\n const { tabId: panelId = '', style, children: content, disabled, applyAriaDisabled } = tab.props;\n const isActive = actualActiveTab === panelId;\n const shouldRender = !onlyRenderActiveTab || isActive;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ panelId });\n\n const baseDescriptor: PanelDescriptor = {\n index,\n tabId: panelId,\n isActive: Boolean(isActive),\n isDSMobile: Boolean(isDSMobile),\n content: shouldRender && !disabled ? content : null,\n style: {\n ...(tabPanelsProps?.style || {}),\n ...(style || {}),\n } as React.CSSProperties,\n tabPanelsProps,\n 'aria-hidden': !(isActive && !applyAriaDisabled),\n 'data-panel-id': panelId,\n 'data-testid': 'ds-tabs-tab-panel',\n hide: !isActive,\n onClick: (event: React.MouseEvent<HTMLDivElement>) => globalClickHandler({ event, target: 'panel' }),\n role: 'tabpanel',\n getOwnerProps,\n getOwnerPropsArguments,\n };\n\n return baseDescriptor;\n });\n\n // Children.map can return null if there are no children; ensure an array is returned\n return mapResult || [];\n }, [tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, globalClickHandler, isDSMobile]);\n\n // Safely compute the active slide index. Default to 0 when none found.\n const activeSlide = (() => {\n const idx = panels.findIndex((panel) => panel.isActive);\n return idx >= 0 ? idx : 0;\n })();\n\n return (\n <DSSwipeCard<PanelDescriptor>\n activeSlide={activeSlide}\n onSwipe={(i) => handleOnChangeIndex(i, activeSlide)}\n enableTouch\n enableAnimation={animated}\n CardRender={CardRender}\n slidesProps={panels}\n />\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React"]
|
|
7
7
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { createElement } from "react";
|
|
4
3
|
import React2, { useMemo, useContext, useCallback } from "react";
|
|
5
4
|
import { DSSwipeCard } from "@elliemae/ds-swipe-card";
|
|
6
5
|
import { StyledPanelContainer } from "./styles.js";
|
|
7
6
|
import { DSTabsContext } from "../../DSTabsCTX.js";
|
|
8
7
|
const CardRender = (props) => {
|
|
9
8
|
const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;
|
|
10
|
-
return /* @__PURE__ */
|
|
9
|
+
return /* @__PURE__ */ jsx(
|
|
11
10
|
StyledPanelContainer,
|
|
12
11
|
{
|
|
13
12
|
id: tabId,
|
|
@@ -17,9 +16,8 @@ const CardRender = (props) => {
|
|
|
17
16
|
hide,
|
|
18
17
|
style,
|
|
19
18
|
role,
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
content
|
|
19
|
+
children: content
|
|
20
|
+
}
|
|
23
21
|
);
|
|
24
22
|
};
|
|
25
23
|
const TabsPanels = () => {
|
|
@@ -53,6 +51,8 @@ const TabsPanels = () => {
|
|
|
53
51
|
const { tabId: panelId = "", style, children: content, disabled, applyAriaDisabled } = tab.props;
|
|
54
52
|
const isActive = actualActiveTab === panelId;
|
|
55
53
|
const shouldRender = !onlyRenderActiveTab || isActive;
|
|
54
|
+
const getOwnerProps = () => tab.props;
|
|
55
|
+
const getOwnerPropsArguments = () => ({ panelId });
|
|
56
56
|
const baseDescriptor = {
|
|
57
57
|
index,
|
|
58
58
|
tabId: panelId,
|
|
@@ -69,7 +69,9 @@ const TabsPanels = () => {
|
|
|
69
69
|
"data-testid": "ds-tabs-tab-panel",
|
|
70
70
|
hide: !isActive,
|
|
71
71
|
onClick: (event) => globalClickHandler({ event, target: "panel" }),
|
|
72
|
-
role: "tabpanel"
|
|
72
|
+
role: "tabpanel",
|
|
73
|
+
getOwnerProps,
|
|
74
|
+
getOwnerPropsArguments
|
|
73
75
|
};
|
|
74
76
|
return baseDescriptor;
|
|
75
77
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/tabsPanel/TabsPanels.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable arrow-body-style */\n/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\nimport React, { useMemo, useContext, useCallback } from 'react';\nimport { DSSwipeCard } from '@elliemae/ds-swipe-card';\nimport type { DSSwipeCardT } from '@elliemae/ds-swipe-card/src/react-desc-prop-types.js';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n/**\n * Describes the data needed to render a single Tab panel slide.\n */\ninterface PanelDescriptor extends Record<string, unknown> {\n index: number;\n tabId: string;\n isActive: boolean;\n isDSMobile: boolean;\n content: React.ReactNode;\n style: React.CSSProperties;\n tabPanelsProps?: GlobalAttributesT<HTMLDivElement>;\n 'aria-hidden': boolean;\n 'data-panel-id': string;\n 'data-testid': string;\n hide: boolean;\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void;\n role: 'tabpanel';\n}\n\n/**\n * Responsible for rendering a single slide using the provided panel descriptor.\n * Receives a `dsIndex` prop from DSSwipeCard which indicates the slide position.\n */\nconst CardRender: React.ComponentType<DSSwipeCardT.CardRenderProps<PanelDescriptor>> = (props) => {\n const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;\n // We pass through all attributes, including accessibility and dataset attributes.\n return (\n <StyledPanelContainer\n id={tabId}\n {...tabPanelsProps}\n {...rest}\n // Styled component specific props\n isDSMobile={isDSMobile}\n hide={hide}\n style={style}\n role={role}\n
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable arrow-body-style */\n/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\nimport React, { useMemo, useContext, useCallback } from 'react';\nimport { DSSwipeCard } from '@elliemae/ds-swipe-card';\nimport type { DSSwipeCardT } from '@elliemae/ds-swipe-card/src/react-desc-prop-types.js';\nimport type { GlobalAttributesT } from '@elliemae/ds-props-helpers';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n/**\n * Describes the data needed to render a single Tab panel slide.\n */\ninterface PanelDescriptor extends Record<string, unknown> {\n index: number;\n tabId: string;\n isActive: boolean;\n isDSMobile: boolean;\n content: React.ReactNode;\n style: React.CSSProperties;\n tabPanelsProps?: GlobalAttributesT<HTMLDivElement>;\n 'aria-hidden': boolean;\n 'data-panel-id': string;\n 'data-testid': string;\n hide: boolean;\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void;\n role: 'tabpanel';\n}\n\n/**\n * Responsible for rendering a single slide using the provided panel descriptor.\n * Receives a `dsIndex` prop from DSSwipeCard which indicates the slide position.\n */\nconst CardRender: React.ComponentType<DSSwipeCardT.CardRenderProps<PanelDescriptor>> = (props) => {\n const { content, tabPanelsProps, isDSMobile, hide, style, role, tabId, renderKey, ...rest } = props;\n // We pass through all attributes, including accessibility and dataset attributes.\n return (\n <StyledPanelContainer\n id={tabId}\n {...tabPanelsProps}\n {...rest}\n // Styled component specific props\n isDSMobile={isDSMobile}\n hide={hide}\n style={style}\n role={role}\n >\n {content}\n </StyledPanelContainer>\n );\n};\n\nexport const TabsPanels = (): JSX.Element => {\n const {\n actualActiveTab,\n focusableTabsRef,\n props: { onlyRenderActiveTab, children: tabs, isDSMobile, tabPanelsProps, animated },\n globalClickHandler,\n } = useContext(DSTabsContext);\n\n /** [PUI-15772] - Tabs Pre Refactor\n * Handler for swipe gestures and tab index changes. It:\n * 1. Calculates the offset between current and new tab index\n * 2. Finds the new focusable tab based on the offset\n * 3. Updates the active tab and forces a click event\n * 4. May cause unnecessary rerenders due to forced click events\n */\n const handleOnChangeIndex = useCallback(\n (index: number, indexLatest: number) => {\n if (!focusableTabsRef.current) return;\n\n const offset = index - indexLatest;\n\n if (focusableTabsRef.current) {\n const currentIndexFocusable = focusableTabsRef.current?.findIndex((el) => el.dataset.tabId === actualActiveTab);\n\n const newFocusableIndex = currentIndexFocusable >= 0 ? currentIndexFocusable + offset : -1;\n\n if (\n newFocusableIndex < 0 ||\n newFocusableIndex > focusableTabsRef.current?.length ||\n !focusableTabsRef.current?.[newFocusableIndex]\n )\n return;\n globalClickHandler({\n event: { type: 'click' } as React.MouseEvent<HTMLDivElement>,\n target: 'swipeableViews',\n tabId: focusableTabsRef.current[newFocusableIndex].dataset.tabId,\n });\n\n // swiping does not trigger centerTab function inside handleOnTabChange because there is no event\n // by clicking we are manually forcing to center the tab\n\n focusableTabsRef.current[newFocusableIndex].click();\n }\n },\n [actualActiveTab, focusableTabsRef, globalClickHandler],\n );\n\n const panels: PanelDescriptor[] = useMemo(() => {\n // this component is based on React.children, swipeable views want an index in the array, not a tabId\n // two bad patterns relying on each others results in:\n // - because of react.children,\n // to guarantee predictability in finding the index based on tabId we should never return \"null\" which is not part of React.Children.toArray\n //\n // when not using swipeable views, we don't need to find the index based on tabId\n // so even if we return null the variable\n // indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull\n // (which will be calculating the wrong index)\n // will have no impact on the rendering\n // https://react.dev/reference/react/Children#children-toarray-caveats\n // Caveats\n // Empty nodes (null, undefined, and Booleans) will be omitted in the returned array.\n //\n // So, long story short,\n // 1 - do not remove next line, keep the <div /> instead of null when \"animated\"\n // 2 - NEVER EVER BUILD API BASED ON REACT.CHILDREN (if you are writing code post 2022 and you are not working on a legacy codebase)\n // To preserve indices for swipe behavior, we return a fully-typed placeholder panel\n // instead of null when a panel should not be rendered. This keeps array length stable.\n const mapResult = React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>, index: number) => {\n const { tabId: panelId = '', style, children: content, disabled, applyAriaDisabled } = tab.props;\n const isActive = actualActiveTab === panelId;\n const shouldRender = !onlyRenderActiveTab || isActive;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ panelId });\n\n const baseDescriptor: PanelDescriptor = {\n index,\n tabId: panelId,\n isActive: Boolean(isActive),\n isDSMobile: Boolean(isDSMobile),\n content: shouldRender && !disabled ? content : null,\n style: {\n ...(tabPanelsProps?.style || {}),\n ...(style || {}),\n } as React.CSSProperties,\n tabPanelsProps,\n 'aria-hidden': !(isActive && !applyAriaDisabled),\n 'data-panel-id': panelId,\n 'data-testid': 'ds-tabs-tab-panel',\n hide: !isActive,\n onClick: (event: React.MouseEvent<HTMLDivElement>) => globalClickHandler({ event, target: 'panel' }),\n role: 'tabpanel',\n getOwnerProps,\n getOwnerPropsArguments,\n };\n\n return baseDescriptor;\n });\n\n // Children.map can return null if there are no children; ensure an array is returned\n return mapResult || [];\n }, [tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, globalClickHandler, isDSMobile]);\n\n // Safely compute the active slide index. Default to 0 when none found.\n const activeSlide = (() => {\n const idx = panels.findIndex((panel) => panel.isActive);\n return idx >= 0 ? idx : 0;\n })();\n\n return (\n <DSSwipeCard<PanelDescriptor>\n activeSlide={activeSlide}\n onSwipe={(i) => handleOnChangeIndex(i, activeSlide)}\n enableTouch\n enableAnimation={animated}\n CardRender={CardRender}\n slidesProps={panels}\n />\n );\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-tabs",
|
|
3
|
-
"version": "3.55.0-next.
|
|
3
|
+
"version": "3.55.0-next.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Tabs",
|
|
6
6
|
"files": [
|
|
@@ -37,19 +37,20 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@react-hook/resize-observer": "~1.2.6",
|
|
40
|
-
"@elliemae/ds-button-v2": "3.55.0-next.
|
|
41
|
-
"@elliemae/ds-
|
|
42
|
-
"@elliemae/ds-
|
|
43
|
-
"@elliemae/ds-
|
|
44
|
-
"@elliemae/ds-
|
|
45
|
-
"@elliemae/ds-
|
|
40
|
+
"@elliemae/ds-button-v2": "3.55.0-next.12",
|
|
41
|
+
"@elliemae/ds-icon": "3.55.0-next.12",
|
|
42
|
+
"@elliemae/ds-swipe-card": "3.55.0-next.12",
|
|
43
|
+
"@elliemae/ds-icons": "3.55.0-next.12",
|
|
44
|
+
"@elliemae/ds-props-helpers": "3.55.0-next.12",
|
|
45
|
+
"@elliemae/ds-system": "3.55.0-next.12",
|
|
46
|
+
"@elliemae/ds-typescript-helpers": "3.55.0-next.12"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@elliemae/pui-cli": "9.0.0-next.65",
|
|
49
50
|
"jest": "~29.7.0",
|
|
50
51
|
"styled-components": "~5.3.9",
|
|
51
|
-
"@elliemae/ds-test-utils": "3.55.0-next.
|
|
52
|
-
"@elliemae/ds-monorepo-devops": "3.55.0-next.
|
|
52
|
+
"@elliemae/ds-test-utils": "3.55.0-next.12",
|
|
53
|
+
"@elliemae/ds-monorepo-devops": "3.55.0-next.12"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"lodash-es": "^4.17.21",
|