diff --git a/__mocks__/platform-bible-react.tsx b/__mocks__/platform-bible-react.tsx index 0966e894..a14d7e7c 100644 --- a/__mocks__/platform-bible-react.tsx +++ b/__mocks__/platform-bible-react.tsx @@ -3,7 +3,17 @@ * without extra transform configuration. This stub provides the subset used by the extension. */ -import { Children, cloneElement, forwardRef, isValidElement, useEffect, useRef } from 'react'; +import { + Children, + cloneElement, + createContext, + forwardRef, + isValidElement, + useContext, + useEffect, + useMemo, + useRef, +} from 'react'; import type { ChangeEventHandler, CSSProperties, @@ -576,6 +586,88 @@ export function Switch({ ); } +/** + * Context carrying the {@link RadioGroup}'s selected value and change handler down to each + * {@link RadioGroupItem}, mirroring how the real Radix-based component coordinates its items. + */ +const RadioGroupContext = createContext<{ + onValueChange?: (value: string) => void; + value?: string; +}>({}); + +/** + * Stub radio group rendered as a `
` that shares its selected value and change + * handler with its {@link RadioGroupItem} children via context. The real component is built on Radix + * primitives; this stub reproduces just the controlled selection behavior tests drive. + * + * @param props - Component props. + * @param props.children - The {@link RadioGroupItem}s (and any surrounding markup). + * @param props.className - CSS class names. + * @param props.onValueChange - Called with an item's value when it becomes selected. + * @param props.value - Currently selected item value. + * @returns A `
` providing selection context to its items. + */ +export function RadioGroup({ + children, + className, + onValueChange, + value, +}: Readonly<{ + children?: ReactNode; + className?: string; + onValueChange?: (value: string) => void; + value?: string; +}>): ReactElement { + const contextValue = useMemo(() => ({ onValueChange, value }), [onValueChange, value]); + return ( +
+ {children} +
+ ); +} + +/** + * Stub radio item rendered as a native `` so `toBeChecked`, `toBeDisabled`, and + * click/`check` interactions work in tests. It reads the enclosing {@link RadioGroup}'s value from + * context, marking itself checked when they match and reporting its own value on change. (The real + * component renders a `