diff --git a/react-common/components/controls/EditorToggle.tsx b/react-common/components/controls/EditorToggle.tsx index 44422de3242..1b40f580263 100644 --- a/react-common/components/controls/EditorToggle.tsx +++ b/react-common/components/controls/EditorToggle.tsx @@ -125,7 +125,11 @@ const EditorToggleAccessibleMenu = (props: EditorToggleProps) => { next.push({...current}); // The selected item will always be a top-level option, not in a dropdown - if (selected === index) next[next.length - 1].selected = true; + if (selected === index) { + next[next.length - 1].selected = true; + } else { + next[next.length - 1].selected = false; + } if (isDropdownItem(current)) { next.push(...current.items.filter(i => i.focusable)) diff --git a/react-common/components/controls/FocusList.tsx b/react-common/components/controls/FocusList.tsx index 102dbd399d9..8e316a2f7fe 100644 --- a/react-common/components/controls/FocusList.tsx +++ b/react-common/components/controls/FocusList.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { ContainerProps } from "../util"; +import { ContainerProps, findNextFocusableElement } from "../util"; export interface FocusListProps extends ContainerProps { role: string; @@ -62,37 +62,6 @@ export const FocusList = (props: FocusListProps) => { && getComputedStyle(e).display !== "none"; } - const firstFocusableElement = () => { - return focusableElements.find(e => isFocusable(e)) - } - - const lastFocusableElement = () => { - for (let i = 0; i < focusableElements.length; i++) { - if (isFocusable(focusableElements[focusableElements.length - 1 - i])) { - return focusableElements[focusableElements.length - 1 - i]; - } - } - - return focusableElements[0]; - } - - const nextFocusableElement = (index: number, forwards: boolean) => { - let current: HTMLElement - for (let i = 1; i < focusableElements.length; i++) { - if (forwards) { - current = focusableElements[(index + i) % focusableElements.length]; - } - else { - current = focusableElements[(index + focusableElements.length - i) % focusableElements.length]; - } - - if (isFocusable(current)) { - return current; - } - } - return focusableElements[0]; - } - const onKeyDown = (e: React.KeyboardEvent) => { if (!focusableElements?.length) return; @@ -120,31 +89,31 @@ export const FocusList = (props: FocusListProps) => { } else if (e.key === (useUpAndDownArrowKeys ? "ArrowDown" : "ArrowRight")) { if (index === focusableElements.length - 1 || target === focusList) { - focus(firstFocusableElement()); + focus(findNextFocusableElement(focusableElements, index, 0, true, isFocusable)); } else { - focus(nextFocusableElement(index, true)); + focus(findNextFocusableElement(focusableElements, index, index + 1, true, isFocusable)); } e.preventDefault(); e.stopPropagation(); } else if (e.key === (useUpAndDownArrowKeys ? "ArrowUp" : "ArrowLeft")) { if (index === 0 || target === focusList) { - focus(lastFocusableElement()); + focus(findNextFocusableElement(focusableElements, index, focusableElements.length - 1, false, isFocusable)); } else { - focus(nextFocusableElement(index, false)); + focus(findNextFocusableElement(focusableElements, index, index - 1, false, isFocusable)); } e.preventDefault(); e.stopPropagation(); } else if (e.key === "Home") { - focus(firstFocusableElement()); + focus(findNextFocusableElement(focusableElements, index, 0, true, isFocusable)); e.preventDefault(); e.stopPropagation(); } else if (e.key === "End") { - focus(lastFocusableElement()); + focus(findNextFocusableElement(focusableElements, index, focusableElements.length - 1, true, isFocusable)); e.preventDefault(); e.stopPropagation(); } diff --git a/react-common/components/controls/FocusTrap.tsx b/react-common/components/controls/FocusTrap.tsx index 17ff6c343ca..5c214a44fc8 100644 --- a/react-common/components/controls/FocusTrap.tsx +++ b/react-common/components/controls/FocusTrap.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { classList, nodeListToArray } from "../util"; +import { classList, nodeListToArray, findNextFocusableElement } from "../util"; export interface FocusTrapProps extends React.PropsWithChildren<{}> { onEscape: () => void; @@ -58,24 +58,24 @@ export const FocusTrap = (props: FocusTrapProps) => { if (forward) { if (goToEnd) { - focusable[focusable.length - 1].focus(); + findNextFocusableElement(focusable, index, focusable.length - 1, forward).focus(); } else if (index === focusable.length - 1) { - focusable[0].focus(); + findNextFocusableElement(focusable, index, 0, forward).focus(); } else { - focusable[index + 1].focus(); + findNextFocusableElement(focusable, index, index + 1, forward).focus(); } } else { if (goToEnd) { - focusable[0].focus(); + findNextFocusableElement(focusable, index, 0, forward).focus(); } else if (index === 0) { - focusable[focusable.length - 1].focus(); + findNextFocusableElement(focusable, index, focusable.length - 1, forward).focus(); } else { - focusable[Math.max(index - 1, 0)].focus(); + findNextFocusableElement(focusable, index, Math.max(index - 1, 0), forward).focus(); } } diff --git a/react-common/components/share/ShareInfo.tsx b/react-common/components/share/ShareInfo.tsx index 159a91cfd9d..a055e7f0cef 100644 --- a/react-common/components/share/ShareInfo.tsx +++ b/react-common/components/share/ShareInfo.tsx @@ -32,6 +32,7 @@ export interface ShareInfoProps { onClose: () => void; } + export const ShareInfo = (props: ShareInfoProps) => { const { projectName, @@ -323,7 +324,7 @@ export const ShareInfo = (props: ShareInfoProps) => { {showSimulator && shareState !== "gifrecord" &&
{thumbnailUri - ? + ? {lf("Preview :
@@ -406,6 +407,7 @@ export const ShareInfo = (props: ShareInfoProps) => {
{ className="menu-button project-qrcode" buttonRef={handleQRCodeButtonRef} title={lf("Show QR Code")} - label={} + label={{lf("QR} onClick={handleQRCodeClick} />
@@ -475,7 +477,8 @@ export const ShareInfo = (props: ShareInfoProps) => { selected={embedOptions.findIndex(i => i.name === embedState)} />