import * as React from "react"; import { AriaSwitchProps, usePress, useSwitch } from "react-aria"; import { useToggleState } from "react-stately"; import { Text } from "#gdq/index"; import { useSetRef } from "#gdq/utils/RefUtils"; import { Check } from "@faulty/gdq-icons/icons/Check"; import { animated, config, useSpring } from "@react-spring/web"; import { ControlInputProps } from "../Control/Control"; import { InputStatus, useInputColorToken, useInputStyleClasses } from "../Input/Input"; import { useResolvedColorToken } from "../ThemeProvider/ThemeProvider"; import styles from "./FormSwitch.module.css"; function Switch(props: { isSelected: boolean; isPressed: boolean; status: InputStatus }) { const { isSelected, isPressed, status } = props; const containerRef = React.useRef(null); const inputColor = useInputColorToken(status, "color"); const resolvedColor = inputColor === "transparent" ? inputColor : inputColor.hsla; const resolvedBackground = useResolvedColorToken("CONTROL_BACKGROUND").hsla; const { progress, pressProgress } = useSpring({ progress: isSelected ? (isPressed ? 0.7 : 1) : isPressed ? 0.3 : 0, pressProgress: isPressed ? 1 : 0, config: config.stiff, }); const trackColor = progress.to([0, 1], [resolvedBackground, resolvedColor]); const transform = progress.to({ extrapolate: "clamp", range: [0, 1], output: [`scale(0.5)`, `scale(1)`], }); const left = progress.to({ extrapolate: "clamp", range: [0, 0.3, 0.7, 1], output: [0, 0, 16, 24], }); const width = pressProgress.to([0, 1], [20, 28]); return ( ); } export interface FormSwitchProps extends Omit, ControlInputProps { checked: boolean; } export const FormSwitch = React.forwardRef( function FormSwitch(props, ref) { const { checked, label, description, errorMessage, status = "default" } = props; const innerRef = React.useRef(null); const setRef = useSetRef(innerRef, ref); const inputStyles = useInputStyleClasses(props); const labelId = React.useId(); const transformedProps = { ...props, isSelected: checked, children: label, }; const state = useToggleState(transformedProps); const { inputProps } = useSwitch({ ...props, "aria-labelledby": labelId }, state, innerRef); const { pressProps, isPressed } = usePress({}); return (
{description != null ? {description} : null} {errorMessage != null ? {errorMessage} : null}
); }, );