|
1 |
| -import { useMergeRefs } from '@floating-ui/react'; |
2 |
| -import { useEffect, useId, useRef, useState } from 'react'; |
| 1 | +import { useId, useState } from 'react'; |
3 | 2 | import type { ReactNode } from 'react';
|
4 | 3 | import type { RadioProps } from '../../../components';
|
5 | 4 |
|
@@ -105,45 +104,49 @@ export function useRadioGroup({
|
105 | 104 | typeof propsOrValue === 'string'
|
106 | 105 | ? { value: propsOrValue }
|
107 | 106 | : propsOrValue;
|
108 |
| - const { ref = undefined, value = '', ...rest } = props; |
109 |
| - const localRef = useRef<HTMLInputElement>(null); |
110 |
| - const mergedRefs = useMergeRefs([ref, localRef]); |
| 107 | + const { ref: forwardedRef = undefined, value = '', ...rest } = props; |
111 | 108 |
|
112 |
| - const handleChange = () => { |
113 |
| - const input = localRef.current; |
114 |
| - const isInput = input instanceof HTMLInputElement; |
| 109 | + const handleRef = (element: HTMLInputElement | null) => { |
| 110 | + if (element) { |
| 111 | + // Set initial checked state |
| 112 | + element.checked = value === groupValue; |
| 113 | + } |
115 | 114 |
|
116 |
| - if (isInput && input.name === radioGroupName) { |
| 115 | + // Handle forwarded ref |
| 116 | + if (forwardedRef) { |
| 117 | + if (typeof forwardedRef === 'function') { |
| 118 | + forwardedRef(element); |
| 119 | + } else { |
| 120 | + forwardedRef.current = element; |
| 121 | + } |
| 122 | + } |
| 123 | + }; |
| 124 | + |
| 125 | + const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
| 126 | + if (e.target.name === radioGroupName) { |
117 | 127 | setGroupValue((prevValue) => {
|
118 |
| - onChange?.(input.value, prevValue); |
119 |
| - return input.value; |
| 128 | + onChange?.(e.target.value, prevValue); |
| 129 | + return e.target.value; |
120 | 130 | });
|
121 | 131 | }
|
122 | 132 | };
|
123 | 133 |
|
124 |
| - useEffect(() => { |
125 |
| - if (!localRef.current) return; |
126 |
| - localRef.current.checked = value === groupValue; |
127 |
| - }, [groupValue, value]); |
128 |
| - |
129 | 134 | return {
|
130 |
| - /* Spread anything the user has set first */ |
131 | 135 | ...rest,
|
132 |
| - /* Concat ours with the user prop */ |
133 | 136 | name: radioGroupName,
|
134 | 137 | 'aria-describedby':
|
135 | 138 | `${error ? errorId : ''} ${rest['aria-describedby'] || ''}`.trim() ||
|
136 | 139 | undefined,
|
137 | 140 | 'aria-invalid': !!error || rest['aria-invalid'],
|
138 | 141 | value,
|
139 |
| - ref: mergedRefs, |
| 142 | + ref: handleRef, |
140 | 143 | required: required || rest.required,
|
141 | 144 | readOnly: readOnly || rest.readOnly,
|
142 | 145 | disabled: disabled || rest.disabled,
|
143 | 146 | onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
|
144 | 147 | rest.onChange?.(e);
|
145 | 148 | if (e.defaultPrevented) return;
|
146 |
| - handleChange(); |
| 149 | + handleChange(e); |
147 | 150 | },
|
148 | 151 | };
|
149 | 152 | },
|
|
0 commit comments