autobrr/web/src/components/inputs/switch.tsx
stacksmash76 279d4ff7a3
feat: add filter dropdown #26 (#142)
feat(FilterItemDropdown): added a filter dropdown component from #26 

* fix(react-multi-select-component): adjusted the component to fit in with other components when comparing across multiple browsers. (where firefox consistently handles pixels and rem's, chromium doesn't agree).

refactor(input): removed shadow from input components to match react-multi-select-component look where needed.

refactor(SwitchGroup): added a small top margin for a less dense look. cleaned up surrounding code.

refactor(DeleteModal): adjusted the background color to fit more nicely across dark/light themes. made the exclamation icon bigger and removed the circle container.

refactor(Logs): adjusted text color on the light theme. cleaned up the code.

refactor(FilterAddForm): adapted to conform with the changes.

feat(FilterItemDropdown): added a dropdown component to the filter list as proposed in #26. could use a better look, though. also, cleaned up surrounding code and got rid of pesky negative margins.

refactor(FilterListItem): made the table striped when using the dark theme. adapter for the dropdown component.

refactor(filters/details):
- removed needless border properties from remove button, which left artifacts after de-focusing the button. also, removed the shadow from the cancel button.
- added invalidation of the filter list on a delete mutation before redirecting to /filters.
- modified certain group descriptions a bit in order to make them a bit more concise.
- overall, cleaned up the surrounding code further.
2022-02-17 20:59:06 +01:00

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="li" 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 }