@elliemae/ds-tabs 3.53.0-next.10 → 3.53.0-next.11

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.
Files changed (38) hide show
  1. package/dist/cjs/DSTabsCTX.js +7 -1
  2. package/dist/cjs/DSTabsCTX.js.map +2 -2
  3. package/dist/cjs/{parts/tabBar → config}/useResizeObserver.js.map +1 -1
  4. package/dist/cjs/config/useTabs.js +102 -3
  5. package/dist/cjs/config/useTabs.js.map +2 -2
  6. package/dist/cjs/parts/tabBar/TabBar.js +8 -12
  7. package/dist/cjs/parts/tabBar/TabBar.js.map +2 -2
  8. package/dist/cjs/parts/tabBar/TabBarItemRenderer.js +3 -7
  9. package/dist/cjs/parts/tabBar/TabBarItemRenderer.js.map +2 -2
  10. package/dist/cjs/parts/tabsPanel/TabsPanels.js +12 -9
  11. package/dist/cjs/parts/tabsPanel/TabsPanels.js.map +2 -2
  12. package/dist/cjs/sharedTypes.js.map +1 -1
  13. package/dist/esm/DSTabsCTX.js +7 -1
  14. package/dist/esm/DSTabsCTX.js.map +2 -2
  15. package/dist/esm/{parts/tabBar → config}/useResizeObserver.js.map +1 -1
  16. package/dist/esm/config/useTabs.js +102 -3
  17. package/dist/esm/config/useTabs.js.map +2 -2
  18. package/dist/esm/parts/tabBar/TabBar.js +8 -12
  19. package/dist/esm/parts/tabBar/TabBar.js.map +2 -2
  20. package/dist/esm/parts/tabBar/TabBarItemRenderer.js +3 -7
  21. package/dist/esm/parts/tabBar/TabBarItemRenderer.js.map +2 -2
  22. package/dist/esm/parts/tabsPanel/TabsPanels.js +12 -9
  23. package/dist/esm/parts/tabsPanel/TabsPanels.js.map +2 -2
  24. package/dist/types/sharedTypes.d.ts +11 -0
  25. package/package.json +8 -8
  26. package/dist/cjs/parts/tabBar/useTabBar.js +0 -105
  27. package/dist/cjs/parts/tabBar/useTabBar.js.map +0 -7
  28. package/dist/cjs/utils/hooks/useTabsCallbacks.js +0 -66
  29. package/dist/cjs/utils/hooks/useTabsCallbacks.js.map +0 -7
  30. package/dist/esm/parts/tabBar/useTabBar.js +0 -75
  31. package/dist/esm/parts/tabBar/useTabBar.js.map +0 -7
  32. package/dist/esm/utils/hooks/useTabsCallbacks.js +0 -36
  33. package/dist/esm/utils/hooks/useTabsCallbacks.js.map +0 -7
  34. package/dist/types/parts/tabBar/useTabBar.d.ts +0 -11
  35. package/dist/types/utils/hooks/useTabsCallbacks.d.ts +0 -7
  36. /package/dist/cjs/{parts/tabBar → config}/useResizeObserver.js +0 -0
  37. /package/dist/esm/{parts/tabBar → config}/useResizeObserver.js +0 -0
  38. /package/dist/types/{parts/tabBar → config}/useResizeObserver.d.ts +0 -0
@@ -2,9 +2,12 @@ import * as React from "react";
2
2
  import React2, { useRef, useState, useMemo, useEffect } from "react";
3
3
  import { useMemoMergePropsWithDefault } from "@elliemae/ds-props-helpers";
4
4
  import { DSTabsDefaultProps } from "../react-desc-prop-types.js";
5
+ import { centerTab, isElementVisible, shouldHaveLeftGradient, shouldHaveRightGradient } from "../utils/helpers.js";
6
+ import { useResizeObserver } from "./useResizeObserver.js";
7
+ import { DEFAULT_INDICATOR_STYLES } from "../constants/index.js";
5
8
  const useTabs = (props) => {
6
9
  const propsWithDefaults = useMemoMergePropsWithDefault(props, DSTabsDefaultProps);
7
- const { activeTab, children } = propsWithDefaults;
10
+ const { activeTab, children, onTabChange, isDSMobile, fixedTabsHeaders, showSelectionIndicator } = propsWithDefaults;
8
11
  const tabsRef = useRef({});
9
12
  const tabsRefAsArray = useRef([]);
10
13
  const focusableTabsRef = useRef([]);
@@ -31,6 +34,86 @@ const useTabs = (props) => {
31
34
  setInternalActiveTab(firstAvailableTab?.dataset.tabId || "");
32
35
  }
33
36
  }, [activeTab]);
