@lobehub/ui 5.55.0 → 5.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/EditableText/ControlInput.mjs +2 -2
- package/es/EditableText/ControlInput.mjs.map +1 -1
- package/es/SearchBar/SearchBar.mjs +2 -2
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/base-ui/Checkbox/Checkbox.d.mts +6 -2
- package/es/base-ui/Checkbox/Checkbox.mjs +2 -1
- package/es/base-ui/Checkbox/Checkbox.mjs.map +1 -1
- package/es/base-ui/Checkbox/CheckboxGroup.mjs +2 -2
- package/es/base-ui/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/base-ui/Checkbox/index.d.mts +2 -2
- package/es/base-ui/ColorPicker/ColorPicker.mjs +4 -4
- package/es/base-ui/ColorPicker/ColorPicker.mjs.map +1 -1
- package/es/base-ui/DatePicker/style.mjs +1 -0
- package/es/base-ui/DatePicker/style.mjs.map +1 -1
- package/es/base-ui/Form/components/FormGroup.mjs +13 -5
- package/es/base-ui/Form/components/FormGroup.mjs.map +1 -1
- package/es/base-ui/Form/index.d.mts +3 -0
- package/es/base-ui/Form/index.mjs +3 -0
- package/es/base-ui/Form/index.mjs.map +1 -1
- package/es/base-ui/Form/style.mjs +32 -6
- package/es/base-ui/Form/style.mjs.map +1 -1
- package/es/base-ui/FormKit/Field.d.mts +9 -0
- package/es/base-ui/FormKit/Field.mjs +167 -0
- package/es/base-ui/FormKit/Field.mjs.map +1 -0
- package/es/base-ui/FormKit/Form.mjs +96 -0
- package/es/base-ui/FormKit/Form.mjs.map +1 -0
- package/es/base-ui/FormKit/List.d.mts +34 -0
- package/es/base-ui/FormKit/List.mjs +102 -0
- package/es/base-ui/FormKit/List.mjs.map +1 -0
- package/es/base-ui/FormKit/SubmitFooter.d.mts +6 -0
- package/es/base-ui/FormKit/SubmitFooter.mjs +36 -0
- package/es/base-ui/FormKit/SubmitFooter.mjs.map +1 -0
- package/es/base-ui/FormKit/binding.mjs +23 -0
- package/es/base-ui/FormKit/binding.mjs.map +1 -0
- package/es/base-ui/FormKit/context.d.mts +7 -0
- package/es/base-ui/FormKit/context.mjs +14 -0
- package/es/base-ui/FormKit/context.mjs.map +1 -0
- package/es/base-ui/FormKit/engine/tanstack.mjs +293 -0
- package/es/base-ui/FormKit/engine/tanstack.mjs.map +1 -0
- package/es/base-ui/FormKit/engine/types.d.mts +6 -0
- package/es/base-ui/FormKit/index.d.mts +31 -0
- package/es/base-ui/FormKit/index.mjs +28 -0
- package/es/base-ui/FormKit/index.mjs.map +1 -0
- package/es/base-ui/FormKit/instance.mjs +67 -0
- package/es/base-ui/FormKit/instance.mjs.map +1 -0
- package/es/base-ui/FormKit/schema.d.mts +33 -0
- package/es/base-ui/FormKit/schema.mjs +23 -0
- package/es/base-ui/FormKit/schema.mjs.map +1 -0
- package/es/base-ui/FormKit/style.mjs +119 -0
- package/es/base-ui/FormKit/style.mjs.map +1 -0
- package/es/base-ui/FormKit/type.d.mts +122 -0
- package/es/base-ui/FormKit/useForm.d.mts +10 -0
- package/es/base-ui/FormKit/useForm.mjs +54 -0
- package/es/base-ui/FormKit/useForm.mjs.map +1 -0
- package/es/base-ui/FormKit/useStoreSelector.mjs +25 -0
- package/es/base-ui/FormKit/useStoreSelector.mjs.map +1 -0
- package/es/base-ui/FormKit/useWatch.d.mts +7 -0
- package/es/base-ui/FormKit/useWatch.mjs +12 -0
- package/es/base-ui/FormKit/useWatch.mjs.map +1 -0
- package/es/base-ui/Input/Input.d.mts +6 -2
- package/es/base-ui/Input/Input.mjs +2 -1
- package/es/base-ui/Input/Input.mjs.map +1 -1
- package/es/base-ui/Input/InputNumber.d.mts +6 -2
- package/es/base-ui/Input/InputNumber.mjs +13 -6
- package/es/base-ui/Input/InputNumber.mjs.map +1 -1
- package/es/base-ui/Input/InputPassword.d.mts +6 -2
- package/es/base-ui/Input/InputPassword.mjs +4 -3
- package/es/base-ui/Input/InputPassword.mjs.map +1 -1
- package/es/base-ui/Input/TextArea.d.mts +6 -2
- package/es/base-ui/Input/TextArea.mjs +2 -1
- package/es/base-ui/Input/TextArea.mjs.map +1 -1
- package/es/base-ui/Input/index.d.mts +5 -5
- package/es/base-ui/Input/style.d.mts +4 -1
- package/es/base-ui/Input/style.mjs +21 -8
- package/es/base-ui/Input/style.mjs.map +1 -1
- package/es/base-ui/Modal/Modal.mjs +4 -8
- package/es/base-ui/Modal/Modal.mjs.map +1 -1
- package/es/base-ui/Slider/SliderWithInput.mjs +2 -2
- package/es/base-ui/Slider/SliderWithInput.mjs.map +1 -1
- package/es/base-ui/Switch/Switch.mjs +2 -2
- package/es/base-ui/Switch/Switch.mjs.map +1 -1
- package/es/base-ui/Text/style.d.mts +1 -1
- package/es/base-ui/Tree/TreeNode.mjs +2 -2
- package/es/base-ui/Tree/TreeNode.mjs.map +1 -1
- package/es/base-ui/index.d.mts +8 -8
- package/es/base-ui/index.mjs +6 -6
- package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs +2 -2
- package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs.map +1 -1
- package/es/chat/MessageInput/MessageInput.mjs +2 -2
- package/es/chat/MessageInput/MessageInput.mjs.map +1 -1
- package/es/chat/MessageModal/MessageModal.mjs +2 -2
- package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
- package/es/eslint/index.d.mts +27 -3
- package/es/eslint/index.mjs +40 -2
- package/es/eslint/index.mjs.map +1 -1
- package/es/eslint/noInlineFormSchema.mjs +44 -0
- package/es/eslint/noInlineFormSchema.mjs.map +1 -0
- package/es/i18n/resources/en/form.d.mts +4 -0
- package/es/i18n/resources/en/form.mjs +4 -0
- package/es/i18n/resources/en/form.mjs.map +1 -1
- package/es/i18n/resources/zhCn/form.d.mts +4 -0
- package/es/i18n/resources/zhCn/form.mjs +4 -0
- package/es/i18n/resources/zhCn/form.mjs.map +1 -1
- package/es/node_modules/.pnpm/@eslint_core@0.17.0/node_modules/@eslint/core/dist/esm/types.d.mts +1139 -0
- package/es/node_modules/.pnpm/@types_estree@1.0.9/node_modules/@types/estree/index.d.mts +528 -0
- package/es/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.mts +201 -0
- package/es/node_modules/.pnpm/eslint@9.39.5_jiti@2.6.1_supports-color@10.2.2/node_modules/eslint/lib/types/index.d.mts +962 -0
- package/package.json +6 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useTranslation } from "../../i18n/useTranslation.mjs";
|
|
3
|
+
import form_default from "../../i18n/resources/en/form.mjs";
|
|
4
|
+
import { fieldStyles, fieldVariants } from "../Form/style.mjs";
|
|
5
|
+
import FormDivider from "../Form/components/FormDivider.mjs";
|
|
6
|
+
import FormTitle from "../Form/components/FormTitle.mjs";
|
|
7
|
+
import { resolveBinding } from "./binding.mjs";
|
|
8
|
+
import { useFormKitContext } from "./context.mjs";
|
|
9
|
+
import { toFieldValidator } from "./schema.mjs";
|
|
10
|
+
import { getInternals } from "./instance.mjs";
|
|
11
|
+
import { fieldKitStyles } from "./style.mjs";
|
|
12
|
+
import { useStoreSelector } from "./useStoreSelector.mjs";
|
|
13
|
+
import { cloneElement, isValidElement, memo, useCallback, useEffect, useId, useRef } from "react";
|
|
14
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
import { cx, useResponsive } from "antd-style";
|
|
16
|
+
//#region src/base-ui/FormKit/Field.tsx
|
|
17
|
+
const isEmpty = (value) => value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
18
|
+
const FieldControl = memo(({ bare, children, deps, emptyValue, getValue, id, name, render, required, trigger, validate, validateDebounce, validateOn, valueProp }) => {
|
|
19
|
+
const { form } = useFormKitContext();
|
|
20
|
+
const { engine, validateOn: formValidateOn } = getInternals(form);
|
|
21
|
+
const { t } = useTranslation(form_default);
|
|
22
|
+
const errorId = `${id}-error`;
|
|
23
|
+
const requiredMessage = typeof required === "string" ? required : t("form.required");
|
|
24
|
+
const fieldValidator = validate ? toFieldValidator(validate) : void 0;
|
|
25
|
+
const validatorRef = useRef(void 0);
|
|
26
|
+
validatorRef.current = async (value, values) => {
|
|
27
|
+
if (required && isEmpty(value)) return requiredMessage;
|
|
28
|
+
return fieldValidator?.(value, values);
|
|
29
|
+
};
|
|
30
|
+
const hasValidator = Boolean(required || validate);
|
|
31
|
+
const depsKey = deps?.join("\0");
|
|
32
|
+
useEffect(() => engine.registerField(name, {
|
|
33
|
+
debounceMs: validateDebounce,
|
|
34
|
+
deps: depsKey ? depsKey.split("\0") : void 0,
|
|
35
|
+
validate: hasValidator ? (value, values) => validatorRef.current(value, values) : void 0,
|
|
36
|
+
validateOn: validateOn ?? formValidateOn
|
|
37
|
+
}), [
|
|
38
|
+
engine,
|
|
39
|
+
name,
|
|
40
|
+
hasValidator,
|
|
41
|
+
depsKey,
|
|
42
|
+
validateDebounce,
|
|
43
|
+
validateOn,
|
|
44
|
+
formValidateOn
|
|
45
|
+
]);
|
|
46
|
+
const field = useStoreSelector(engine, (e) => e.getField(name));
|
|
47
|
+
const child = isValidElement(children) ? children : void 0;
|
|
48
|
+
const binding = child ? resolveBinding(child, {
|
|
49
|
+
emptyValue,
|
|
50
|
+
getValue,
|
|
51
|
+
trigger,
|
|
52
|
+
valueProp
|
|
53
|
+
}) : void 0;
|
|
54
|
+
const handlerRef = useRef({
|
|
55
|
+
binding,
|
|
56
|
+
childProps: child?.props
|
|
57
|
+
});
|
|
58
|
+
handlerRef.current = {
|
|
59
|
+
binding,
|
|
60
|
+
childProps: child?.props
|
|
61
|
+
};
|
|
62
|
+
const onChange = useCallback((...args) => {
|
|
63
|
+
const { binding: current, childProps } = handlerRef.current;
|
|
64
|
+
if (current) childProps?.[current.trigger]?.(...args);
|
|
65
|
+
const next = current ? current.getValue(...args) : args[0];
|
|
66
|
+
engine.setValue(name, next, "user");
|
|
67
|
+
}, [engine, name]);
|
|
68
|
+
const onBlur = useCallback((...args) => {
|
|
69
|
+
handlerRef.current.childProps?.onBlur?.(...args);
|
|
70
|
+
engine.blurField(name);
|
|
71
|
+
}, [engine, name]);
|
|
72
|
+
const warnedRef = useRef(false);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (render || child || warnedRef.current || process.env.NODE_ENV === "production") return;
|
|
75
|
+
warnedRef.current = true;
|
|
76
|
+
console.warn(`[@lobehub/ui/base-ui/form] Form.Field "${name}" needs a single element child or a render prop; nothing was bound.`);
|
|
77
|
+
}, [
|
|
78
|
+
render,
|
|
79
|
+
child,
|
|
80
|
+
name
|
|
81
|
+
]);
|
|
82
|
+
const errorNode = field.error && !bare ? /* @__PURE__ */ jsx("div", {
|
|
83
|
+
className: fieldStyles.error,
|
|
84
|
+
id: errorId,
|
|
85
|
+
children: field.error
|
|
86
|
+
}) : null;
|
|
87
|
+
if (render) {
|
|
88
|
+
const renderProps = {
|
|
89
|
+
error: field.error,
|
|
90
|
+
name,
|
|
91
|
+
onBlur,
|
|
92
|
+
onChange,
|
|
93
|
+
touched: field.touched,
|
|
94
|
+
validating: field.validating,
|
|
95
|
+
value: field.value
|
|
96
|
+
};
|
|
97
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [render(renderProps), errorNode] });
|
|
98
|
+
}
|
|
99
|
+
if (!child || !binding) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
100
|
+
const control = cloneElement(child, {
|
|
101
|
+
"aria-describedby": field.error ? errorId : void 0,
|
|
102
|
+
"aria-invalid": field.error ? true : void 0,
|
|
103
|
+
"id": child.props.id ?? id,
|
|
104
|
+
[binding.trigger]: onChange,
|
|
105
|
+
[binding.valueProp]: field.value === void 0 ? binding.emptyValue : field.value,
|
|
106
|
+
"onBlur": onBlur
|
|
107
|
+
});
|
|
108
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [control, errorNode] });
|
|
109
|
+
});
|
|
110
|
+
FieldControl.displayName = "FormFieldControl";
|
|
111
|
+
const FormField = memo(({ avatar, bare, children, className, deps, desc, divider, emptyValue, extra, getValue, hidden, label, layout, minWidth, name, render, required, style, tag, trigger, validate, validateDebounce, validateOn, valueProp, variant }) => {
|
|
112
|
+
const id = useId();
|
|
113
|
+
const { mobile } = useResponsive();
|
|
114
|
+
const config = useFormKitContext();
|
|
115
|
+
if (hidden) return null;
|
|
116
|
+
const control = !name ? children : /* @__PURE__ */ jsx(FieldControl, {
|
|
117
|
+
bare,
|
|
118
|
+
deps,
|
|
119
|
+
emptyValue,
|
|
120
|
+
getValue,
|
|
121
|
+
id,
|
|
122
|
+
name,
|
|
123
|
+
render,
|
|
124
|
+
required,
|
|
125
|
+
trigger,
|
|
126
|
+
validate,
|
|
127
|
+
validateDebounce,
|
|
128
|
+
validateOn,
|
|
129
|
+
valueProp,
|
|
130
|
+
children
|
|
131
|
+
});
|
|
132
|
+
if (bare) return /* @__PURE__ */ jsx(Fragment$1, { children: control });
|
|
133
|
+
const labelFor = render ? void 0 : name ? id : isValidElement(children) ? children.props.id : void 0;
|
|
134
|
+
const mergedLayout = layout || (mobile ? "vertical" : config.layout);
|
|
135
|
+
const mergedVariant = variant || config.variant;
|
|
136
|
+
const controlWidth = mergedLayout === "vertical" || minWidth === void 0 || minWidth === "" ? void 0 : typeof minWidth === "number" ? `${minWidth}px` : minWidth;
|
|
137
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [divider && /* @__PURE__ */ jsx(FormDivider, { visible: mergedVariant !== "borderless" }), /* @__PURE__ */ jsxs("div", {
|
|
138
|
+
className: cx(fieldVariants({ layout: mergedLayout }), className),
|
|
139
|
+
style,
|
|
140
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
141
|
+
className: fieldStyles.label,
|
|
142
|
+
htmlFor: labelFor,
|
|
143
|
+
children: /* @__PURE__ */ jsx(FormTitle, {
|
|
144
|
+
avatar,
|
|
145
|
+
desc,
|
|
146
|
+
tag,
|
|
147
|
+
title: required ? /* @__PURE__ */ jsxs(Fragment$1, { children: [label, /* @__PURE__ */ jsx("span", {
|
|
148
|
+
"aria-hidden": true,
|
|
149
|
+
className: fieldKitStyles.required,
|
|
150
|
+
children: "*"
|
|
151
|
+
})] }) : label
|
|
152
|
+
})
|
|
153
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
154
|
+
style: controlWidth ? { width: controlWidth } : void 0,
|
|
155
|
+
className: cx(fieldStyles.control, mergedLayout === "vertical" && fieldStyles.controlVertical, controlWidth && fieldKitStyles.controlFixed),
|
|
156
|
+
children: [control, extra && /* @__PURE__ */ jsx("div", {
|
|
157
|
+
className: fieldKitStyles.extra,
|
|
158
|
+
children: extra
|
|
159
|
+
})]
|
|
160
|
+
})]
|
|
161
|
+
})] });
|
|
162
|
+
});
|
|
163
|
+
FormField.displayName = "FormField";
|
|
164
|
+
//#endregion
|
|
165
|
+
export { FormField as default };
|
|
166
|
+
|
|
167
|
+
//# sourceMappingURL=Field.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Field.mjs","names":["formMessages"],"sources":["../../../src/base-ui/FormKit/Field.tsx"],"sourcesContent":["'use client';\n\nimport { cx, useResponsive } from 'antd-style';\nimport {\n cloneElement,\n isValidElement,\n memo,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n} from 'react';\n\nimport formMessages from '@/i18n/resources/en/form';\nimport { useTranslation } from '@/i18n/useTranslation';\n\nimport FormDivider from '../Form/components/FormDivider';\nimport FormTitle from '../Form/components/FormTitle';\nimport { fieldStyles, fieldVariants } from '../Form/style';\nimport { resolveBinding } from './binding';\nimport { useFormKitContext } from './context';\nimport type { FieldValidator } from './engine/types';\nimport { getInternals } from './instance';\nimport { toFieldValidator } from './schema';\nimport { fieldKitStyles } from './style';\nimport type { FieldRenderProps, FormFieldProps, FormValues } from './type';\nimport { useStoreSelector } from './useStoreSelector';\n\nconst isEmpty = (value: unknown) =>\n value === undefined ||\n value === null ||\n value === '' ||\n (Array.isArray(value) && value.length === 0);\n\ntype ControlProps = Pick<\n FormFieldProps,\n | 'bare'\n | 'children'\n | 'deps'\n | 'emptyValue'\n | 'getValue'\n | 'name'\n | 'render'\n | 'required'\n | 'trigger'\n | 'validate'\n | 'validateDebounce'\n | 'validateOn'\n | 'valueProp'\n> & { id: string; name: string };\n\nconst FieldControl = memo<ControlProps>(\n ({\n bare,\n children,\n deps,\n emptyValue,\n getValue,\n id,\n name,\n render,\n required,\n trigger,\n validate,\n validateDebounce,\n validateOn,\n valueProp,\n }) => {\n const { form } = useFormKitContext();\n const { engine, validateOn: formValidateOn } = getInternals(form);\n const { t } = useTranslation(formMessages);\n const errorId = `${id}-error`;\n\n const requiredMessage = typeof required === 'string' ? required : t('form.required');\n const fieldValidator = validate ? toFieldValidator(validate) : undefined;\n const validatorRef = useRef<FieldValidator | undefined>(undefined);\n validatorRef.current = async (value, values) => {\n if (required && isEmpty(value)) return requiredMessage;\n return fieldValidator?.(value, values);\n };\n const hasValidator = Boolean(required || validate);\n const depsKey = deps?.join('\\u0000');\n\n useEffect(\n () =>\n engine.registerField(name, {\n debounceMs: validateDebounce,\n deps: depsKey ? depsKey.split('\\u0000') : undefined,\n validate: hasValidator\n ? (value, values) => validatorRef.current!(value, values)\n : undefined,\n validateOn: validateOn ?? formValidateOn,\n }),\n [engine, name, hasValidator, depsKey, validateDebounce, validateOn, formValidateOn],\n );\n\n const field = useStoreSelector(engine, (e) => e.getField(name));\n\n const child = isValidElement(children) ? (children as ReactElement<any>) : undefined;\n const binding = child\n ? resolveBinding(child, { emptyValue, getValue, trigger, valueProp })\n : undefined;\n const handlerRef = useRef({ binding, childProps: child?.props as Record<string, any> });\n handlerRef.current = { binding, childProps: child?.props as Record<string, any> };\n\n const onChange = useCallback(\n (...args: unknown[]) => {\n const { binding: current, childProps } = handlerRef.current;\n if (current) childProps?.[current.trigger]?.(...args);\n const next = current ? current.getValue(...args) : args[0];\n engine.setValue(name, next, 'user');\n },\n [engine, name],\n );\n const onBlur = useCallback(\n (...args: unknown[]) => {\n handlerRef.current.childProps?.onBlur?.(...args);\n engine.blurField(name);\n },\n [engine, name],\n );\n\n const warnedRef = useRef(false);\n useEffect(() => {\n if (render || child || warnedRef.current || process.env.NODE_ENV === 'production') return;\n warnedRef.current = true;\n console.warn(\n `[@lobehub/ui/base-ui/form] Form.Field \"${name}\" needs a single element child or a render prop; nothing was bound.`,\n );\n }, [render, child, name]);\n\n const errorNode =\n field.error && !bare ? (\n <div className={fieldStyles.error} id={errorId}>\n {field.error}\n </div>\n ) : null;\n\n if (render) {\n const renderProps: FieldRenderProps = {\n error: field.error,\n name,\n onBlur,\n onChange,\n touched: field.touched,\n validating: field.validating,\n value: field.value,\n };\n return (\n <>\n {render(renderProps)}\n {errorNode}\n </>\n );\n }\n\n if (!child || !binding) return <>{children}</>;\n\n const control = cloneElement(child, {\n 'aria-describedby': field.error ? errorId : undefined,\n 'aria-invalid': field.error ? true : undefined,\n 'id': child.props.id ?? id,\n [binding.trigger]: onChange,\n [binding.valueProp]: field.value === undefined ? binding.emptyValue : field.value,\n 'onBlur': onBlur,\n });\n\n return (\n <>\n {control}\n {errorNode}\n </>\n );\n },\n);\n\nFieldControl.displayName = 'FormFieldControl';\n\nconst FormField = memo<FormFieldProps>(\n ({\n avatar,\n bare,\n children,\n className,\n deps,\n desc,\n divider,\n emptyValue,\n extra,\n getValue,\n hidden,\n label,\n layout,\n minWidth,\n name,\n render,\n required,\n style,\n tag,\n trigger,\n validate,\n validateDebounce,\n validateOn,\n valueProp,\n variant,\n }) => {\n const id = useId();\n const { mobile } = useResponsive();\n const config = useFormKitContext();\n\n if (hidden) return null;\n\n const control = !name ? (\n children\n ) : (\n <FieldControl\n bare={bare}\n deps={deps}\n emptyValue={emptyValue}\n getValue={getValue}\n id={id}\n name={name}\n render={render}\n required={required}\n trigger={trigger}\n validate={validate}\n validateDebounce={validateDebounce}\n validateOn={validateOn}\n valueProp={valueProp}\n >\n {children}\n </FieldControl>\n );\n\n if (bare) return <>{control}</>;\n\n const labelFor = render\n ? undefined\n : name\n ? id\n : isValidElement<{ id?: string }>(children)\n ? children.props.id\n : undefined;\n const mergedLayout = layout || (mobile ? 'vertical' : config.layout);\n const mergedVariant = variant || config.variant;\n const controlWidth =\n mergedLayout === 'vertical' || minWidth === undefined || minWidth === ''\n ? undefined\n : typeof minWidth === 'number'\n ? `${minWidth}px`\n : minWidth;\n\n return (\n <>\n {divider && <FormDivider visible={mergedVariant !== 'borderless'} />}\n <div className={cx(fieldVariants({ layout: mergedLayout }), className)} style={style}>\n <label className={fieldStyles.label} htmlFor={labelFor}>\n <FormTitle\n avatar={avatar}\n desc={desc}\n tag={tag}\n title={\n required ? (\n <>\n {label}\n <span aria-hidden className={fieldKitStyles.required}>\n *\n </span>\n </>\n ) : (\n label\n )\n }\n />\n </label>\n <div\n style={controlWidth ? { width: controlWidth } : undefined}\n className={cx(\n fieldStyles.control,\n mergedLayout === 'vertical' && fieldStyles.controlVertical,\n controlWidth && fieldKitStyles.controlFixed,\n )}\n >\n {control}\n {extra && <div className={fieldKitStyles.extra}>{extra}</div>}\n </div>\n </div>\n </>\n );\n },\n);\n\nFormField.displayName = 'FormField';\n\nexport default FormField as unknown as (<T extends FormValues = FormValues>(\n props: FormFieldProps<T>,\n) => ReactNode) & { displayName?: string };\n"],"mappings":";;;;;;;;;;;;;;;;AA8BA,MAAM,WAAW,UACf,UAAU,KAAA,KACV,UAAU,QACV,UAAU,MACT,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAmB5C,MAAM,eAAe,MAClB,EACC,MACA,UACA,MACA,YACA,UACA,IACA,MACA,QACA,UACA,SACA,UACA,kBACA,YACA,gBACI;CACJ,MAAM,EAAE,SAAS,kBAAkB;CACnC,MAAM,EAAE,QAAQ,YAAY,mBAAmB,aAAa,IAAI;CAChE,MAAM,EAAE,MAAM,eAAeA,YAAY;CACzC,MAAM,UAAU,GAAG,GAAG;CAEtB,MAAM,kBAAkB,OAAO,aAAa,WAAW,WAAW,EAAE,eAAe;CACnF,MAAM,iBAAiB,WAAW,iBAAiB,QAAQ,IAAI,KAAA;CAC/D,MAAM,eAAe,OAAmC,KAAA,CAAS;CACjE,aAAa,UAAU,OAAO,OAAO,WAAW;EAC9C,IAAI,YAAY,QAAQ,KAAK,GAAG,OAAO;EACvC,OAAO,iBAAiB,OAAO,MAAM;CACvC;CACA,MAAM,eAAe,QAAQ,YAAY,QAAQ;CACjD,MAAM,UAAU,MAAM,KAAK,IAAQ;CAEnC,gBAEI,OAAO,cAAc,MAAM;EACzB,YAAY;EACZ,MAAM,UAAU,QAAQ,MAAM,IAAQ,IAAI,KAAA;EAC1C,UAAU,gBACL,OAAO,WAAW,aAAa,QAAS,OAAO,MAAM,IACtD,KAAA;EACJ,YAAY,cAAc;CAC5B,CAAC,GACH;EAAC;EAAQ;EAAM;EAAc;EAAS;EAAkB;EAAY;CAAc,CACpF;CAEA,MAAM,QAAQ,iBAAiB,SAAS,MAAM,EAAE,SAAS,IAAI,CAAC;CAE9D,MAAM,QAAQ,eAAe,QAAQ,IAAK,WAAiC,KAAA;CAC3E,MAAM,UAAU,QACZ,eAAe,OAAO;EAAE;EAAY;EAAU;EAAS;CAAU,CAAC,IAClE,KAAA;CACJ,MAAM,aAAa,OAAO;EAAE;EAAS,YAAY,OAAO;CAA6B,CAAC;CACtF,WAAW,UAAU;EAAE;EAAS,YAAY,OAAO;CAA6B;CAEhF,MAAM,WAAW,aACd,GAAG,SAAoB;EACtB,MAAM,EAAE,SAAS,SAAS,eAAe,WAAW;EACpD,IAAI,SAAS,aAAa,QAAQ,QAAQ,GAAG,GAAG,IAAI;EACpD,MAAM,OAAO,UAAU,QAAQ,SAAS,GAAG,IAAI,IAAI,KAAK;EACxD,OAAO,SAAS,MAAM,MAAM,MAAM;CACpC,GACA,CAAC,QAAQ,IAAI,CACf;CACA,MAAM,SAAS,aACZ,GAAG,SAAoB;EACtB,WAAW,QAAQ,YAAY,SAAS,GAAG,IAAI;EAC/C,OAAO,UAAU,IAAI;CACvB,GACA,CAAC,QAAQ,IAAI,CACf;CAEA,MAAM,YAAY,OAAO,KAAK;CAC9B,gBAAgB;EACd,IAAI,UAAU,SAAS,UAAU,WAAW,QAAQ,IAAI,aAAa,cAAc;EACnF,UAAU,UAAU;EACpB,QAAQ,KACN,0CAA0C,KAAK,oEACjD;CACF,GAAG;EAAC;EAAQ;EAAO;CAAI,CAAC;CAExB,MAAM,YACJ,MAAM,SAAS,CAAC,OACd,oBAAC,OAAD;EAAK,WAAW,YAAY;EAAO,IAAI;EACpC,UAAA,MAAM;CACJ,CAAA,IACH;CAEN,IAAI,QAAQ;EACV,MAAM,cAAgC;GACpC,OAAO,MAAM;GACb;GACA;GACA;GACA,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,OAAO,MAAM;EACf;EACA,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,OAAO,WAAW,GAClB,SACD,EAAA,CAAA;CAEN;CAEA,IAAI,CAAC,SAAS,CAAC,SAAS,OAAO,oBAAA,YAAA,EAAG,SAAW,CAAA;CAE7C,MAAM,UAAU,aAAa,OAAO;EAClC,oBAAoB,MAAM,QAAQ,UAAU,KAAA;EAC5C,gBAAgB,MAAM,QAAQ,OAAO,KAAA;EACrC,MAAM,MAAM,MAAM,MAAM;GACvB,QAAQ,UAAU;GAClB,QAAQ,YAAY,MAAM,UAAU,KAAA,IAAY,QAAQ,aAAa,MAAM;EAC5E,UAAU;CACZ,CAAC;CAED,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,SACA,SACD,EAAA,CAAA;AAEN,CACF;AAEA,aAAa,cAAc;AAE3B,MAAM,YAAY,MACf,EACC,QACA,MACA,UACA,WACA,MACA,MACA,SACA,YACA,OACA,UACA,QACA,OACA,QACA,UACA,MACA,QACA,UACA,OACA,KACA,SACA,UACA,kBACA,YACA,WACA,cACI;CACJ,MAAM,KAAK,MAAM;CACjB,MAAM,EAAE,WAAW,cAAc;CACjC,MAAM,SAAS,kBAAkB;CAEjC,IAAI,QAAQ,OAAO;CAEnB,MAAM,UAAU,CAAC,OACf,WAEA,oBAAC,cAAD;EACQ;EACA;EACM;EACF;EACN;EACE;EACE;EACE;EACD;EACC;EACQ;EACN;EACD;EAEV;CACW,CAAA;CAGhB,IAAI,MAAM,OAAO,oBAAA,YAAA,EAAA,UAAG,QAAU,CAAA;CAE9B,MAAM,WAAW,SACb,KAAA,IACA,OACE,KACA,eAAgC,QAAQ,IACtC,SAAS,MAAM,KACf,KAAA;CACR,MAAM,eAAe,WAAW,SAAS,aAAa,OAAO;CAC7D,MAAM,gBAAgB,WAAW,OAAO;CACxC,MAAM,eACJ,iBAAiB,cAAc,aAAa,KAAA,KAAa,aAAa,KAClE,KAAA,IACA,OAAO,aAAa,WAClB,GAAG,SAAS,MACZ;CAER,OACE,qBAAA,YAAA,EAAA,UAAA,CACG,WAAW,oBAAC,aAAD,EAAa,SAAS,kBAAkB,aAAe,CAAA,GACnE,qBAAC,OAAD;EAAK,WAAW,GAAG,cAAc,EAAE,QAAQ,aAAa,CAAC,GAAG,SAAS;EAAU;EAA/E,UAAA,CACE,oBAAC,SAAD;GAAO,WAAW,YAAY;GAAO,SAAS;GAC5C,UAAA,oBAAC,WAAD;IACU;IACF;IACD;IACL,OACE,WACE,qBAAA,YAAA,EAAA,UAAA,CACG,OACD,oBAAC,QAAD;KAAM,eAAA;KAAY,WAAW,eAAe;KAAU,UAAA;IAEhD,CAAA,CACN,EAAA,CAAA,IAEF;GAGL,CAAA;EACI,CAAA,GACP,qBAAC,OAAD;GACE,OAAO,eAAe,EAAE,OAAO,aAAa,IAAI,KAAA;GAChD,WAAW,GACT,YAAY,SACZ,iBAAiB,cAAc,YAAY,iBAC3C,gBAAgB,eAAe,YACjC;GANF,UAAA,CAQG,SACA,SAAS,oBAAC,OAAD;IAAK,WAAW,eAAe;IAAQ,UAAA;GAAW,CAAA,CACzD;EACF,CAAA,CAAA;CACL,CAAA,CAAA,EAAA,CAAA;AAEN,CACF;AAEA,UAAU,cAAc"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { rootVariants } from "../Form/style.mjs";
|
|
3
|
+
import FormFlatGroup from "../Form/components/FormFlatGroup.mjs";
|
|
4
|
+
import FormGroup from "../Form/components/FormGroup.mjs";
|
|
5
|
+
import { FormKitContext } from "./context.mjs";
|
|
6
|
+
import FormField from "./Field.mjs";
|
|
7
|
+
import { useCallback, useMemo, useRef } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { cx, useResponsive } from "antd-style";
|
|
10
|
+
//#region src/base-ui/FormKit/Form.tsx
|
|
11
|
+
const focusFirstInvalid = (root) => {
|
|
12
|
+
const target = root?.querySelector("[aria-invalid=\"true\"]");
|
|
13
|
+
if (!target) return;
|
|
14
|
+
target.scrollIntoView?.({ block: "center" });
|
|
15
|
+
target.focus();
|
|
16
|
+
};
|
|
17
|
+
const Form = ({ activeKey, children, className, classNames, collapsible, defaultActiveKey, footer, form, gap, itemMinWidth, items, itemsType = "group", layout, onCollapse, ref, style, styles: customStyles, variant = "borderless", ...rest }) => {
|
|
18
|
+
const { mobile } = useResponsive();
|
|
19
|
+
const formRef = useRef(null);
|
|
20
|
+
const context = useMemo(() => ({
|
|
21
|
+
form,
|
|
22
|
+
layout: layout || (mobile ? "vertical" : "horizontal"),
|
|
23
|
+
variant
|
|
24
|
+
}), [
|
|
25
|
+
form,
|
|
26
|
+
layout,
|
|
27
|
+
mobile,
|
|
28
|
+
variant
|
|
29
|
+
]);
|
|
30
|
+
const mergedRef = useCallback((node) => {
|
|
31
|
+
formRef.current = node;
|
|
32
|
+
if (typeof ref === "function") ref(node);
|
|
33
|
+
else if (ref) ref.current = node;
|
|
34
|
+
}, [ref]);
|
|
35
|
+
const handleSubmit = useCallback(async (event) => {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
if (!(await form.submit()).valid) setTimeout(() => focusFirstInvalid(formRef.current), 0);
|
|
38
|
+
}, [form]);
|
|
39
|
+
const renderField = (item, index) => /* @__PURE__ */ jsx(FormField, {
|
|
40
|
+
className: classNames?.item,
|
|
41
|
+
divider: index !== 0,
|
|
42
|
+
style: customStyles?.item,
|
|
43
|
+
...item,
|
|
44
|
+
minWidth: "minWidth" in item ? item.minWidth : itemMinWidth
|
|
45
|
+
}, item.name ?? index);
|
|
46
|
+
const renderGroup = (group, index) => {
|
|
47
|
+
const key = group.key ?? index;
|
|
48
|
+
return /* @__PURE__ */ jsx(FormGroup, {
|
|
49
|
+
active: activeKey && group.key ? activeKey.includes(key) : void 0,
|
|
50
|
+
className: classNames?.group,
|
|
51
|
+
collapsible: group.collapsible ?? collapsible,
|
|
52
|
+
desc: group.desc,
|
|
53
|
+
extra: group.extra,
|
|
54
|
+
icon: group.icon,
|
|
55
|
+
style: customStyles?.group,
|
|
56
|
+
title: group.title,
|
|
57
|
+
variant: group.variant || variant,
|
|
58
|
+
defaultActive: defaultActiveKey && group.key ? defaultActiveKey.includes(key) : group.defaultActive,
|
|
59
|
+
onCollapse: (active) => {
|
|
60
|
+
const keys = (activeKey || defaultActiveKey || []).filter((k) => k !== key);
|
|
61
|
+
onCollapse?.(active ? [...keys, key] : keys);
|
|
62
|
+
},
|
|
63
|
+
children: Array.isArray(group.children) ? group.children.filter((item) => !item.hidden).map(renderField) : group.children
|
|
64
|
+
}, key);
|
|
65
|
+
};
|
|
66
|
+
const renderedItems = items && items.length > 0 ? itemsType === "group" ? items.map(renderGroup) : /* @__PURE__ */ jsx(FormFlatGroup, {
|
|
67
|
+
className: classNames?.group,
|
|
68
|
+
style: customStyles?.group,
|
|
69
|
+
variant,
|
|
70
|
+
children: items.filter((item) => !item.hidden).map(renderField)
|
|
71
|
+
}) : null;
|
|
72
|
+
return /* @__PURE__ */ jsx(FormKitContext, {
|
|
73
|
+
value: context,
|
|
74
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
75
|
+
...rest,
|
|
76
|
+
noValidate: true,
|
|
77
|
+
className: cx(rootVariants({ variant }), className),
|
|
78
|
+
ref: mergedRef,
|
|
79
|
+
style: {
|
|
80
|
+
gap: gap ?? (layout === "vertical" ? 0 : void 0),
|
|
81
|
+
...style
|
|
82
|
+
},
|
|
83
|
+
onSubmit: handleSubmit,
|
|
84
|
+
children: [
|
|
85
|
+
renderedItems,
|
|
86
|
+
children,
|
|
87
|
+
footer
|
|
88
|
+
]
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
Form.displayName = "Form";
|
|
93
|
+
//#endregion
|
|
94
|
+
export { Form as default };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=Form.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Form.mjs","names":[],"sources":["../../../src/base-ui/FormKit/Form.tsx"],"sourcesContent":["'use client';\n\nimport { cx, useResponsive } from 'antd-style';\nimport { type FormEvent, useCallback, useMemo, useRef } from 'react';\n\nimport FormFlatGroup from '../Form/components/FormFlatGroup';\nimport FormGroup from '../Form/components/FormGroup';\nimport { rootVariants } from '../Form/style';\nimport { FormKitContext, type FormKitContextValue } from './context';\nimport FormField from './Field';\nimport type { FormFieldProps, FormGroupItem, FormProps, FormValues } from './type';\n\nconst focusFirstInvalid = (root: HTMLFormElement | null) => {\n const target = root?.querySelector<HTMLElement>('[aria-invalid=\"true\"]');\n if (!target) return;\n target.scrollIntoView?.({ block: 'center' });\n target.focus();\n};\n\nconst Form = <T extends FormValues>({\n activeKey,\n children,\n className,\n classNames,\n collapsible,\n defaultActiveKey,\n footer,\n form,\n gap,\n itemMinWidth,\n items,\n itemsType = 'group',\n layout,\n onCollapse,\n ref,\n style,\n styles: customStyles,\n variant = 'borderless',\n ...rest\n}: FormProps<T>) => {\n const { mobile } = useResponsive();\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const context = useMemo<FormKitContextValue>(\n () => ({\n form,\n layout: layout || (mobile ? 'vertical' : 'horizontal'),\n variant,\n }),\n [form, layout, mobile, variant],\n );\n\n const mergedRef = useCallback(\n (node: HTMLFormElement | null) => {\n formRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n\n const handleSubmit = useCallback(\n async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const result = await form.submit();\n if (!result.valid) setTimeout(() => focusFirstInvalid(formRef.current), 0);\n },\n [form],\n );\n\n const renderField = (item: FormFieldProps<T>, index: number) => (\n <FormField\n className={classNames?.item}\n divider={index !== 0}\n key={item.name ?? index}\n style={customStyles?.item}\n {...(item as FormFieldProps)}\n minWidth={'minWidth' in item ? item.minWidth : itemMinWidth}\n />\n );\n\n const renderGroup = (group: FormGroupItem<T>, index: number) => {\n const key = group.key ?? index;\n return (\n <FormGroup\n active={activeKey && group.key ? activeKey.includes(key) : undefined}\n className={classNames?.group}\n collapsible={group.collapsible ?? collapsible}\n desc={group.desc}\n extra={group.extra}\n icon={group.icon}\n key={key}\n style={customStyles?.group}\n title={group.title}\n variant={group.variant || variant}\n defaultActive={\n defaultActiveKey && group.key ? defaultActiveKey.includes(key) : group.defaultActive\n }\n onCollapse={(active) => {\n const keys = (activeKey || defaultActiveKey || []).filter((k) => k !== key);\n onCollapse?.(active ? [...keys, key] : keys);\n }}\n >\n {Array.isArray(group.children)\n ? group.children.filter((item) => !item.hidden).map(renderField)\n : group.children}\n </FormGroup>\n );\n };\n\n const renderedItems =\n items && items.length > 0 ? (\n itemsType === 'group' ? (\n (items as FormGroupItem<T>[]).map(renderGroup)\n ) : (\n <FormFlatGroup className={classNames?.group} style={customStyles?.group} variant={variant}>\n {(items as FormFieldProps<T>[]).filter((item) => !item.hidden).map(renderField)}\n </FormFlatGroup>\n )\n ) : null;\n\n return (\n <FormKitContext value={context}>\n <form\n {...rest}\n noValidate\n className={cx(rootVariants({ variant }), className)}\n ref={mergedRef}\n style={{ gap: gap ?? (layout === 'vertical' ? 0 : undefined), ...style }}\n onSubmit={handleSubmit}\n >\n {renderedItems}\n {children}\n {footer}\n </form>\n </FormKitContext>\n );\n};\n\nForm.displayName = 'Form';\n\nexport default Form;\n"],"mappings":";;;;;;;;;;AAYA,MAAM,qBAAqB,SAAiC;CAC1D,MAAM,SAAS,MAAM,cAA2B,yBAAuB;CACvE,IAAI,CAAC,QAAQ;CACb,OAAO,iBAAiB,EAAE,OAAO,SAAS,CAAC;CAC3C,OAAO,MAAM;AACf;AAEA,MAAM,QAA8B,EAClC,WACA,UACA,WACA,YACA,aACA,kBACA,QACA,MACA,KACA,cACA,OACA,YAAY,SACZ,QACA,YACA,KACA,OACA,QAAQ,cACR,UAAU,cACV,GAAG,WACe;CAClB,MAAM,EAAE,WAAW,cAAc;CACjC,MAAM,UAAU,OAA+B,IAAI;CAEnD,MAAM,UAAU,eACP;EACL;EACA,QAAQ,WAAW,SAAS,aAAa;EACzC;CACF,IACA;EAAC;EAAM;EAAQ;EAAQ;CAAO,CAChC;CAEA,MAAM,YAAY,aACf,SAAiC;EAChC,QAAQ,UAAU;EAClB,IAAI,OAAO,QAAQ,YAAY,IAAI,IAAI;OAClC,IAAI,KAAK,IAAI,UAAU;CAC9B,GACA,CAAC,GAAG,CACN;CAEA,MAAM,eAAe,YACnB,OAAO,UAAsC;EAC3C,MAAM,eAAe;EAErB,IAAI,EAAC,MADgB,KAAK,OAAO,EAAA,CACrB,OAAO,iBAAiB,kBAAkB,QAAQ,OAAO,GAAG,CAAC;CAC3E,GACA,CAAC,IAAI,CACP;CAEA,MAAM,eAAe,MAAyB,UAC5C,oBAAC,WAAD;EACE,WAAW,YAAY;EACvB,SAAS,UAAU;EAEnB,OAAO,cAAc;EACrB,GAAK;EACL,UAAU,cAAc,OAAO,KAAK,WAAW;CAChD,GAJM,KAAK,QAAQ,KAInB;CAGH,MAAM,eAAe,OAAyB,UAAkB;EAC9D,MAAM,MAAM,MAAM,OAAO;EACzB,OACE,oBAAC,WAAD;GACE,QAAQ,aAAa,MAAM,MAAM,UAAU,SAAS,GAAG,IAAI,KAAA;GAC3D,WAAW,YAAY;GACvB,aAAa,MAAM,eAAe;GAClC,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,MAAM,MAAM;GAEZ,OAAO,cAAc;GACrB,OAAO,MAAM;GACb,SAAS,MAAM,WAAW;GAC1B,eACE,oBAAoB,MAAM,MAAM,iBAAiB,SAAS,GAAG,IAAI,MAAM;GAEzE,aAAa,WAAW;IACtB,MAAM,QAAQ,aAAa,oBAAoB,CAAC,EAAA,CAAG,QAAQ,MAAM,MAAM,GAAG;IAC1E,aAAa,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,IAAI;GAC7C;GAEC,UAAA,MAAM,QAAQ,MAAM,QAAQ,IACzB,MAAM,SAAS,QAAQ,SAAS,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,WAAW,IAC7D,MAAM;EACD,GAfJ,GAeI;CAEf;CAEA,MAAM,gBACJ,SAAS,MAAM,SAAS,IACtB,cAAc,UACX,MAA6B,IAAI,WAAW,IAE7C,oBAAC,eAAD;EAAe,WAAW,YAAY;EAAO,OAAO,cAAc;EAAgB;EAC9E,UAAA,MAA8B,QAAQ,SAAS,CAAC,KAAK,MAAM,CAAC,CAAC,IAAI,WAAW;CACjE,CAAA,IAEf;CAEN,OACE,oBAAC,gBAAD;EAAgB,OAAO;EACrB,UAAA,qBAAC,QAAD;GACE,GAAI;GACJ,YAAA;GACA,WAAW,GAAG,aAAa,EAAE,QAAQ,CAAC,GAAG,SAAS;GAClD,KAAK;GACL,OAAO;IAAE,KAAK,QAAQ,WAAW,aAAa,IAAI,KAAA;IAAY,GAAG;GAAM;GACvE,UAAU;GANZ,UAAA;IAQG;IACA;IACA;GACG;;CACQ,CAAA;AAEpB;AAEA,KAAK,cAAc"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FieldValidate } from "./schema.mjs";
|
|
2
|
+
import { ReactElement, ReactNode } from "react";
|
|
3
|
+
//#region src/base-ui/FormKit/List.d.ts
|
|
4
|
+
interface FormListField {
|
|
5
|
+
index: number;
|
|
6
|
+
key: string;
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
9
|
+
interface FormListRenderProps {
|
|
10
|
+
add: (item?: unknown) => void;
|
|
11
|
+
fields: FormListField[];
|
|
12
|
+
move: (from: number, to: number) => void;
|
|
13
|
+
remove: (index: number) => void;
|
|
14
|
+
}
|
|
15
|
+
interface FormListColumn {
|
|
16
|
+
children: ReactElement;
|
|
17
|
+
flex?: number;
|
|
18
|
+
name: string;
|
|
19
|
+
required?: boolean | string;
|
|
20
|
+
title?: ReactNode;
|
|
21
|
+
validate?: FieldValidate;
|
|
22
|
+
}
|
|
23
|
+
interface FormListProps {
|
|
24
|
+
addText?: ReactNode;
|
|
25
|
+
children?: (props: FormListRenderProps) => ReactNode;
|
|
26
|
+
columns?: FormListColumn[];
|
|
27
|
+
emptyText?: ReactNode;
|
|
28
|
+
name: string;
|
|
29
|
+
newItem?: unknown;
|
|
30
|
+
}
|
|
31
|
+
declare const FormList: import("react").NamedExoticComponent<FormListProps>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { FormListColumn, FormListField, FormListProps, FormListRenderProps, FormList as default };
|
|
34
|
+
//# sourceMappingURL=List.d.mts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import ActionIcon from "../ActionIcon/ActionIcon.mjs";
|
|
3
|
+
import { useTranslation } from "../../i18n/useTranslation.mjs";
|
|
4
|
+
import form_default from "../../i18n/resources/en/form.mjs";
|
|
5
|
+
import { useFormKitContext } from "./context.mjs";
|
|
6
|
+
import { getInternals } from "./instance.mjs";
|
|
7
|
+
import { listStyles } from "./style.mjs";
|
|
8
|
+
import { useStoreSelector } from "./useStoreSelector.mjs";
|
|
9
|
+
import FormField from "./Field.mjs";
|
|
10
|
+
import { cloneElement, memo, useCallback, useRef } from "react";
|
|
11
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { PlusIcon, XIcon } from "lucide-react";
|
|
13
|
+
//#region src/base-ui/FormKit/List.tsx
|
|
14
|
+
let rowSeed = 0;
|
|
15
|
+
const nextRowKey = () => `row-${rowSeed += 1}`;
|
|
16
|
+
const createItem = (newItem) => typeof newItem === "function" ? newItem() : newItem && typeof newItem === "object" ? structuredClone(newItem) : newItem ?? {};
|
|
17
|
+
const labelFor = (column, index) => column.children.props["aria-label"] ?? (typeof column.title === "string" ? `${column.title} ${index + 1}` : void 0);
|
|
18
|
+
const FormList = memo(({ addText, children, columns, emptyText, name, newItem }) => {
|
|
19
|
+
const { form } = useFormKitContext();
|
|
20
|
+
const { engine } = getInternals(form);
|
|
21
|
+
const { t } = useTranslation(form_default);
|
|
22
|
+
const length = useStoreSelector(engine, (e) => {
|
|
23
|
+
const value = e.getValue(name);
|
|
24
|
+
return Array.isArray(value) ? value.length : 0;
|
|
25
|
+
});
|
|
26
|
+
const keysRef = useRef([]);
|
|
27
|
+
const keys = keysRef.current;
|
|
28
|
+
if (keys.length > length) keys.length = length;
|
|
29
|
+
while (keys.length < length) keys.push(nextRowKey());
|
|
30
|
+
const add = useCallback((item) => {
|
|
31
|
+
keysRef.current.push(nextRowKey());
|
|
32
|
+
engine.pushItem(name, item);
|
|
33
|
+
}, [engine, name]);
|
|
34
|
+
const remove = useCallback((index) => {
|
|
35
|
+
keysRef.current.splice(index, 1);
|
|
36
|
+
engine.removeItem(name, index);
|
|
37
|
+
}, [engine, name]);
|
|
38
|
+
const move = useCallback((from, to) => {
|
|
39
|
+
const [moved] = keysRef.current.splice(from, 1);
|
|
40
|
+
keysRef.current.splice(to, 0, moved);
|
|
41
|
+
engine.moveItem(name, from, to);
|
|
42
|
+
}, [engine, name]);
|
|
43
|
+
const fields = keys.map((key, index) => ({
|
|
44
|
+
index,
|
|
45
|
+
key,
|
|
46
|
+
name: `${name}.${index}`
|
|
47
|
+
}));
|
|
48
|
+
if (children || !columns) return /* @__PURE__ */ jsx(Fragment$1, { children: children?.({
|
|
49
|
+
add,
|
|
50
|
+
fields,
|
|
51
|
+
move,
|
|
52
|
+
remove
|
|
53
|
+
}) });
|
|
54
|
+
const gridTemplateColumns = `${columns.map((c) => `minmax(0, ${c.flex ?? 1}fr)`).join(" ")} 36px`;
|
|
55
|
+
const addButton = /* @__PURE__ */ jsxs("button", {
|
|
56
|
+
className: listStyles.add,
|
|
57
|
+
type: "button",
|
|
58
|
+
onClick: () => add(createItem(newItem)),
|
|
59
|
+
children: [/* @__PURE__ */ jsx(PlusIcon, { size: 14 }), addText ?? t("form.list.add")]
|
|
60
|
+
});
|
|
61
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
62
|
+
className: listStyles.table,
|
|
63
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
64
|
+
className: listStyles.head,
|
|
65
|
+
style: { gridTemplateColumns },
|
|
66
|
+
children: columns.map((column) => /* @__PURE__ */ jsx("div", {
|
|
67
|
+
className: listStyles.title,
|
|
68
|
+
children: column.title
|
|
69
|
+
}, column.name))
|
|
70
|
+
}), fields.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
71
|
+
className: listStyles.empty,
|
|
72
|
+
children: [/* @__PURE__ */ jsx("span", { children: emptyText ?? t("form.list.empty") }), addButton]
|
|
73
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [fields.map((field) => /* @__PURE__ */ jsxs("div", {
|
|
74
|
+
className: listStyles.row,
|
|
75
|
+
style: { gridTemplateColumns },
|
|
76
|
+
children: [columns.map((column) => /* @__PURE__ */ jsx("div", {
|
|
77
|
+
className: listStyles.cell,
|
|
78
|
+
children: /* @__PURE__ */ jsx(FormField, {
|
|
79
|
+
bare: true,
|
|
80
|
+
name: `${field.name}.${column.name}`,
|
|
81
|
+
required: column.required,
|
|
82
|
+
validate: column.validate,
|
|
83
|
+
children: cloneElement(column.children, { "aria-label": labelFor(column, field.index) })
|
|
84
|
+
})
|
|
85
|
+
}, column.name)), /* @__PURE__ */ jsx(ActionIcon, {
|
|
86
|
+
"aria-label": t("form.list.remove"),
|
|
87
|
+
icon: XIcon,
|
|
88
|
+
size: "small",
|
|
89
|
+
title: t("form.list.remove"),
|
|
90
|
+
onClick: () => remove(field.index)
|
|
91
|
+
})]
|
|
92
|
+
}, field.key)), /* @__PURE__ */ jsx("div", {
|
|
93
|
+
className: listStyles.foot,
|
|
94
|
+
children: addButton
|
|
95
|
+
})] })]
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
FormList.displayName = "FormList";
|
|
99
|
+
//#endregion
|
|
100
|
+
export { FormList as default };
|
|
101
|
+
|
|
102
|
+
//# sourceMappingURL=List.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.mjs","names":["formMessages"],"sources":["../../../src/base-ui/FormKit/List.tsx"],"sourcesContent":["'use client';\n\nimport { PlusIcon, XIcon } from 'lucide-react';\nimport { cloneElement, memo, type ReactElement, type ReactNode, useCallback, useRef } from 'react';\n\nimport ActionIcon from '@/base-ui/ActionIcon';\nimport formMessages from '@/i18n/resources/en/form';\nimport { useTranslation } from '@/i18n/useTranslation';\n\nimport { useFormKitContext } from './context';\nimport FormField from './Field';\nimport { getInternals } from './instance';\nimport type { FieldValidate } from './schema';\nimport { listStyles } from './style';\nimport { useStoreSelector } from './useStoreSelector';\n\nexport interface FormListField {\n index: number;\n key: string;\n name: string;\n}\n\nexport interface FormListRenderProps {\n add: (item?: unknown) => void;\n fields: FormListField[];\n move: (from: number, to: number) => void;\n remove: (index: number) => void;\n}\n\nexport interface FormListColumn {\n children: ReactElement;\n flex?: number;\n name: string;\n required?: boolean | string;\n title?: ReactNode;\n validate?: FieldValidate;\n}\n\nexport interface FormListProps {\n addText?: ReactNode;\n children?: (props: FormListRenderProps) => ReactNode;\n columns?: FormListColumn[];\n emptyText?: ReactNode;\n name: string;\n newItem?: unknown;\n}\n\nlet rowSeed = 0;\nconst nextRowKey = () => `row-${(rowSeed += 1)}`;\n\nconst createItem = (newItem: unknown) =>\n typeof newItem === 'function'\n ? newItem()\n : newItem && typeof newItem === 'object'\n ? structuredClone(newItem)\n : (newItem ?? {});\n\nconst labelFor = (column: FormListColumn, index: number) =>\n (column.children as ReactElement<{ 'aria-label'?: string }>).props['aria-label'] ??\n (typeof column.title === 'string' ? `${column.title} ${index + 1}` : undefined);\n\nconst FormList = memo<FormListProps>(({ addText, children, columns, emptyText, name, newItem }) => {\n const { form } = useFormKitContext();\n const { engine } = getInternals(form);\n const { t } = useTranslation(formMessages);\n const length = useStoreSelector(engine, (e) => {\n const value = e.getValue(name);\n return Array.isArray(value) ? value.length : 0;\n });\n\n const keysRef = useRef<string[]>([]);\n const keys = keysRef.current;\n if (keys.length > length) keys.length = length;\n while (keys.length < length) keys.push(nextRowKey());\n\n const add = useCallback(\n (item?: unknown) => {\n keysRef.current.push(nextRowKey());\n engine.pushItem(name, item);\n },\n [engine, name],\n );\n const remove = useCallback(\n (index: number) => {\n keysRef.current.splice(index, 1);\n engine.removeItem(name, index);\n },\n [engine, name],\n );\n const move = useCallback(\n (from: number, to: number) => {\n const [moved] = keysRef.current.splice(from, 1);\n keysRef.current.splice(to, 0, moved);\n engine.moveItem(name, from, to);\n },\n [engine, name],\n );\n\n const fields = keys.map((key, index) => ({ index, key, name: `${name}.${index}` }));\n\n if (children || !columns) return <>{children?.({ add, fields, move, remove })}</>;\n\n const gridTemplateColumns = `${columns.map((c) => `minmax(0, ${c.flex ?? 1}fr)`).join(' ')} 36px`;\n const addButton = (\n <button className={listStyles.add} type=\"button\" onClick={() => add(createItem(newItem))}>\n <PlusIcon size={14} />\n {addText ?? t('form.list.add')}\n </button>\n );\n\n return (\n <div className={listStyles.table}>\n <div className={listStyles.head} style={{ gridTemplateColumns }}>\n {columns.map((column) => (\n <div className={listStyles.title} key={column.name}>\n {column.title}\n </div>\n ))}\n </div>\n {fields.length === 0 ? (\n <div className={listStyles.empty}>\n <span>{emptyText ?? t('form.list.empty')}</span>\n {addButton}\n </div>\n ) : (\n <>\n {fields.map((field) => (\n <div className={listStyles.row} key={field.key} style={{ gridTemplateColumns }}>\n {columns.map((column) => (\n <div className={listStyles.cell} key={column.name}>\n <FormField\n bare\n name={`${field.name}.${column.name}`}\n required={column.required}\n validate={column.validate}\n >\n {cloneElement(column.children as ReactElement<any>, {\n 'aria-label': labelFor(column, field.index),\n })}\n </FormField>\n </div>\n ))}\n <ActionIcon\n aria-label={t('form.list.remove')}\n icon={XIcon}\n size={'small'}\n title={t('form.list.remove')}\n onClick={() => remove(field.index)}\n />\n </div>\n ))}\n <div className={listStyles.foot}>{addButton}</div>\n </>\n )}\n </div>\n );\n});\n\nFormList.displayName = 'FormList';\n\nexport default FormList;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { FormSubmitFooterProps } from "../Form/type.mjs";
|
|
2
|
+
//#region src/base-ui/FormKit/SubmitFooter.d.ts
|
|
3
|
+
declare const SubmitFooter: import("react").NamedExoticComponent<FormSubmitFooterProps>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { SubmitFooter as default };
|
|
6
|
+
//# sourceMappingURL=SubmitFooter.d.mts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { FormContext } from "../Form/context.mjs";
|
|
3
|
+
import FormSubmitFooter from "../Form/components/FormSubmitFooter.mjs";
|
|
4
|
+
import { useFormKitContext } from "./context.mjs";
|
|
5
|
+
import { getInternals } from "./instance.mjs";
|
|
6
|
+
import { useStoreSelector } from "./useStoreSelector.mjs";
|
|
7
|
+
import { memo, useMemo } from "react";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
//#region src/base-ui/FormKit/SubmitFooter.tsx
|
|
10
|
+
const SubmitFooter = memo((props) => {
|
|
11
|
+
const { form, layout, variant } = useFormKitContext();
|
|
12
|
+
const { engine } = getInternals(form);
|
|
13
|
+
const status = useStoreSelector(engine, (e) => e.getStatus());
|
|
14
|
+
const legacyContext = useMemo(() => ({
|
|
15
|
+
hasUnsavedChanges: status.dirty,
|
|
16
|
+
layout,
|
|
17
|
+
requestReset: () => form.reset(),
|
|
18
|
+
submitLoading: status.submitting,
|
|
19
|
+
variant
|
|
20
|
+
}), [
|
|
21
|
+
form,
|
|
22
|
+
layout,
|
|
23
|
+
status.dirty,
|
|
24
|
+
status.submitting,
|
|
25
|
+
variant
|
|
26
|
+
]);
|
|
27
|
+
return /* @__PURE__ */ jsx(FormContext, {
|
|
28
|
+
value: legacyContext,
|
|
29
|
+
children: /* @__PURE__ */ jsx(FormSubmitFooter, { ...props })
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
SubmitFooter.displayName = "FormSubmitFooter";
|
|
33
|
+
//#endregion
|
|
34
|
+
export { SubmitFooter as default };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=SubmitFooter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitFooter.mjs","names":[],"sources":["../../../src/base-ui/FormKit/SubmitFooter.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useMemo } from 'react';\n\nimport FormSubmitFooter from '../Form/components/FormSubmitFooter';\nimport { FormContext } from '../Form/context';\nimport type { FormSubmitFooterProps } from '../Form/type';\nimport { useFormKitContext } from './context';\nimport { getInternals } from './instance';\nimport { useStoreSelector } from './useStoreSelector';\n\nconst SubmitFooter = memo<FormSubmitFooterProps>((props) => {\n const { form, layout, variant } = useFormKitContext();\n const { engine } = getInternals(form);\n const status = useStoreSelector(engine, (e) => e.getStatus());\n\n const legacyContext = useMemo(\n () => ({\n hasUnsavedChanges: status.dirty,\n layout,\n requestReset: () => form.reset(),\n submitLoading: status.submitting,\n variant,\n }),\n [form, layout, status.dirty, status.submitting, variant],\n );\n\n return (\n <FormContext value={legacyContext}>\n <FormSubmitFooter {...props} />\n </FormContext>\n );\n});\n\nSubmitFooter.displayName = 'FormSubmitFooter';\n\nexport default SubmitFooter;\n"],"mappings":";;;;;;;;;AAWA,MAAM,eAAe,MAA6B,UAAU;CAC1D,MAAM,EAAE,MAAM,QAAQ,YAAY,kBAAkB;CACpD,MAAM,EAAE,WAAW,aAAa,IAAI;CACpC,MAAM,SAAS,iBAAiB,SAAS,MAAM,EAAE,UAAU,CAAC;CAE5D,MAAM,gBAAgB,eACb;EACL,mBAAmB,OAAO;EAC1B;EACA,oBAAoB,KAAK,MAAM;EAC/B,eAAe,OAAO;EACtB;CACF,IACA;EAAC;EAAM;EAAQ,OAAO;EAAO,OAAO;EAAY;CAAO,CACzD;CAEA,OACE,oBAAC,aAAD;EAAa,OAAO;EAClB,UAAA,oBAAC,kBAAD,EAAkB,GAAI,MAAQ,CAAA;CACnB,CAAA;AAEjB,CAAC;AAED,aAAa,cAAc"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/base-ui/FormKit/binding.ts
|
|
2
|
+
const isEventLike = (arg) => typeof arg === "object" && arg !== null && "target" in arg && typeof arg.target === "object" && arg.target !== null;
|
|
3
|
+
const defaultGetValue = (arg) => {
|
|
4
|
+
if (!isEventLike(arg)) return arg;
|
|
5
|
+
const { target } = arg;
|
|
6
|
+
return target.type === "checkbox" || target.type === "radio" ? target.checked : target.value;
|
|
7
|
+
};
|
|
8
|
+
const resolveBinding = (child, override) => {
|
|
9
|
+
const { type } = child;
|
|
10
|
+
const declared = typeof type === "object" || typeof type === "function" ? type.formBinding : void 0;
|
|
11
|
+
const props = child.props;
|
|
12
|
+
const nativeCheckable = type === "input" && (props.type === "checkbox" || props.type === "radio");
|
|
13
|
+
return {
|
|
14
|
+
emptyValue: override.emptyValue ?? declared?.emptyValue,
|
|
15
|
+
getValue: override.getValue ?? declared?.getValue ?? defaultGetValue,
|
|
16
|
+
trigger: override.trigger ?? declared?.trigger ?? "onChange",
|
|
17
|
+
valueProp: override.valueProp ?? declared?.valueProp ?? (nativeCheckable ? "checked" : "value")
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { defaultGetValue, resolveBinding };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=binding.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.mjs","names":[],"sources":["../../../src/base-ui/FormKit/binding.ts"],"sourcesContent":["import type { ReactElement } from 'react';\n\nimport type { FieldBinding } from './type';\n\nconst isEventLike = (arg: unknown): arg is { target: HTMLInputElement } =>\n typeof arg === 'object' &&\n arg !== null &&\n 'target' in arg &&\n typeof (arg as { target: unknown }).target === 'object' &&\n (arg as { target: unknown }).target !== null;\n\nexport const defaultGetValue = (arg: unknown) => {\n if (!isEventLike(arg)) return arg;\n const { target } = arg;\n return target.type === 'checkbox' || target.type === 'radio' ? target.checked : target.value;\n};\n\nexport interface ResolvedBinding {\n emptyValue: unknown;\n getValue: (...args: any[]) => unknown;\n trigger: string;\n valueProp: string;\n}\n\nexport const resolveBinding = (child: ReactElement, override: FieldBinding): ResolvedBinding => {\n const { type } = child;\n const declared =\n typeof type === 'object' || typeof type === 'function'\n ? (type as { formBinding?: FieldBinding }).formBinding\n : undefined;\n const props = child.props as { type?: string };\n const nativeCheckable = type === 'input' && (props.type === 'checkbox' || props.type === 'radio');\n\n return {\n emptyValue: override.emptyValue ?? declared?.emptyValue,\n getValue: override.getValue ?? declared?.getValue ?? defaultGetValue,\n trigger: override.trigger ?? declared?.trigger ?? 'onChange',\n valueProp: override.valueProp ?? declared?.valueProp ?? (nativeCheckable ? 'checked' : 'value'),\n };\n};\n"],"mappings":";AAIA,MAAM,eAAe,QACnB,OAAO,QAAQ,YACf,QAAQ,QACR,YAAY,OACZ,OAAQ,IAA4B,WAAW,YAC9C,IAA4B,WAAW;AAE1C,MAAa,mBAAmB,QAAiB;CAC/C,IAAI,CAAC,YAAY,GAAG,GAAG,OAAO;CAC9B,MAAM,EAAE,WAAW;CACnB,OAAO,OAAO,SAAS,cAAc,OAAO,SAAS,UAAU,OAAO,UAAU,OAAO;AACzF;AASA,MAAa,kBAAkB,OAAqB,aAA4C;CAC9F,MAAM,EAAE,SAAS;CACjB,MAAM,WACJ,OAAO,SAAS,YAAY,OAAO,SAAS,aACvC,KAAwC,cACzC,KAAA;CACN,MAAM,QAAQ,MAAM;CACpB,MAAM,kBAAkB,SAAS,YAAY,MAAM,SAAS,cAAc,MAAM,SAAS;CAEzF,OAAO;EACL,YAAY,SAAS,cAAc,UAAU;EAC7C,UAAU,SAAS,YAAY,UAAU,YAAY;EACrD,SAAS,SAAS,WAAW,UAAU,WAAW;EAClD,WAAW,SAAS,aAAa,UAAU,cAAc,kBAAkB,YAAY;CACzF;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import "../Form/type.mjs";
|
|
2
|
+
import { FormInstance, FormValues } from "./type.mjs";
|
|
3
|
+
//#region src/base-ui/FormKit/context.d.ts
|
|
4
|
+
declare const useFormInstance: <T extends FormValues = FormValues>() => FormInstance<T>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { useFormInstance };
|
|
7
|
+
//# sourceMappingURL=context.d.mts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, use } from "react";
|
|
3
|
+
//#region src/base-ui/FormKit/context.ts
|
|
4
|
+
const FormKitContext = createContext(null);
|
|
5
|
+
const useFormKitContext = () => {
|
|
6
|
+
const value = use(FormKitContext);
|
|
7
|
+
if (!value) throw new Error("[@lobehub/ui/base-ui/form] Form.Field must be rendered inside <Form>");
|
|
8
|
+
return value;
|
|
9
|
+
};
|
|
10
|
+
const useFormInstance = () => useFormKitContext().form;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { FormKitContext, useFormInstance, useFormKitContext };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../../src/base-ui/FormKit/context.ts"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\n\nimport type { FormLayout, FormVariant } from '../Form/type';\nimport type { FormInstance, FormValues } from './type';\n\nexport interface FormKitContextValue {\n form: FormInstance<any>;\n layout: FormLayout;\n variant: FormVariant;\n}\n\nexport const FormKitContext = createContext<FormKitContextValue | null>(null);\n\nexport const useFormKitContext = () => {\n const value = use(FormKitContext);\n if (!value)\n throw new Error('[@lobehub/ui/base-ui/form] Form.Field must be rendered inside <Form>');\n return value;\n};\n\nexport const useFormInstance = <T extends FormValues = FormValues>() =>\n useFormKitContext().form as FormInstance<T>;\n"],"mappings":";;;AAaA,MAAa,iBAAiB,cAA0C,IAAI;AAE5E,MAAa,0BAA0B;CACrC,MAAM,QAAQ,IAAI,cAAc;CAChC,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,sEAAsE;CACxF,OAAO;AACT;AAEA,MAAa,wBACX,kBAAkB,CAAC,CAAC"}
|