import React, { InputHTMLAttributes, forwardRef, useState } from "react"; import { Loader } from "../../loader"; import { BodyShort } from "../../typography"; import { omit } from "../../utils-external"; import { cl } from "../../utils/helpers"; import { ReadOnlyIconWithTitle } from "../ReadOnlyIcon"; import { FormFieldProps, useFormField } from "../useFormField"; export interface SwitchProps extends Omit, Omit, "size"> { /** * Switch-label. */ children: React.ReactNode; /** * If enabled shows the label and description for screenreaders only. */ hideLabel?: boolean; /** * Toggles loading state with loader-component on switch. */ loading?: boolean; /** * Positions switch on left/right side of label. * @default "left" */ position?: "left" | "right"; /** * Adds a description to extend labeling of Switch. */ description?: string; } /** * A component that displays a switch input field. * * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/switch) * @see 🏷️ {@link SwitchProps} * * @example * ```jsx * Varsle med SMS * ``` */ export const Switch = forwardRef( (props, ref) => { const { inputProps, size, readOnly } = useFormField(props, "switch"); const { children, className, description, hideLabel = false, loading, checked: checkedProp, defaultChecked, position = "left", ...rest } = props; const [_checked, setChecked] = useState( defaultChecked ?? checkedProp ?? false, ); if (checkedProp !== undefined && checkedProp !== _checked) { setChecked(checkedProp); } const checked = checkedProp ?? _checked; return (
{ if (readOnly) { return; } setChecked(event.target.checked); props.onChange?.(event); }} onClick={(event) => { if (readOnly) { event.preventDefault(); return; } props.onClick?.(event); }} className={cl(className, "aksel-switch__input")} />
); }, ); const SwitchIcon = ({ size, checked, loading, }: { size: SwitchProps["size"]; checked: SwitchProps["checked"]; loading: SwitchProps["loading"]; }) => { if (loading) { let baseSize = 16; if (size === "small") { baseSize = 12; } if (checked) { baseSize += 2; } return ( ); } if (!checked) { return null; } if (size === "small") { return ( ); } return ( ); }; export default Switch;