1- import { createContext , useContext , useCallback , useEffect , useState } from 'react' ;
2- import { Button , ButtonVariant , Flex , FlexItem , Popover } from '../..' ;
1+ import { createContext , useContext , useCallback , useEffect , useState , useRef } from 'react' ;
2+ import { Button , ButtonVariant , debounce , Flex , FlexItem , getResizeObserver , Popover } from '../..' ;
33import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon' ;
44import { GuidedTourStep } from './types' ;
55
@@ -9,6 +9,7 @@ interface GuidedTourContextType {
99 onPrevStep : ( ) => void ;
1010 onFinish : ( ) => void ;
1111 tourStep : GuidedTourStep | undefined ;
12+ isFinished : boolean ;
1213 setCustomStepContent : ( customContent : React . ReactNode ) => void ;
1314 renderTourStepElement : ( forStepId : string , child : React . ReactElement ) => React . ReactElement ;
1415}
@@ -20,7 +21,8 @@ const GuidedTourContext = createContext<GuidedTourContextType>({
2021 onFinish : ( ) => { } ,
2122 setCustomStepContent : ( ) => { } ,
2223 renderTourStepElement : ( ) => null ,
23- tourStep : undefined
24+ tourStep : undefined ,
25+ isFinished : false
2426} ) ;
2527
2628export const GuidedTourProvider : React . FC < { steps : GuidedTourStep [ ] ; children : React . ReactNode } > = ( {
@@ -29,6 +31,10 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
2931} ) => {
3032 const [ currentStep , setCurrentStep ] = useState < number | undefined > ( ) ;
3133 const [ customStepContent , setCustomStepContent ] = useState < React . ReactNode | undefined > ( ) ;
34+ const [ windowWidth , setWindowWidth ] = useState < number > ( ) ;
35+ const unObserver = useRef ( null ) ;
36+
37+ const isMobile = windowWidth < 500 ;
3238
3339 useEffect ( ( ) => {
3440 setCurrentStep ( undefined ) ;
@@ -48,12 +54,12 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
4854 const onNextStep = useCallback ( ( ) => {
4955 setCustomStepContent ( undefined ) ;
5056 setCurrentStep ( ( prev ) => {
51- if ( prev === undefined || prev === steps . length ) {
57+ if ( prev === undefined ) {
5258 return prev ;
5359 }
5460 return prev + 1 ;
5561 } ) ;
56- } , [ steps ] ) ;
62+ } , [ ] ) ;
5763
5864 const onPrevStep = useCallback ( ( ) => {
5965 setCustomStepContent ( undefined ) ;
@@ -66,6 +72,7 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
6672 } , [ ] ) ;
6773
6874 const tourStep = currentStep !== undefined ? steps [ currentStep ] : undefined ;
75+ const isFinished = currentStep !== undefined ? currentStep >= steps . length : false ;
6976
7077 const renderTourStepElement = useCallback (
7178 ( forStepId : string , child : React . ReactElement ) => {
@@ -76,7 +83,7 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
7683 < Popover
7784 isVisible
7885 showClose
79- maxWidth = " 28rem"
86+ maxWidth = { isMobile ? undefined : ' 28rem' }
8087 hideOnOutsideClick = { false }
8188 position = { tourStep . position }
8289 headerContent = {
@@ -113,11 +120,8 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
113120 </ Button >
114121 </ FlexItem >
115122 < FlexItem >
116- < Button
117- variant = { ButtonVariant . primary }
118- onClick = { ( ) => ( currentStep < steps . length ? onNextStep ( ) : onFinish ( ) ) }
119- >
120- { currentStep < steps . length - 1 ? 'Next' : 'Finish' }
123+ < Button variant = { ButtonVariant . primary } onClick = { onNextStep } >
124+ Next
121125 </ Button >
122126 </ FlexItem >
123127 </ Flex >
@@ -129,13 +133,53 @@ export const GuidedTourProvider: React.FC<{ steps: GuidedTourStep[]; children: R
129133 </ Popover >
130134 ) ;
131135 } ,
132- [ tourStep , currentStep , steps , onNextStep , onPrevStep , onFinish , customStepContent ]
136+ [ tourStep , currentStep , steps , onNextStep , onPrevStep , onFinish , customStepContent , isMobile ]
137+ ) ;
138+
139+ const measureRef = ( ref : HTMLDivElement ) => {
140+ // Remove any previous observer
141+ if ( unObserver . current ) {
142+ unObserver . current ( ) ;
143+ }
144+
145+ if ( ! ref ) {
146+ return ;
147+ }
148+
149+ const handleResize = ( ) => setWindowWidth ( ref . clientWidth ) ;
150+
151+ // Set size on initialization
152+ handleResize ( ) ;
153+
154+ const debounceResize = debounce ( handleResize , 100 ) ;
155+
156+ // Update graph size on resize events
157+ unObserver . current = getResizeObserver ( ref , debounceResize ) ;
158+ } ;
159+
160+ useEffect (
161+ ( ) => ( ) => {
162+ if ( unObserver . current ) {
163+ unObserver . current ( ) ;
164+ }
165+ } ,
166+ [ ]
133167 ) ;
134168
135169 return (
136170 < GuidedTourContext . Provider
137- value = { { onStart, onNextStep, onPrevStep, onFinish, setCustomStepContent, renderTourStepElement, tourStep } }
171+ value = { {
172+ onStart,
173+ onNextStep,
174+ onPrevStep,
175+ onFinish,
176+ setCustomStepContent,
177+ renderTourStepElement,
178+ tourStep,
179+ isFinished
180+ } }
138181 >
182+ < div ref = { measureRef } style = { { width : '100%' } } />
139183 { children }
140184 </ GuidedTourContext . Provider >
141185 ) ;
0 commit comments