@kwiz/fluentui
Version:
KWIZ common controls for FluentUI
80 lines • 5.47 kB
JavaScript
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