From dc7c6bc572d7357e62e689fa5e0c7b6fa917ec18 Mon Sep 17 00:00:00 2001 From: Dipu Raj Date: Mon, 29 Jan 2024 23:00:31 +0530 Subject: [PATCH] Dev updates --- example/src/App.js | 19 ++++- example/src/index.css | 4 ++ src/components/TabNavItem.js | 4 +- src/components/Tabs.js | 136 ++++++++++++++++++++++++++++++----- src/helpers/utility.js | 93 ++++++++++++++++++++++++ 5 files changed, 236 insertions(+), 20 deletions(-) diff --git a/example/src/App.js b/example/src/App.js index 63ab72b..9ab6e25 100644 --- a/example/src/App.js +++ b/example/src/App.js @@ -69,14 +69,20 @@ const App = () => { orientation={tabSettings.vertical ? 'vertical' : 'horizontal'} justified={tabSettings.justified.toString()} enableURLhash={true} + backButtonSupport={true} + keyNavigation={true} + scrollOffset="20" + autoProgress={false} + autoProgressInterval={3500} + stopOnFocus={true} onLeaveTab={(e) => { console.log("leaveTab", e) }} onShowTab={(e) => { console.log("showTab", e) }} > Tab 1 This is tab description - Tab 2 This is tab description + Tab 2 This is tab description Tab 3 This is tab description - Tab 4 This is tab description + Tab 4 This is tab description @@ -100,6 +106,7 @@ const App = () => { +


@@ -139,6 +146,9 @@ const App = () => { orientation={tabSettings2.vertical ? 'vertical' : 'horizontal'} justified={tabSettings2.justified.toString()} enableURLhash={true} + backButtonSupport={true} + keyNavigation={true} + scrollOffset="30" onLeaveTab={(currentIndex, nextIndex) => { console.log("leaveTab", currentIndex, nextIndex) }} onShowTab={(e) => { console.log("showTab", e) }} > @@ -169,6 +179,11 @@ const App = () => { +

+
+
+ + } diff --git a/example/src/index.css b/example/src/index.css index 1cd0993..8846396 100644 --- a/example/src/index.css +++ b/example/src/index.css @@ -10,3 +10,7 @@ body { padding-left: 5%; padding-right: 5%; } + +.spacer { + height: 500px; +} diff --git a/src/components/TabNavItem.js b/src/components/TabNavItem.js index 32bcf91..467adab 100644 --- a/src/components/TabNavItem.js +++ b/src/components/TabNavItem.js @@ -35,14 +35,14 @@ export default function TabNavItem(props) { const getNavIdx = () => { return tabIdx + '-' + (index + 1) } - +// {'#' + getNavIdx()} return (
  • { - navigateTab(selected) - }, [selected]) const navigateTab = (index) => { const nextIndex = parseInt(index) - if (nextIndex !== selectedIndex) { + if (nextIndex !== selectedIndex && isShowableTabIndex(props.children, nextIndex)) { if (typeof onLeaveTab === 'function') { if (onLeaveTab(selectedIndex, nextIndex) === false) return } + // console.log("navigateTab", nextIndex, selectedIndex) updateSelectedIndex(nextIndex) + // console.log("navigateTab2", nextIndex, selectedIndex) + + if (enableURLhash !== false) { + setURLHash(getTabNavHash(tabIdx, nextIndex)) + } if (typeof onShowTab === 'function') { onShowTab(nextIndex) @@ -53,6 +77,7 @@ export default function Tabs(props) { const getChildren = (children) => { return recursiveMap(children, (child, index) => { if (child.type === TabNavItem) { + // console.log("getChildren", index, selectedIndex) return React.cloneElement(child, { index: index, tabIdx: tabIdx, @@ -70,10 +95,75 @@ export default function Tabs(props) { }) } - const handleClick = (e) => { - if (props.enableURLhash === false) { - e.preventDefault() + useEffect(() => { + navigateTab(selected) + }, [selected]) + + + const [counter, setCounter] = useState(0); + + useEffect(() => { + // console.log("Timer Init", autoProgress); + if (autoProgress) { + + // let tId = startTimer(() => { + // let newIdx = getNextTabIndex(props.children, selectedIndex) + // console.log("Timer Call", selectedIndex, newIdx); + // navigateTab(selectedIndex => getNextTabIndex(props.children, selectedIndex)) + // }) + + let tId = setInterval(() => { + ((selectedIndex) => { + let newIdx = getNextTabIndex(props.children, selectedIndex) + console.log("Timer Call", selectedIndex, newIdx); + navigateTab(newIdx) + return selectedIndex + })(selectedIndex) + // updateSelectedIndex(newIdx => newIdx) + // console.log("Timer Call", timerId); + // let tt = timerId + 1 + // navigateTab(selectedIndex => getNextTabIndex(props.children, selectedIndex)) + updateTimerId(timerId => timerId + 1) + // setCounter(counter => counter + 1); + }, 3500) + // + // updateTimerId(tId) } + }, []) + + + + // useEffect(() => { + // const interval = setInterval(() => { + // setCounter(counter => counter + 1); + // }, 5000); + // + // return () => { + // clearInterval(interval); + // }; + // }, []); + + useEffect(() => { + console.log("backButtonSupport", backButtonSupport); + if (backButtonSupport) { + window.addEventListener('hashchange', onHashChange) + return () => window.removeEventListener('hashchange', onHashChange) + } + }, [backButtonSupport]) + + const onHashChange = (e) => { + const hash = window.location.hash + if (hash.indexOf(tabIdx) !== -1) { + const hashChunks = hash.split('-'); + if (hashChunks.length == 2) { + scrollToRef(tabRef, scrollOffset) + navigateTab(hashChunks[1] - 1) + } + } + } + + const handleClick = (e) => { + e.preventDefault() const node = e.currentTarget if (node && node.getAttribute('role') === 'tab') { @@ -81,12 +171,25 @@ export default function Tabs(props) { } } + const handleKeyUp = (e) => { + if (keyNavigation) { + if (e.keyCode === 37 || e.keyCode === 38) { + // Left + navigateTab(getPreviousTabIndex(props.children, selectedIndex)) + } else if (e.keyCode === 39 || e.keyCode === 40) { + // Right + navigateTab(getNextTabIndex(props.children, selectedIndex)) + } else if (e.keyCode === 35) { + // End + navigateTab(getLastTabIndex(props.children)) + } else if (e.keyCode === 36) { + // Home + navigateTab(getFirstTabIndex(props.children)) + } + } + } + const getClassName = () => { - console.log( - 'justified', - justified, - justified === true ? ' st-justified' : '' - ) return ( 'st st-theme-' + (theme || 'default') + @@ -97,7 +200,8 @@ export default function Tabs(props) { } return ( -
    +
    + {timerId} {getChildren(props.children)}
    ) diff --git a/src/helpers/utility.js b/src/helpers/utility.js index aa4ba3a..a1c5b09 100644 --- a/src/helpers/utility.js +++ b/src/helpers/utility.js @@ -12,6 +12,7 @@ import React from 'react' import TabNavItem from '../components/TabNavItem' +import TabNav from '../components/TabNav' export const recursiveMap = (children, fn) => { return React.Children.map(children, (child, index) => { @@ -43,3 +44,95 @@ export const getTabCount = (children) => { }) return tabCount } + +export const getTabNavs = (children) => { + return children.filter(el => { + if (el.type === TabNav) { + return true + } + }); +} + +export const getTabNavItems = (children) => { + return getTabNavs(children)[0].props.children.filter(el => { + if (el.type === TabNavItem) { + return true + } + }); +} + +export const getTabNavElement = (children, index) => { + return getTabNavItems(children).filter((el, idx) => { + if (idx === index) { + return true + } + }); +} + +export const getNextTabIndex = (children, index) => { + const tabNavItems = getTabNavItems(children); + let nextIndex = 0 + for(let i = index+1; i < tabNavItems.length; i++) { + if (isShowableTabElement(tabNavItems[i]) === true) { + nextIndex = i + break; + } + } + return nextIndex +} + +export const getPreviousTabIndex = (children, index) => { + const tabNavItems = getTabNavItems(children); + let nextIndex = tabNavItems.length - 1 + for(let i = index-1; i >= 0; i--) { + if (isShowableTabElement(tabNavItems[i]) === true) { + nextIndex = i + break; + } + } + return nextIndex +} + +export const getFirstTabIndex = (children) => { + return getNextTabIndex(children, -1) +} + +export const getLastTabIndex = (children) => { + return getPreviousTabIndex(children, getTabNavItems(children).length) +} + +export const isShowableTabIndex = (children, index) => { + return isShowableTabElement(getTabNavElement(children, index)[0]) +} + +export const isShowableTabElement = (elm) => { + if (elm == null) return false + if (elm.props.disabled !== true) { + return true + } +} + +export const getTabNavHash = (tabIdx, index) => { + index++ + return '#' + tabIdx + '-' + index +} + +export const setURLHash = (hash) => { + history.pushState(null,null,hash) +} + +export const scrollToRef = (ref, scrollOffset) => { + window.scrollTo(0, ref.current.offsetTop - (parseInt(scrollOffset) || 0)) +} + +export const startTimer = (fn) => { + return setInterval(() => fn(), 3500) +} + +export const stopTimer = (timerId) => { + clearInterval(timerId) +} + +export const resetTimer = (fn) => { + return fn() +}