UNPKG

@open-formulieren/formio-builder

Version:

An opinionated Formio webform builder for Open Forms

77 lines (76 loc) 5.48 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.withMultiple = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); /** * Wrapper/HOC component to enable multi-input behaviour for (certain) fields. * * This component operates on arrays of values instead of just scalars, e.g. a list of * strings, a list of dates... This is not guaranteed to be compatible with every * 'atomic' component type of Form.io - Select/File upload handle this property * themselves rather than needing to be wrapped. * * Usage: * * const MyComponent = ({name, label, description, ...props}) => {...} * const MultipleMyComponent = withMultiple(MyComponent); * * <MyComponent name="foo" {...props} /> // <input name="foo" /> * <MultipleMyComponent multiple={true|false} name="foo" {...props} /> // <input name="foo[0]" /> etc. /> * */ const formik_1 = require("formik"); const react_intl_1 = require("react-intl"); const context_1 = require("../../context"); const component_label_1 = __importDefault(require("./component-label")); const description_1 = __importDefault(require("./description")); const Multiple = (props) => { const { label, description, required, tooltip } = props; const { as: WrappedComponent, defaultValue, name } = props, otherProps = __rest(props, ["as", "defaultValue", "name"]); // TypeScript can't infer this itself with generics, as it doesn't know yet what P looks // like by omitting multiple - but *we* know that HoC forward the remainder of the props. const nestedProps = otherProps; const { getFieldProps } = (0, formik_1.useFormikContext)(); let { value: fieldValue } = getFieldProps(name); // due to possibly bad value initialization, it's possible the value is undefined or // even a completely different type (because you're switching from multiple false -> true) // TODO: figure out we can figure this at the formik level? this probably depends on render // order though if (!Array.isArray(fieldValue)) { fieldValue = []; } return ((0, jsx_runtime_1.jsxs)(context_1.RenderContext.Provider, Object.assign({ value: { bareInput: true } }, { children: [label && (0, jsx_runtime_1.jsx)(component_label_1.default, { label: label, required: required, tooltip: tooltip }), (0, jsx_runtime_1.jsx)(formik_1.FieldArray, Object.assign({ name: name }, { children: arrayHelpers => ((0, jsx_runtime_1.jsx)("table", Object.assign({ className: "table table-bordered" }, { children: (0, jsx_runtime_1.jsxs)("tbody", { children: [(fieldValue || []).map((_, index) => ((0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsx)(WrappedComponent, Object.assign({ name: `${name}[${index}]` }, nestedProps)) }), (0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsxs)("button", Object.assign({ className: "btn btn-secondary", type: "button", onClick: () => arrayHelpers.remove(index) }, { children: [(0, jsx_runtime_1.jsx)("span", Object.assign({ className: "sr-only" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'd5SKAT', defaultMessage: [{ type: 0, value: "Remove item" }] }) })), (0, jsx_runtime_1.jsx)("i", { className: "fa fa-times-circle-o", "aria-hidden": "true" })] })) })] }, index))), (0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", Object.assign({ colSpan: 2 }, { children: (0, jsx_runtime_1.jsxs)("button", Object.assign({ type: "button", className: "btn btn-primary formio-button-add-another", onClick: () => arrayHelpers.push(defaultValue) }, { children: [(0, jsx_runtime_1.jsx)("i", { className: "fa fa-plus", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: 'Fc/emc', defaultMessage: [{ type: 0, value: "Add another" }] })] })) })) })] }) }))) })), description && (0, jsx_runtime_1.jsx)(description_1.default, { text: description })] }))); }; /** * Wrap a given component into a higher order Multiple component. */ function withMultiple(WrappedComponent, defaultValue) { return (props) => { const { multiple } = props, otherProps = __rest(props, ["multiple"]); // TypeScript can't infer this itself with generics, as it doesn't know yet what P looks // like by omitting multiple - but *we* know that HoC forward the remainder of the props. const nestedProps = otherProps; // in single value/scalar mode -> just render the component itself if (!multiple) { return (0, jsx_runtime_1.jsx)(WrappedComponent, Object.assign({}, nestedProps)); } // otherwise, go into array-of-fields mode return (0, jsx_runtime_1.jsx)(Multiple, Object.assign({ as: WrappedComponent, defaultValue: defaultValue }, otherProps)); }; } exports.withMultiple = withMultiple; exports.default = Multiple;