@aappddeevv/dynamics-client-ui
Version:
## What is it? A library to help you create great dynamics applications.
152 lines • 7.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const React = require("react");
const recompose_1 = require("recompose");
const R = require("ramda");
const Utils_1 = require("../Dynamics/Utils");
/**
* Parent for checkbox list. Only passes enhanced props to and then renders the first child.
* The only requirement for the child is to receive `getInputProps` and potentially
* use it to render a checkbox. Children can use `updateList` in getInputProps to contribute
* to the overall checkbox list reporting from the mangaer.
*
* The underyling "checkbox creator" can optionally use `getInputProps` to set the props
* for the input element and `updateList` to add and remove checked status
* back to the manager for reporting in `onListChange`.
*/
class CheckBoxListManager extends React.Component {
constructor(props) {
super(props);
/** Non-state in the sense it does not drive rendering. */
this.checkedValues = new Set();
this.input_handleOnChange = (e) => {
this.props.onListChange && this.props.onListChange(this.checkedValues);
};
this.input_updateList = (key, checked) => checked ?
this.checkedValues.add(key) : this.checkedValues.delete(key);
// Factor out type, it's always "checked" for this component.
this.getInputProps = (_a) => {
var { type, onChange } = _a, rest = tslib_1.__rest(_a, ["type", "onChange"]);
return Object.assign({ role: "checkbox", 'type': "checkbox", onChange: Utils_1.composeEventHandlers(onChange, this.input_handleOnChange), updateList: this.input_updateList }, rest);
};
this.getCombinedProps = () => ({
getInputProps: this.getInputProps
});
}
render() {
this.checkedValues.clear();
const children = Utils_1.firstOrElse(this.props.children, Utils_1.noop);
const element = Utils_1.firstOrElse(children(this.getCombinedProps()), null);
return element;
}
}
CheckBoxListManager.defaultProps = {
onChange: Utils_1.noop,
onListChange: Utils_1.noop
};
exports.CheckBoxListManager = CheckBoxListManager;
const isNilOr = (v, o) => R.isNil(v) ? o : v;
/**
* Default and fairly standard checkbox list implementation. Renders a list of checkboxes from an options list (a strict value).
* The outer container does not need to know about ChcekBoxListManager. The callback onChange receives
* convenient properties such as the option item and its checked status as well as the event object. This
* class takes over the rendering process and makes assumptions about the options data model.
*
*/
class _CheckBoxList extends React.Component {
constructor(props) {
super(props);
// make map func an arrow outside of render so the callback func does not force a render
this.makeItem = (opt, idx, checkme, CheckBoxComponent, getInputProps, firstOnChange) => {
const value = isNilOr(opt.value, `value-${idx}`);
const label = isNilOr(opt.label, `label-${idx}`);
const isChecked = checkme(value);
const cprops = {
key: value.toString(),
label: label,
checked: isChecked,
value: value,
option: opt,
// the only trick we do is to make the onChange API easier to use.
// so we change the onChange handler from getInputProps().
getInputProps: (_a) => {
var { onChange } = _a, p = tslib_1.__rest(_a, ["onChange"]);
return getInputProps(Object.assign({}, p, {
//onChange: composeEventHandlers(firstOnChange(value, isChecked), onChange)})}
onChange: Utils_1.composeEventHandlers(firstOnChange(value, isChecked), onChange) }));
}
};
//console.log(cprops)
return (React.createElement(CheckBoxComponent, Object.assign({}, cprops)));
};
}
render() {
const _a = this.props, { options, checked, onListChange, onChange, CheckBoxComponent, Container } = _a, rest = tslib_1.__rest(_a, ["options", "checked", "onListChange", "onChange", "CheckBoxComponent", "Container"]);
const originalOnChange = onChange;
// When rendering, we already know what is checked or not, so curry onChange handler with that info.
/* const localOnChange = (value, isChecked, onOneChanged) => onOneChanged ?
* R.curry(onOneChanged)(value, !isChecked) : null*/
const localOnChange = (value, isChecked) => originalOnChange ?
(evt) => originalOnChange(value, !isChecked, evt) :
null;
const checkme = (value) => {
if (Array.isArray(checked))
return checked.includes(value);
else if (checked && R.is(Function, checked))
return checked(value);
return false;
};
return (React.createElement(CheckBoxListManager, { onChange: onChange, onListChange: onListChange }, ({ getInputProps }) => (React.createElement(Container, Object.assign({}, rest), options.map((opt, idx) => this.makeItem(opt, idx, checkme, CheckBoxComponent, getInputProps, localOnChange))))));
}
}
//R.curry(localOnChange)(R.__, R.__, originalOnChange)))}
/**
* A checkbox input element wrapped with a label.
*/
function CheckBox(_a) {
var { getInputProps } = _a, rest = tslib_1.__rest(_a, ["getInputProps"]);
const _b = getInputProps(rest), { key, value, label, checked, option, onChange, updateList } = _b, iprops = tslib_1.__rest(_b, ["key", "value", "label", "checked", "option", "onChange", "updateList"]);
//const { key, value, label, checked, option, updateList, ...iprops } = rest
const id = value.toString();
if (checked)
updateList(value, checked);
return (React.createElement("label", { htmlFor: id },
React.createElement("input", Object.assign({ id: id, name: id, style: { verticalAlign: "middle" }, checked: checked, onChange: onChange }, iprops)),
label));
}
exports.CheckBox = CheckBox;
/** Render items using a flexbox.
* @param direction "column"|"row", default is column.
*/
function DefaultContainer(props) {
const { direction, children } = props;
return (React.createElement("div", { style: { display: "flex", flexDirection: isNilOr(direction, "column") } }, children));
}
exports.DefaultContainer = DefaultContainer;
exports.CheckBoxList = recompose_1.defaultProps({
options: [],
checked: [],
onChange: (arg) => { },
Container: DefaultContainer,
CheckBoxComponent: CheckBox
})(_CheckBoxList);
exports.default = exports.CheckBoxList;
/** Render items using an HTML ul element. Each checkbox item is wrapped in a li.
*/
function ListContainer({ children, className, style }) {
return (React.createElement("ul", { style: Object.assign({ margin: 0, padding: 0, listStyleType: "none" }, style), className: className }, children));
}
exports.ListContainer = ListContainer;
function ListCheckBox(props) {
return (React.createElement("li", null,
React.createElement(CheckBox, Object.assign({}, props))));
}
exports.ListCheckBox = ListCheckBox;
exports.CheckBoxListUsingList = recompose_1.defaultProps({
options: [],
checked: [],
Container: ListContainer,
CheckBoxComponent: ListCheckBox
})(_CheckBoxList);
//# sourceMappingURL=CheckBoxList.js.map