@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
96 lines (95 loc) • 3.36 kB
JavaScript
"use client";
import { rootVariants } from "../Form/style.mjs";
import FormFlatGroup from "../Form/components/FormFlatGroup.mjs";
import FormGroup from "../Form/components/FormGroup.mjs";
import { FormKitContext } from "./context.mjs";
import FormField from "./Field.mjs";
import { useCallback, useMemo, useRef } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { cx, useResponsive } from "antd-style";
//#region src/base-ui/FormKit/Form.tsx
const focusFirstInvalid = (root) => {
const target = root?.querySelector("[aria-invalid=\"true\"]");
if (!target) return;
target.scrollIntoView?.({ block: "center" });
target.focus();
};
const Form = ({ activeKey, children, className, classNames, collapsible, defaultActiveKey, footer, form, gap, itemMinWidth, items, itemsType = "group", layout, onCollapse, ref, style, styles: customStyles, variant = "borderless", ...rest }) => {
const { mobile } = useResponsive();
const formRef = useRef(null);
const context = useMemo(() => ({
form,
layout: layout || (mobile ? "vertical" : "horizontal"),
variant
}), [
form,
layout,
mobile,
variant
]);
const mergedRef = useCallback((node) => {
formRef.current = node;
if (typeof ref === "function") ref(node);
else if (ref) ref.current = node;
}, [ref]);
const handleSubmit = useCallback(async (event) => {
event.preventDefault();
if (!(await form.submit()).valid) setTimeout(() => focusFirstInvalid(formRef.current), 0);
}, [form]);
const renderField = (item, index) => /* @__PURE__ */ jsx(FormField, {
className: classNames?.item,
divider: index !== 0,
style: customStyles?.item,
...item,
minWidth: "minWidth" in item ? item.minWidth : itemMinWidth
}, item.name ?? index);
const renderGroup = (group, index) => {
const key = group.key ?? index;
return /* @__PURE__ */ jsx(FormGroup, {
active: activeKey && group.key ? activeKey.includes(key) : void 0,
className: classNames?.group,
collapsible: group.collapsible ?? collapsible,
desc: group.desc,
extra: group.extra,
icon: group.icon,
style: customStyles?.group,
title: group.title,
variant: group.variant || variant,
defaultActive: defaultActiveKey && group.key ? defaultActiveKey.includes(key) : group.defaultActive,
onCollapse: (active) => {
const keys = (activeKey || defaultActiveKey || []).filter((k) => k !== key);
onCollapse?.(active ? [...keys, key] : keys);
},
children: Array.isArray(group.children) ? group.children.filter((item) => !item.hidden).map(renderField) : group.children
}, key);
};
const renderedItems = items && items.length > 0 ? itemsType === "group" ? items.map(renderGroup) : /* @__PURE__ */ jsx(FormFlatGroup, {
className: classNames?.group,
style: customStyles?.group,
variant,
children: items.filter((item) => !item.hidden).map(renderField)
}) : null;
return /* @__PURE__ */ jsx(FormKitContext, {
value: context,
children: /* @__PURE__ */ jsxs("form", {
...rest,
noValidate: true,
className: cx(rootVariants({ variant }), className),
ref: mergedRef,
style: {
gap: gap ?? (layout === "vertical" ? 0 : void 0),
...style
},
onSubmit: handleSubmit,
children: [
renderedItems,
children,
footer
]
})
});
};
Form.displayName = "Form";
//#endregion
export { Form as default };
//# sourceMappingURL=Form.mjs.map