Skip to content

Commit

Permalink
fix(toggleswitch component): added forwardRef to ToggleSwitch compone…
Browse files Browse the repository at this point in the history
…nt (themesberg#1198)

fix themesberg#1078

Co-authored-by: Nikita Dubyk <nikita.dubyk@sweetcode.pro>
  • Loading branch information
2 people authored and ddiasfront committed Dec 29, 2023
1 parent ad763d8 commit 7ce311d
Showing 1 changed file with 70 additions and 65 deletions.
135 changes: 70 additions & 65 deletions src/components/ToggleSwitch/ToggleSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ComponentProps, FC, KeyboardEvent } from 'react';
import { useId } from 'react';
import type { ComponentProps, KeyboardEvent } from 'react';
import { useId, forwardRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import { getTheme } from '../../theme-store';
Expand All @@ -26,7 +26,7 @@ export interface FlowbiteToggleSwitchToggleTheme {
};
}

export type ToggleSwitchProps = Omit<ComponentProps<'button'>, 'onChange'> & {
export type ToggleSwitchProps = Omit<ComponentProps<'button'>, 'onChange' | 'ref'> & {
checked: boolean;
color?: keyof FlowbiteColors;
sizing?: keyof FlowbiteTextInputSizes;
Expand All @@ -35,72 +35,77 @@ export type ToggleSwitchProps = Omit<ComponentProps<'button'>, 'onChange'> & {
theme?: DeepPartial<FlowbiteToggleSwitchTheme>;
};

export const ToggleSwitch: FC<ToggleSwitchProps> = ({
checked,
className,
color = 'blue',
sizing = 'md',
disabled,
label,
name,
onChange,
theme: customTheme = {},
...props
}) => {
const id = useId();
const theme = mergeDeep(getTheme().toggleSwitch, customTheme);
export const ToggleSwitch = forwardRef<HTMLInputElement, ToggleSwitchProps>(
(
{
checked,
className,
color = 'blue',
sizing = 'md',
disabled,
label,
name,
onChange,
theme: customTheme = {},
...props
},
ref,
) => {
const id = useId();
const theme = mergeDeep(getTheme().toggleSwitch, customTheme);

const toggle = (): void => onChange(!checked);
const toggle = (): void => onChange(!checked);

const handleClick = (): void => {
toggle();
};
const handleClick = (): void => {
toggle();
};

const handleOnKeyDown = (event: KeyboardEvent<HTMLButtonElement>): void => {
if (event.code == 'Enter') {
event.preventDefault();
}
};
const handleOnKeyDown = (event: KeyboardEvent<HTMLButtonElement>): void => {
if (event.code == 'Enter') {
event.preventDefault();
}
};

return (
<>
{name && checked ? (
<input checked={checked} hidden name={name} readOnly type="checkbox" className="sr-only" />
) : null}
<button
aria-checked={checked}
aria-labelledby={`${id}-flowbite-toggleswitch-label`}
disabled={disabled}
id={`${id}-flowbite-toggleswitch`}
onClick={handleClick}
onKeyDown={handleOnKeyDown}
role="switch"
tabIndex={0}
type="button"
className={twMerge(theme.root.base, theme.root.active[disabled ? 'off' : 'on'], className)}
{...props}
>
<div
data-testid="flowbite-toggleswitch-toggle"
className={twMerge(
theme.toggle.base,
theme.toggle.checked[checked ? 'on' : 'off'],
checked && theme.toggle.checked.color[color],
theme.toggle.sizes[sizing],
)}
/>
{label?.length ? (
<span
data-testid="flowbite-toggleswitch-label"
id={`${id}-flowbite-toggleswitch-label`}
className={theme.root.label}
>
{label}
</span>
return (
<>
{name && checked ? (
<input ref={ref} checked={checked} hidden name={name} readOnly type="checkbox" className="sr-only" />
) : null}
</button>
</>
);
};
<button
aria-checked={checked}
aria-labelledby={`${id}-flowbite-toggleswitch-label`}
disabled={disabled}
id={`${id}-flowbite-toggleswitch`}
onClick={handleClick}
onKeyDown={handleOnKeyDown}
role="switch"
tabIndex={0}
type="button"
className={twMerge(theme.root.base, theme.root.active[disabled ? 'off' : 'on'], className)}
{...props}
>
<div
data-testid="flowbite-toggleswitch-toggle"
className={twMerge(
theme.toggle.base,
theme.toggle.checked[checked ? 'on' : 'off'],
checked && theme.toggle.checked.color[color],
theme.toggle.sizes[sizing],
)}
/>
{label?.length ? (
<span
data-testid="flowbite-toggleswitch-label"
id={`${id}-flowbite-toggleswitch-label`}
className={theme.root.label}
>
{label}
</span>
) : null}
</button>
</>
);
},
);

ToggleSwitch.displayName = 'ToggleSwitch';

0 comments on commit 7ce311d

Please sign in to comment.