mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
126 lines
No EOL
4.3 KiB
TypeScript
126 lines
No EOL
4.3 KiB
TypeScript
import { Field } from "formik";
|
|
import type {
|
|
FieldInputProps,
|
|
FieldMetaProps,
|
|
FieldProps,
|
|
FormikProps,
|
|
FormikValues
|
|
} from "formik";
|
|
import { Switch as HeadlessSwitch } from "@headlessui/react";
|
|
import { classNames } from "../../utils";
|
|
|
|
type SwitchProps<V = any> = {
|
|
label: string
|
|
checked: boolean
|
|
disabled?: boolean
|
|
onChange: (value: boolean) => void
|
|
field?: FieldInputProps<V>
|
|
form?: FormikProps<FormikValues>
|
|
meta?: FieldMetaProps<V>
|
|
}
|
|
|
|
export const Switch = ({
|
|
label,
|
|
checked: $checked,
|
|
disabled = false,
|
|
onChange: $onChange,
|
|
field,
|
|
form,
|
|
}: SwitchProps) => {
|
|
const checked = field?.checked ?? $checked
|
|
|
|
return (
|
|
<HeadlessSwitch.Group as="div" className="flex items-center space-x-4">
|
|
<HeadlessSwitch.Label>{label}</HeadlessSwitch.Label>
|
|
<HeadlessSwitch
|
|
as="button"
|
|
name={field?.name}
|
|
disabled={disabled}
|
|
checked={checked}
|
|
onChange={value => {
|
|
form?.setFieldValue(field?.name ?? '', value)
|
|
$onChange && $onChange(value)
|
|
}}
|
|
|
|
className={classNames(
|
|
checked ? 'bg-teal-500 dark:bg-blue-500' : 'bg-gray-200 dark:bg-gray-600',
|
|
'ml-4 relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
|
|
)}
|
|
>
|
|
{({ checked }) => (
|
|
<span
|
|
aria-hidden="true"
|
|
className={classNames(
|
|
checked ? 'translate-x-5' : 'translate-x-0',
|
|
'inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200'
|
|
)}
|
|
/>
|
|
)}
|
|
</HeadlessSwitch>
|
|
</HeadlessSwitch.Group>
|
|
)
|
|
}
|
|
|
|
export type SwitchFormikProps = SwitchProps & FieldProps & React.InputHTMLAttributes<HTMLInputElement>;
|
|
|
|
export const SwitchFormik = (props: SwitchProps) => <Switch {...props} />
|
|
|
|
interface SwitchGroupProps {
|
|
name: string;
|
|
label?: string;
|
|
description?: string;
|
|
className?: string;
|
|
}
|
|
|
|
const SwitchGroup = ({
|
|
name,
|
|
label,
|
|
description
|
|
}: SwitchGroupProps) => (
|
|
<HeadlessSwitch.Group as="ol" className="py-4 flex items-center justify-between">
|
|
{label && <div className="flex flex-col">
|
|
<HeadlessSwitch.Label as="p" className="text-sm font-medium text-gray-900 dark:text-gray-100"
|
|
passive>
|
|
{label}
|
|
</HeadlessSwitch.Label>
|
|
{description && (
|
|
<HeadlessSwitch.Description className="text-sm mt-1 text-gray-500 dark:text-gray-400">
|
|
{description}
|
|
</HeadlessSwitch.Description>
|
|
)}
|
|
</div>
|
|
}
|
|
|
|
<Field name={name} type="checkbox">
|
|
{({
|
|
field,
|
|
form: { setFieldValue },
|
|
}: any) => (
|
|
<Switch
|
|
{...field}
|
|
type="button"
|
|
value={field.value}
|
|
checked={field.checked}
|
|
onChange={value => {
|
|
setFieldValue(field?.name ?? '', value)
|
|
}}
|
|
className={classNames(
|
|
field.value ? 'bg-teal-500 dark:bg-blue-500' : 'bg-gray-200',
|
|
'ml-4 relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
|
|
)}
|
|
>
|
|
<span
|
|
aria-hidden="true"
|
|
className={classNames(
|
|
field.value ? 'translate-x-5' : 'translate-x-0',
|
|
'inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200'
|
|
)}
|
|
/>
|
|
</Switch>
|
|
|
|
)}
|
|
</Field>
|
|
</HeadlessSwitch.Group>
|
|
);
|
|
|
|
export { SwitchGroup } |