/** * Copyright (c) Microsoft Corporation. * Licensed under the MIT License. * @format */ /** @jsxImportSource @fluentui-react-native/framework-base */ import * as React from 'react'; import type { ISlots } from '@uifabricshared/foundation-composable'; import { compose } from '@uifabricshared/foundation-compose'; import type { IUseComposeStyling } from '@uifabricshared/foundation-compose'; import { mergeSettings } from '@uifabricshared/foundation-settings'; import NativeRadioButtonView from './MacOSRadioButtonNativeComponent'; import type { IRadioButtonProps, IRadioButtonSlotProps, IRadioButtonType } from './RadioButton.types'; import { radioButtonName } from './RadioButton.types'; import { RadioGroupContext } from './RadioGroup'; export const RadioButton = compose({ displayName: radioButtonName, usePrepareProps: (userProps: IRadioButtonProps, useStyling: IUseComposeStyling) => { const defaultComponentRef = React.useRef(null); const { content, buttonKey, disabled, componentRef = defaultComponentRef } = userProps; const info = React.useContext(RadioGroupContext); const { onChange, selectedKey, updateSelectedButtonRef } = info; // Reroute the native component's onPress event to RadioGroup's onChange const onPressRerouted = React.useCallback(() => { // Prevent calls to RadioGroup's onChange on the currently selected button if (buttonKey != selectedKey) { onChange && onChange(buttonKey); updateSelectedButtonRef && componentRef && updateSelectedButtonRef(componentRef); } }, [buttonKey, componentRef, onChange, selectedKey, updateSelectedButtonRef]); /* We use the componentRef of the currently selected button to maintain the default tabbable element in a RadioGroup. Since the componentRef isn't generated until after initial render, we must update it once here. */ React.useEffect(() => { if (buttonKey === selectedKey) { updateSelectedButtonRef && componentRef && updateSelectedButtonRef(componentRef); } // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally run only on mount/unmount }, []); const styleProps = useStyling(userProps); const isSelected = selectedKey === buttonKey; const slotProps = mergeSettings(styleProps, { root: { ref: componentRef, buttonKey: buttonKey, content: content, disabled: disabled, onPress: onPressRerouted, selected: isSelected, style: { minWidth: '100%', minHeight: 20, }, }, }); return { slotProps }; }, slots: { root: NativeRadioButtonView, }, styles: { root: [], }, render: (Slots: ISlots) => { return ; }, }); export default RadioButton;