import * as React from "react"; import { cx } from "@emotion/css"; import nextId from "react-id-generator"; import { flex, flexItem, visuallyHidden, display, tintContent, tintContentSecondary, vAlignChildren } from "../../shared/styles/styleUtils"; import { themeError, themeSuccess, themeBgPrimary } from "../../design-tokens/build/js/designTokens"; import { InputAppearance } from "../../shared/types/inputAppearance"; import FormFieldWrapper from "../../shared/components/FormFieldWrapper"; import { SystemIcons } from "../../icons/dist/system-icons-enum"; import { Icon } from "../../icon"; import { checkContainer, toggle, toggleRound, toggleContainer, toggleInputAppearances, toggleInputLabel, toggleInputFeedbackText } from "../style"; export interface SlideToggleProps extends React.HTMLProps { /** * Sets the current appearance of the input component. This defaults to InputAppearance.Standard, but supports `InputAppearance.Error` & `InputAppearance.Success` appearances as well. */ appearance?: InputAppearance; /** * Whether or not the input is checked */ checked?: boolean; /** * Unique identifier used for the input element */ id?: string; /** * The text or node content that appears next to the input */ inputLabel: React.ReactNode | string; /** * Defaults to `true`, but can be set to `false` to visibly hide the content passed to `inputLabel`. The `inputLabel` should still be set even when hidden for accessibility support. */ showInputLabel?: boolean; /** * The value being toggled */ value?: string; /** * How the text content vertically aligns with the input */ vertAlign?: "center" | "top"; /** * hintContent is text or a ReactNode that is displayed directly under the input with additional information about the expected input. */ hintContent?: React.ReactNode; /** * Sets the contents for validation errors. This will be displayed below the input element. Errors are only visible when the `TextInput` appearance is also set to `TextInputAppearance.Error`. */ errors?: React.ReactNode[]; } const SlideToggle = (props: React.PropsWithRef) => { const { appearance = InputAppearance.Standard, children, disabled, hintContent, id = nextId("slideToggle-"), inputLabel, showInputLabel = "true", vertAlign = "center", checked, value, errors, onBlur, onFocus, ...other } = props; const inputType = "SlideToggle"; const inputDataCy = [ `${inputType}-input`, ...(checked ? [`${inputType}-input.checked`] : []), ...(appearance && appearance !== InputAppearance.Standard ? [`${inputType}-input.${appearance}`] : []) ].join(" "); const parentDataCy = [ `${inputType}`, ...(checked ? [`${inputType}.checked`] : []), ...(appearance && appearance !== InputAppearance.Standard ? [`${inputType}.${appearance}`] : []) ].join(" "); const [hasFocus, setHasFocus] = React.useState(false); const handleFocus = e => { setHasFocus(true); onFocus?.(e); }; const handleBlur = e => { setHasFocus(false); onBlur?.(e); }; return ( {({ getValidationErrors, isValid, describedByIds, getHintContent }) => (
{(getHintContent || getValidationErrors) && (
{getHintContent} {appearance === InputAppearance.Error && getValidationErrors}
)}
)}
); }; export default SlideToggle;