next-enterprise/components/Form/ToggleField.tsx

76 lines
2.7 KiB
TypeScript
Raw Normal View History

2024-03-05 17:42:30 -05:00
/**
* ToggleField Component
*
* Renders a toggle switch using Radix UI, integrated with Formik for form state management.
* Supports custom child content and displays an error message if validation fails.
*/
2024-03-03 22:34:43 -05:00
import * as SwitchPrimitive from "@radix-ui/react-switch"
import { useField } from "formik"
import React, { useState } from "react"
import ErrorMessage from "./ErrorMessage"
import RequiredAsterisk from "./RequiredAsterisk"
2024-03-04 20:50:32 -05:00
import Separator from "./Separator"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faClock } from "@fortawesome/free-regular-svg-icons"
2024-03-03 22:09:33 -05:00
2024-03-05 17:42:30 -05:00
/**
* Props for ToggleField.
*
* @param children ReactNode - The content to be displayed alongside the toggle switch.
* @extends React.InputHTMLAttributes<HTMLInputElement> - Inherits standard input attributes.
*/
2024-03-03 22:09:33 -05:00
const ToggleField = ({
children,
...props
}: {
2024-03-03 22:34:43 -05:00
children: React.ReactNode
2024-03-03 22:09:33 -05:00
} & React.InputHTMLAttributes<HTMLInputElement>) => {
2024-03-03 22:34:43 -05:00
const { required, ...restProps } = props
2024-03-05 17:42:30 -05:00
// Formik hook for managing form state and validation
2024-03-03 22:34:43 -05:00
const [field, meta] = useField({ ...(restProps as { name: string }), type: "checkbox" })
2024-03-05 17:42:30 -05:00
// Local state to manage the checked status of the switch
2024-03-03 22:34:43 -05:00
const [checked, setChecked] = useState(false)
2024-03-03 22:09:33 -05:00
2024-03-05 17:42:30 -05:00
// Handles checked state change, updates Formik's state accordingly
const handleCheckedChange = (isChecked: boolean) => {
setChecked(isChecked);
field.onChange({ target: { name: field.name, value: isChecked } });
};
2024-03-03 22:09:33 -05:00
return (
2024-03-04 20:50:32 -05:00
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-4">
<Separator/>
2024-03-04 23:33:49 -05:00
<label className="flex items-center gap-2 font-bold text-sm leading-tight text-indigo-900">
2024-03-04 20:50:32 -05:00
{children}
<RequiredAsterisk required={required} />
</label>
</div>
<div className="flex gap-3 itens-center">
<SwitchPrimitive.Root
2024-03-05 21:32:42 -05:00
className="toggle-switch relative h-[25px] w-[42px] cursor-default rounded-full bg-indigo-900 outline-none"
2024-03-05 17:42:30 -05:00
onCheckedChange={(isChecked) => handleCheckedChange(isChecked)}
2024-03-04 20:50:32 -05:00
>
2024-03-04 23:33:49 -05:00
<SwitchPrimitive.Thumb className="block h-[21px] w-[21px] translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
2024-03-04 20:50:32 -05:00
</SwitchPrimitive.Root>
2024-03-05 17:42:30 -05:00
<div className="flex gap-2 md:gap-4 items-center text-xs md:text-sm leading-tight">
2024-03-04 23:33:49 -05:00
<span>Toggle ON</span>
<span>|</span>
<span className="flex gap-2 items-center"><FontAwesomeIcon icon={faClock} />Select Tolerance Level</span>
</div>
2024-03-04 20:50:32 -05:00
</div>
2024-03-03 22:09:33 -05:00
<ErrorMessage touched={meta.touched} error={meta.error} />
</div>
2024-03-03 22:34:43 -05:00
)
}
2024-03-03 22:09:33 -05:00
2024-03-03 22:34:43 -05:00
export default ToggleField