@open-formulieren/formio-builder
Version:
An opinionated Formio webform builder for Open Forms
75 lines (74 loc) • 6.27 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Field, FieldArray, useFormikContext } from 'formik';
import { useContext, useEffect, useRef, useState } from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import { ClearOnHide, Hidden, Key } from '../../components/builder';
import { Component } from '../../components/formio';
import { BuilderContext } from '../../context';
/**
* Form to configure a Formio 'columns' type component.
*/
const EditForm = () => {
const { uniquifyKey } = useContext(BuilderContext);
const isKeyManuallySetRef = useRef(false);
const { values } = useFormikContext();
const generatedKey = uniquifyKey(values.key);
return (_jsx("div", Object.assign({ className: "card" }, { children: _jsxs("div", Object.assign({ className: "card-body" }, { children: [_jsx(Key, { isManuallySetRef: isKeyManuallySetRef, generatedValue: generatedKey }), _jsx(Hidden, {}), _jsx(ClearOnHide, {}), _jsx(Columns, {})] })) })));
};
EditForm.defaultValues = {
key: '',
hidden: false,
clearOnHide: true,
columns: [
{
size: 6,
sizeMobile: 4,
components: [],
},
{
size: 6,
sizeMobile: 4,
components: [],
},
],
};
const ColumnRow = ({ index, arrayHelpers }) => {
var _a;
const intl = useIntl();
const { getFieldProps, setFieldError } = useFormikContext();
const numCols = ((_a = getFieldProps('columns').value) === null || _a === void 0 ? void 0 : _a.length) || 0;
const prefix = `columns.${index}`;
const { value: column } = getFieldProps(prefix);
return (_jsxs(_Fragment, { children: [_jsx("td", Object.assign({ style: { verticalAlign: 'middle' } }, { children: _jsxs("div", Object.assign({ style: { display: 'flex', gap: '1em' } }, { children: [_jsx(Field, { as: "input", type: "range", name: `${prefix}.size`, className: "form-control-range", min: 1, max: 12, "aria-label": intl.formatMessage({ id: "yrz/oC", defaultMessage: [{ type: 0, value: "Column size, value between 1 and 12." }] }) }), _jsxs("span", Object.assign({ style: { flexShrink: '0' } }, { children: [column.size, " / 12"] }))] })) })), _jsx("td", Object.assign({ style: { verticalAlign: 'middle' } }, { children: _jsxs("div", Object.assign({ style: { display: 'flex', gap: '1em' } }, { children: [_jsx(Field, { as: "input", type: "range", name: `${prefix}.sizeMobile`, className: "form-control-range", min: 1, max: 4, "aria-label": intl.formatMessage({ id: "pT5jx/", defaultMessage: [{ type: 0, value: "Column size on mobile, value between 1 and 4." }] }) }), _jsxs("span", Object.assign({ style: { flexShrink: '0' } }, { children: [column.sizeMobile, " / 4"] }))] })) })), _jsx("td", { children: _jsx("button", Object.assign({ type: "button", className: "btn btn-secondary formio-button-remove-row",
// TODO: in new design -> implement this in a proper accessible way
disabled: numCols <= 1, "aria-label": intl.formatMessage({ id: "Xj1uvL", defaultMessage: [{ type: 0, value: "Remove" }] }), onClick: () => {
arrayHelpers.remove(index);
// Reset possible array-level validation error, to work around the mangled
// validation errors. This effectively masks the problem described in
// https://github.com/jaredpalmer/formik/issues/3352, it does not *solve*
// it. A fresh submit attempt will re-run validation.
setFieldError('columns', undefined);
} }, { children: _jsx("i", { className: "fa fa-times-circle-o" }) })) })] }));
};
const Columns = () => {
const intl = useIntl();
const { getFieldProps, validateField } = useFormikContext();
const { value: columns = [] } = getFieldProps('columns');
const [mustValidate, setMustValidate] = useState(false);
const tooltip = intl.formatMessage({ id: "GjumK9", defaultMessage: [{ type: 0, value: "Specify the size of each column. The sum of all the widths should be 100%." }] });
useEffect(() => {
if (!mustValidate)
return;
validateField('columns');
setMustValidate(false);
}, [mustValidate, validateField]);
return (_jsx(Component, Object.assign({ type: "datagrid", field: "columns", label: _jsx(FormattedMessage, { id: 'Fn2vnC', defaultMessage: [{ type: 0, value: "Column sizes" }] }), tooltip: tooltip }, { children: _jsx(FieldArray, Object.assign({ name: "columns" }, { children: arrayHelpers => (_jsxs("table", Object.assign({ className: "table table-bordered" }, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", Object.assign({ className: "field-required" }, { children: _jsx(FormattedMessage, { id: 'nSRkSW', defaultMessage: [{ type: 0, value: "Size" }] }) })), _jsx("th", Object.assign({ className: "field-required" }, { children: _jsx(FormattedMessage, { id: 'KMbfsU', defaultMessage: [{ type: 0, value: "Size (mobile)" }] }) })), _jsx("th", { children: _jsx("span", Object.assign({ className: "sr-only" }, { children: _jsx(FormattedMessage, { id: 'BR10QN', defaultMessage: [{ type: 0, value: "Add/remove" }] }) })) })] }) }), _jsx("tbody", { children: columns.map((_, index) => (_jsx("tr", { children: _jsx(ColumnRow, { index: index, arrayHelpers: arrayHelpers }) }, index))) }), _jsx("tfoot", { children: _jsx("tr", { children: _jsx("td", Object.assign({ colSpan: 3 }, { children: _jsxs("button", Object.assign({ type: "button", className: "btn btn-primary formio-button-add-row", onClick: () => {
arrayHelpers.push({
size: 6,
sizeMobile: 4,
components: [],
});
setMustValidate(true);
} }, { children: [_jsx("i", { className: "fa fa-plus", "aria-hidden": "true" }), _jsx(FormattedMessage, { id: 'ee4oWr', defaultMessage: [{ type: 0, value: "Add column" }] })] })) })) }) })] }))) })) })));
};
export default EditForm;