import React from 'react'
import { View } from '../View'
import { InputBase, InputBaseDefaultOrder, selectInputBaseProps } from '../InputBase'
import { useAnimatedVariantStyles } from '../..'
import { Touchable } from '../Touchable'
import { Icon } from '../Icon'
import { CheckboxProps } from './types'
import { AnyRecord, AppIcon, IJSX, StyledComponentProps } from '@codeleap/styles'
import { MobileStyleRegistry } from '../../Registry'
import { useStylesFor } from '../../hooks'
import { useInputBase } from '../InputBase/useInputBase'
import { fields } from '@codeleap/form'
export * from './styles'
export * from './types'
/** Reversed order puts the innerWrapper (the visual checkbox) before the label, matching right-aligned checkbox layouts without a separate style override. */
const reversedOrder = [...InputBaseDefaultOrder].reverse()
export const Checkbox = (props: CheckboxProps) => {
const {
inputBaseProps,
others,
} = selectInputBaseProps({
...Checkbox.defaultProps,
...props,
})
const {
style,
disabled,
debugName,
checkboxOnLeft,
checkIcon,
field,
forceError,
value,
onValueChange,
} = others
const styles = useStylesFor(Checkbox.styleRegistryName, style)
const {
validation,
wrapperRef,
inputValue,
onInputValueChange,
} = useInputBase(field, fields.boolean, { value, onValueChange })
const boxAnimation = useAnimatedVariantStyles({
variantStyles: styles,
animatedProperties: ['box:unchecked', 'box:disabled', 'box:checked', 'box:disabled-checked', 'box:disabled-unchecked'],
transition: styles['box:transition'],
updater: () => {
'worklet'
let disabledStyle = {}
if (disabled) {
disabledStyle = inputValue ? styles['box:disabled-checked'] : styles['box:disabled-unchecked']
}
const style = inputValue ? styles['box:checked'] : styles['box:unchecked']
return {
...style,
...disabledStyle,
}
},
dependencies: [inputValue, disabled],
})
const checkmarkWrapperAnimation = useAnimatedVariantStyles({
variantStyles: styles,
animatedProperties: ['checkmarkWrapper:unchecked', 'checkmarkWrapper:disabled', 'checkmarkWrapper:checked', 'checkmarkWrapper:disabled-unchecked', 'checkmarkWrapper:disabled-checked'],
transition: styles['checkmarkWrapper:transition'],
updater: () => {
'worklet'
let disabledStyle = {}
if (disabled) {
disabledStyle = inputValue ? styles['checkmarkWrapper:disabled-checked'] : styles['checkmarkWrapper:disabled-unchecked']
}
const style = inputValue ? styles['checkmarkWrapper:checked'] : styles['checkmarkWrapper:unchecked']
return {
...style,
...disabledStyle,
}
},
dependencies: [inputValue, disabled],
})
/** Same `__props` escape-hatch as RadioGroup — lets the style variant set the default side without requiring a prop at every call site. */
// @ts-expect-error
const _checkboxOnLeft = checkboxOnLeft ?? styles.__props?.checkboxOnLeft
const hasError = validation?.showError || forceError
return onInputValueChange(!inputValue),
disabled,
rippleDisabled: true,
}}
order={_checkboxOnLeft ? reversedOrder : InputBaseDefaultOrder}
>
}
Checkbox.styleRegistryName = 'Checkbox'
Checkbox.rootElement = 'wrapper'
Checkbox.elements = [...InputBase.elements, 'checkmark', 'box', '__props']
Checkbox.withVariantTypes = (styles: S) => {
return Checkbox as (props: StyledComponentProps) => IJSX
}
Checkbox.defaultProps = {
checkIcon: 'check' as AppIcon,
} as Partial
MobileStyleRegistry.registerComponent(Checkbox)