UNPKG

@appbuckets/react-ui

Version:
213 lines (210 loc) 5.78 kB
import { __rest, __read, __assign, __spreadArray } from 'tslib'; import * as React from 'react'; import clsx from 'clsx'; import { useAutoControlledValue, useForkRef, createShorthandFactory, } from '@appbuckets/react-ui-core'; import { useField } from '../hooks/useField.js'; import { useSharedClassName, useSplitStateClassName, } from '../utils/customHook.js'; import '../BucketTheme/BucketTheme.js'; import { useWithDefaultProps } from '../BucketTheme/BucketContext.js'; import { useTabIndex } from '../hooks/useTabIndex.js'; import Icon from '../Icon/Icon.js'; import Field from '../Field/Field.js'; /* -------- * Component Render * -------- */ var Checkbox = React.forwardRef(function (receivedProps, ref) { /** Get component props */ var props = useWithDefaultProps('checkbox', receivedProps); var _a = useSharedClassName(props), className = _a.className, _b = _a.rest, /** Strict Checkbox Props */ checkedProp = _b.checked, defaultChecked = _b.defaultChecked, indeterminate = _b.indeterminate, radio = _b.radio, userDefinedTabIndex = _b.tabIndex; _b.type; var handleChecked = _b.onChecked, handleClick = _b.onClick, handleUnchecked = _b.onUnchecked, asSwitch = _b.switch, /** All other Checkbox props */ rawRest = __rest(_b, [ 'checked', 'defaultChecked', 'indeterminate', 'radio', 'tabIndex', 'type', 'onChecked', 'onClick', 'onUnchecked', 'switch', ]); var _c = __read(useSplitStateClassName(rawRest), 1), stateClassName = _c[0]; // ---- // Build field and Helpers // ---- var _d = useField(rawRest), fieldRef = _d.fieldRef, _e = _d.fieldProps, label = _e.label, fieldProps = __rest(_e, ['label']), rest = _d.rest, addClassesToField = _d.addClassesToField, removeClassesFromField = _d.removeClassesFromField, helpers = __rest(_d, [ 'fieldRef', 'fieldProps', 'rest', 'addClassesToField', 'removeClassesFromField', ]); var disabled = fieldProps.disabled, readOnly = fieldProps.readOnly, required = fieldProps.required; /* -------- * AutoControlled Checked State * -------- */ var _f = __read( useAutoControlledValue(false, { prop: checkedProp, defaultProp: defaultChecked, }), 2 ), checked = _f[0], trySetChecked = _f[1]; /* -------- * Internal Component Ref * -------- */ var inputRef = React.useRef(null); var handleRef = useForkRef(ref, inputRef); /* -------- * Change Field Classes based on State * -------- */ React.useEffect( function () { if (checked) { addClassesToField('checked'); } else { removeClassesFromField('checked'); } }, [checked, addClassesToField, removeClassesFromField] ); /* -------- * Component Classes * -------- */ var checkBoxType = radio ? 'radio' : asSwitch ? 'switch' : 'checkbox'; var classes = clsx( { required: required, disabled: disabled, checked: checked }, !label && 'unlabeled', !checked && indeterminate && 'indeterminate', checkBoxType, stateClassName, className ); /* -------- * Internal Checkbox Props * -------- */ var canToggle = !disabled && !readOnly && !(radio && checked); var tabIndex = useTabIndex({ disabled: disabled, readOnly: readOnly, prop: userDefinedTabIndex, }); /* -------- * Component Handlers * -------- */ var handleLabelClick = function (e) { /** If checkbox could not toggle, return */ if (!canToggle) { return; } e.stopPropagation(); /** Set field as touched and dirty */ helpers.setFieldClicked(); helpers.setFieldChanged(); /** Build the Handler Params to be reused */ var changeHandlerParams = [ e, __assign(__assign({}, props), { checked: !checked }), ]; /** Call user defined Handlers */ if (handleClick) { handleClick.apply( void 0, __spreadArray([], __read(changeHandlerParams), false) ); } if (!checked && handleChecked) { handleChecked.apply( void 0, __spreadArray([], __read(changeHandlerParams), false) ); } else if (checked && handleUnchecked) { handleUnchecked.apply( void 0, __spreadArray([], __read(changeHandlerParams), false) ); } /** Try to set the internal auto controlled state */ trySetChecked(!checked); }; /* -------- * Memoized Component Element * -------- */ var checkboxIcon = React.useMemo( function () { if (asSwitch) { return null; } return React.createElement(Icon, { className: 'checkbox-icon', name: radio ? 'circle' : indeterminate ? 'minus' : 'check', }); }, [asSwitch, radio, indeterminate] ); var labelElement = React.createElement( 'label', { htmlFor: rest.id, onClick: handleLabelClick }, React.createElement('div', { className: 'checkbox-toggle' }, checkboxIcon), label && React.createElement('span', null, label) ); /* -------- * Component Render * -------- */ return React.createElement( Field, __assign({ ref: fieldRef }, fieldProps, { contentType: checkBoxType }), React.createElement( 'input', __assign({}, rest, { ref: handleRef, readOnly: true, className: classes, disabled: disabled, checked: checked, tabIndex: tabIndex, type: radio ? 'radio' : 'checkbox', }) ), labelElement ); }); Checkbox.displayName = 'Checkbox'; Checkbox.create = createShorthandFactory(Checkbox, function (label) { return { label: label }; }); export { Checkbox as default };