@elliemae/ds-tabs 3.60.0-next.9 → 3.70.0-next.1
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/dist/cjs/config/useTabs.js +14 -3
- package/dist/cjs/config/useTabs.js.map +2 -2
- package/dist/cjs/parts/carousel/Carousel.js +14 -49
- package/dist/cjs/parts/carousel/Carousel.js.map +2 -2
- package/dist/cjs/parts/carousel/styles.js +7 -1
- package/dist/cjs/parts/carousel/styles.js.map +2 -2
- package/dist/cjs/parts/carousel/useCarousel.js +28 -43
- package/dist/cjs/parts/carousel/useCarousel.js.map +3 -3
- package/dist/cjs/parts/tabBar/TabBar.js +3 -1
- package/dist/cjs/parts/tabBar/TabBar.js.map +2 -2
- package/dist/cjs/parts/tabBar/TabBarItemRenderer.js +28 -20
- package/dist/cjs/parts/tabBar/TabBarItemRenderer.js.map +2 -2
- package/dist/cjs/parts/tabBar/styles.js +36 -200
- package/dist/cjs/parts/tabBar/styles.js.map +2 -2
- package/dist/cjs/parts/tabsContent/TabsContent.js +13 -5
- package/dist/cjs/parts/tabsContent/TabsContent.js.map +2 -2
- package/dist/cjs/parts/tabsPanel/TabsPanels.js +15 -1
- package/dist/cjs/parts/tabsPanel/TabsPanels.js.map +2 -2
- package/dist/cjs/parts/tabsPanel/styles.js +4 -4
- package/dist/cjs/parts/tabsPanel/styles.js.map +2 -2
- package/dist/cjs/react-desc-prop-types.js +1 -0
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/sharedTypes.js.map +1 -1
- package/dist/cjs/utils/hooks/useKeyboardNavigation.js +10 -4
- package/dist/cjs/utils/hooks/useKeyboardNavigation.js.map +2 -2
- package/dist/esm/config/useTabs.js +14 -3
- package/dist/esm/config/useTabs.js.map +2 -2
- package/dist/esm/parts/carousel/Carousel.js +16 -57
- package/dist/esm/parts/carousel/Carousel.js.map +2 -2
- package/dist/esm/parts/carousel/styles.js +7 -1
- package/dist/esm/parts/carousel/styles.js.map +2 -2
- package/dist/esm/parts/carousel/useCarousel.js +29 -44
- package/dist/esm/parts/carousel/useCarousel.js.map +2 -2
- package/dist/esm/parts/tabBar/TabBar.js +3 -1
- package/dist/esm/parts/tabBar/TabBar.js.map +2 -2
- package/dist/esm/parts/tabBar/TabBarItemRenderer.js +30 -28
- package/dist/esm/parts/tabBar/TabBarItemRenderer.js.map +2 -2
- package/dist/esm/parts/tabBar/styles.js +37 -201
- package/dist/esm/parts/tabBar/styles.js.map +2 -2
- package/dist/esm/parts/tabsContent/TabsContent.js +13 -5
- package/dist/esm/parts/tabsContent/TabsContent.js.map +2 -2
- package/dist/esm/parts/tabsPanel/TabsPanels.js +15 -1
- package/dist/esm/parts/tabsPanel/TabsPanels.js.map +2 -2
- package/dist/esm/parts/tabsPanel/styles.js +4 -4
- package/dist/esm/parts/tabsPanel/styles.js.map +2 -2
- package/dist/esm/react-desc-prop-types.js +1 -0
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/dist/esm/utils/hooks/useKeyboardNavigation.js +10 -4
- package/dist/esm/utils/hooks/useKeyboardNavigation.js.map +2 -2
- package/dist/types/parts/carousel/useCarousel.d.ts +0 -5
- package/dist/types/parts/tabBar/styles.d.ts +7 -16
- package/dist/types/parts/tabsPanel/styles.d.ts +3 -2
- package/dist/types/react-desc-prop-types.d.ts +1 -0
- package/dist/types/sharedTypes.d.ts +3 -0
- package/dist/types/tests/DSTabs.allDisabled.test.d.ts +1 -0
- package/dist/types/tests/DSTabs.roving-tabindex-PUI-17883.test.d.ts +1 -0
- package/package.json +27 -29
- package/dist/cjs/parts/carousel/useCarouselCallbacks.js +0 -89
- package/dist/cjs/parts/carousel/useCarouselCallbacks.js.map +0 -7
- package/dist/esm/parts/carousel/useCarouselCallbacks.js +0 -59
- package/dist/esm/parts/carousel/useCarouselCallbacks.js.map +0 -7
- package/dist/types/parts/carousel/useCarouselCallbacks.d.ts +0 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/utils/hooks/useKeyboardNavigation.tsx", "../../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useContext } from 'react';\nimport { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';\n\ninterface UseKeyboardNavigationReturnTypeT {\n handleOnKeyDown: (e: React.KeyboardEvent) => void;\n}\n\nexport const useKeyboardNavigation = (): UseKeyboardNavigationReturnTypeT => {\n const { focusableTabsRef } = useContext(DSTabsContext);\n const { firstSubtabInternalRef, lastTabInternalRef } = useContext(DSTabsCrossRefContext);\n\n const handleOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowRight' && focusableTabsRef.current) {\n e.preventDefault();\n e.stopPropagation();\n const nextTab =\n focusableTabsRef.current[(focusableTabsRef?.current?.indexOf?.(e.target as HTMLButtonElement) ?? 0) + 1];\n if (nextTab) nextTab.focus();\n if (!nextTab) return;\n }\n\n if (e.key === 'ArrowLeft' && focusableTabsRef.current) {\n e.preventDefault();\n e.stopPropagation();\n const prevTab =\n focusableTabsRef.current[(focusableTabsRef?.current?.indexOf?.(e.target as HTMLButtonElement) ?? 0) - 1];\n if (prevTab) prevTab.focus();\n if (!prevTab) return;\n }\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n const canFocusCrossTabs = firstSubtabInternalRef?.current && lastTabInternalRef?.current;\n if (canFocusCrossTabs) firstSubtabInternalRef.current?.focus();\n }\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n const canFocusCrossTabs = firstSubtabInternalRef?.current && lastTabInternalRef?.current;\n if (canFocusCrossTabs) lastTabInternalRef.current?.focus();\n }\n },\n [firstSubtabInternalRef, lastTabInternalRef, focusableTabsRef],\n );\n\n return {\n handleOnKeyDown,\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,mBAAwC;AACxC,uBAAqD;AAM9C,MAAM,wBAAwB,MAAwC;AAC3E,QAAM,EAAE,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useContext } from 'react';\nimport { DSTabsContext, DSTabsCrossRefContext } from '../../DSTabsCTX.js';\n\ninterface UseKeyboardNavigationReturnTypeT {\n handleOnKeyDown: (e: React.KeyboardEvent) => void;\n}\n\nexport const useKeyboardNavigation = (): UseKeyboardNavigationReturnTypeT => {\n const { focusableTabsRef, setFocusedTabId } = useContext(DSTabsContext);\n const { firstSubtabInternalRef, lastTabInternalRef } = useContext(DSTabsCrossRefContext);\n\n const handleOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowRight' && focusableTabsRef.current) {\n e.preventDefault();\n e.stopPropagation();\n const nextTab =\n focusableTabsRef.current[(focusableTabsRef?.current?.indexOf?.(e.target as HTMLButtonElement) ?? 0) + 1];\n if (nextTab) {\n nextTab.focus();\n setFocusedTabId(nextTab.dataset.tabId || '');\n }\n if (!nextTab) return;\n }\n\n if (e.key === 'ArrowLeft' && focusableTabsRef.current) {\n e.preventDefault();\n e.stopPropagation();\n const prevTab =\n focusableTabsRef.current[(focusableTabsRef?.current?.indexOf?.(e.target as HTMLButtonElement) ?? 0) - 1];\n if (prevTab) {\n prevTab.focus();\n setFocusedTabId(prevTab.dataset.tabId || '');\n }\n if (!prevTab) return;\n }\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n const canFocusCrossTabs = firstSubtabInternalRef?.current && lastTabInternalRef?.current;\n if (canFocusCrossTabs) firstSubtabInternalRef.current?.focus();\n }\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n const canFocusCrossTabs = firstSubtabInternalRef?.current && lastTabInternalRef?.current;\n if (canFocusCrossTabs) lastTabInternalRef.current?.focus();\n }\n },\n [firstSubtabInternalRef, lastTabInternalRef, focusableTabsRef, setFocusedTabId],\n );\n\n return {\n handleOnKeyDown,\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,mBAAwC;AACxC,uBAAqD;AAM9C,MAAM,wBAAwB,MAAwC;AAC3E,QAAM,EAAE,kBAAkB,gBAAgB,QAAI,yBAAW,8BAAa;AACtE,QAAM,EAAE,wBAAwB,mBAAmB,QAAI,yBAAW,sCAAqB;AAEvF,QAAM,sBAAkB;AAAA,IACtB,CAAC,MAA2B;AAC1B,UAAI,EAAE,QAAQ,gBAAgB,iBAAiB,SAAS;AACtD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,UACJ,iBAAiB,SAAS,kBAAkB,SAAS,UAAU,EAAE,MAA2B,KAAK,KAAK,CAAC;AACzG,YAAI,SAAS;AACX,kBAAQ,MAAM;AACd,0BAAgB,QAAQ,QAAQ,SAAS,EAAE;AAAA,QAC7C;AACA,YAAI,CAAC,QAAS;AAAA,MAChB;AAEA,UAAI,EAAE,QAAQ,eAAe,iBAAiB,SAAS;AACrD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,UACJ,iBAAiB,SAAS,kBAAkB,SAAS,UAAU,EAAE,MAA2B,KAAK,KAAK,CAAC;AACzG,YAAI,SAAS;AACX,kBAAQ,MAAM;AACd,0BAAgB,QAAQ,QAAQ,SAAS,EAAE;AAAA,QAC7C;AACA,YAAI,CAAC,QAAS;AAAA,MAChB;AAEA,UAAI,EAAE,QAAQ,aAAa;AACzB,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,oBAAoB,wBAAwB,WAAW,oBAAoB;AACjF,YAAI,kBAAmB,wBAAuB,SAAS,MAAM;AAAA,MAC/D;AAEA,UAAI,EAAE,QAAQ,WAAW;AACvB,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,cAAM,oBAAoB,wBAAwB,WAAW,oBAAoB;AACjF,YAAI,kBAAmB,oBAAmB,SAAS,MAAM;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,CAAC,wBAAwB,oBAAoB,kBAAkB,eAAe;AAAA,EAChF;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,10 +15,16 @@ const useTabs = (props) => {
|
|
|
15
15
|
const firstActivableTabId = useMemo(() => {
|
|
16
16
|
const childrenArray = React2.Children.toArray(children);
|
|
17
17
|
const firstActivableTab = childrenArray.filter((tab) => tab.props.disabled !== true)[0];
|
|
18
|
-
if (firstActivableTab
|
|
18
|
+
if (!firstActivableTab) return "";
|
|
19
19
|
return firstActivableTab.props.tabId ?? "";
|
|
20
20
|
}, [children]);
|
|
21
21
|
const [internalActiveTab, setInternalActiveTab] = useState(firstActivableTabId);
|
|
22
|
+
const [focusedTabId, setFocusedTabId] = useState(firstActivableTabId);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (activeTab !== void 0) {
|
|
25
|
+
setFocusedTabId(activeTab);
|
|
26
|
+
}
|
|
27
|
+
}, [activeTab]);
|
|
22
28
|
const actualActiveTab = useMemo(() => {
|
|
23
29
|
if (activeTab !== void 0) return activeTab;
|
|
24
30
|
return internalActiveTab;
|
|
@@ -102,7 +108,10 @@ const useTabs = (props) => {
|
|
|
102
108
|
mobileGradients,
|
|
103
109
|
updateMobileGradients,
|
|
104
110
|
handleOnTabChange,
|
|
105
|
-
userDidChangeTabAtleastOnceRef
|
|
111
|
+
userDidChangeTabAtleastOnceRef,
|
|
112
|
+
firstActivableTabId,
|
|
113
|
+
focusedTabId,
|
|
114
|
+
setFocusedTabId
|
|
106
115
|
}),
|
|
107
116
|
[
|
|
108
117
|
propsWithDefaults,
|
|
@@ -111,7 +120,9 @@ const useTabs = (props) => {
|
|
|
111
120
|
mobileGradients,
|
|
112
121
|
updateMobileGradients,
|
|
113
122
|
handleOnTabChange,
|
|
114
|
-
userDidChangeTabAtleastOnceRef
|
|
123
|
+
userDidChangeTabAtleastOnceRef,
|
|
124
|
+
firstActivableTabId,
|
|
125
|
+
focusedTabId
|
|
115
126
|
]
|
|
116
127
|
);
|
|
117
128
|
return ctx;
|
|
@@ -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", "/* eslint-disable complexity */\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, shouldHaveLeftGradient, shouldHaveRightGradient } from '../utils/helpers.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 } = 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
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACEvB,OAAOA,UAAS,QAAQ,UAAU,SAAS,iBAAiB;AAC5D,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AAGnC,SAAS,WAAW,wBAAwB,+BAA+B;AAEpE,MAAM,UAAU,CAAC,UAAiE;AACvF,QAAM,oBAAoB,6BAAoD,OAAO,kBAAkB;AAEvG,QAAM,EAAE,WAAW,UAAU,aAAa,YAAY,iBAAiB,IAAI;AAE3E,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,
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\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, shouldHaveLeftGradient, shouldHaveRightGradient } from '../utils/helpers.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 } = 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) return '';\n return firstActivableTab.props.tabId ?? '';\n }, [children]);\n\n const [internalActiveTab, setInternalActiveTab] = useState<string>(firstActivableTabId);\n const [focusedTabId, setFocusedTabId] = useState<string>(firstActivableTabId);\n\n useEffect(() => {\n if (activeTab !== undefined) {\n setFocusedTabId(activeTab);\n }\n }, [activeTab]);\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\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 (isDSMobile && !fixedTabsHeaders) {\n updateMobileGradients();\n }\n }, [updateMobileGradients, isDSMobile, fixedTabsHeaders, actualActiveTab]);\n\n // due to a bunch of reasons and the component being biting more than it can chew\n // optimizing renders to make the swipe-card work \"as expected\"(not animating on first render)\n // simply isn't feasible at this time.\n // how do we fix this anyway?\n // we track the first time a tab change triggered by the user happens\n // after the first user interaction we enable animations,\n // after that we give the animation handling control back to the swipe-card.\n const userDidChangeTabAtleastOnceRef = useRef(false);\n\n const handleOnTabChange = React.useCallback(\n (tabId: string, e?: React.MouseEvent) => {\n setInternalActiveTab(tabId);\n onTabChange(tabId, e);\n userDidChangeTabAtleastOnceRef.current = true;\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 if (isDSMobile && !fixedTabsHeaders && data.event) {\n centerTab({ e: data.event, listRef: tabsListRef });\n }\n }\n }\n if (data.target === 'swipeableViews') {\n handleOnTabChange(data.tabId!);\n }\n if (data.target === 'tabItem' && data.tabId && !(data.event.currentTarget as HTMLButtonElement).disabled) {\n handleOnTabChange(data.tabId, data.event);\n }\n },\n [propsWithDefaults.allowTextSelection, handleOnTabChange, tabsListRef, fixedTabsHeaders, isDSMobile],\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 mobileGradients,\n updateMobileGradients,\n handleOnTabChange,\n userDidChangeTabAtleastOnceRef,\n firstActivableTabId,\n focusedTabId,\n setFocusedTabId,\n }),\n [\n propsWithDefaults,\n actualActiveTab,\n globalClickHandler,\n mobileGradients,\n updateMobileGradients,\n handleOnTabChange,\n userDidChangeTabAtleastOnceRef,\n firstActivableTabId,\n focusedTabId,\n ],\n );\n\n return ctx;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React"]
|
|
7
7
|
}
|
|
@@ -1,66 +1,25 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { jsx
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useContext } from "react";
|
|
4
|
-
import { DSIconSizes } from "@elliemae/ds-icon";
|
|
5
|
-
import { BUTTON_TYPES } from "@elliemae/ds-button-v2";
|
|
6
|
-
import { ChevronRight, ChevronLeft } from "@elliemae/ds-icons";
|
|
7
4
|
import { useOwnerProps } from "@elliemae/ds-props-helpers";
|
|
8
|
-
import {
|
|
9
|
-
StyledCarouselBtnLeft,
|
|
10
|
-
StyledCarouselBtnRight,
|
|
11
|
-
StyledCarouselButtonWrapper,
|
|
12
|
-
StyledCarouselWrapper,
|
|
13
|
-
StyledChildrenWrap
|
|
14
|
-
} from "./styles.js";
|
|
5
|
+
import { StyledCarouselWrapper, StyledChildrenWrap } from "./styles.js";
|
|
15
6
|
import { useCarousel } from "./useCarousel.js";
|
|
16
7
|
import { DSTabsContext } from "../../DSTabsCTX.js";
|
|
17
|
-
import { TABS_DATA_TESTID } from "../../constants/index.js";
|
|
18
8
|
const Carousel = ({ children }) => {
|
|
19
|
-
const {
|
|
20
|
-
const {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"data-testid": TABS_DATA_TESTID.CAROUSEL_BUTTON_LEFT,
|
|
34
|
-
buttonType: BUTTON_TYPES.ICON,
|
|
35
|
-
"aria-label": "Scroll Left",
|
|
36
|
-
getOwnerProps,
|
|
37
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: DSIconSizes.S })
|
|
38
|
-
}
|
|
39
|
-
) }),
|
|
40
|
-
showChevrons.right && /* @__PURE__ */ jsx(StyledCarouselButtonWrapper, { tabType: type, right: showChevrons.right, children: /* @__PURE__ */ jsx(
|
|
41
|
-
StyledCarouselBtnRight,
|
|
42
|
-
{
|
|
43
|
-
size: "s",
|
|
44
|
-
onClick: rightButtonOnClick,
|
|
45
|
-
tabIndex: -1,
|
|
46
|
-
"data-testid": TABS_DATA_TESTID.CAROUSEL_BUTTON_RIGHT,
|
|
47
|
-
buttonType: BUTTON_TYPES.ICON,
|
|
48
|
-
"aria-label": "Scroll Right",
|
|
49
|
-
getOwnerProps,
|
|
50
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: DSIconSizes.S })
|
|
51
|
-
}
|
|
52
|
-
) }),
|
|
53
|
-
/* @__PURE__ */ jsx(
|
|
54
|
-
StyledChildrenWrap,
|
|
55
|
-
{
|
|
56
|
-
role: "tablist",
|
|
57
|
-
innerRef: carouselOnlyListRef,
|
|
58
|
-
onClick: handleOnClick,
|
|
59
|
-
onScroll: handleOnScroll,
|
|
60
|
-
children
|
|
61
|
-
}
|
|
62
|
-
)
|
|
63
|
-
] });
|
|
9
|
+
const { handleOnClick } = useCarousel();
|
|
10
|
+
const { carouselOnlyListRef, props } = useContext(DSTabsContext);
|
|
11
|
+
const { getOwnerProps, getOwnerPropsArguments } = useOwnerProps(props);
|
|
12
|
+
return /* @__PURE__ */ jsx(StyledCarouselWrapper, { getOwnerProps, getOwnerPropsArguments, children: /* @__PURE__ */ jsx(
|
|
13
|
+
StyledChildrenWrap,
|
|
14
|
+
{
|
|
15
|
+
role: "tablist",
|
|
16
|
+
innerRef: carouselOnlyListRef,
|
|
17
|
+
onClick: handleOnClick,
|
|
18
|
+
getOwnerProps,
|
|
19
|
+
getOwnerPropsArguments,
|
|
20
|
+
children
|
|
21
|
+
}
|
|
22
|
+
) });
|
|
64
23
|
};
|
|
65
24
|
export {
|
|
66
25
|
Carousel
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/carousel/Carousel.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useContext } from 'react';\nimport {
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useContext } from 'react';\nimport { useOwnerProps } from '@elliemae/ds-props-helpers';\nimport { StyledCarouselWrapper, StyledChildrenWrap } from './styles.js';\nimport { useCarousel } from './useCarousel.js';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\n\ninterface CarouselPropsT {\n children: React.ReactNode;\n}\n\nexport const Carousel = ({ children }: CarouselPropsT): JSX.Element => {\n const { handleOnClick } = useCarousel();\n\n const { carouselOnlyListRef, props } = useContext(DSTabsContext);\n\n const { getOwnerProps, getOwnerPropsArguments } = useOwnerProps(props);\n\n return (\n <StyledCarouselWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <StyledChildrenWrap\n role=\"tablist\"\n innerRef={carouselOnlyListRef}\n onClick={handleOnClick}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {children}\n </StyledChildrenWrap>\n </StyledCarouselWrapper>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACmBjB;AAnBN,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAMvB,MAAM,WAAW,CAAC,EAAE,SAAS,MAAmC;AACrE,QAAM,EAAE,cAAc,IAAI,YAAY;AAEtC,QAAM,EAAE,qBAAqB,MAAM,IAAI,WAAW,aAAa;AAE/D,QAAM,EAAE,eAAe,uBAAuB,IAAI,cAAc,KAAK;AAErE,SACE,oBAAC,yBAAsB,eAA8B,wBACnD;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACH,GACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -38,7 +38,13 @@ const StyledChildrenWrap = styled.div`
|
|
|
38
38
|
display: flex;
|
|
39
39
|
flex-wrap: nowrap;
|
|
40
40
|
flex: 1;
|
|
41
|
-
overflow-x:
|
|
41
|
+
overflow-x: auto;
|
|
42
|
+
scrollbar-gutter: stable;
|
|
43
|
+
|
|
44
|
+
&:focus-visible {
|
|
45
|
+
outline: 2px solid ${({ theme }) => theme.colors.brand[700]};
|
|
46
|
+
outline-offset: -2px;
|
|
47
|
+
}
|
|
42
48
|
`;
|
|
43
49
|
const StyledCarouselButtonWrapper = styled.div`
|
|
44
50
|
max-width: 16px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/carousel/styles.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { css, styled } from '@elliemae/ds-system';\nimport { DSButtonV2 } from '@elliemae/ds-button-v2';\n\nimport type { DSTabsInternalsT } from '../../sharedTypes.js';\nimport { DSTabsName, TABS_SLOTS, TAB_TYPES } from '../../constants/index.js';\n\ninterface StyledCarouselButtonWrapperPropsT {\n right?: boolean;\n tabType: DSTabsInternalsT.TabTypesT;\n}\n\nconst baseCarouselButtonStyles = css`\n margin: 0;\n min-width: ${({ theme }) => theme.space.xs};\n width: ${({ theme }) => theme.space.xs};\n\n &:hover:not(:disabled) {\n background-color: transparent;\n }\n background-color: transparent;\n border-radius: 0px;\n\n & .em-ds-icon svg {\n fill: ${({ theme }) => theme.colors.brand[600]};\n }\n`;\n\nexport const StyledCarouselBtnLeft = styled(DSButtonV2, {\n name: DSTabsName,\n slot: TABS_SLOTS.CAROUSEL_BUTTON_LEFT,\n})`\n ${baseCarouselButtonStyles}\n`;\n\nexport const StyledCarouselBtnRight = styled(DSButtonV2, {\n name: DSTabsName,\n slot: TABS_SLOTS.CAROUSEL_BUTTON_RIGHT,\n})`\n ${baseCarouselButtonStyles}\n`;\n\nexport const StyledCarouselWrapper = styled.span`\n position: relative;\n width: 100%;\n display: flex;\n`;\n\nexport const StyledChildrenWrap = styled.div`\n display: flex;\n flex-wrap: nowrap;\n flex: 1;\n overflow-x:
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,KAAK,cAAc;AAC5B,SAAS,kBAAkB;AAG3B,SAAS,YAAY,YAAY,iBAAiB;AAOlD,MAAM,2BAA2B;AAAA;AAAA,eAElB,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA,WACjC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAS5B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,GAAG,CAAC;AAAA;AAAA;AAI3C,MAAM,wBAAwB,OAAO,YAAY;AAAA,EACtD,MAAM;AAAA,EACN,MAAM,WAAW;AACnB,CAAC;AAAA,IACG,wBAAwB;AAAA;AAGrB,MAAM,yBAAyB,OAAO,YAAY;AAAA,EACvD,MAAM;AAAA,EACN,MAAM,WAAW;AACnB,CAAC;AAAA,IACG,wBAAwB;AAAA;AAGrB,MAAM,wBAAwB,OAAO;AAAA;AAAA;AAAA;AAAA;AAMrC,MAAM,qBAAqB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { css, styled } from '@elliemae/ds-system';\nimport { DSButtonV2 } from '@elliemae/ds-button-v2';\n\nimport type { DSTabsInternalsT } from '../../sharedTypes.js';\nimport { DSTabsName, TABS_SLOTS, TAB_TYPES } from '../../constants/index.js';\n\ninterface StyledCarouselButtonWrapperPropsT {\n right?: boolean;\n tabType: DSTabsInternalsT.TabTypesT;\n}\n\nconst baseCarouselButtonStyles = css`\n margin: 0;\n min-width: ${({ theme }) => theme.space.xs};\n width: ${({ theme }) => theme.space.xs};\n\n &:hover:not(:disabled) {\n background-color: transparent;\n }\n background-color: transparent;\n border-radius: 0px;\n\n & .em-ds-icon svg {\n fill: ${({ theme }) => theme.colors.brand[600]};\n }\n`;\n\nexport const StyledCarouselBtnLeft = styled(DSButtonV2, {\n name: DSTabsName,\n slot: TABS_SLOTS.CAROUSEL_BUTTON_LEFT,\n})`\n ${baseCarouselButtonStyles}\n`;\n\nexport const StyledCarouselBtnRight = styled(DSButtonV2, {\n name: DSTabsName,\n slot: TABS_SLOTS.CAROUSEL_BUTTON_RIGHT,\n})`\n ${baseCarouselButtonStyles}\n`;\n\nexport const StyledCarouselWrapper = styled.span`\n position: relative;\n width: 100%;\n display: flex;\n`;\n\nexport const StyledChildrenWrap = styled.div`\n display: flex;\n flex-wrap: nowrap;\n flex: 1;\n overflow-x: auto;\n scrollbar-gutter: stable;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.brand[700]};\n outline-offset: -2px;\n }\n`;\n\nexport const StyledCarouselButtonWrapper = styled.div<StyledCarouselButtonWrapperPropsT>`\n max-width: 16px;\n position: absolute;\n z-index: 200;\n ${({ right }) => (right ? 'right: 0;' : `left: 0;`)}\n width: 16px;\n height: ${({ tabType }) => (tabType === TAB_TYPES.NORMAL ? '32px' : '22px')};\n padding-top: ${({ tabType }) => (tabType === TAB_TYPES.NORMAL ? '5px' : '0px')};\n background: white;\n ${({ theme, tabType }) =>\n tabType === TAB_TYPES.NORMAL\n ? `\n background: linear-gradient(to bottom, white 0px, white 30px, ${theme.colors.neutral[400]} 30px, ${theme.colors.neutral[400]} 31px, white 31px , white 32px );\n `\n : ``};\n`;\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,KAAK,cAAc;AAC5B,SAAS,kBAAkB;AAG3B,SAAS,YAAY,YAAY,iBAAiB;AAOlD,MAAM,2BAA2B;AAAA;AAAA,eAElB,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA,WACjC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAS5B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,GAAG,CAAC;AAAA;AAAA;AAI3C,MAAM,wBAAwB,OAAO,YAAY;AAAA,EACtD,MAAM;AAAA,EACN,MAAM,WAAW;AACnB,CAAC;AAAA,IACG,wBAAwB;AAAA;AAGrB,MAAM,yBAAyB,OAAO,YAAY;AAAA,EACvD,MAAM;AAAA,EACN,MAAM,WAAW;AACnB,CAAC;AAAA,IACG,wBAAwB;AAAA;AAGrB,MAAM,wBAAwB,OAAO;AAAA;AAAA;AAAA;AAAA;AAMrC,MAAM,qBAAqB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAQhB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,GAAG,CAAC;AAAA;AAAA;AAAA;AAKxD,MAAM,8BAA8B,OAAO;AAAA;AAAA;AAAA;AAAA,IAI9C,CAAC,EAAE,MAAM,MAAO,QAAQ,cAAc,UAAW;AAAA;AAAA,YAEzC,CAAC,EAAE,QAAQ,MAAO,YAAY,UAAU,SAAS,SAAS,MAAO;AAAA,iBAC5D,CAAC,EAAE,QAAQ,MAAO,YAAY,UAAU,SAAS,QAAQ,KAAM;AAAA;AAAA,IAE5E,CAAC,EAAE,OAAO,QAAQ,MAClB,YAAY,UAAU,SAClB;AAAA,sEAC8D,MAAM,OAAO,QAAQ,GAAG,CAAC,UAAU,MAAM,OAAO,QAAQ,GAAG,CAAC;AAAA,KAE1H,EAAE;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,53 +1,38 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { useCallback,
|
|
3
|
-
import useResizeObserver from "@react-hook/resize-observer";
|
|
2
|
+
import { useCallback, useContext } from "react";
|
|
4
3
|
import { DSTabsContext } from "../../DSTabsCTX.js";
|
|
5
4
|
import { isElementVisibleCarousel } from "../../utils/helpers.js";
|
|
6
|
-
import { useCarouselCallbacks } from "./useCarouselCallbacks.js";
|
|
7
5
|
const useCarousel = () => {
|
|
8
|
-
const { carouselOnlyListRef } = useContext(DSTabsContext);
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const margin = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
|
|
32
|
-
return acc + (width + margin);
|
|
6
|
+
const { carouselOnlyListRef, focusableTabsRef } = useContext(DSTabsContext);
|
|
7
|
+
const handleOnClick = useCallback(
|
|
8
|
+
({ target }) => {
|
|
9
|
+
if (focusableTabsRef.current && target.getAttribute("role") === "tab") {
|
|
10
|
+
const tabList = carouselOnlyListRef.current;
|
|
11
|
+
const tabButton = target;
|
|
12
|
+
const tabButtonDimensions = tabButton.getBoundingClientRect();
|
|
13
|
+
const tabListDimensions = tabList?.getBoundingClientRect();
|
|
14
|
+
const tabButtonIndex = tabButton.dataset.index;
|
|
15
|
+
const lastItemIndex = focusableTabsRef.current.length.toString();
|
|
16
|
+
const magicNumber = 34;
|
|
17
|
+
const firstOrLastItem = tabButtonIndex === "0" || tabButtonIndex === lastItemIndex;
|
|
18
|
+
if (!isElementVisibleCarousel(tabButton, tabList, firstOrLastItem) && tabListDimensions && carouselOnlyListRef.current) {
|
|
19
|
+
const containerWidth = tabListDimensions.width;
|
|
20
|
+
const halfContainer = containerWidth / 2;
|
|
21
|
+
const elementScrollPosition = tabButtonDimensions.left - tabListDimensions.left;
|
|
22
|
+
const positionInContainer = elementScrollPosition % containerWidth;
|
|
23
|
+
const width = tabButton.offsetWidth + magicNumber;
|
|
24
|
+
if (positionInContainer > halfContainer) {
|
|
25
|
+
carouselOnlyListRef.current.scrollLeft += width + positionInContainer - containerWidth;
|
|
26
|
+
} else {
|
|
27
|
+
carouselOnlyListRef.current.scrollLeft += positionInContainer - magicNumber;
|
|
28
|
+
}
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return 0;
|
|
39
|
-
}, [tabsRefAsArray, carouselOnlyListRef]);
|
|
40
|
-
useResizeObserver(carouselOnlyListRef, recalcChevrons);
|
|
41
|
-
const { leftButtonOnClick, rightButtonOnClick, handleOnClick, handleOnScroll } = useCarouselCallbacks({
|
|
42
|
-
getVisibleItemsOffset,
|
|
43
|
-
recalcChevrons
|
|
44
|
-
});
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
[focusableTabsRef, carouselOnlyListRef]
|
|
33
|
+
);
|
|
45
34
|
return {
|
|
46
|
-
|
|
47
|
-
leftButtonOnClick,
|
|
48
|
-
rightButtonOnClick,
|
|
49
|
-
handleOnClick,
|
|
50
|
-
handleOnScroll
|
|
35
|
+
handleOnClick
|
|
51
36
|
};
|
|
52
37
|
};
|
|
53
38
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/carousel/useCarousel.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useCallback,
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,aAAa,
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useCallback, useContext } from 'react';\nimport { DSTabsContext } from '../../DSTabsCTX.js';\nimport { isElementVisibleCarousel } from '../../utils/helpers.js';\n\ninterface UseCarouselReturnTypeT {\n handleOnClick: (e: React.MouseEvent) => void;\n}\n\nexport const useCarousel = (): UseCarouselReturnTypeT => {\n const { carouselOnlyListRef, focusableTabsRef } = useContext(DSTabsContext);\n\n /** [PUI-15772] - Tabs Pre Refactor\n * Click handler for carousel tabs. It:\n * 1. Checks if clicked element is a tab\n * 2. Calculates scroll position to center the tab\n * 3. Updates scroll position with magic number adjustments\n * 4. May cause rerenders due to scroll position updates\n */\n const handleOnClick = useCallback(\n ({ target }: React.MouseEvent) => {\n if (focusableTabsRef.current && (target as HTMLButtonElement).getAttribute('role') === 'tab') {\n const tabList = carouselOnlyListRef.current;\n const tabButton = target as HTMLButtonElement;\n const tabButtonDimensions = tabButton.getBoundingClientRect();\n const tabListDimensions = tabList?.getBoundingClientRect();\n const tabButtonIndex = tabButton.dataset.index as string;\n const lastItemIndex = focusableTabsRef.current.length.toString();\n const magicNumber = 34;\n\n const firstOrLastItem = tabButtonIndex === '0' || tabButtonIndex === lastItemIndex;\n\n if (\n !isElementVisibleCarousel(tabButton, tabList, firstOrLastItem) &&\n tabListDimensions &&\n carouselOnlyListRef.current\n ) {\n const containerWidth = tabListDimensions.width;\n const halfContainer = containerWidth / 2;\n const elementScrollPosition = tabButtonDimensions.left - tabListDimensions.left;\n const positionInContainer = elementScrollPosition % containerWidth;\n const width = tabButton.offsetWidth + magicNumber;\n\n if (positionInContainer > halfContainer) {\n carouselOnlyListRef.current.scrollLeft += width + positionInContainer - containerWidth;\n } else {\n carouselOnlyListRef.current.scrollLeft += positionInContainer - magicNumber;\n }\n }\n }\n },\n [focusableTabsRef, carouselOnlyListRef],\n );\n\n return {\n handleOnClick,\n };\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,aAAa,kBAAkB;AACxC,SAAS,qBAAqB;AAC9B,SAAS,gCAAgC;AAMlC,MAAM,cAAc,MAA8B;AACvD,QAAM,EAAE,qBAAqB,iBAAiB,IAAI,WAAW,aAAa;AAS1E,QAAM,gBAAgB;AAAA,IACpB,CAAC,EAAE,OAAO,MAAwB;AAChC,UAAI,iBAAiB,WAAY,OAA6B,aAAa,MAAM,MAAM,OAAO;AAC5F,cAAM,UAAU,oBAAoB;AACpC,cAAM,YAAY;AAClB,cAAM,sBAAsB,UAAU,sBAAsB;AAC5D,cAAM,oBAAoB,SAAS,sBAAsB;AACzD,cAAM,iBAAiB,UAAU,QAAQ;AACzC,cAAM,gBAAgB,iBAAiB,QAAQ,OAAO,SAAS;AAC/D,cAAM,cAAc;AAEpB,cAAM,kBAAkB,mBAAmB,OAAO,mBAAmB;AAErE,YACE,CAAC,yBAAyB,WAAW,SAAS,eAAe,KAC7D,qBACA,oBAAoB,SACpB;AACA,gBAAM,iBAAiB,kBAAkB;AACzC,gBAAM,gBAAgB,iBAAiB;AACvC,gBAAM,wBAAwB,oBAAoB,OAAO,kBAAkB;AAC3E,gBAAM,sBAAsB,wBAAwB;AACpD,gBAAM,QAAQ,UAAU,cAAc;AAEtC,cAAI,sBAAsB,eAAe;AACvC,gCAAoB,QAAQ,cAAc,QAAQ,sBAAsB;AAAA,UAC1E,OAAO;AACL,gCAAoB,QAAQ,cAAc,sBAAsB;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,mBAAmB;AAAA,EACxC;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -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 { StyledMobileGradient, StyledTabList, StyledTabWrapper, StyledSubTabsList } 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 mobileGradients,\n updateMobileGradients,\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 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>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledTabWrapper>\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;ACkCX,cAUR,YAVQ;AAjCZ,SAAgB,kBAAkB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,sBAAsB,eAAe,kBAAkB,yBAAyB;AACzF,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,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,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,YACC,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB,GAExB;AAAA,QACC,cAAc,CAAC,oBACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,YAAY,SAAS;AAAA,YAC3B,OAAO,YAAY,SAAS;AAAA;AAAA,
|
|
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 { StyledMobileGradient, StyledTabList, StyledTabWrapper, StyledSubTabsList } 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 mobileGradients,\n updateMobileGradients,\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 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>\n <TabBarItemRenderer />\n </Carousel>\n ) : (\n <TabBarItemRenderer />\n )}\n </StyledTabWrapper>\n {isDSMobile && !fixedTabsHeaders && (\n <StyledMobileGradient\n mobileGradients={mobileGradients}\n left={tabsListRef.current?.scrollLeft}\n width={tabsListRef.current?.scrollWidth}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n </StyledTabList>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACkCX,cAUR,YAVQ;AAjCZ,SAAgB,kBAAkB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,sBAAsB,eAAe,kBAAkB,yBAAyB;AACzF,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,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,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,YACC,8BAAC,sBAAmB,GACtB,IAEA,oBAAC,sBAAmB,GAExB;AAAA,QACC,cAAc,CAAC,oBACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,YAAY,SAAS;AAAA,YAC3B,OAAO,YAAY,SAAS;AAAA,YAC5B;AAAA,YACA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { createElement } from "react";
|
|
4
4
|
import React2, { useContext } from "react";
|
|
5
|
-
import {
|
|
6
|
-
StyledTabButton,
|
|
7
|
-
StyledRequiredMark,
|
|
8
|
-
ScreenReaderOnly,
|
|
9
|
-
StyledSubTabButton,
|
|
10
|
-
StyledSelectionIndicator
|
|
11
|
-
} from "./styles.js";
|
|
5
|
+
import { StyledTabButton, StyledSubTabButton } from "./styles.js";
|
|
12
6
|
import { DSTabsContext, DSTabsCrossRefContext } from "../../DSTabsCTX.js";
|
|
13
7
|
import { useKeyboardNavigation } from "../../utils/hooks/useKeyboardNavigation.js";
|
|
14
8
|
import { centerTab } from "../../utils/helpers.js";
|
|
15
9
|
import { TABS_DATA_TESTID, TAB_TYPES } from "../../constants/index.js";
|
|
10
|
+
const TAB_TYPE_TO_VARIANT = {
|
|
11
|
+
[TAB_TYPES.NORMAL]: "primary",
|
|
12
|
+
[TAB_TYPES.NORMAL_SMALL]: "primary-small",
|
|
13
|
+
[TAB_TYPES.SUBTABS]: "secondary"
|
|
14
|
+
};
|
|
16
15
|
const TabBarItemRenderer = React2.memo(() => {
|
|
17
16
|
const {
|
|
18
17
|
tabsRef,
|
|
@@ -20,12 +19,14 @@ const TabBarItemRenderer = React2.memo(() => {
|
|
|
20
19
|
tabsRefAsArray,
|
|
21
20
|
carouselOnlyListRef,
|
|
22
21
|
actualActiveTab,
|
|
23
|
-
|
|
22
|
+
focusedTabId,
|
|
23
|
+
props: { type, withCarousel, isDSMobile, showSeparator, children: tabs },
|
|
24
24
|
globalClickHandler
|
|
25
25
|
} = useContext(DSTabsContext);
|
|
26
26
|
const { lastTabInternalRef, firstSubtabInternalRef } = useContext(DSTabsCrossRefContext);
|
|
27
27
|
const { handleOnKeyDown } = useKeyboardNavigation();
|
|
28
28
|
const availableTabIndexes = [];
|
|
29
|
+
const size = tabs.length || 0;
|
|
29
30
|
return React2.Children.map(tabs, (tab, index) => {
|
|
30
31
|
const {
|
|
31
32
|
tabId = "",
|
|
@@ -34,24 +35,34 @@ const TabBarItemRenderer = React2.memo(() => {
|
|
|
34
35
|
required = false,
|
|
35
36
|
disabled = false,
|
|
36
37
|
applyAriaDisabled = false,
|
|
38
|
+
RenderBadge,
|
|
37
39
|
ref,
|
|
38
40
|
onClick,
|
|
39
41
|
onKeyDown,
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
43
|
+
children: _panelContent,
|
|
40
44
|
...rest
|
|
41
45
|
} = tab.props;
|
|
42
46
|
const getOwnerProps = () => tab.props;
|
|
43
47
|
const getOwnerPropsArguments = () => ({ tabId });
|
|
44
48
|
if (!disabled) availableTabIndexes.push(index);
|
|
45
|
-
const ButtonComponent = type === TAB_TYPES.SUBTABS ? StyledSubTabButton : StyledTabButton;
|
|
46
49
|
const isActive = actualActiveTab === tabId;
|
|
50
|
+
const variant = TAB_TYPE_TO_VARIANT[type] ?? "primary";
|
|
51
|
+
const isLastItem = index === size - 1;
|
|
52
|
+
const ButtonComponent = type === TAB_TYPES.SUBTABS ? StyledSubTabButton : StyledTabButton;
|
|
47
53
|
return /* @__PURE__ */ createElement(
|
|
48
54
|
ButtonComponent,
|
|
49
55
|
{
|
|
56
|
+
tabIndex: focusedTabId === tabId ? 0 : -1,
|
|
50
57
|
...rest,
|
|
51
|
-
getOwnerProps,
|
|
52
|
-
getOwnerPropsArguments,
|
|
53
58
|
key: tabId,
|
|
54
59
|
role: "tab",
|
|
60
|
+
label: title,
|
|
61
|
+
variant,
|
|
62
|
+
isSelected: isActive,
|
|
63
|
+
disabled,
|
|
64
|
+
applyAriaDisabled,
|
|
65
|
+
required,
|
|
55
66
|
innerRef: (tabButtonRef) => {
|
|
56
67
|
if (tabButtonRef && tabsRefAsArray.current && focusableTabsRef.current && tabsRef.current) {
|
|
57
68
|
tabsRefAsArray.current[index] = tabButtonRef;
|
|
@@ -67,20 +78,11 @@ const TabBarItemRenderer = React2.memo(() => {
|
|
|
67
78
|
if (ref) ref.current = tabButtonRef;
|
|
68
79
|
}
|
|
69
80
|
},
|
|
70
|
-
type: "button",
|
|
71
81
|
"aria-controls": tabId,
|
|
72
82
|
"aria-selected": actualActiveTab === tabId && !applyAriaDisabled,
|
|
73
|
-
"aria-disabled": disabled || applyAriaDisabled,
|
|
74
|
-
isDSMobile,
|
|
75
|
-
fixedTabsHeaders,
|
|
76
|
-
tabType: type,
|
|
77
83
|
"data-required": required,
|
|
78
84
|
"data-tab-id": tabId,
|
|
79
85
|
"data-index": index,
|
|
80
|
-
withCarousel,
|
|
81
|
-
isActive,
|
|
82
|
-
disabled,
|
|
83
|
-
showSeparator: showSeparator && type !== TAB_TYPES.NORMAL,
|
|
84
86
|
"data-testid": type === TAB_TYPES.NORMAL ? TABS_DATA_TESTID.TAB_BUTTON : TABS_DATA_TESTID.SUBTAB_BUTTON,
|
|
85
87
|
id: `${tabId}-label`,
|
|
86
88
|
onClick: (e) => {
|
|
@@ -98,14 +100,14 @@ const TabBarItemRenderer = React2.memo(() => {
|
|
|
98
100
|
if (!disabled) handleOnKeyDown(e);
|
|
99
101
|
if (onKeyDown && !disabled) onKeyDown(e);
|
|
100
102
|
},
|
|
101
|
-
style
|
|
103
|
+
style,
|
|
104
|
+
showSeparator: showSeparator && type !== TAB_TYPES.NORMAL && !isLastItem,
|
|
105
|
+
isDSMobile,
|
|
106
|
+
tabType: type,
|
|
107
|
+
getOwnerProps,
|
|
108
|
+
getOwnerPropsArguments
|
|
102
109
|
},
|
|
103
|
-
|
|
104
|
-
required && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
105
|
-
/* @__PURE__ */ jsx(StyledRequiredMark, { "aria-hidden": "true", children: "\u25CF" }),
|
|
106
|
-
/* @__PURE__ */ jsx(ScreenReaderOnly, { children: "Required" })
|
|
107
|
-
] }),
|
|
108
|
-
isActive && type !== TAB_TYPES.SUBTABS ? /* @__PURE__ */ jsx(StyledSelectionIndicator, { "aria-hidden": "true", isDSMobile, tabType: type }) : null
|
|
110
|
+
RenderBadge ? /* @__PURE__ */ jsx(RenderBadge, {}) : null
|
|
109
111
|
);
|
|
110
112
|
});
|
|
111
113
|
});
|
|
@@ -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", "
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\nimport React, { useContext } from 'react';\nimport { StyledTabButton, 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\n/**\n * Maps ds-tabs TAB_TYPES to ds-tab-button variant strings.\n * NORMAL \u2192 'primary', NORMAL_SMALL \u2192 'primary-small', SUBTABS \u2192 'secondary'\n */\nconst TAB_TYPE_TO_VARIANT = {\n [TAB_TYPES.NORMAL]: 'primary',\n [TAB_TYPES.NORMAL_SMALL]: 'primary-small',\n [TAB_TYPES.SUBTABS]: 'secondary',\n} as const;\n\nexport const TabBarItemRenderer: React.ComponentType<Record<never, never>> = React.memo(() => {\n const {\n tabsRef,\n focusableTabsRef,\n tabsRefAsArray,\n carouselOnlyListRef,\n actualActiveTab,\n focusedTabId,\n props: { type, 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 const size = tabs.length || 0;\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 RenderBadge,\n ref,\n onClick,\n onKeyDown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n children: _panelContent,\n ...rest\n } = tab.props;\n const getOwnerProps = () => tab.props;\n const getOwnerPropsArguments = () => ({ tabId });\n\n if (!disabled) availableTabIndexes.push(index);\n\n const isActive = actualActiveTab === tabId;\n const variant = TAB_TYPE_TO_VARIANT[type] ?? 'primary';\n const isLastItem = index === size - 1;\n const ButtonComponent = type === TAB_TYPES.SUBTABS ? StyledSubTabButton : StyledTabButton;\n\n return (\n <ButtonComponent\n tabIndex={focusedTabId === tabId ? 0 : -1}\n {...rest}\n key={tabId}\n role=\"tab\"\n label={title}\n variant={variant}\n isSelected={isActive}\n disabled={disabled}\n applyAriaDisabled={applyAriaDisabled}\n required={required}\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 aria-controls={tabId}\n aria-selected={actualActiveTab === tabId && !applyAriaDisabled}\n data-required={required}\n data-tab-id={tabId}\n data-index={index}\n data-testid={type === TAB_TYPES.NORMAL ? TABS_DATA_TESTID.TAB_BUTTON : TABS_DATA_TESTID.SUBTAB_BUTTON}\n id={`${tabId}-label`}\n onClick={(e: React.MouseEvent) => {\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: React.FocusEvent) => {\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: React.KeyboardEvent) => {\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 showSeparator={showSeparator && type !== TAB_TYPES.NORMAL && !isLastItem}\n isDSMobile={isDSMobile}\n tabType={type}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {RenderBadge ? <RenderBadge /> : null}\n </ButtonComponent>\n );\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React"]
|
|
7
7
|
}
|