({
show: isTutorialOpen,
setShow: setIsTutorialOpen,
initialStep = 0,
})
| 89 | }; |
| 90 | |
| 91 | const TutorialDialog: FC<TutorialProps> = ({ |
| 92 | show: isTutorialOpen, |
| 93 | setShow: setIsTutorialOpen, |
| 94 | initialStep = 0, |
| 95 | }) => { |
| 96 | const [currentStep, setCurrentStep] = useState(initialStep); |
| 97 | const steps = useMemo(() => tutorialSteps, []); |
| 98 | |
| 99 | // Hotkeys for tutorial |
| 100 | // ArrowLeft: Go to previous slide |
| 101 | // ArrowRight: Go to next slide |
| 102 | const hotKeysMap: HotKeysType = { |
| 103 | ARROW_LEFT: { |
| 104 | key: "ArrowLeft", |
| 105 | asyncHandler: async (event: KeyboardEvent<HTMLElement>) => { |
| 106 | event.preventDefault(); |
| 107 | |
| 108 | decreaseSlide(); |
| 109 | logAnalyticsEvent("tutorial_arrow_left"); |
| 110 | }, |
| 111 | }, |
| 112 | ARROW_RIGHT: { |
| 113 | key: "ArrowRight", |
| 114 | asyncHandler: async (event: KeyboardEvent<HTMLElement>) => { |
| 115 | event.preventDefault(); |
| 116 | |
| 117 | increaseSlide(); |
| 118 | logAnalyticsEvent("tutorial_arrow_right"); |
| 119 | }, |
| 120 | }, |
| 121 | }; |
| 122 | |
| 123 | const increaseSlide = () => { |
| 124 | if (currentStep === steps.length - 1) { |
| 125 | closeTutorial(); |
| 126 | return; |
| 127 | } |
| 128 | |
| 129 | setCurrentStep(currentStep + 1); |
| 130 | }; |
| 131 | |
| 132 | const decreaseSlide = () => { |
| 133 | if (currentStep === 0) return; |
| 134 | setCurrentStep(currentStep - 1); |
| 135 | }; |
| 136 | |
| 137 | const closeTutorial = () => { |
| 138 | setIsTutorialOpen(false); |
| 139 | setCurrentStep(0); |
| 140 | logAnalyticsEvent("tutorial_closed"); |
| 141 | }; |
| 142 | |
| 143 | return ( |
| 144 | <Modal isOpen={isTutorialOpen} closeModal={closeTutorial}> |
| 145 | <div |
| 146 | className="w-[30rem]" |
| 147 | onKeyDown={async (event: KeyboardEvent<HTMLElement>) => { |
| 148 | const hotKey = event.key; |
nothing calls this directly
no test coverage detected