refactor(sw): share roving focus and outside pointer handling

- components/shared/roving-focus.ts (moveRovingFocus): the same Arrow / Home / End algorithm of SWFooter, SWToolGroup,
  the SWViewerHeader tabs and SWHomeMenu; each caller passes its own keys, wrap and select behavior.
- components/shared/use-outside-pointer.ts (useOutsidePointerDown): the same pointerdown effect of the SWHeader
  dropdowns, layer menu, document title and More. Escape, focus return and positioning stay in each component.
Both modules are internal: the package entry and the public declarations are unchanged.
This commit is contained in:
shkim4 committed 2026-10-21 06:08:45 +09:00
1 parent af7f98d66b
commit 7cc3aa1ff8
10 files changed
+55 -69

No files matched your search

@@ -3,6 +3,7 @@ import {
type ButtonHTMLAttributes, type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode,
} from "react"
import { useSWPopupStack } from "../sw-header/components/SWHeaderPropertyPanel"
import { moveRovingFocus } from "../shared/roving-focus"
import titleBadge from "./assets/title-badge.svg"
// Imported where the component is used (not only in index.ts) so bundlers keep it with sideEffects: ["**/*.css"].
import "../../theme/sw-home-menu.css"
@@ -354,14 +355,7 @@ export const SWHomeMenu = forwardRef<HTMLDivElement, SWHomeMenuProps>(function S
else rows[Math.min(rows.length - 1, Math.max(0, index + (event.key === "ArrowDown" ? 1 : -1)))]?.focus()
return
}
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return
const items = focusableItems(rootRef.current)
const index = items.indexOf(document.activeElement as HTMLElement)
if (index < 0) return
event.preventDefault()
const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1
: (index + (event.key === "ArrowRight" ? 1 : -1) + items.length) % items.length
items[next].focus()
if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) moveRovingFocus(event, focusableItems(rootRef.current))
}
const resolvedAccent = accent === "auto" ? (openPanelId ? "outline" : "sections") : accent