import classnames from "classnames"; import React, { createContext, useContext, useMemo } from "react"; import { ControlStatusProps } from "../../common/controls.type"; type RadioIndicatorAligment = "start" | "end"; interface RadioContextProps extends ControlStatusProps { value?: T; onChange: (value?: T) => void; disabled?: boolean; indicatorAligment?: RadioIndicatorAligment; customIndicator?: | React.ReactElement | ((status?: boolean) => React.ReactElement); } const RadioContext = createContext>({ onChange: () => {}, }); const useRadioGroupContext = () => useContext(RadioContext); interface PropsGroup extends ControlStatusProps { value: T; onChange: (value: T) => void; children: JSX.Element | JSX.Element[]; disabled?: boolean; indicatorAligment?: RadioIndicatorAligment; customIndicator?: | React.ReactElement | ((status?: boolean) => React.ReactElement); } export function RadioGroup({ value, onChange, children, disabled, indicatorAligment, customIndicator, success, error, warning, }: PropsGroup) { return (
{children}
); } interface PropsOption extends ControlStatusProps { value: T; children: | string | React.ReactElement | ((selected?: boolean) => React.ReactElement); suffix?: | string | React.ReactElement | React.ReactNode | ((selected?: boolean) => React.ReactElement | React.ReactNode); disabled?: boolean; indicatorAligment?: RadioIndicatorAligment; customIndicator?: | React.ReactElement | ((status?: boolean) => React.ReactElement); } export const RadioIndicator = ({ enabled = false, className, }: { enabled?: boolean; className?: string; }) => { if (enabled) { return ( ); } else { return ( ); } }; export function RadioOption({ value, children, disabled, suffix, indicatorAligment: optionIndicatorAligment, customIndicator: optionCustomIndicator, success, error, warning, }: PropsOption) { const { value: currentValue, onChange, disabled: groupDisabled, indicatorAligment: groupIndicatorAligment, customIndicator: groupCustomIndicator, success: groupSuccess, error: groupError, warning: groupWarning, } = useRadioGroupContext(); const isSuccess = success || groupSuccess; const isError = error || groupError; const isWarning = warning || groupWarning; const indicatorAligment: RadioIndicatorAligment = optionIndicatorAligment || groupIndicatorAligment || "start"; const customIndicator = optionCustomIndicator || groupCustomIndicator; const selected = useMemo(() => currentValue == value, [currentValue, value]); const enabled = useMemo( () => !disabled && !groupDisabled, [disabled, groupDisabled] ); const handleClick = () => { if (!enabled) { return; } onChange(value); }; const el = (elChildren: typeof children | typeof suffix) => { if (typeof elChildren === "string") { return <>{elChildren}; } if (typeof elChildren === "function") { return elChildren(currentValue == value); } return elChildren as React.ReactElement; }; return (
{indicatorAligment == "start" && (customIndicator ? ( typeof customIndicator === "function" ? ( customIndicator(selected) ) : ( customIndicator ) ) : ( ))}
{el(children)}
{suffix &&
{el(suffix)}
}
{indicatorAligment == "end" && (customIndicator ? ( typeof customIndicator === "function" ? ( customIndicator(selected) ) : ( customIndicator ) ) : ( ))}
); }