1
- import type { ComponentProps , FC , KeyboardEvent } from 'react' ;
2
- import { useId } from 'react' ;
1
+ import type { ComponentProps , KeyboardEvent } from 'react' ;
2
+ import { useId , forwardRef } from 'react' ;
3
3
import { twMerge } from 'tailwind-merge' ;
4
4
import { mergeDeep } from '../../helpers/merge-deep' ;
5
5
import { getTheme } from '../../theme-store' ;
@@ -26,7 +26,7 @@ export interface FlowbiteToggleSwitchToggleTheme {
26
26
} ;
27
27
}
28
28
29
- export type ToggleSwitchProps = Omit < ComponentProps < 'button' > , 'onChange' > & {
29
+ export type ToggleSwitchProps = Omit < ComponentProps < 'button' > , 'onChange' | 'ref' > & {
30
30
checked : boolean ;
31
31
color ?: keyof FlowbiteColors ;
32
32
sizing ?: keyof FlowbiteTextInputSizes ;
@@ -35,72 +35,77 @@ export type ToggleSwitchProps = Omit<ComponentProps<'button'>, 'onChange'> & {
35
35
theme ?: DeepPartial < FlowbiteToggleSwitchTheme > ;
36
36
} ;
37
37
38
- export const ToggleSwitch : FC < ToggleSwitchProps > = ( {
39
- checked,
40
- className,
41
- color = 'blue' ,
42
- sizing = 'md' ,
43
- disabled,
44
- label,
45
- name,
46
- onChange,
47
- theme : customTheme = { } ,
48
- ...props
49
- } ) => {
50
- const id = useId ( ) ;
51
- const theme = mergeDeep ( getTheme ( ) . toggleSwitch , customTheme ) ;
38
+ export const ToggleSwitch = forwardRef < HTMLInputElement , ToggleSwitchProps > (
39
+ (
40
+ {
41
+ checked,
42
+ className,
43
+ color = 'blue' ,
44
+ sizing = 'md' ,
45
+ disabled,
46
+ label,
47
+ name,
48
+ onChange,
49
+ theme : customTheme = { } ,
50
+ ...props
51
+ } ,
52
+ ref ,
53
+ ) => {
54
+ const id = useId ( ) ;
55
+ const theme = mergeDeep ( getTheme ( ) . toggleSwitch , customTheme ) ;
52
56
53
- const toggle = ( ) : void => onChange ( ! checked ) ;
57
+ const toggle = ( ) : void => onChange ( ! checked ) ;
54
58
55
- const handleClick = ( ) : void => {
56
- toggle ( ) ;
57
- } ;
59
+ const handleClick = ( ) : void => {
60
+ toggle ( ) ;
61
+ } ;
58
62
59
- const handleOnKeyDown = ( event : KeyboardEvent < HTMLButtonElement > ) : void => {
60
- if ( event . code == 'Enter' ) {
61
- event . preventDefault ( ) ;
62
- }
63
- } ;
63
+ const handleOnKeyDown = ( event : KeyboardEvent < HTMLButtonElement > ) : void => {
64
+ if ( event . code == 'Enter' ) {
65
+ event . preventDefault ( ) ;
66
+ }
67
+ } ;
64
68
65
- return (
66
- < >
67
- { name && checked ? (
68
- < input checked = { checked } hidden name = { name } readOnly type = "checkbox" className = "sr-only" />
69
- ) : null }
70
- < button
71
- aria-checked = { checked }
72
- aria-labelledby = { `${ id } -flowbite-toggleswitch-label` }
73
- disabled = { disabled }
74
- id = { `${ id } -flowbite-toggleswitch` }
75
- onClick = { handleClick }
76
- onKeyDown = { handleOnKeyDown }
77
- role = "switch"
78
- tabIndex = { 0 }
79
- type = "button"
80
- className = { twMerge ( theme . root . base , theme . root . active [ disabled ? 'off' : 'on' ] , className ) }
81
- { ...props }
82
- >
83
- < div
84
- data-testid = "flowbite-toggleswitch-toggle"
85
- className = { twMerge (
86
- theme . toggle . base ,
87
- theme . toggle . checked [ checked ? 'on' : 'off' ] ,
88
- checked && theme . toggle . checked . color [ color ] ,
89
- theme . toggle . sizes [ sizing ] ,
90
- ) }
91
- />
92
- { label ?. length ? (
93
- < span
94
- data-testid = "flowbite-toggleswitch-label"
95
- id = { `${ id } -flowbite-toggleswitch-label` }
96
- className = { theme . root . label }
97
- >
98
- { label }
99
- </ span >
69
+ return (
70
+ < >
71
+ { name && checked ? (
72
+ < input ref = { ref } checked = { checked } hidden name = { name } readOnly type = "checkbox" className = "sr-only" />
100
73
) : null }
101
- </ button >
102
- </ >
103
- ) ;
104
- } ;
74
+ < button
75
+ aria-checked = { checked }
76
+ aria-labelledby = { `${ id } -flowbite-toggleswitch-label` }
77
+ disabled = { disabled }
78
+ id = { `${ id } -flowbite-toggleswitch` }
79
+ onClick = { handleClick }
80
+ onKeyDown = { handleOnKeyDown }
81
+ role = "switch"
82
+ tabIndex = { 0 }
83
+ type = "button"
84
+ className = { twMerge ( theme . root . base , theme . root . active [ disabled ? 'off' : 'on' ] , className ) }
85
+ { ...props }
86
+ >
87
+ < div
88
+ data-testid = "flowbite-toggleswitch-toggle"
89
+ className = { twMerge (
90
+ theme . toggle . base ,
91
+ theme . toggle . checked [ checked ? 'on' : 'off' ] ,
92
+ checked && theme . toggle . checked . color [ color ] ,
93
+ theme . toggle . sizes [ sizing ] ,
94
+ ) }
95
+ />
96
+ { label ?. length ? (
97
+ < span
98
+ data-testid = "flowbite-toggleswitch-label"
99
+ id = { `${ id } -flowbite-toggleswitch-label` }
100
+ className = { theme . root . label }
101
+ >
102
+ { label }
103
+ </ span >
104
+ ) : null }
105
+ </ button >
106
+ </ >
107
+ ) ;
108
+ } ,
109
+ ) ;
105
110
106
111
ToggleSwitch . displayName = 'ToggleSwitch' ;
0 commit comments