UNPKG

@kwiz/fluentui

Version:
80 lines 5.47 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { MessageBar } from "@fluentui/react-components"; import { CommonConfig, filterEmptyEntries, isNotEmptyString, isNullOrEmptyString, isNullOrUndefined, jsonClone } from "@kwiz/common"; import { useCallback, useRef, useState } from "react"; import { ButtonEXPrimarySubtle } from "./button"; import { FormFieldEX } from "./field"; import { Internal_FormEX } from "./form-context"; import { PleaseWait } from "./please-wait"; import { Prompter } from "./prompt"; import { Vertical } from "./vertical"; /** render a form in a dialog, with or without a trigger button to open/close the dialog. */ export function FormDialogEX({ defaultValues, fields, buttonIcon, buttonTitle, buttonProps, dialogTitle, onSubmit, onClose, actions }) { const addButton = !isNullOrUndefined(buttonIcon) || isNotEmptyString(buttonTitle); const [show, setShow] = useState(false); const clear = useRef(); const submit = useRef(); return _jsxs(_Fragment, { children: [addButton && _jsx(ButtonEXPrimarySubtle, Object.assign({}, (buttonProps || {}), { icon: buttonIcon, title: buttonTitle, onClick: () => { var _a; (_a = clear.current) === null || _a === void 0 ? void 0 : _a.call(clear); setShow(true); } })), (show || !addButton) && _jsx(Prompter, { title: dialogTitle, onCancel: () => { setShow(false); onClose === null || onClose === void 0 ? void 0 : onClose(); }, okButtonProps: { //disabled: !valid >> no other way to show field validations appearance: "primary" }, onOK: () => { var _a; return (_a = submit.current) === null || _a === void 0 ? void 0 : _a.call(submit); }, actions: actions, children: _jsx(FormEX, { defaultValues: defaultValues, fields: fields, submit: submit, clear: clear, onSubmit: (values) => __awaiter(this, void 0, void 0, function* () { let serverError = yield onSubmit(values); if (isNullOrEmptyString(serverError)) setShow(false); return serverError; }) }) })] }); } /** render a form in-line, set the handlers for clear / submit and trigger them from your own code */ export function FormEX({ defaultValues, fields, onSubmit, clear, submit }) { const [inProgress, setInProgress] = useState(false); const [valid, setValid] = useState(false); const [submitError, setSubmitError] = useState(""); const [values, setValues] = useState(defaultValues); const clearForm = useCallback(() => { setValid(false); setSubmitError(""); setValues(jsonClone(defaultValues)); }, [defaultValues]); if (clear) clear.current = clearForm; const submitForm = useCallback(() => __awaiter(this, void 0, void 0, function* () { if (valid) { setInProgress(true); let serverError = ""; try { serverError = yield onSubmit(values); } catch (e) { console.error(e); serverError = "Unknown server error"; } if (isNotEmptyString(serverError)) { setSubmitError(serverError); } setInProgress(false); } else setSubmitError("Some form values are not valid."); }), [valid, values, onSubmit]); if (submit) submit.current = submitForm; return _jsx(FormEX_internal, { fields: fields, setValid: setValid, inProgress: inProgress, submitError: submitError, values: values, setValues: setValues }); } function FormEX_internal({ fields, setValid, inProgress, submitError, values, setValues }) { return _jsxs(Vertical, { children: [inProgress && _jsx(PleaseWait, {}), _jsx(Internal_FormEX, { submitError: submitError, onValid: isValid => setValid(isValid), children: filterEmptyEntries(fields).map(field => _jsxs(FormFieldEX, { label: field.label, hint: field.hint, formKey: field.key, required: field.required, value: values[field.key], validation: field.validation ? () => { return field.validation(values[field.key], values); } : undefined, children: [isNullOrUndefined(values[field.key]) && CommonConfig.i.IsLocalDev && _jsx(MessageBar, { layout: "multiline", intent: "warning", children: "This should be a controlled element, value should never be null or your control might get out of sync." }), field.fieldControl(values[field.key], (newValue, otherValues) => setValues(Object.assign(Object.assign(Object.assign({}, values), (otherValues || {})), { [field.key]: newValue })), values)] }, field.key)) })] }); } //# sourceMappingURL=form.js.map