37
+ const [mobileGradients, setMobileGradients] = useState({
38
+ left: false,
39
+ right: false
40
+ });
41
+ const [indicatorStyle, setIndicatorStyle] = useState(DEFAULT_INDICATOR_STYLES);
42
+ const getIndicatorStyles = React2.useCallback(() => {
43
+ if (tabsListRef.current) {
44
+ const tabList = tabsListRef.current;
45
+ const activeTabButton = actualActiveTabRef.current;
46
+ if (!activeTabButton || !isElementVisible(activeTabButton, tabList)) return DEFAULT_INDICATOR_STYLES;
47
+ const missingMargins = isDSMobile ? 0 : 16;
48
+ const tabClientWidth = isDSMobile && !fixedTabsHeaders ? activeTabButton.clientWidth : activeTabButton.clientWidth + missingMargins * 2;
49
+ const position = isDSMobile && !fixedTabsHeaders ? activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left + tabList.scrollLeft : activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left - missingMargins;
50
+ return {
51
+ left: Math.round(position),
52
+ width: Math.round(tabClientWidth)
53
+ };
54
+ }
55
+ return DEFAULT_INDICATOR_STYLES;
56
+ }, [actualActiveTabRef, fixedTabsHeaders, isDSMobile, tabsListRef]);
57
+ const updateIndicatorStyle = React2.useCallback(
58
+ () => setTimeout(() => setIndicatorStyle(getIndicatorStyles()), 100),
59
+ [getIndicatorStyles, setIndicatorStyle]
60
+ );
61
+ useResizeObserver(updateIndicatorStyle, tabsListRef.current);
62
+ useResizeObserver(updateIndicatorStyle, actualActiveTabRef.current);
63
+ const updateMobileGradients = React2.useCallback(() => {
64
+ if (tabsListRef.current && isDSMobile && !fixedTabsHeaders) {
65
+ const { scrollLeft, scrollWidth, clientWidth } = tabsListRef.current;
66
+ setMobileGradients({
67
+ left: shouldHaveLeftGradient(scrollLeft),
68
+ right: shouldHaveRightGradient(scrollLeft, clientWidth, scrollWidth)
69
+ });
70
+ }
71
+ }, [fixedTabsHeaders, isDSMobile, tabsListRef]);
72
+ React2.useLayoutEffect(() => {
73
+ if (showSelectionIndicator) {
74
+ updateIndicatorStyle();
75
+ }
76
+ if (isDSMobile && !fixedTabsHeaders) {
77
+ updateMobileGradients();
78
+ }
79
+ }, [
80
+ updateMobileGradients,
81
+ updateIndicatorStyle,
82
+ isDSMobile,
83
+ fixedTabsHeaders,
84
+ actualActiveTab,
85
+ showSelectionIndicator
86
+ ]);
87
+ const handleOnTabChange = React2.useCallback(
88
+ (tabId, e) => {
89
+ setInternalActiveTab(tabId);
90
+ onTabChange(tabId, e);
91
+ if (isDSMobile && !fixedTabsHeaders && e) {
92
+ centerTab({ e, listRef: tabsListRef });
93
+ }
94
+ },
95
+ [fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab, tabsListRef]
96
+ );
97
+ const globalClickHandler = React2.useCallback(
98
+ (data) => {
99
+ if (data.target === "panel") {
100
+ if (propsWithDefaults.allowTextSelection) {
101
+ data.event.stopPropagation();
102
+ }
103
+ }
104
+ if (data.target === "tabsList") {
105
+ const target = data.event.target;
106
+ const { dataset, ariaDisabled } = target;
107
+ if (dataset.tabId && ariaDisabled !== "true") {
108
+ handleOnTabChange(dataset.tabId, data.event);
109
+ }
110
+ }
111
+ if (data.target === "swipeableViews") {
112
+ handleOnTabChange(data.tabId);
113
+ }
114
+ },
115
+ [propsWithDefaults.allowTextSelection, handleOnTabChange]
116
+ );
34
117
  const ctx = useMemo(
35
118
  () => ({
36
119
  props: propsWithDefaults,
@@ -41,9 +124,25 @@ const useTabs = (props) => {
41
124
  setInternalActiveTab,
42
125
  actualActiveTab,
43
126
  actualActiveTabRef,
44
- carouselOnlyListRef
127
+ carouselOnlyListRef,
128
+ globalClickHandler,
129
+ updateIndicatorStyle,
130
+ setIndicatorStyle,
131
+ indicatorStyle,
132
+ mobileGradients,
133
+ updateMobileGradients,
134
+ handleOnTabChange
45
135
  }),
46
- [actualActiveTab, propsWithDefaults]
136
+ [
137
+ propsWithDefaults,
138
+ actualActiveTab,
139
+ globalClickHandler,
140
+ updateIndicatorStyle,
141
+ indicatorStyle,
142
+ mobileGradients,
143
+ updateMobileGradients,
144
+ handleOnTabChange
145
+ ]
47
146
  );
48
147
  return ctx;
49
148
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useTabs.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useRef, useState, useMemo, useEffect } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTabsDefaultProps } from '../react-desc-prop-types.js';\nimport type { DSTabsT, DSTabT } from '../react-desc-prop-types.js';\nimport type { DSTabsInternalsT } from '../sharedTypes.js';\n\nexport const useTabs = (props: DSTabsT.Props): DSTabsInternalsT.DSTabsUseTabsContextT => {\n const propsWithDefaults = useMemoMergePropsWithDefault<DSTabsT.InternalProps>(props, DSTabsDefaultProps);\n\n const { activeTab, children } = propsWithDefaults;\n\n const tabsRef = useRef<Record<number, HTMLButtonElement>>({});\n const tabsRefAsArray = useRef<HTMLButtonElement[]>([]);\n const focusableTabsRef = useRef<HTMLButtonElement[]>([]);\n const carouselOnlyListRef = useRef<HTMLDivElement | null>(null);\n const tabsListRef = useRef<HTMLDivElement | null>(null);\n const actualActiveTabRef = useRef<HTMLButtonElement | null>(null);\n\n // we can't activate disabled tabs, we search for the first activable tab\n const firstActivableTabId = useMemo(() => {\n const childrenArray = React.Children.toArray(children) as React.ReactElement<DSTabT.Props>[];\n const firstActivableTab = childrenArray.filter((tab) => tab.props.disabled !== true)[0];\n\n if (firstActivableTab === null) return '';\n return firstActivableTab.props.tabId ?? '';\n }, [children]);\n\n const [internalActiveTab, setInternalActiveTab] = useState<string>(firstActivableTabId);\n\n const actualActiveTab = useMemo(() => {\n if (activeTab !== undefined) return activeTab;\n return internalActiveTab;\n }, [activeTab, internalActiveTab]);\n\n useEffect(() => {\n actualActiveTabRef.current = focusableTabsRef.current.find((el) => el.dataset.tabId === actualActiveTab) ?? null;\n }, [actualActiveTab]);\n\n useEffect(() => {\n if (activeTab === undefined) {\n const firstAvailableTab = focusableTabsRef.current.find((el) => el.ariaDisabled !== 'true');\n setInternalActiveTab(firstAvailableTab?.dataset.tabId || '');\n }\n }, [activeTab]);\n\n const ctx = useMemo(\n () => ({\n props: propsWithDefaults,\n tabsRef,\n focusableTabsRef,\n tabsListRef,\n tabsRefAsArray,\n setInternalActiveTab,\n actualActiveTab,\n actualActiveTabRef,\n carouselOnlyListRef,\n }),\n [actualActiveTab, propsWithDefaults],\n );\n\n return ctx;\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,UAAS,QAAQ,UAAU,SAAS,iBAAiB;AAC5D,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AAI5B,MAAM,UAAU,CAAC,UAAiE;AACvF,QAAM,oBAAoB,6BAAoD,OAAO,kBAAkB;AAEvG,QAAM,EAAE,WAAW,SAAS,IAAI;AAEhC,QAAM,UAAU,OAA0C,CAAC,CAAC;AAC5D,QAAM,iBAAiB,OAA4B,CAAC,CAAC;AACrD,QAAM,mBAAmB,OAA4B,CAAC,CAAC;AACvD,QAAM,sBAAsB,OAA8B,IAAI;AAC9D,QAAM,cAAc,OAA8B,IAAI;AACtD,QAAM,qBAAqB,OAAiC,IAAI;AAGhE,QAAM,sBAAsB,QAAQ,MAAM;AACxC,UAAM,gBAAgBA,OAAM,SAAS,QAAQ,QAAQ;AACrD,UAAM,oBAAoB,cAAc,OAAO,CAAC,QAAQ,IAAI,MAAM,aAAa,IAAI,EAAE,CAAC;AAEtF,QAAI,sBAAsB,KAAM,QAAO;AACvC,WAAO,kBAAkB,MAAM,SAAS;AAAA,EAC1C,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAiB,mBAAmB;AAEtF,QAAM,kBAAkB,QAAQ,MAAM;AACpC,QAAI,cAAc,OAAW,QAAO;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,iBAAiB,CAAC;AAEjC,YAAU,MAAM;AACd,uBAAmB,UAAU,iBAAiB,QAAQ,KAAK,CAAC,OAAO,GAAG,QAAQ,UAAU,eAAe,KAAK;AAAA,EAC9G,GAAG,CAAC,eAAe,CAAC;AAEpB,YAAU,MAAM;AACd,QAAI,cAAc,QAAW;AAC3B,YAAM,oBAAoB,iBAAiB,QAAQ,KAAK,CAAC,OAAO,GAAG,iBAAiB,MAAM;AAC1F,2BAAqB,mBAAmB,QAAQ,SAAS,EAAE;AAAA,IAC7D;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,MAAM;AAAA,IACV,OAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,iBAAiB,iBAAiB;AAAA,EACrC;AAEA,SAAO;AACT;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\nimport React, { useRef, useState, useMemo, useEffect } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTabsDefaultProps } from '../react-desc-prop-types.js';\nimport type { DSTabsT, DSTabT } from '../react-desc-prop-types.js';\nimport type { DSTabsInternalsT } from '../sharedTypes.js';\nimport { centerTab, isElementVisible, shouldHaveLeftGradient, shouldHaveRightGradient } from '../utils/helpers.js';\nimport { useResizeObserver } from './useResizeObserver.js';\nimport { DEFAULT_INDICATOR_STYLES } from '../constants/index.js';\n\nexport const useTabs = (props: DSTabsT.Props): DSTabsInternalsT.DSTabsUseTabsContextT => {\n const propsWithDefaults = useMemoMergePropsWithDefault<DSTabsT.InternalProps>(props, DSTabsDefaultProps);\n\n const { activeTab, children, onTabChange, isDSMobile, fixedTabsHeaders, showSelectionIndicator } = propsWithDefaults;\n\n const tabsRef = useRef<Record<number, HTMLButtonElement>>({});\n const tabsRefAsArray = useRef<HTMLButtonElement[]>([]);\n const focusableTabsRef = useRef<HTMLButtonElement[]>([]);\n const carouselOnlyListRef = useRef<HTMLDivElement | null>(null);\n const tabsListRef = useRef<HTMLDivElement | null>(null);\n const actualActiveTabRef = useRef<HTMLButtonElement | null>(null);\n\n // we can't activate disabled tabs, we search for the first activable tab\n const firstActivableTabId = useMemo(() => {\n const childrenArray = React.Children.toArray(children) as React.ReactElement<DSTabT.Props>[];\n const firstActivableTab = childrenArray.filter((tab) => tab.props.disabled !== true)[0];\n\n if (firstActivableTab === null) return '';\n return firstActivableTab.props.tabId ?? '';\n }, [children]);\n\n const [internalActiveTab, setInternalActiveTab] = useState<string>(firstActivableTabId);\n\n const actualActiveTab = useMemo(() => {\n if (activeTab !== undefined) return activeTab;\n return internalActiveTab;\n }, [activeTab, internalActiveTab]);\n\n useEffect(() => {\n actualActiveTabRef.current = focusableTabsRef.current.find((el) => el.dataset.tabId === actualActiveTab) ?? null;\n }, [actualActiveTab]);\n\n useEffect(() => {\n if (activeTab === undefined) {\n const firstAvailableTab = focusableTabsRef.current.find((el) => el.ariaDisabled !== 'true');\n setInternalActiveTab(firstAvailableTab?.dataset.tabId || '');\n }\n }, [activeTab]);\n\n const [mobileGradients, setMobileGradients] = useState<DSTabsInternalsT.MobileGradientsT>({\n left: false,\n right: false,\n });\n const [indicatorStyle, setIndicatorStyle] = useState<DSTabsInternalsT.IndicatorStyleT>(DEFAULT_INDICATOR_STYLES);\n\n const getIndicatorStyles = React.useCallback(() => {\n if (tabsListRef.current) {\n const tabList = tabsListRef.current;\n const activeTabButton = actualActiveTabRef.current;\n\n if (!activeTabButton || !isElementVisible(activeTabButton, tabList)) return DEFAULT_INDICATOR_STYLES;\n\n // The missingMargins are to make the selection indicator white marks work properly in desktop, we need\n // the full width of the tab button with margins.\n const missingMargins = isDSMobile ? 0 : 16;\n\n const tabClientWidth =\n isDSMobile && !fixedTabsHeaders\n ? activeTabButton.clientWidth\n : activeTabButton.clientWidth + missingMargins * 2;\n\n // The reason why we use the tabList.scrollLeft is due to the centerOnTabChange (only in Mobile and FlexibleTabs)\n // behavior that adds scroll to the tabList\n const position =\n isDSMobile && !fixedTabsHeaders\n ? activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left + tabList.scrollLeft\n : activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left - missingMargins;\n\n return {\n left: Math.round(position),\n width: Math.round(tabClientWidth),\n };\n }\n return DEFAULT_INDICATOR_STYLES;\n }, [actualActiveTabRef, fixedTabsHeaders, isDSMobile, tabsListRef]);\n\n /** [PUI-15772] - Tabs Pre Refactor\n * Updates indicator style with a delay. It:\n * 1. Uses setTimeout to delay style updates\n * 2. Called on resize and tab changes\n */\n const updateIndicatorStyle = React.useCallback(\n () => setTimeout(() => setIndicatorStyle(getIndicatorStyles()), 100),\n [getIndicatorStyles, setIndicatorStyle],\n );\n\n useResizeObserver(updateIndicatorStyle, tabsListRef.current);\n useResizeObserver(updateIndicatorStyle, actualActiveTabRef.current);\n\n /** [PUI-15772] - Tabs Pre Refactor\n * Updates mobile gradient visibility. It:\n * 1. Calculates scroll position\n * 2. Updates gradient visibility based on scroll\n */\n const updateMobileGradients = React.useCallback(() => {\n if (tabsListRef.current && isDSMobile && !fixedTabsHeaders) {\n const { scrollLeft, scrollWidth, clientWidth } = tabsListRef.current;\n setMobileGradients({\n left: shouldHaveLeftGradient(scrollLeft),\n right: shouldHaveRightGradient(scrollLeft, clientWidth, scrollWidth),\n });\n }\n }, [fixedTabsHeaders, isDSMobile, tabsListRef]);\n\n React.useLayoutEffect(() => {\n if (showSelectionIndicator) {\n updateIndicatorStyle();\n }\n if (isDSMobile && !fixedTabsHeaders) {\n updateMobileGradients();\n }\n }, [\n updateMobileGradients,\n updateIndicatorStyle,\n isDSMobile,\n fixedTabsHeaders,\n actualActiveTab,\n showSelectionIndicator,\n ]);\n\n const handleOnTabChange = React.useCallback(\n (tabId: string, e?: React.MouseEvent) => {\n setInternalActiveTab(tabId);\n onTabChange(tabId, e);\n if (isDSMobile && !fixedTabsHeaders && e) {\n centerTab({ e, listRef: tabsListRef });\n }\n },\n [fixedTabsHeaders, isDSMobile, onTabChange, setInternalActiveTab, tabsListRef],\n );\n\n const globalClickHandler = React.useCallback(\n (data: DSTabsInternalsT.GlobalClickHandlerT): void => {\n if (data.target === 'panel') {\n // we need to allow the text selection in the panel\n // this enters on conflict with the SwipeableViews component\n if (propsWithDefaults.allowTextSelection) {\n data.event.stopPropagation();\n }\n }\n\n if (data.target === 'tabsList') {\n const target = data.event.target as HTMLButtonElement;\n const { dataset, ariaDisabled } = target;\n if (dataset.tabId && ariaDisabled !== 'true') {\n handleOnTabChange(dataset.tabId, data.event);\n }\n }\n if (data.target === 'swipeableViews') {\n handleOnTabChange(data.tabId!);\n }\n },\n [propsWithDefaults.allowTextSelection, handleOnTabChange],\n );\n const ctx = useMemo(\n () => ({\n props: propsWithDefaults,\n tabsRef,\n focusableTabsRef,\n tabsListRef,\n tabsRefAsArray,\n setInternalActiveTab,\n actualActiveTab,\n actualActiveTabRef,\n carouselOnlyListRef,\n globalClickHandler,\n updateIndicatorStyle,\n setIndicatorStyle,\n indicatorStyle,\n mobileGradients,\n updateMobileGradients,\n handleOnTabChange,\n }),\n [\n propsWithDefaults,\n actualActiveTab,\n globalClickHandler,\n updateIndicatorStyle,\n indicatorStyle,\n mobileGradients,\n updateMobileGradients,\n handleOnTabChange,\n ],\n );\n\n return ctx;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -3,7 +3,6 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useContext } from "react";
4
4
  import { useOwnerProps } from "@elliemae/ds-props-helpers";
5
5
  import { Carousel } from "../carousel/Carousel.js";
6
- import { useTabBar } from "./useTabBar.js";
7
6
  import {
8
7
  StyledMobileGradient,
9
8
  StyledTabList,
@@ -14,15 +13,17 @@ import {
14
13
  import { DSTabsContext } from "../../DSTabsCTX.js";
15
14
  import { TABS_DATA_TESTID, TAB_TYPES } from "../../constants/index.js";
16
15
  import { TabBarItemRenderer } from "./TabBarItemRenderer.js";
17
- import { useTabsCallbacks } from "../../utils/hooks/useTabsCallbacks.js";
18
16
  const TabBar = () => {
19
17
  const {
20
18
  tabsListRef,
21
19
  props,
22
- props: { type, fixedTabsHeaders, withCarousel, isDSMobile }
20
+ props: { type, fixedTabsHeaders, withCarousel, isDSMobile },
21
+ globalClickHandler,
22
+ indicatorStyle,
23
+ mobileGradients,
24
+ updateMobileGradients,
25
+ updateIndicatorStyle
23
26
  } = useContext(DSTabsContext);
24
- const { handleOnTabChange } = useTabsCallbacks();
25
- const { indicatorStyle, mobileGradients, updateMobileGradients, updateIndicatorStyle } = useTabBar();
26
27
  const { getOwnerProps, getOwnerPropsArguments } = useOwnerProps(props);
27
28
  if (type === TAB_TYPES.SUBTABS && !isDSMobile) {
28
29
  return /* @__PURE__ */ jsx(
@@ -53,13 +54,8 @@ const TabBar = () => {
53
54
  onScroll: updateMobileGradients,
54
55
  indicatorStyle,
55
56
  tabType: type,
56
- onMouseDown: (e) => {
57
- const target = e.target;
58
- const { dataset, ariaDisabled } = target;
59
- if (dataset.tabId && ariaDisabled !== "true") {
60
- handleOnTabChange(dataset.tabId, e);
61
- updateIndicatorStyle();
62
- }
57
+ onClick: (e) => {
58
+ globalClickHandler({ event: e, target: "tabsList" });
63
59
  },
64
60
  children: [
65
61
  /* @__PURE__ */ jsx(StyledTabWrapper, { "data-testid": "tab-wrapper", isDSMobile, fixedTabsHeaders, children: !isDSMobile && withCarousel ? /* @__PURE__ */ jsx(Carousel, { updateIndicatorStyle, children: /* @__PURE__ */ jsx(TabBarItemRenderer, {}) }) : /* @__PURE__ */ jsx(TabBarItemRenderer, {}) }),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/tabBar/TabBar.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\nimport React, { useContext } from 'react';\nimport { useOwnerProps } from '@elliemae/ds-props-helpers';\nimport { Carousel } from '../carousel/Carousel.js';\nimport { useTabBar } from './useTabBar.js';\nimport {\n StyledMobileGradient,\n StyledTabList,\n StyledTabWrapper,\n StyledSelectionIndicator,\n StyledSubTabsList,\n} from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\n\nimport { TABS_DATA_TESTID, TAB_TYPES } from '../../constants/index.js';\n\nimport { TabBarItemRenderer } from './TabBarItemRenderer.js';\nimport { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';\n\nexport const TabBar = (): JSX.Element => {\n const {\n tabsListRef,\n props,\n props: { type, fixedTabsHeaders, withCarousel, isDSMobile },\n } = useContext(DSTabsContext);\n\n const { handleOnTabChange } = useTabsCallbacks();\n const { indicatorStyle, mobileGradients, updateMobileGradients, updateIndicatorStyle } = useTabBar();\n const { getOwnerProps, getOwnerPropsArguments } = useOwnerProps(props);\n\n if (type === TAB_TYPES.SUBTABS && !isDSMobile) {\n return (\n <StyledSubTabsList\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n withCarousel={withCarousel}\n data-testid={TABS_DATA_TESTID.SUB_TAB_LIST}\n role={withCarousel ? undefined : 'tablist'}\n innerRef={tabsListRef}\n >\n {withCarousel ? (\n <Carousel>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledSubTabsList>\n );\n }\n\n return (\n <StyledTabList\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n withCarousel={withCarousel}\n role={withCarousel ? undefined : 'tablist'}\n innerRef={tabsListRef}\n data-testid={TABS_DATA_TESTID.TAB_LIST}\n isDSMobile={isDSMobile}\n fixedTabsHeaders={fixedTabsHeaders}\n mobileGradients={mobileGradients}\n onScroll={updateMobileGradients}\n indicatorStyle={indicatorStyle}\n tabType={type}\n onMouseDown={(e) => {\n /**\n * [PUI-15396](https://jira.elliemae.io/browse/PUI-15396)\n * This is a workaround for an issue where clicks on tab buttons within a carousel\n * sometimes fail to trigger state updates. The problem occurs because:\n *\n * 1. When clicking on certain tabs, the click event reaches the tablist\n * wrapper instead of the tab button\n * 2. The carousel's scroll logic interferes with the normal event propagation\n * 3. This prevents the tab's onClick handler from being called consistently\n *\n * By adding an onMouseDown handler at the tablist level, we can:\n * - Capture the event earlier in the event cycle (before onClick)\n * - Check if the clicked element has a tab ID (data-tab-id attribute)\n * - Directly call handleOnTabChange with the appropriate tab ID\n *\n * This ensures the tab state updates correctly regardless of event bubbling issues\n * or interference from the carousel's scroll behavior.\n */\n const target = e.target as HTMLElement;\n const { dataset, ariaDisabled } = target;\n if (dataset.tabId && ariaDisabled !== 'true') {\n handleOnTabChange(dataset.tabId, e);\n updateIndicatorStyle();\n }\n }}\n >\n <StyledTabWrapper data-testid=\"tab-wrapper\" isDSMobile={isDSMobile} fixedTabsHeaders={fixedTabsHeaders}>\n {!isDSMobile && withCarousel ? (\n <Carousel updateIndicatorStyle={updateIndicatorStyle}>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledTabWrapper>\n <StyledSelectionIndicator isDSMobile={isDSMobile} tabType={type} />\n {isDSMobile && !fixedTabsHeaders && (\n <StyledMobileGradient\n mobileGradients={mobileGradients}\n left={tabsListRef.current?.scrollLeft}\n width={tabsListRef.current?.scrollWidth}\n />\n )}\n </StyledTabList>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC0CX,cAUR,YAVQ;AAzCZ,SAAgB,kBAAkB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB;AAE9B,SAAS,kBAAkB,iBAAiB;AAE5C,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AAE1B,MAAM,SAAS,MAAmB;AACvC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,OAAO,EAAE,MAAM,kBAAkB,cAAc,WAAW;AAAA,EAC5D,IAAI,WAAW,aAAa;AAE5B,QAAM,EAAE,kBAAkB,IAAI,iBAAiB;AAC/C,QAAM,EAAE,gBAAgB,iBAAiB,uBAAuB,qBAAqB,IAAI,UAAU;AACnG,QAAM,EAAE,eAAe,uBAAuB,IAAI,cAAc,KAAK;AAErE,MAAI,SAAS,UAAU,WAAW,CAAC,YAAY;AAC7C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAa,iBAAiB;AAAA,QAC9B,MAAM,eAAe,SAAY;AAAA,QACjC,UAAU;AAAA,QAET,yBACC,oBAAC,YACC,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB;AAAA;AAAA,IAExB;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,eAAe,SAAY;AAAA,MACjC,UAAU;AAAA,MACV,eAAa,iBAAiB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,aAAa,CAAC,MAAM;AAmBlB,cAAM,SAAS,EAAE;AACjB,cAAM,EAAE,SAAS,aAAa,IAAI;AAClC,YAAI,QAAQ,SAAS,iBAAiB,QAAQ;AAC5C,4BAAkB,QAAQ,OAAO,CAAC;AAClC,+BAAqB;AAAA,QACvB;AAAA,MACF;AAAA,MAEA;AAAA,4BAAC,oBAAiB,eAAY,eAAc,YAAwB,kBACjE,WAAC,cAAc,eACd,oBAAC,YAAS,sBACR,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB,GAExB;AAAA,QACA,oBAAC,4BAAyB,YAAwB,SAAS,MAAM;AAAA,QAChE,cAAc,CAAC,oBACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,YAAY,SAAS;AAAA,YAC3B,OAAO,YAAY,SAAS;AAAA;AAAA,QAC9B;AAAA;AAAA;AAAA,EAEJ;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\nimport React, { useContext } from 'react';\nimport { useOwnerProps } from '@elliemae/ds-props-helpers';\nimport { Carousel } from '../carousel/Carousel.js';\nimport {\n StyledMobileGradient,\n StyledTabList,\n StyledTabWrapper,\n StyledSelectionIndicator,\n StyledSubTabsList,\n} from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\n\nimport { TABS_DATA_TESTID, TAB_TYPES } from '../../constants/index.js';\n\nimport { TabBarItemRenderer } from './TabBarItemRenderer.js';\n\nexport const TabBar = (): JSX.Element => {\n const {\n tabsListRef,\n props,\n props: { type, fixedTabsHeaders, withCarousel, isDSMobile },\n globalClickHandler,\n indicatorStyle,\n mobileGradients,\n updateMobileGradients,\n updateIndicatorStyle,\n } = useContext(DSTabsContext);\n const { getOwnerProps, getOwnerPropsArguments } = useOwnerProps(props);\n\n if (type === TAB_TYPES.SUBTABS && !isDSMobile) {\n return (\n <StyledSubTabsList\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n withCarousel={withCarousel}\n data-testid={TABS_DATA_TESTID.SUB_TAB_LIST}\n role={withCarousel ? undefined : 'tablist'}\n innerRef={tabsListRef}\n >\n {withCarousel ? (\n <Carousel>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledSubTabsList>\n );\n }\n\n return (\n <StyledTabList\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n withCarousel={withCarousel}\n role={withCarousel ? undefined : 'tablist'}\n innerRef={tabsListRef}\n data-testid={TABS_DATA_TESTID.TAB_LIST}\n isDSMobile={isDSMobile}\n fixedTabsHeaders={fixedTabsHeaders}\n mobileGradients={mobileGradients}\n onScroll={updateMobileGradients}\n indicatorStyle={indicatorStyle}\n tabType={type}\n onClick={(e) => {\n globalClickHandler({ event: e, target: 'tabsList' });\n }}\n >\n <StyledTabWrapper data-testid=\"tab-wrapper\" isDSMobile={isDSMobile} fixedTabsHeaders={fixedTabsHeaders}>\n {!isDSMobile && withCarousel ? (\n <Carousel updateIndicatorStyle={updateIndicatorStyle}>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledTabWrapper>\n <StyledSelectionIndicator isDSMobile={isDSMobile} tabType={type} />\n {isDSMobile && !fixedTabsHeaders && (\n <StyledMobileGradient\n mobileGradients={mobileGradients}\n left={tabsListRef.current?.scrollLeft}\n width={tabsListRef.current?.scrollWidth}\n />\n )}\n </StyledTabList>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;AC0CX,cAUR,YAVQ;AAzCZ,SAAgB,kBAAkB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB;AAE9B,SAAS,kBAAkB,iBAAiB;AAE5C,SAAS,0BAA0B;AAE5B,MAAM,SAAS,MAAmB;AACvC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,OAAO,EAAE,MAAM,kBAAkB,cAAc,WAAW;AAAA,IAC1D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,WAAW,aAAa;AAC5B,QAAM,EAAE,eAAe,uBAAuB,IAAI,cAAc,KAAK;AAErE,MAAI,SAAS,UAAU,WAAW,CAAC,YAAY;AAC7C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAa,iBAAiB;AAAA,QAC9B,MAAM,eAAe,SAAY;AAAA,QACjC,UAAU;AAAA,QAET,yBACC,oBAAC,YACC,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB;AAAA;AAAA,IAExB;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,eAAe,SAAY;AAAA,MACjC,UAAU;AAAA,MACV,eAAa,iBAAiB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AACd,2BAAmB,EAAE,OAAO,GAAG,QAAQ,WAAW,CAAC;AAAA,MACrD;AAAA,MAEA;AAAA,4BAAC,oBAAiB,eAAY,eAAc,YAAwB,kBACjE,WAAC,cAAc,eACd,oBAAC,YAAS,sBACR,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB,GAExB;AAAA,QACA,oBAAC,4BAAyB,YAAwB,SAAS,MAAM;AAAA,QAChE,cAAc,CAAC,oBACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,YAAY,SAAS;AAAA,YAC3B,OAAO,YAAY,SAAS;AAAA;AAAA,QAC9B;AAAA;AAAA;AAAA,EAEJ;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -2,12 +2,10 @@ import * as React from "react";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { createElement } from "react";
4
4
  import React2, { useContext } from "react";
5
- import { useTabBar } from "./useTabBar.js";
6
5
  import { StyledTabButton, StyledRequiredMark, ScreenReaderOnly, StyledSubTabButton } from "./styles.js";
7
6
  import { DSTabsContext, DSTabsCrossRefContext } from "../../DSTabsCTX.js";
8
7
  import { useKeyboardNavigation } from "../../utils/hooks/useKeyboardNavigation.js";
9
8
  import { centerTab } from "../../utils/helpers.js";
10
- import { useTabsCallbacks } from "../../utils/hooks/useTabsCallbacks.js";
11
9
  import { TABS_DATA_TESTID, TAB_TYPES } from "../../constants/index.js";
12
10
  const TabBarItemRenderer = React2.memo(() => {
13
11
  const {
@@ -16,12 +14,11 @@ const TabBarItemRenderer = React2.memo(() => {
16
14
  tabsRefAsArray,
17
15
  carouselOnlyListRef,
18
16
  actualActiveTab,
19
- props: { type, fixedTabsHeaders, withCarousel, isDSMobile, showSeparator, children: tabs }
17
+ props: { type, fixedTabsHeaders, withCarousel, isDSMobile, showSeparator, children: tabs },
18
+ globalClickHandler
20
19
  } = useContext(DSTabsContext);
21
20
  const { lastTabInternalRef, firstSubtabInternalRef } = useContext(DSTabsCrossRefContext);
22
- const { handleOnTabChange } = useTabsCallbacks();
23
21
  const { handleOnKeyDown } = useKeyboardNavigation();
24
- const { updateIndicatorStyle } = useTabBar();
25
22
  const availableTabIndexes = [];
26
23
  return React2.Children.map(tabs, (tab, index) => {
27
24
  const {
@@ -82,8 +79,7 @@ const TabBarItemRenderer = React2.memo(() => {
82
79
  onClick: (e) => {
83
80
  if (applyAriaDisabled) return;
84
81
  if (!disabled) {
85
- handleOnTabChange(tabId, e);
86
- updateIndicatorStyle();
82
+ globalClickHandler({ event: e, target: "tabItem", tabId });
87
83
  }
88
84
  if (onClick && !disabled) onClick(tabId, e);
89
85
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/tabBar/TabBarItemRenderer.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext } from 'react';\n\nimport { useTabBar } from './useTabBar.js';\nimport { StyledTabButton, StyledRequiredMark, ScreenReaderOnly, StyledSubTabButton } from './styles.js';\nimport { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';\nimport { useKeyboardNavigation } from '../../utils/hooks/useKeyboardNavigation.js';\nimport { centerTab } from '../../utils/helpers.js';\n\nimport { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';\n\nimport type { DSTabT } from '../../react-desc-prop-types.js';\nimport { TABS_DATA_TESTID, TAB_TYPES } from '../../constants/index.js';\n\nexport const TabBarItemRenderer: React.ComponentType<Record<never, never>> = React.memo(() => {\n const {\n tabsRef,\n focusableTabsRef,\n tabsRefAsArray,\n carouselOnlyListRef,\n actualActiveTab,\n props: { type, fixedTabsHeaders, withCarousel, isDSMobile, showSeparator, children: tabs },\n } = useContext(DSTabsContext);\n\n const { lastTabInternalRef, firstSubtabInternalRef } = useContext(DSTabsCrossRefContext);\n const { handleOnTabChange } = useTabsCallbacks();\n const { handleOnKeyDown } = useKeyboardNavigation();\n\n const { updateIndicatorStyle } = useTabBar();\n const availableTabIndexes: number[] = [];\n\n return React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>, index) => {\n const {\n tabId = '',\n title = '',\n style,\n required = false,\n disabled = false,\n applyAriaDisabled = false,\n ref,\n onClick,\n onKeyDown,\n ...rest\n } = tab.props;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ tabId });\n\n if (!disabled) availableTabIndexes.push(index);\n const ButtonComponent = type === TAB_TYPES.SUBTABS ? StyledSubTabButton : StyledTabButton;\n\n return (\n <ButtonComponent\n {...rest}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n key={tabId}\n role=\"tab\"\n // eslint-disable-next-line complexity\n innerRef={(tabButtonRef: HTMLButtonElement) => {\n if (tabButtonRef && tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {\n tabsRefAsArray.current[index] = tabButtonRef;\n if (!disabled && !focusableTabsRef.current.includes(tabButtonRef))\n focusableTabsRef.current.push(tabButtonRef);\n tabsRef.current[index] = tabButtonRef;\n if (type === TAB_TYPES.SUBTABS && firstSubtabInternalRef && index === availableTabIndexes[0]) {\n firstSubtabInternalRef.current = tabButtonRef;\n }\n if (type !== TAB_TYPES.SUBTABS && index === availableTabIndexes[availableTabIndexes.length - 1]) {\n lastTabInternalRef.current = tabButtonRef;\n }\n if (ref) ref.current = tabButtonRef;\n }\n }}\n type=\"button\"\n aria-controls={tabId}\n aria-selected={actualActiveTab === tabId && !applyAriaDisabled}\n aria-disabled={disabled || applyAriaDisabled}\n isDSMobile={isDSMobile}\n fixedTabsHeaders={fixedTabsHeaders}\n tabType={type}\n data-required={required}\n data-tab-id={tabId}\n data-index={index}\n withCarousel={withCarousel}\n isActive={actualActiveTab === tabId}\n disabled={disabled}\n showSeparator={showSeparator && type !== TAB_TYPES.NORMAL}\n data-testid={type === TAB_TYPES.NORMAL ? TABS_DATA_TESTID.TAB_BUTTON : TABS_DATA_TESTID.SUBTAB_BUTTON}\n id={`${tabId}-label`}\n onClick={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Click handler for tab buttons. It:\n * 1. Prevents tab change if aria-disabled is true\n * 2. Updates active tab and indicator style if not disabled\n * 3. Calls the user's onClick callback if provided\n */\n if (applyAriaDisabled) return;\n if (!disabled) {\n handleOnTabChange(tabId, e);\n updateIndicatorStyle();\n }\n if (onClick && !disabled) onClick(tabId, e);\n }}\n onFocus={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Focus handler for carousel tabs. It:\n * 1. Centers the focused tab in the carousel viewport\n * 2. Only applies when withCarousel prop is true\n */\n if (withCarousel) centerTab({ e, listRef: carouselOnlyListRef });\n }}\n onKeyDown={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Keyboard navigation handler. It:\n * 1. Prevents Enter key propagation\n * 2. Handles keyboard navigation if not disabled\n * 3. Calls the user's onKeyDown callback if provided\n */\n if (e.key === 'Enter') e.stopPropagation();\n if (!disabled) handleOnKeyDown(e);\n if (onKeyDown && !disabled) onKeyDown(e);\n }}\n style={style}\n >\n {title}\n {required && (\n <>\n <StyledRequiredMark aria-hidden=\"true\">&#9679;</StyledRequiredMark>\n <ScreenReaderOnly>Required</ScreenReaderOnly>\n </>\n )}\n </ButtonComponent>\n );\n });\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useContext } from 'react';\nimport { StyledTabButton, StyledRequiredMark, ScreenReaderOnly, StyledSubTabButton } from './styles.js';\nimport { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';\nimport { useKeyboardNavigation } from '../../utils/hooks/useKeyboardNavigation.js';\nimport { centerTab } from '../../utils/helpers.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\nimport { TABS_DATA_TESTID, TAB_TYPES } from '../../constants/index.js';\n\nexport const TabBarItemRenderer: React.ComponentType<Record<never, never>> = React.memo(() => {\n const {\n tabsRef,\n focusableTabsRef,\n tabsRefAsArray,\n carouselOnlyListRef,\n actualActiveTab,\n props: { type, fixedTabsHeaders, withCarousel, isDSMobile, showSeparator, children: tabs },\n globalClickHandler,\n } = useContext(DSTabsContext);\n\n const { lastTabInternalRef, firstSubtabInternalRef } = useContext(DSTabsCrossRefContext);\n const { handleOnKeyDown } = useKeyboardNavigation();\n\n const availableTabIndexes: number[] = [];\n\n return React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>, index) => {\n const {\n tabId = '',\n title = '',\n style,\n required = false,\n disabled = false,\n applyAriaDisabled = false,\n ref,\n onClick,\n onKeyDown,\n ...rest\n } = tab.props;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ tabId });\n\n if (!disabled) availableTabIndexes.push(index);\n const ButtonComponent = type === TAB_TYPES.SUBTABS ? StyledSubTabButton : StyledTabButton;\n\n return (\n <ButtonComponent\n {...rest}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n key={tabId}\n role=\"tab\"\n // eslint-disable-next-line complexity\n innerRef={(tabButtonRef: HTMLButtonElement) => {\n if (tabButtonRef && tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {\n tabsRefAsArray.current[index] = tabButtonRef;\n if (!disabled && !focusableTabsRef.current.includes(tabButtonRef))\n focusableTabsRef.current.push(tabButtonRef);\n tabsRef.current[index] = tabButtonRef;\n if (type === TAB_TYPES.SUBTABS && firstSubtabInternalRef && index === availableTabIndexes[0]) {\n firstSubtabInternalRef.current = tabButtonRef;\n }\n if (type !== TAB_TYPES.SUBTABS && index === availableTabIndexes[availableTabIndexes.length - 1]) {\n lastTabInternalRef.current = tabButtonRef;\n }\n if (ref) ref.current = tabButtonRef;\n }\n }}\n type=\"button\"\n aria-controls={tabId}\n aria-selected={actualActiveTab === tabId && !applyAriaDisabled}\n aria-disabled={disabled || applyAriaDisabled}\n isDSMobile={isDSMobile}\n fixedTabsHeaders={fixedTabsHeaders}\n tabType={type}\n data-required={required}\n data-tab-id={tabId}\n data-index={index}\n withCarousel={withCarousel}\n isActive={actualActiveTab === tabId}\n disabled={disabled}\n showSeparator={showSeparator && type !== TAB_TYPES.NORMAL}\n data-testid={type === TAB_TYPES.NORMAL ? TABS_DATA_TESTID.TAB_BUTTON : TABS_DATA_TESTID.SUBTAB_BUTTON}\n id={`${tabId}-label`}\n onClick={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Click handler for tab buttons. It:\n * 1. Prevents tab change if aria-disabled is true\n * 2. Updates active tab and indicator style if not disabled\n * 3. Calls the user's onClick callback if provided\n */\n if (applyAriaDisabled) return;\n if (!disabled) {\n globalClickHandler({ event: e, target: 'tabItem', tabId });\n }\n if (onClick && !disabled) onClick(tabId, e);\n }}\n onFocus={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Focus handler for carousel tabs. It:\n * 1. Centers the focused tab in the carousel viewport\n * 2. Only applies when withCarousel prop is true\n */\n if (withCarousel) centerTab({ e, listRef: carouselOnlyListRef });\n }}\n onKeyDown={(e) => {\n /** [PUI-15772] - Tabs Pre Refactor\n * Keyboard navigation handler. It:\n * 1. Prevents Enter key propagation\n * 2. Handles keyboard navigation if not disabled\n * 3. Calls the user's onKeyDown callback if provided\n */\n if (e.key === 'Enter') e.stopPropagation();\n if (!disabled) handleOnKeyDown(e);\n if (onKeyDown && !disabled) onKeyDown(e);\n }}\n style={style}\n >\n {title}\n {required && (\n <>\n <StyledRequiredMark aria-hidden=\"true\">&#9679;</StyledRequiredMark>\n <ScreenReaderOnly>Required</ScreenReaderOnly>\n </>\n )}\n </ButtonComponent>\n );\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -5,7 +5,6 @@ import React2, { useMemo, useContext, useCallback } from "react";
5
5
  import SwipeableViews from "react-swipeable-views";
6
6
  import { StyledPanelContainer } from "./styles.js";
7
7
  import { DSTabsContext } from "../../DSTabsCTX.js";
8
- import { useTabsCallbacks } from "../../utils/hooks/useTabsCallbacks.js";
9
8
  const TabsPanels = () => {
10
9
  const {
11
10
  actualActiveTab,
@@ -18,9 +17,9 @@ const TabsPanels = () => {
18
17
  isDSMobile,
19
18
  tabPanelsProps,
20
19
  swipeableViewsContainerProps
21
- }
20
+ },
21
+ globalClickHandler
22
22
  } = useContext(DSTabsContext);
23
- const { handleOnTabChange, handleOnMouseDown } = useTabsCallbacks();
24
23
  const handleOnChangeIndex = useCallback(
25
24
  (index, indexLatest) => {
26
25
  if (!focusableTabsRef.current) return;
@@ -30,16 +29,20 @@ const TabsPanels = () => {
30
29
  const newFocusableIndex = currentIndexFocusable >= 0 ? currentIndexFocusable + offset : -1;
31
30
  if (newFocusableIndex < 0 || newFocusableIndex > focusableTabsRef.current?.length || !focusableTabsRef.current?.[newFocusableIndex])
32
31
  return;
33
- handleOnTabChange(focusableTabsRef.current[newFocusableIndex].dataset?.tabId);
32
+ globalClickHandler({
33
+ event: { type: "click" },
34
+ target: "swipeableViews",
35
+ tabId: focusableTabsRef.current[newFocusableIndex].dataset.tabId
36
+ });
34
37
  focusableTabsRef.current[newFocusableIndex].click();
35
38
  }
36
39
  },
37
- [actualActiveTab, focusableTabsRef, handleOnTabChange]
40
+ [actualActiveTab, focusableTabsRef, globalClickHandler]
38
41
  );
39
42
  const panels = useMemo(() => {
40
43
  const emptyPanelRender = animated ? /* @__PURE__ */ jsx("div", {}) : null;
41
44
  return React2.Children.map(tabs, (tab) => {
42
- const { tabId: panelId = "", style, children: content, disabled } = tab.props;
45
+ const { tabId: panelId = "", style, children: content, disabled, applyAriaDisabled } = tab.props;
43
46
  const isActive = actualActiveTab === panelId;
44
47
  const shouldRender = !onlyRenderActiveTab || isActive;
45
48
  const getOwnerProps = () => tab.props;
@@ -55,11 +58,11 @@ const TabsPanels = () => {
55
58
  key: panelId,
56
59
  id: panelId,
57
60
  "aria-labelledby": `${panelId}-label`,
58
- "aria-hidden": !isActive,
61
+ "aria-hidden": !isActive || !!applyAriaDisabled,
59
62
  "data-panel-id": panelId,
60
63
  "data-testid": "ds-tabs-tab-panel",
61
64
  hide: !isActive,
62
- onMouseDown: handleOnMouseDown,
65
+ onClick: (event) => globalClickHandler({ event, target: "panel" }),
63
66
  role: "tabpanel",
64
67
  style: {
65
68
  ...tabPanelsProps?.style || {},
@@ -70,7 +73,7 @@ const TabsPanels = () => {
70
73
  content
71
74
  );
72
75
  });
73
- }, [animated, tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, handleOnMouseDown, isDSMobile]);
76
+ }, [animated, tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, globalClickHandler, isDSMobile]);
74
77
  const indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull = useMemo(() => {
75
78
  const childrenArray = React2.Children.toArray(tabs);
76
79
  const index = childrenArray.findIndex((tab) => tab.props.tabId === actualActiveTab);
@@ -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 SwipeableViews from 'react-swipeable-views';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport { useTabsCallbacks } from '../../utils/hooks/useTabsCallbacks.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n\nexport const TabsPanels = (): JSX.Element | JSX.Element[] => {\n const {\n actualActiveTab,\n focusableTabsRef,\n props: {\n animated,\n enableMouseEvents,\n onlyRenderActiveTab,\n children: tabs,\n isDSMobile,\n tabPanelsProps,\n swipeableViewsContainerProps,\n },\n } = useContext(DSTabsContext);\n\n const { handleOnTabChange, handleOnMouseDown } = useTabsCallbacks();\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 handleOnTabChange(focusableTabsRef.current[newFocusableIndex].dataset?.tabId as string);\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, handleOnTabChange],\n );\n\n const panels = 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 const emptyPanelRender = animated ? <div /> : null;\n return React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>) => {\n const { tabId: panelId = '', style, children: content, disabled } = tab.props;\n const isActive = actualActiveTab === panelId;\n const shouldRender = !onlyRenderActiveTab || isActive;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ panelId });\n\n if (disabled) return emptyPanelRender;\n if (!shouldRender) return emptyPanelRender;\n return (\n <StyledPanelContainer\n {...tabPanelsProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n key={panelId}\n id={panelId}\n aria-labelledby={`${panelId}-label`}\n aria-hidden={!isActive}\n data-panel-id={panelId}\n data-testid=\"ds-tabs-tab-panel\"\n hide={!isActive}\n onMouseDown={handleOnMouseDown}\n role=\"tabpanel\"\n style={{\n ...(tabPanelsProps?.style || {}),\n ...(style || {}),\n }}\n isDSMobile={isDSMobile}\n >\n {content}\n </StyledPanelContainer>\n );\n });\n }, [animated, tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, handleOnMouseDown, isDSMobile]);\n\n const indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull = useMemo(() => {\n const childrenArray = React.Children.toArray(tabs) as React.ReactElement<DSTabT.Props>[];\n const index = childrenArray.findIndex((tab) => tab.props.tabId === actualActiveTab);\n\n if (index === -1) return 0;\n return index;\n }, [actualActiveTab, tabs]);\n\n if (animated) {\n // Ignore ts errors on the next line because the 'react-swipeable-views' package does not export a type for the SwipeableViews component\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment\n const Comp = (SwipeableViews as any)?.default ?? SwipeableViews;\n return (\n <Comp\n {...swipeableViewsContainerProps}\n style={{\n overflow: 'hidden', // https://jira.elliemae.io/browse/PUI-9906\n ...(swipeableViewsContainerProps?.style || {}),\n }}\n enableMouseEvents={enableMouseEvents}\n index={indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull}\n onChangeIndex={handleOnChangeIndex}\n >\n {panels}\n </Comp>\n );\n }\n\n return panels;\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC+EiB;AAWhC;AAxFR,OAAOA,UAAS,SAAS,YAAY,mBAAmB;AACxD,OAAO,oBAAoB;AAC3B,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAG1B,MAAM,aAAa,MAAmC;AAC3D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAI,WAAW,aAAa;AAE5B,QAAM,EAAE,mBAAmB,kBAAkB,IAAI,iBAAiB;AASlE,QAAM,sBAAsB;AAAA,IAC1B,CAAC,OAAe,gBAAwB;AACtC,UAAI,CAAC,iBAAiB,QAAS;AAE/B,YAAM,SAAS,QAAQ;AAEvB,UAAI,iBAAiB,SAAS;AAC5B,cAAM,wBAAwB,iBAAiB,SAAS,UAAU,CAAC,OAAO,GAAG,QAAQ,UAAU,eAAe;AAE9G,cAAM,oBAAoB,yBAAyB,IAAI,wBAAwB,SAAS;AAExF,YACE,oBAAoB,KACpB,oBAAoB,iBAAiB,SAAS,UAC9C,CAAC,iBAAiB,UAAU,iBAAiB;AAE7C;AACF,0BAAkB,iBAAiB,QAAQ,iBAAiB,EAAE,SAAS,KAAe;AAKtF,yBAAiB,QAAQ,iBAAiB,EAAE,MAAM;AAAA,MACpD;AAAA,IACF;AAAA,IACA,CAAC,iBAAiB,kBAAkB,iBAAiB;AAAA,EACvD;AAEA,QAAM,SAAS,QAAQ,MAAM;AAkB3B,UAAM,mBAAmB,WAAW,oBAAC,SAAI,IAAK;AAC9C,WAAOA,OAAM,SAAS,IAAI,MAAM,CAAC,QAA0C;AACzE,YAAM,EAAE,OAAO,UAAU,IAAI,OAAO,UAAU,SAAS,SAAS,IAAI,IAAI;AACxE,YAAM,WAAW,oBAAoB;AACrC,YAAM,eAAe,CAAC,uBAAuB;AAC7C,YAAM,gBAAgB,MAAM,IAAI;AAChC,YAAM,yBAAyB,OAAO,EAAE,QAAQ;AAEhD,UAAI,SAAU,QAAO;AACrB,UAAI,CAAC,aAAc,QAAO;AAC1B,aACE;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA;AAAA,UACA,KAAK;AAAA,UACL,IAAI;AAAA,UACJ,mBAAiB,GAAG,OAAO;AAAA,UAC3B,eAAa,CAAC;AAAA,UACd,iBAAe;AAAA,UACf,eAAY;AAAA,UACZ,MAAM,CAAC;AAAA,UACP,aAAa;AAAA,UACb,MAAK;AAAA,UACL,OAAO;AAAA,YACL,GAAI,gBAAgB,SAAS,CAAC;AAAA,YAC9B,GAAI,SAAS,CAAC;AAAA,UAChB;AAAA,UACA;AAAA;AAAA,QAEC;AAAA,MACH;AAAA,IAEJ,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,MAAM,iBAAiB,qBAAqB,gBAAgB,mBAAmB,UAAU,CAAC;AAExG,QAAM,qFAAqF,QAAQ,MAAM;AACvG,UAAM,gBAAgBA,OAAM,SAAS,QAAQ,IAAI;AACjD,UAAM,QAAQ,cAAc,UAAU,CAAC,QAAQ,IAAI,MAAM,UAAU,eAAe;AAElF,QAAI,UAAU,GAAI,QAAO;AACzB,WAAO;AAAA,EACT,GAAG,CAAC,iBAAiB,IAAI,CAAC;AAE1B,MAAI,UAAU;AAGZ,UAAM,OAAQ,gBAAwB,WAAW;AACjD,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,UAAU;AAAA;AAAA,UACV,GAAI,8BAA8B,SAAS,CAAC;AAAA,QAC9C;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,eAAe;AAAA,QAEd;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO;AACT;",
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 SwipeableViews from 'react-swipeable-views';\nimport { StyledPanelContainer } from './styles.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport type { DSTabT } from '../../react-desc-prop-types.js';\n\nexport const TabsPanels = (): JSX.Element | JSX.Element[] => {\n const {\n actualActiveTab,\n focusableTabsRef,\n props: {\n animated,\n enableMouseEvents,\n onlyRenderActiveTab,\n children: tabs,\n isDSMobile,\n tabPanelsProps,\n swipeableViewsContainerProps,\n },\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 = 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 const emptyPanelRender = animated ? <div /> : null;\n return React.Children.map(tabs, (tab: React.ReactElement<DSTabT.Props>) => {\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 if (disabled) return emptyPanelRender;\n if (!shouldRender) return emptyPanelRender;\n return (\n <StyledPanelContainer\n {...tabPanelsProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n key={panelId}\n id={panelId}\n aria-labelledby={`${panelId}-label`}\n aria-hidden={!isActive || !!applyAriaDisabled}\n data-panel-id={panelId}\n data-testid=\"ds-tabs-tab-panel\"\n hide={!isActive}\n onClick={(event) => globalClickHandler({ event, target: 'panel' })}\n role=\"tabpanel\"\n style={{\n ...(tabPanelsProps?.style || {}),\n ...(style || {}),\n }}\n isDSMobile={isDSMobile}\n >\n {content}\n </StyledPanelContainer>\n );\n });\n }, [animated, tabs, actualActiveTab, onlyRenderActiveTab, tabPanelsProps, globalClickHandler, isDSMobile]);\n\n const indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull = useMemo(() => {\n const childrenArray = React.Children.toArray(tabs) as React.ReactElement<DSTabT.Props>[];\n const index = childrenArray.findIndex((tab) => tab.props.tabId === actualActiveTab);\n\n if (index === -1) return 0;\n return index;\n }, [actualActiveTab, tabs]);\n\n if (animated) {\n // Ignore ts errors on the next line because the 'react-swipeable-views' package does not export a type for the SwipeableViews component\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment\n const Comp = (SwipeableViews as any)?.default ?? SwipeableViews;\n return (\n <Comp\n {...swipeableViewsContainerProps}\n style={{\n overflow: 'hidden', // https://jira.elliemae.io/browse/PUI-9906\n ...(swipeableViewsContainerProps?.style || {}),\n }}\n enableMouseEvents={enableMouseEvents}\n index={indexExclusiveToSwipeableIndexThatReliesOnReactChildrenToArrayWhichAutoFiltersNull}\n onChangeIndex={handleOnChangeIndex}\n >\n {panels}\n </Comp>\n );\n }\n\n return panels;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -15,6 +15,11 @@ export declare namespace DSTabsInternalsT {
15
15
  right: boolean;
16
16
  left: boolean;
17
17
  }
18
+ interface GlobalClickHandlerT {
19
+ event: React.MouseEvent;
20
+ target: 'panel' | 'tabItem' | 'tabsList' | 'swipeableViews';
21
+ tabId?: string;
22
+ }
18
23
  interface DSTabsUseTabsContextT {
19
24
  props: DSTabsT.InternalProps;
20
25
  tabsRef: React.MutableRefObject<Record<number, HTMLButtonElement> | null>;
@@ -25,6 +30,12 @@ export declare namespace DSTabsInternalsT {
25
30
  carouselOnlyListRef: React.MutableRefObject<HTMLDivElement | null>;
26
31
  setInternalActiveTab: React.Dispatch<React.SetStateAction<string>>;
27
32
  actualActiveTab: string;
33
+ globalClickHandler: (data: GlobalClickHandlerT) => void;
34
+ updateIndicatorStyle: () => void;
35
+ updateMobileGradients: () => void;
36
+ setIndicatorStyle: React.Dispatch<React.SetStateAction<DSTabsInternalsT.IndicatorStyleT>>;
37
+ indicatorStyle: DSTabsInternalsT.IndicatorStyleT;
38
+ mobileGradients: DSTabsInternalsT.MobileGradientsT;
28
39
  }
29
40
  interface DSTabsUseCrossRefContextT {
30
41
  lastTabInternalRef: React.MutableRefObject<HTMLButtonElement | null | undefined>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-tabs",
3
- "version": "3.53.0-next.10",
3
+ "version": "3.53.0-next.11",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Tabs",
6
6
  "files": [
@@ -38,18 +38,18 @@
38
38
  "dependencies": {
39
39
  "@react-hook/resize-observer": "~1.2.6",
40
40
  "react-swipeable-views": "~0.14.0",
41
- "@elliemae/ds-button-v2": "3.53.0-next.10",
42
- "@elliemae/ds-system": "3.53.0-next.10",
43
- "@elliemae/ds-icons": "3.53.0-next.10",
44
- "@elliemae/ds-props-helpers": "3.53.0-next.10",
45
- "@elliemae/ds-typescript-helpers": "3.53.0-next.10",
46
- "@elliemae/ds-icon": "3.53.0-next.10"
41
+ "@elliemae/ds-button-v2": "3.53.0-next.11",
42
+ "@elliemae/ds-icon": "3.53.0-next.11",
43
+ "@elliemae/ds-props-helpers": "3.53.0-next.11",
44
+ "@elliemae/ds-icons": "3.53.0-next.11",
45
+ "@elliemae/ds-system": "3.53.0-next.11",
46
+ "@elliemae/ds-typescript-helpers": "3.53.0-next.11"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@elliemae/pui-cli": "9.0.0-next.63",
50
50
  "jest": "~29.7.0",
51
51
  "styled-components": "~5.3.9",
52
- "@elliemae/ds-monorepo-devops": "3.53.0-next.10"
52
+ "@elliemae/ds-monorepo-devops": "3.53.0-next.11"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "lodash-es": "^4.17.21",
@@ -1,105 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var useTabBar_exports = {};
30
- __export(useTabBar_exports, {
31
- useTabBar: () => useTabBar
32
- });
33
- module.exports = __toCommonJS(useTabBar_exports);
34
- var React = __toESM(require("react"));
35
- var import_react = require("react");
36
- var import_useResizeObserver = require("./useResizeObserver.js");
37
- var import_helpers = require("../../utils/helpers.js");
38
- var import_DSTabsCTX = require("../../DSTabsCTX.js");
39
- var import_constants = require("../../constants/index.js");
40
- const useTabBar = () => {
41
- const {
42
- actualActiveTab,
43
- actualActiveTabRef,
44
- tabsListRef,
45
- props: { showSelectionIndicator, isDSMobile, fixedTabsHeaders }
46
- } = (0, import_react.useContext)(import_DSTabsCTX.DSTabsContext);
47
- const [mobileGradients, setMobileGradients] = (0, import_react.useState)({
48
- left: false,
49
- right: false
50
- });
51
- const [indicatorStyle, setIndicatorStyle] = (0, import_react.useState)(import_constants.DEFAULT_INDICATOR_STYLES);
52
- const getIndicatorStyles = (0, import_react.useCallback)(() => {
53
- if (tabsListRef.current) {
54
- const tabList = tabsListRef.current;
55
- const activeTabButton = actualActiveTabRef.current;
56
- if (!activeTabButton || !(0, import_helpers.isElementVisible)(activeTabButton, tabList)) return import_constants.DEFAULT_INDICATOR_STYLES;
57
- const missingMargins = isDSMobile ? 0 : 16;
58
- const tabClientWidth = isDSMobile && !fixedTabsHeaders ? activeTabButton.clientWidth : activeTabButton.clientWidth + missingMargins * 2;
59
- const position = isDSMobile && !fixedTabsHeaders ? activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left + tabList.scrollLeft : activeTabButton.getBoundingClientRect().left - tabList.getBoundingClientRect().left - missingMargins;
60
- return {
61
- left: Math.round(position),
62
- width: Math.round(tabClientWidth)
63
- };
64
- }
65
- return import_constants.DEFAULT_INDICATOR_STYLES;
66
- }, [actualActiveTabRef, fixedTabsHeaders, isDSMobile, tabsListRef]);
67
- const updateIndicatorStyle = (0, import_react.useCallback)(
68
- () => setTimeout(() => setIndicatorStyle(getIndicatorStyles()), 100),
69
- [getIndicatorStyles, setIndicatorStyle]
70
- );
71
- (0, import_useResizeObserver.useResizeObserver)(updateIndicatorStyle, tabsListRef.current);
72
- (0, import_useResizeObserver.useResizeObserver)(updateIndicatorStyle, actualActiveTabRef.current);
73
- const updateMobileGradients = (0, import_react.useCallback)(() => {
74
- if (tabsListRef.current && isDSMobile && !fixedTabsHeaders) {
75
- const { scrollLeft, scrollWidth, clientWidth } = tabsListRef.current;
76
- setMobileGradients({
77
- left: (0, import_helpers.shouldHaveLeftGradient)(scrollLeft),
78
- right: (0, import_helpers.shouldHaveRightGradient)(scrollLeft, clientWidth, scrollWidth)
79
- });
80
- }
81
- }, [fixedTabsHeaders, isDSMobile, tabsListRef]);
82
- (0, import_react.useLayoutEffect)(() => {
83
- if (showSelectionIndicator) {
84
- updateIndicatorStyle();
85
- }
86
- if (isDSMobile && !fixedTabsHeaders) {
87
- updateMobileGradients();
88
- }
89
- }, [
90
- updateMobileGradients,
91
- showSelectionIndicator,
92
- updateIndicatorStyle,
93
- isDSMobile,
94
- fixedTabsHeaders,
95
- actualActiveTab
96
- ]);
97
- return {
98
- updateIndicatorStyle,
99
- setIndicatorStyle,
100
- indicatorStyle,
101
- mobileGradients,
102
- updateMobileGradients
103
- };
104
- };
105
- //# sourceMappingURL=useTabBar.js.map