@s-ui/react-organism-nested-checkboxes
Version:
This component shows a parent checkbox with children that their controls his own state.
201 lines • 8.09 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
var _excluded = ["children", "id", "name", "value", "defaultChecked", "checked", "uncheckedIcon", "checkedIcon", "defaultIndeterminate", "indeterminate", "indeterminateIcon", "label", "onChange", "onExpandToggle", "defaultIsExpanded", "isExpanded", "isIndented", "expandedIcon", "collapsedIcon"];
import cx from 'classnames';
import PropTypes from 'prop-types';
import useControlledState from '@s-ui/react-hooks/lib/useControlledState';
import useMount from '@s-ui/react-hooks/lib/useMount';
import MoleculeCheckboxField from '@s-ui/react-molecule-checkbox-field';
import useMutationObserver from './hooks/useMutationObserver.js';
import { BASE_CLASS, BUTTON_CLASS, CHILD_CLASS, CONTAINER_CLASS, getInnerCheckboxes, isFunction } from './settings.js';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
var OrganismNestedCheckboxes = function OrganismNestedCheckboxes(_ref) {
var _cx;
var children = _ref.children,
id = _ref.id,
name = _ref.name,
value = _ref.value,
_ref$defaultChecked = _ref.defaultChecked,
defaultChecked = _ref$defaultChecked === void 0 ? false : _ref$defaultChecked,
checked = _ref.checked,
UncheckedIcon = _ref.uncheckedIcon,
CheckedIcon = _ref.checkedIcon,
_ref$defaultIndetermi = _ref.defaultIndeterminate,
defaultIndeterminate = _ref$defaultIndetermi === void 0 ? false : _ref$defaultIndetermi,
indeterminate = _ref.indeterminate,
IndeterminateIcon = _ref.indeterminateIcon,
label = _ref.label,
onChange = _ref.onChange,
onExpandToggle = _ref.onExpandToggle,
_ref$defaultIsExpande = _ref.defaultIsExpanded,
defaultIsExpandedProp = _ref$defaultIsExpande === void 0 ? true : _ref$defaultIsExpande,
isExpandedProp = _ref.isExpanded,
_ref$isIndented = _ref.isIndented,
isIndented = _ref$isIndented === void 0 ? true : _ref$isIndented,
expandedIcon = _ref.expandedIcon,
collapsedIcon = _ref.collapsedIcon,
props = _objectWithoutPropertiesLoose(_ref, _excluded);
var _useControlledState = useControlledState(checked, defaultChecked),
checkedValue = _useControlledState[0],
setCheckedValue = _useControlledState[1],
isCheckedValueControlled = _useControlledState[2];
var _useControlledState2 = useControlledState(indeterminate, defaultIndeterminate),
indeterminateValue = _useControlledState2[0],
setIndeterminateValue = _useControlledState2[1],
isIndeterminateValueControlled = _useControlledState2[2];
var _useControlledState3 = useControlledState(isExpandedProp, defaultIsExpandedProp),
isExpandedValue = _useControlledState3[0],
setIsExpanded = _useControlledState3[1];
var isControlled = isCheckedValueControlled || isIndeterminateValueControlled;
var handleExpand = function handleExpand(event) {
setIsExpanded(!isExpandedValue);
isFunction(onExpandToggle) && onExpandToggle(event, {
checked: checkedValue,
expanded: !isExpandedValue,
indeterminate: indeterminateValue,
name: name,
value: value
});
};
useMount(function () {
if (!isControlled) {
var _getInnerCheckboxes = getInnerCheckboxes(ref.current, {
checked: checkedValue,
indeterminate: indeterminateValue
}),
checkboxes = _getInnerCheckboxes[0];
if (!indeterminateValue) {
checkboxes.forEach(function (element) {
element.checked !== checkedValue && element.click();
});
}
}
});
var _useMutationObserver = useMutationObserver(function (node) {
var _getInnerCheckboxes2 = getInnerCheckboxes(node, {
checked: checkedValue,
indeterminate: indeterminateValue
}),
checkboxes = _getInnerCheckboxes2[0],
_getInnerCheckboxes2$ = _getInnerCheckboxes2[1],
checked = _getInnerCheckboxes2$.checked,
indeterminate = _getInnerCheckboxes2$.indeterminate;
if (!isControlled) {
setCheckedValue(checked);
setIndeterminateValue(indeterminate);
}
if (isFunction(onChange)) {
var values = new Set();
var skippedValues = new Set();
if (checked) {
values.add(value);
} else {
checkboxes.forEach(function (element) {
if (element.checked !== checked) {
var baseElement = element.closest("." + BASE_CLASS);
var childElement = baseElement && (baseElement == null ? void 0 : baseElement.querySelector("." + CHILD_CLASS));
var hasNestedCheckboxes = baseElement.querySelector('input[type="checkbox"]') === element;
if (childElement !== ref.current && hasNestedCheckboxes) {
var _getInnerCheckboxes3 = getInnerCheckboxes(childElement, {
checked: true,
indeterminate: false
}),
innerCheckboxes = _getInnerCheckboxes3[0];
if (!skippedValues.has(element.value)) {
values.add(element.value);
innerCheckboxes.filter(function (n) {
return n !== element;
}).forEach(function (n) {
return skippedValues.add(n.value);
});
}
} else {
if (!skippedValues.has(element.value)) {
values.add(element.value);
}
}
}
});
}
onChange(event, {
value: value,
name: name,
expanded: isExpandedValue,
checked: checked,
indeterminate: indeterminate,
values: Array.from(values)
});
}
}),
ref = _useMutationObserver[0];
var onChangeHandler = function onChangeHandler(event, opts) {
var checked = opts.checked,
indeterminate = opts.indeterminate;
var _getInnerCheckboxes4 = getInnerCheckboxes(ref.current, {
checked: checked,
indeterminate: indeterminate
}),
checkboxes = _getInnerCheckboxes4[0];
checkboxes.forEach(function (element) {
if (element.checked !== checked) {
element.click();
}
});
if (!isControlled) {
setIndeterminateValue(indeterminate);
setCheckedValue(checked);
}
if (isFunction(onChange)) {
var values = new Set();
if (checked) {
values.add(value);
} else {
checkboxes.forEach(function (element) {
if (element.checked !== checked) {
values.add(element.value);
}
});
}
onChange(event, _extends({}, opts, {
checked: checked,
indeterminate: indeterminate,
expanded: isExpandedValue,
values: Array.from(values)
}));
}
};
return /*#__PURE__*/_jsxs("div", {
className: BASE_CLASS,
children: [/*#__PURE__*/_jsxs("div", {
className: CONTAINER_CLASS,
children: [/*#__PURE__*/_jsx(MoleculeCheckboxField, _extends({
id: id,
name: name,
value: value,
checked: checkedValue,
checkedIcon: CheckedIcon,
uncheckedIcon: UncheckedIcon,
indeterminate: indeterminateValue,
indeterminateIcon: IndeterminateIcon,
label: label,
onChange: onChangeHandler
}, props)), /*#__PURE__*/_jsx("button", {
type: "button",
className: cx(BUTTON_CLASS, BUTTON_CLASS + "--" + (isExpandedValue ? 'expanded' : 'hidden')),
onClick: handleExpand,
children: isExpandedValue ? expandedIcon : collapsedIcon
})]
}), /*#__PURE__*/_jsx("div", _extends({
ref: ref,
className: cx(CHILD_CLASS, (_cx = {}, _cx[CHILD_CLASS + "--indented"] = isIndented, _cx))
}, isExpandedValue ? {
'aria-expanded': true
} : {
'aria-hidden': true
}, {
children: children
}))]
});
};
OrganismNestedCheckboxes.displayName = 'OrganismNestedCheckboxes';
export default OrganismNestedCheckboxes;