@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.
Files changed (108) hide show
  1. package/es/EditableText/ControlInput.mjs +2 -2
  2. package/es/EditableText/ControlInput.mjs.map +1 -1
  3. package/es/SearchBar/SearchBar.mjs +2 -2
  4. package/es/SearchBar/SearchBar.mjs.map +1 -1
  5. package/es/base-ui/Checkbox/Checkbox.d.mts +6 -2
  6. package/es/base-ui/Checkbox/Checkbox.mjs +2 -1
  7. package/es/base-ui/Checkbox/Checkbox.mjs.map +1 -1
  8. package/es/base-ui/Checkbox/CheckboxGroup.mjs +2 -2
  9. package/es/base-ui/Checkbox/CheckboxGroup.mjs.map +1 -1
  10. package/es/base-ui/Checkbox/index.d.mts +2 -2
  11. package/es/base-ui/ColorPicker/ColorPicker.mjs +4 -4
  12. package/es/base-ui/ColorPicker/ColorPicker.mjs.map +1 -1
  13. package/es/base-ui/DatePicker/style.mjs +1 -0
  14. package/es/base-ui/DatePicker/style.mjs.map +1 -1
  15. package/es/base-ui/Form/components/FormGroup.mjs +13 -5
  16. package/es/base-ui/Form/components/FormGroup.mjs.map +1 -1
  17. package/es/base-ui/Form/index.d.mts +3 -0
  18. package/es/base-ui/Form/index.mjs +3 -0
  19. package/es/base-ui/Form/index.mjs.map +1 -1
  20. package/es/base-ui/Form/style.mjs +32 -6
  21. package/es/base-ui/Form/style.mjs.map +1 -1
  22. package/es/base-ui/FormKit/Field.d.mts +9 -0
  23. package/es/base-ui/FormKit/Field.mjs +167 -0
  24. package/es/base-ui/FormKit/Field.mjs.map +1 -0
  25. package/es/base-ui/FormKit/Form.mjs +96 -0
  26. package/es/base-ui/FormKit/Form.mjs.map +1 -0
  27. package/es/base-ui/FormKit/List.d.mts +34 -0
  28. package/es/base-ui/FormKit/List.mjs +102 -0
  29. package/es/base-ui/FormKit/List.mjs.map +1 -0
  30. package/es/base-ui/FormKit/SubmitFooter.d.mts +6 -0
  31. package/es/base-ui/FormKit/SubmitFooter.mjs +36 -0
  32. package/es/base-ui/FormKit/SubmitFooter.mjs.map +1 -0
  33. package/es/base-ui/FormKit/binding.mjs +23 -0
  34. package/es/base-ui/FormKit/binding.mjs.map +1 -0
  35. package/es/base-ui/FormKit/context.d.mts +7 -0
  36. package/es/base-ui/FormKit/context.mjs +14 -0
  37. package/es/base-ui/FormKit/context.mjs.map +1 -0
  38. package/es/base-ui/FormKit/engine/tanstack.mjs +293 -0
  39. package/es/base-ui/FormKit/engine/tanstack.mjs.map +1 -0
  40. package/es/base-ui/FormKit/engine/types.d.mts +6 -0
  41. package/es/base-ui/FormKit/index.d.mts +31 -0
  42. package/es/base-ui/FormKit/index.mjs +28 -0
  43. package/es/base-ui/FormKit/index.mjs.map +1 -0
  44. package/es/base-ui/FormKit/instance.mjs +67 -0
  45. package/es/base-ui/FormKit/instance.mjs.map +1 -0
  46. package/es/base-ui/FormKit/schema.d.mts +33 -0
  47. package/es/base-ui/FormKit/schema.mjs +23 -0
  48. package/es/base-ui/FormKit/schema.mjs.map +1 -0
  49. package/es/base-ui/FormKit/style.mjs +119 -0
  50. package/es/base-ui/FormKit/style.mjs.map +1 -0
  51. package/es/base-ui/FormKit/type.d.mts +122 -0
  52. package/es/base-ui/FormKit/useForm.d.mts +10 -0
  53. package/es/base-ui/FormKit/useForm.mjs +54 -0
  54. package/es/base-ui/FormKit/useForm.mjs.map +1 -0
  55. package/es/base-ui/FormKit/useStoreSelector.mjs +25 -0
  56. package/es/base-ui/FormKit/useStoreSelector.mjs.map +1 -0
  57. package/es/base-ui/FormKit/useWatch.d.mts +7 -0
  58. package/es/base-ui/FormKit/useWatch.mjs +12 -0
  59. package/es/base-ui/FormKit/useWatch.mjs.map +1 -0
  60. package/es/base-ui/Input/Input.d.mts +6 -2
  61. package/es/base-ui/Input/Input.mjs +2 -1
  62. package/es/base-ui/Input/Input.mjs.map +1 -1
  63. package/es/base-ui/Input/InputNumber.d.mts +6 -2
  64. package/es/base-ui/Input/InputNumber.mjs +13 -6
  65. package/es/base-ui/Input/InputNumber.mjs.map +1 -1
  66. package/es/base-ui/Input/InputPassword.d.mts +6 -2
  67. package/es/base-ui/Input/InputPassword.mjs +4 -3
  68. package/es/base-ui/Input/InputPassword.mjs.map +1 -1
  69. package/es/base-ui/Input/TextArea.d.mts +6 -2
  70. package/es/base-ui/Input/TextArea.mjs +2 -1
  71. package/es/base-ui/Input/TextArea.mjs.map +1 -1
  72. package/es/base-ui/Input/index.d.mts +5 -5
  73. package/es/base-ui/Input/style.d.mts +4 -1
  74. package/es/base-ui/Input/style.mjs +21 -8
  75. package/es/base-ui/Input/style.mjs.map +1 -1
  76. package/es/base-ui/Modal/Modal.mjs +4 -8
  77. package/es/base-ui/Modal/Modal.mjs.map +1 -1
  78. package/es/base-ui/Slider/SliderWithInput.mjs +2 -2
  79. package/es/base-ui/Slider/SliderWithInput.mjs.map +1 -1
  80. package/es/base-ui/Switch/Switch.mjs +2 -2
  81. package/es/base-ui/Switch/Switch.mjs.map +1 -1
  82. package/es/base-ui/Text/style.d.mts +1 -1
  83. package/es/base-ui/Tree/TreeNode.mjs +2 -2
  84. package/es/base-ui/Tree/TreeNode.mjs.map +1 -1
  85. package/es/base-ui/index.d.mts +8 -8
  86. package/es/base-ui/index.mjs +6 -6
  87. package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs +2 -2
  88. package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs.map +1 -1
  89. package/es/chat/MessageInput/MessageInput.mjs +2 -2
  90. package/es/chat/MessageInput/MessageInput.mjs.map +1 -1
  91. package/es/chat/MessageModal/MessageModal.mjs +2 -2
  92. package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
  93. package/es/eslint/index.d.mts +27 -3
  94. package/es/eslint/index.mjs +40 -2
  95. package/es/eslint/index.mjs.map +1 -1
  96. package/es/eslint/noInlineFormSchema.mjs +44 -0
  97. package/es/eslint/noInlineFormSchema.mjs.map +1 -0
  98. package/es/i18n/resources/en/form.d.mts +4 -0
  99. package/es/i18n/resources/en/form.mjs +4 -0
  100. package/es/i18n/resources/en/form.mjs.map +1 -1
  101. package/es/i18n/resources/zhCn/form.d.mts +4 -0
  102. package/es/i18n/resources/zhCn/form.mjs +4 -0
  103. package/es/i18n/resources/zhCn/form.mjs.map +1 -1
  104. package/es/node_modules/.pnpm/@eslint_core@0.17.0/node_modules/@eslint/core/dist/esm/types.d.mts +1139 -0
  105. package/es/node_modules/.pnpm/@types_estree@1.0.9/node_modules/@types/estree/index.d.mts +528 -0
  106. package/es/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.mts +201 -0
  107. 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
  108. 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":"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"}
@@ -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"}