{"version":3,"file":"Radio.mjs","sources":["../../../src/components/Radio/Radio.tsx"],"sourcesContent":["import { useId } from '@raikou/hooks';\nimport {\n  Box,\n  BoxProps,\n  createVarsResolver,\n  ElementProps,\n  extractStyleProps,\n  factory,\n  Factory,\n  getAutoContrastValue,\n  getContrastColor,\n  getRadius,\n  getSize,\n  getThemeColor,\n  parseThemeColor,\n  RaikouColor,\n  RaikouRadius,\n  RaikouSize,\n  StylesApiProps,\n  useProps,\n  useStyles,\n} from '../../core';\nimport { InlineInput, InlineInputStylesNames } from '../InlineInput';\nimport { RadioCard } from './RadioCard/RadioCard';\nimport { useRadioGroupContext } from './RadioGroup.context';\nimport { RadioGroup } from './RadioGroup/RadioGroup';\nimport { RadioIcon, RadioIconProps } from './RadioIcon';\nimport { RadioIndicator } from './RadioIndicator/RadioIndicator';\nimport { RadioIconStyle, RadioInnerStyle, RadioRadioStyle, RadioRootStyle } from './Radio.css';\n\nexport type RadioVariant = 'filled' | 'outline';\nexport type RadioStylesNames = InlineInputStylesNames | 'inner' | 'radio' | 'icon';\nexport type RadioCssVariables = {\n  root:\n    | '--radio-size'\n    | '--radio-radius'\n    | '--radio-color'\n    | '--radio-icon-color'\n    | '--radio-icon-size';\n};\n\nexport interface RadioProps\n  extends BoxProps,\n    StylesApiProps<RadioFactory>,\n    ElementProps<'input', 'size' | 'children'> {\n  /** Content of the `label` associated with the radio */\n  label?: React.ReactNode;\n\n  /** Key of `theme.colors` or any valid CSS color to set input color in checked state, `theme.primaryColor` by default */\n  color?: RaikouColor;\n\n  /** Controls size of the component, `'sm'` by default */\n  size?: RaikouSize | (string & {});\n\n  /** A component that replaces default check icon */\n  icon?: React.FC<RadioIconProps>;\n\n  /** Props passed down to the root element */\n  wrapperProps?: Record<string, any>;\n\n  /** Position of the label relative to the input, `'right'` by default */\n  labelPosition?: 'left' | 'right';\n\n  /** Description displayed below the label */\n  description?: React.ReactNode;\n\n  /** Error displayed below the label */\n  error?: React.ReactNode;\n\n  /** Key of `theme.radius` or any valid CSS value to set `border-radius,` \"xl\" by default */\n  radius?: RaikouRadius;\n\n  /** Assigns ref of the root element */\n  rootRef?: React.ForwardedRef<HTMLDivElement>;\n\n  /** Key of `theme.colors` or any valid CSS color to set icon color, by default value depends on `theme.autoContrast` */\n  iconColor?: RaikouColor;\n\n  /** Determines whether icon color with filled variant should depend on `background-color`. If luminosity of the `color` prop is less than `theme.luminosityThreshold`, then `theme.white` will be used for text color, otherwise `theme.black`. Overrides `theme.autoContrast`. */\n  autoContrast?: boolean;\n}\n\nexport type RadioFactory = Factory<{\n  props: RadioProps;\n  ref: HTMLInputElement;\n  stylesNames: RadioStylesNames;\n  vars: RadioCssVariables;\n  variant: RadioVariant;\n  staticComponents: {\n    Group: typeof RadioGroup;\n    Card: typeof RadioCard;\n    Indicator: typeof RadioIndicator;\n  };\n}>;\n\nconst defaultProps: Partial<RadioProps> = {\n  labelPosition: 'right',\n};\n\nconst varsResolver = createVarsResolver<RadioFactory>(\n  (theme, { size, radius, color, iconColor, variant, autoContrast }) => {\n    const parsedColor = parseThemeColor({ color: color || theme.primaryColor, theme });\n    const outlineColor =\n      parsedColor.isThemeColor && parsedColor.shade === undefined\n        ? `var(--raikou-color-${parsedColor.color}-outline)`\n        : parsedColor.color;\n\n    return {\n      root: {\n        '--radio-size': getSize(size, 'radio-size'),\n        '--radio-radius': radius === undefined ? undefined : getRadius(radius),\n        '--radio-color': variant === 'outline' ? outlineColor : getThemeColor(color, theme),\n        '--radio-icon-color': iconColor\n          ? getThemeColor(iconColor, theme)\n          : getAutoContrastValue(autoContrast, theme)\n            ? getContrastColor({ color, theme, autoContrast })\n            : undefined,\n        '--radio-icon-size': getSize(size, 'radio-icon-size'),\n      },\n    };\n  }\n);\n\nexport const Radio = factory<RadioFactory>((_props, ref) => {\n  const props = useProps('Radio', defaultProps, _props);\n  const {\n    classNames,\n    className,\n    style,\n    styles,\n    unstyled,\n    vars,\n    id,\n    size,\n    label,\n    labelPosition,\n    description,\n    error,\n    radius,\n    color,\n    variant,\n    disabled,\n    wrapperProps,\n    icon: Icon = RadioIcon,\n    rootRef,\n    iconColor,\n    onChange,\n    mod,\n    ...others\n  } = props;\n\n  const getStyles = useStyles<RadioFactory>({\n    name: 'Radio',\n    classes: {\n      root: RadioRootStyle,\n      inner: RadioInnerStyle,\n      radio: RadioRadioStyle,\n      icon: RadioIconStyle,\n    },\n    props,\n    className,\n    style,\n    classNames,\n    styles,\n    unstyled,\n    vars,\n    varsResolver,\n  });\n\n  const ctx = useRadioGroupContext();\n\n  const contextSize = ctx?.size ?? size;\n  const componentSize = props.size ? size : contextSize;\n\n  const { styleProps, rest } = extractStyleProps(others);\n  const uuid = useId(id);\n\n  const contextProps = ctx\n    ? {\n        checked: ctx.value === rest.value,\n        name: rest.name ?? ctx.name,\n        onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n          ctx.onChange(event);\n          onChange?.(event);\n        },\n      }\n    : {};\n\n  return (\n    <InlineInput\n      {...getStyles('root')}\n      __staticSelector=\"Radio\"\n      __stylesApiProps={props}\n      id={uuid}\n      size={componentSize}\n      labelPosition={labelPosition}\n      label={label}\n      description={description}\n      error={error}\n      disabled={disabled}\n      classNames={classNames}\n      styles={styles}\n      unstyled={unstyled}\n      data-checked={contextProps.checked || undefined}\n      variant={variant}\n      ref={rootRef}\n      mod={mod}\n      {...styleProps}\n      {...wrapperProps}\n    >\n      <Box {...getStyles('inner')} mod={{ 'label-position': labelPosition }}>\n        <Box\n          {...getStyles('radio', { focusable: true, variant })}\n          onChange={onChange}\n          {...rest}\n          {...contextProps}\n          component=\"input\"\n          mod={{ error: !!error }}\n          ref={ref}\n          id={uuid}\n          disabled={disabled}\n          type=\"radio\"\n        />\n        <Icon {...getStyles('icon')} aria-hidden />\n      </Box>\n    </InlineInput>\n  );\n});\n\nRadio.displayName = '@raikou/core/Radio';\nRadio.Group = RadioGroup;\nRadio.Card = RadioCard;\nRadio.Indicator = RadioIndicator;\n"],"names":[],"mappings":"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"}