11import * as React from 'react'
2- import { FancySwitchProps , OptionObject , OptionType } from '../types'
2+ import {
3+ FancySwitchProps ,
4+ OptionObject ,
5+ OptionType ,
6+ OptionValue
7+ } from '../types'
38
49export const FancySwitch = React . forwardRef < HTMLDivElement , FancySwitchProps > (
510 (
@@ -17,18 +22,22 @@ export const FancySwitch = React.forwardRef<HTMLDivElement, FancySwitchProps>(
1722 ref
1823 ) => {
1924 const getOptionValue = React . useCallback (
20- ( option : OptionType ) =>
21- typeof option === 'string'
22- ? option
23- : ( option as OptionObject ) [ valueKey ] ,
25+ ( option : OptionType ) : OptionValue => {
26+ if ( typeof option === 'string' || typeof option === 'number' ) {
27+ return option
28+ }
29+ return ( option as OptionObject ) [ valueKey ] as OptionValue
30+ } ,
2431 [ valueKey ]
2532 )
2633
2734 const getOptionLabel = React . useCallback (
28- ( option : OptionType ) =>
29- typeof option === 'string'
30- ? option
31- : ( option as OptionObject ) [ labelKey ] ,
35+ ( option : OptionType ) : string => {
36+ if ( typeof option === 'string' || typeof option === 'number' ) {
37+ return String ( option )
38+ }
39+ return String ( ( option as OptionObject ) [ labelKey ] )
40+ } ,
3241 [ labelKey ]
3342 )
3443
@@ -41,9 +50,27 @@ export const FancySwitch = React.forwardRef<HTMLDivElement, FancySwitchProps>(
4150 [ options , getOptionValue , getOptionLabel ]
4251 )
4352
44- const [ activeIndex , setActiveIndex ] = React . useState ( ( ) =>
45- memoizedOptions . findIndex ( ( option ) => option . value === value )
46- )
53+ const [ activeIndex , setActiveIndex ] = React . useState ( ( ) => {
54+ const index = memoizedOptions . findIndex (
55+ ( option ) => option . value === value
56+ )
57+ if ( index === - 1 ) {
58+ console . warn (
59+ `FancySwitch: No option found for value "${ value } ". Defaulting to first option.`
60+ )
61+ return 0
62+ }
63+ return index
64+ } )
65+
66+ React . useEffect ( ( ) => {
67+ const newIndex = memoizedOptions . findIndex (
68+ ( option ) => option . value === value
69+ )
70+ if ( newIndex !== - 1 && newIndex !== activeIndex ) {
71+ setActiveIndex ( newIndex )
72+ }
73+ } , [ value , memoizedOptions , activeIndex ] )
4774
4875 const [ highlighterStyle , setHighlighterStyle ] = React . useState ( {
4976 height : 0 ,
@@ -158,7 +185,7 @@ export const FancySwitch = React.forwardRef<HTMLDivElement, FancySwitchProps>(
158185 return (
159186 < div
160187 role = "radiogroup"
161- aria-labelledby = "fancy-switch-label "
188+ aria-label = "Fancy Switch Options "
162189 { ...props }
163190 ref = { containerRef }
164191 >
@@ -186,10 +213,28 @@ export const FancySwitch = React.forwardRef<HTMLDivElement, FancySwitchProps>(
186213 onKeyDown = { ( e ) => handleKeyDown ( e , index ) }
187214 className = { radioClassName }
188215 { ...( index === activeIndex ? { 'data-checked' : true } : { } ) }
216+ aria-label = { `${ option . label } option` }
189217 >
190218 { option . label }
191219 </ div >
192220 ) ) }
221+
222+ < div
223+ aria-live = "polite"
224+ style = { {
225+ position : 'absolute' ,
226+ width : '1px' ,
227+ height : '1px' ,
228+ padding : 0 ,
229+ margin : '-1px' ,
230+ overflow : 'hidden' ,
231+ clip : 'rect(0, 0, 0, 0)' ,
232+ whiteSpace : 'nowrap' ,
233+ borderWidth : 0
234+ } }
235+ >
236+ { memoizedOptions [ activeIndex ] ?. label } selected
237+ </ div >
193238 </ div >
194239 )
195240 }
0 commit comments