feat(dashboard): SwitchBox component (#7607)

**What**
- In the latest design changes, the Switch component needs to be wrapped in a container with a label and description. It doesn't make sense to add this "variant" to `@medusajs/ui`, so I have created a local component that we can use every time the design calls for this setup, to avoid re-implementing it multiple times, and the design being inconsistent across usages. 
- Updates the Product domain forms to use the component. There are other places that needs to be updated to use it, but we can tackle those in our clean up tasks. I have checked with Ludvig and this design should be used everywhere we previously had the design shown in the first image.

 
<img width="604" alt="image" src="https://github.com/medusajs/medusa/assets/45367945/053e40c4-fa8f-4cac-96b3-659deeb6d760">

<img width="745" alt="image" src="https://github.com/medusajs/medusa/assets/45367945/890eb28f-83ac-4fa6-968f-cc204f1acd1e">
This commit is contained in:
Kasper Fabricius Kristensen
2024-06-06 08:09:38 +00:00
committed by GitHub
parent cc0452d29e
commit 1f203774cb
6 changed files with 107 additions and 123 deletions
@@ -0,0 +1 @@
export * from "./switch-box"
@@ -0,0 +1,70 @@
import { Switch } from "@medusajs/ui"
import { ReactNode } from "react"
import { ControllerProps, FieldPath, FieldValues } from "react-hook-form"
import { Form } from "../../common/form"
interface HeadlessControllerProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> extends Omit<ControllerProps<TFieldValues, TName>, "render"> {}
interface SwitchBoxProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> extends HeadlessControllerProps<TFieldValues, TName>{
label: string
description: string
optional?: boolean
tooltip?: ReactNode
/**
* Callback for performing additional actions when the checked state changes.
* This does not intercept the form control, it is only used for injecting side-effects.
*/
onCheckedChange?: (checked: boolean) => void
}
/**
* Wrapper for the Switch component to be used with `react-hook-form`.
*
* Use this component whenever a design calls for wrapping the Switch component
* in a container with a label and description.
*/
export const SwitchBox = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
label,
description,
optional = false,
tooltip,
onCheckedChange,
...props
}: SwitchBoxProps<TFieldValues, TName>) => {
return (
<Form.Field
{...props}
render={({ field: { value, onChange, ...field } }) => {
return (
<Form.Item>
<div className="bg-ui-bg-component shadow-elevation-card-rest flex items-start gap-x-3 rounded-lg p-3">
<Form.Control>
<Switch {...field} checked={value} onCheckedChange={(e) => {
onCheckedChange?.(e)
onChange(e)
}} />
</Form.Control>
<div>
<Form.Label optional={optional} tooltip={tooltip}>
{label}
</Form.Label>
<Form.Hint>{description}</Form.Hint>
</div>
</div>
<Form.ErrorMessage />
</Form.Item>
)
}}
/>
)
}