import React, { HTMLProps, forwardRef, useId } from "react"; import classNames from "classnames"; import { Box, BoxProps } from "../Box"; import { Input } from "../Input"; import { Icon, ICON_TYPE } from "../Icon"; import { Stack, StackProps } from "../Stack"; import { bemHOF } from "../../utilities/bem"; import isUndefined from "../../utilities/isUndefined"; import { ORIENTATION } from "../../types"; import { OptionButtonContext, useOptionButtonContext } from "./context"; const cn = bemHOF("OptionButton"); /** * OptionButton.Group * ============================================================================= */ export interface OptionButtonGroupProps extends StackProps { /** * Using context, the name prop is passed down to each input within the group. * You may also define `name` on each individual `OptionButton` or * `OptionButton.Input` manually if you choose not to use `OptionButton.Group`. */ name?: string; /** * Defines the type of control to render each input as. This value is stored * in the context and passed onto each input. You may also define `type` on * each individual `OptionButton` or `OptionButton.Input` manually if you * choose not to use `OptionButton.Group`. */ type?: "radio" | "checkbox"; } export const OptionButtonGroup = (props: OptionButtonGroupProps) => { const { name = "", type = "radio", orientation = ORIENTATION.VERTICAL, ...rest } = props; return ( ); }; /** * OptionButton.Root * ============================================================================= */ export type OptionButtonRootProps = HTMLProps & { theme?: "blue" | "green"; }; export const OptionButtonRoot = forwardRef< HTMLLabelElement, OptionButtonRootProps >(({ children, className, theme = "blue", ...rest }, ref) => { return ( // eslint-disable-next-line jsx-a11y/label-has-associated-control ); }); /** * OptionButton.Input * ============================================================================= */ export type OptionButtonInputProps = HTMLProps; export const OptionButtonInput = (props: OptionButtonInputProps) => { const { name: nameFromContext, type: typeFromContext, } = useOptionButtonContext(); const { id: idProp, name: nameProp, checked, className, defaultValue, type: typeProp = "radio", ...rest } = props; const fallbackId = `OptionButton-${useId()}`; const id = isUndefined(idProp) ? fallbackId : idProp; const name = isUndefined(nameFromContext) ? nameProp : nameFromContext; const type = isUndefined(typeFromContext) ? typeProp : typeFromContext; return ( ); }; /** * OptionButton.Content * ============================================================================= */ export const OptionButtonContent = ({ className, children, ...rest }: BoxProps) => ( {children} ); /** * OptionButton.Heading * ============================================================================= */ export const OptionButtonHeading = ({ className, children, ...rest }: BoxProps) => ( {children} ); /** * OptionButton.Description * ============================================================================= */ export const OptionButtonDescription = ({ className, children, ...rest }: BoxProps) => ( {children} ); /** * OptionButton.Backdrop * ============================================================================= */ export const OptionButtonBackdrop = ({ className, ...rest }: BoxProps) => ( ); /** * OptionButton.SelectedIcon * ============================================================================= */ export const OptionButtonSelectedIcon = ({ className, ...rest }: BoxProps) => ( Selected ); /** * OptionButton * ============================================================================= */ interface OptionButtonProps extends HTMLProps { heading: string; description?: string; theme?: "blue" | "green"; } export const OptionButton = (props: OptionButtonProps) => { const { name: nameFromContext, type: typeFromContext, } = useOptionButtonContext(); const { heading, description, id: idProp, name: nameProp, checked, className, defaultValue, type: typeProp = "radio", disabled = false, theme = "blue", ...rest } = props; const fallbackId = `OptionButton-${useId()}`; const id = isUndefined(idProp) ? fallbackId : idProp; const name = isUndefined(nameFromContext) ? nameProp : nameFromContext; const type = isUndefined(typeFromContext) ? typeProp : typeFromContext; const rootClassName = classNames([ cn(), disabled && cn({ m: "disabled" }), className, ]); return ( {heading && {heading}} {description && ( {description} )} ); }; OptionButton.Group = OptionButtonGroup; OptionButton.Root = OptionButtonRoot; OptionButton.Input = OptionButtonInput; OptionButton.Content = OptionButtonContent; OptionButton.Heading = OptionButtonHeading; OptionButton.Description = OptionButtonDescription; OptionButton.Backdrop = OptionButtonBackdrop; OptionButton.SelectedIcon = OptionButtonSelectedIcon;