diff --git a/src/components/LanguageChoice/LanguagesList.tsx b/src/components/LanguageChoice/LanguagesList.tsx index 2d0c9dbf7..e10bfd36a 100644 --- a/src/components/LanguageChoice/LanguagesList.tsx +++ b/src/components/LanguageChoice/LanguagesList.tsx @@ -1,17 +1,16 @@ -import React from "react"; +import React, { useEffect, useRef } from "react"; import i18n from "i18next"; - -import { useRecoilState } from "recoil"; +import { useSetRecoilState } from "recoil"; import { ILanguageListProps, ILanguage } from "@src/Interfaces/ILanguage"; import { vibrateWorks } from "@src/constants/vibrateCheck"; import { languageSelectionState } from "@src/store"; +import { useLanguageSelection } from "../../hooks/useLanguageSelection"; -export const LanguagesList = (props: ILanguageListProps) => { - const { languages, navigationCallback, type, hideSelected } = props; - const [, setIsLanguageChosen] = useRecoilState(languageSelectionState); - const sortedLanguages = [languages[0], ...languages.slice(1).sort((a, b) => a.title.localeCompare(b.title))]; +export const LanguagesList = ({ languages, navigationCallback, type, hideSelected }: ILanguageListProps) => { + const setIsLanguageChosen = useSetRecoilState(languageSelectionState); + const labelRefs = useRef([]); - const handleClick = (langId: string) => { + const handleLanguageSelect = (langId: string) => { if (vibrateWorks) { navigator.vibrate(100); } @@ -21,20 +20,38 @@ export const LanguagesList = (props: ILanguageListProps) => { if (type === "fragment" && navigationCallback) navigationCallback("/ZinZenFAQ"); else window.history.back(); }; + + const handleClick = (event: React.MouseEvent, langId: string) => { + event.preventDefault(); + handleLanguageSelect(langId); + }; + + const focusedIndex = useLanguageSelection(languages, handleLanguageSelect); + + useEffect(() => { + labelRefs.current[focusedIndex]?.focus(); + }, [focusedIndex]); + return (
- {sortedLanguages.map((lang: ILanguage) => ( - + handleClick(e, lang.langId)} + checked={lang.selected} + readOnly + id={lang.sno.toString()} + /> + ))}
); diff --git a/src/hooks/useKeyPress.ts b/src/hooks/useKeyPress.ts new file mode 100644 index 000000000..0645a4ff0 --- /dev/null +++ b/src/hooks/useKeyPress.ts @@ -0,0 +1,26 @@ +import { useEffect, useState, useCallback } from "react"; + +export const useKeyPress = (targetKey: string) => { + const [keyPressed, setKeyPressed] = useState(false); + + const keyHandler = useCallback( + (event: KeyboardEvent) => { + if (event.key === targetKey) { + setKeyPressed(event.type === "keydown"); + } + }, + [targetKey], + ); + + useEffect(() => { + window.addEventListener("keydown", keyHandler); + window.addEventListener("keyup", keyHandler); + + return () => { + window.removeEventListener("keydown", keyHandler); + window.removeEventListener("keyup", keyHandler); + }; + }, [keyHandler]); + + return keyPressed; +}; diff --git a/src/hooks/useLanguageSelection.ts b/src/hooks/useLanguageSelection.ts new file mode 100644 index 000000000..6e81ab8e8 --- /dev/null +++ b/src/hooks/useLanguageSelection.ts @@ -0,0 +1,32 @@ +import { ILanguage } from "@src/Interfaces"; +import { useEffect, useState } from "react"; +import { useKeyPress } from "./useKeyPress"; + +export const useLanguageSelection = (languages: ILanguage[], handleClick: (langId: string) => void): number => { + const [focusedIndex, setFocusedIndex] = useState(0); + + const upPress = useKeyPress("ArrowUp"); + const downPress = useKeyPress("ArrowDown"); + const enterPress = useKeyPress("Enter"); + + useEffect(() => { + if (downPress) { + setFocusedIndex((prevIndex) => (prevIndex + 1) % languages.length); + } + }, [downPress]); + + useEffect(() => { + if (upPress) { + setFocusedIndex((prevIndex) => (prevIndex - 1 + languages.length) % languages.length); + } + }, [upPress]); + + useEffect(() => { + if (enterPress) { + const { langId } = languages[focusedIndex]; + handleClick(langId); + } + }, [enterPress]); + + return focusedIndex; +}; diff --git a/src/pages/FAQPage/FAQPage.tsx b/src/pages/FAQPage/FAQPage.tsx index 954aac0cc..b29626ad0 100644 --- a/src/pages/FAQPage/FAQPage.tsx +++ b/src/pages/FAQPage/FAQPage.tsx @@ -1,15 +1,15 @@ /* eslint-disable no-unused-expressions */ -import React from "react"; +import React, { useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; - +import { useRecoilValue } from "recoil"; +import { darkModeState } from "@src/store"; import chevronLeftIcon from "@assets/images/chevronLeft.svg"; - import ZAccordion from "@src/common/Accordion"; -import { vibrateWorks } from "@src/constants/vibrateCheck"; import OnboardingLayout from "@src/layouts/OnboardingLayout"; -import { useRecoilValue } from "recoil"; -import { darkModeState } from "@src/store"; +import { vibrateWorks } from "@src/constants/vibrateCheck"; +import { useKeyPress } from "@src/hooks/useKeyPress"; + import "./FAQPage.scss"; import "@translations/i18n"; @@ -24,6 +24,8 @@ export const FAQPage = () => { { header: t("qTooGoodToBeTrue"), body: t("ansTooGoodToBeTrue") }, ]; + const enterPressed = useKeyPress("Enter"); + const handleClick = () => { localStorage.setItem("checkedIn", "yes"); const invite = localStorage.getItem("pendingInvite"); @@ -36,6 +38,12 @@ export const FAQPage = () => { } }; + useEffect(() => { + if (enterPressed) { + handleClick(); + } + }, [enterPressed]); + return (

@@ -46,7 +54,8 @@ export const FAQPage = () => { defaultActiveKey={["1"]} showCount={false} style={{ background: "var(--bottom-nav-color)" }} - panels={QnA.map((ele) => ({ + panels={QnA.map((ele, index) => ({ + key: index.toString(), header: ele.header, body: (

diff --git a/src/pages/LandingPage/LandingPage.scss b/src/pages/LandingPage/LandingPage.scss index 378257937..cf1dd5fab 100644 --- a/src/pages/LandingPage/LandingPage.scss +++ b/src/pages/LandingPage/LandingPage.scss @@ -14,7 +14,7 @@ border-radius: 0.5rem; box-shadow: 0px 5px 6px rgba(0, 0, 0, 0.25); - button { + label { width: 100%; display: flex; justify-content: space-between; @@ -27,8 +27,14 @@ border-bottom: 1px solid var(--default-border-color); } + .focused { + border: var(--icon-grad-2) 2px solid; + border-radius: 4px; + } + input[type="radio"] { accent-color: #cd6e51 !important; + outline: none; } .selected {