@rxdrag/form 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/context.tsx","../../../node_modules/.pnpm/react@19.2.8/node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/.pnpm/react@19.2.8/node_modules/react/cjs/react-jsx-runtime.development.js","../../../node_modules/.pnpm/react@19.2.8/node_modules/react/jsx-runtime.js","../src/AppForm.tsx","../src/validators.ts","../src/bindField.tsx","../src/components/Input.tsx","../src/components/Textarea.tsx","../src/components/Select.tsx","../src/components/SingleSelect.tsx","../src/components/Switch.tsx","../src/components/Checkbox.tsx","../src/components/ColorInput.tsx","../src/components/Password.tsx","../src/fields.tsx","../src/ObjectField.tsx","../src/hooks.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { createContext, useContext } from \"react\";\r\n\r\n/**\r\n * AppForm 上下文:向字段组件提供 TanStack form 实例 + 字段元数据登记表。\r\n *\r\n * form 类型收敛为 any:TanStack Form 的泛型链按字面 name 做类型级校验,而本项目字段组件\r\n * 以动态字符串 name(XxxFields.name 常量)工作——功能兼容优先,类型宽松收敛在包内部,\r\n * 业务层拿到的字段组件 props 仍是强类型。\r\n */\r\nexport type AnyAppForm = any;\r\n\r\n/** 已挂载字段的元数据(供枚举/调试/未来 agent 工作台)。 */\r\nexport interface RegisteredFieldMeta {\r\n name: string;\r\n label?: string;\r\n type?: string;\r\n}\r\n\r\nexport interface AppFormContextValue {\r\n /** 表单名(= 实体名)。 */\r\n name?: string;\r\n form: AnyAppForm;\r\n /** 字段挂载时登记元数据,返回注销函数。 */\r\n registerFieldMeta: (meta: RegisteredFieldMeta) => () => void;\r\n /** 枚举当前挂载字段(按登记序)。 */\r\n getFieldMetas: () => RegisteredFieldMeta[];\r\n}\r\n\r\nexport const AppFormContext = createContext<AppFormContextValue | undefined>(\r\n undefined\r\n);\r\n\r\nexport function useAppFormContext(): AppFormContextValue {\r\n const ctx = useContext(AppFormContext);\r\n if (!ctx) throw new Error(\"useAppFormContext 必须在 <AppForm> 内使用\");\r\n return ctx;\r\n}\r\n\r\n/** 宽松版:不在 AppForm 内返回 undefined(供可选场景探测)。 */\r\nexport function useMaybeAppFormContext(): AppFormContextValue | undefined {\r\n return useContext(AppFormContext);\r\n}\r\n\r\n/**\r\n * 字段名前缀上下文(ObjectField 用)。TanStack Form 用点号路径(如 \"meta.title\")表达嵌套,\r\n * ObjectField 把自己的 name 作为前缀下发,内部字段 name=\"title\" 解析成 \"meta.title\"。\r\n */\r\nexport const FieldNamePrefixContext = createContext<string>(\"\");\r\n\r\nexport function useFieldNamePrefix(): string {\r\n return useContext(FieldNamePrefixContext);\r\n}\r\n\r\n/** 拼接前缀与字段名(空前缀直接返回 name)。 */\r\nexport function joinFieldName(prefix: string, name: string): string {\r\n if (!prefix) return name;\r\n if (!name) return prefix;\r\n return `${prefix}.${name}`;\r\n}\r\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { CSSProperties, ReactNode, useCallback, useEffect, useMemo, useRef } from \"react\";\r\nimport { useForm, useStore } from \"@tanstack/react-form\";\r\nimport { Button, type ButtonProps } from \"@rxdrag/shadcn\";\r\nimport {\r\n AppFormContext,\r\n type AppFormContextValue,\r\n type AnyAppForm,\r\n type RegisteredFieldMeta,\r\n useAppFormContext,\r\n} from \"./context\";\r\n\r\n/**\r\n * TanStack Form 表单层(替代 fieldy 的 VirtualForm/EntityForm 内核)。\r\n *\r\n * - useAppForm:包 TanStack useForm——defaultValues 即初始值(编辑=实体对象,新建=空对象/预填);\r\n * onSubmit 在校验全部通过后拿到整表单值。\r\n * - AppForm:渲染 <form> + 提供上下文;**脏判定用 `!form.state.isDefaultValue`**(TanStack 内置\r\n * 逐字段深比较 defaultValue,改回去即不脏——语义正确,无 fieldy modified 黑盒/整对象结构噪音)。\r\n * - SubmitButton:type=submit + 提交中 loading。\r\n */\r\nexport interface UseAppFormOptions<T> {\r\n defaultValues: T;\r\n onSubmit?: (value: T) => void | Promise<void>;\r\n}\r\n\r\nexport function useAppForm<T extends object>(opts: UseAppFormOptions<T>): AnyAppForm {\r\n // onSubmit 经 ref 保持最新(业务闭包常依赖外部状态)。\r\n const submitRef = useRef(opts.onSubmit);\r\n submitRef.current = opts.onSubmit;\r\n // ── 防错契约:options **零响应性**(源码级结论 @tanstack/form-core)──\r\n // TanStack useForm 每次渲染 layoutEffect 都调「原始 FormApi 实例」的 update(opts):\r\n // shouldUpdateValues = defaultValues 变化 && !state.isTouched → **整表 values 直接换成 defaultValues**。\r\n // 而 reset(next)(保存回填/重灌,含 setModified(false) 的 reset(当前值))把 next 写进真身\r\n // options.defaultValues 且清空 touched——下一次渲染 update(宿主 defaultValues) 与真身比较\"变化\"\r\n // → 全表拉回(\"保存成功页面却整表回滚\",渲染帧内、无 reset 调用栈)。两个失败教训:①固定首帧\r\n // 引用不够(reset 改了真身 defaultValues,首帧引用对比依旧\"变化\");②覆写返回对象的 update 封不到\r\n // 真身——useForm 返回的是 FormApi **浅拷贝扩展对象**,内部 layoutEffect 调的是原始实例。\r\n // 终稿 = **记账同步**:传给 useForm 一个稳定 options 对象(appOptions);refillForm/commitForm 重灌时\r\n // 把 next 同步写进 appOptions.defaultValues——真身 update(appOptions) 时两边**同一引用**恒相等 →\r\n // shouldUpdateValues 恒 false → 永不覆写。不摸私有结构、不赌拷贝层次。\r\n const appOptionsRef = useRef<{\r\n defaultValues: T;\r\n onSubmit: (ctx: { value: unknown }) => Promise<void>;\r\n } | null>(null);\r\n if (!appOptionsRef.current) {\r\n appOptionsRef.current = {\r\n defaultValues: opts.defaultValues,\r\n onSubmit: async ({ value }: { value: unknown }) => {\r\n await submitRef.current?.(value as T);\r\n },\r\n };\r\n }\r\n const form = useForm(appOptionsRef.current as any);\r\n // 记账句柄挂到 form(内部约定,refillForm/commitForm 用;业务不直接碰)。\r\n (form as unknown as Record<string, unknown>).__appOptions = appOptionsRef.current;\r\n return form;\r\n}\r\n\r\n/** 内部:重灌记账——让真身 update(appOptions) 的 defaultValues 对比恒相等。 */\r\nfunction syncAppDefaults(form: AnyAppForm, next: unknown): void {\r\n const appOptions = (form as unknown as Record<string, unknown>).__appOptions as\r\n | { defaultValues: unknown }\r\n | undefined;\r\n if (appOptions) appOptions.defaultValues = next;\r\n}\r\n\r\n/**\r\n * refillForm —— 表单重灌的唯一入口:值 + 脏基线(defaultValues) 一起换新。\r\n * 语义(form-core 源码确认):reset(next) = options.defaultValues←next + 全字段 meta 清空\r\n * (isTouched=false、isDefaultValue=true)。配合 useAppForm 已关闭 options 同步,重灌后\r\n * 任何渲染都不会把值拉回旧默认值。用于「编辑态数据到达/重新加载整表/手动重置到基线」。\r\n */\r\nexport function refillForm<T extends object>(form: AnyAppForm, next: T): void {\r\n (form as unknown as { reset: (v: T) => void }).reset(next);\r\n // 记账:真身 options.defaultValues 已被 reset 写为 next(同一引用),appOptions 同步后\r\n // 每渲染 update 的 evaluate(next, next) 恒相等——覆写通道从此关闭。\r\n syncAppDefaults(form, next);\r\n}\r\n\r\n/**\r\n * commitForm —— 保存成功后的基线提交:把「当前表单值 +(可选)服务端补丁」设为新值与新脏基线。\r\n * 替代业务手拼 form.reset({...values,...serverPatch,id}) 的易错写法;patch 只应含服务端\r\n * 生成字段(id/code/createdAt/updatedAt 等白名单),用户填的值一律以表单现值为准。\r\n */\r\nexport function commitForm<T extends object>(form: AnyAppForm, patch?: Partial<T>): void {\r\n const current = (form as unknown as { state: { values: T } }).state.values;\r\n refillForm(form, { ...(current as object), ...(patch as object | undefined) } as T);\r\n}\r\n\r\nexport interface AppFormProps {\r\n form: AnyAppForm;\r\n children?: ReactNode;\r\n className?: string;\r\n style?: CSSProperties;\r\n /** 表单名(= 实体名,调试标识)。 */\r\n name?: string;\r\n /** 未保存脏态上报(= !isDefaultValue,供 useUnsavedGuard)。 */\r\n onDirtyChange?: (dirty: boolean) => void;\r\n}\r\n\r\nexport function AppForm(props: AppFormProps) {\r\n const { form, children, className, style, onDirtyChange } = props;\r\n\r\n // 字段元数据登记表(枚举当前挂载字段)。\r\n const metasRef = useRef<RegisteredFieldMeta[]>([]);\r\n const registerFieldMeta = useCallback((meta: RegisteredFieldMeta) => {\r\n metasRef.current = [...metasRef.current, meta];\r\n return () => {\r\n metasRef.current = metasRef.current.filter((m) => m !== meta);\r\n };\r\n }, []);\r\n const getFieldMetas = useCallback(() => metasRef.current, []);\r\n\r\n const ctx = useMemo<AppFormContextValue>(\r\n () => ({ form, registerFieldMeta, getFieldMetas, name: props.name }),\r\n [form, registerFieldMeta, getFieldMetas, props.name]\r\n );\r\n\r\n // 脏态上报:isDefaultValue = 所有已注册字段的值深等于 defaultValue(改回去即不脏)。\r\n const isDefaultValue = useStore(form.store, (s: any) => s.isDefaultValue);\r\n useEffect(() => {\r\n onDirtyChange?.(!isDefaultValue);\r\n }, [isDefaultValue, onDirtyChange]);\r\n\r\n return (\r\n <AppFormContext.Provider value={ctx}>\r\n <form\r\n className={className}\r\n style={style}\r\n onSubmit={(e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n void form.handleSubmit();\r\n }}\r\n >\r\n {children}\r\n </form>\r\n </AppFormContext.Provider>\r\n );\r\n}\r\n\r\n/** 提交按钮:submit 类型 + 提交中 loading/禁用。放在 AppForm 内使用。 */\r\nexport function SubmitButton(props: ButtonProps) {\r\n const { form } = useAppFormContext();\r\n const isSubmitting = useStore(form.store, (s: any) => s.isSubmitting);\r\n return (\r\n <Button\r\n type=\"submit\"\r\n className=\"cursor-pointer\"\r\n loading={isSubmitting}\r\n disabled={isSubmitting || props.disabled}\r\n {...props}\r\n />\r\n );\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n\r\n/**\r\n * 字段校验(提交/输入时执行)。\r\n *\r\n * 支持两条写法:\r\n * 1) 新写法(对齐 deepclaw):`required`(bool/文案)+ `zodSchema`(任何带 safeParse 的 schema,可选)。\r\n * 2) 旧兼容写法(fieldy 遗留):`validateSchema={{ type, required, rules: { max/min/email/url } }}`。\r\n *\r\n * validator 统一是「值 → 错误消息 | undefined」的纯函数,挂到 TanStack Field 的\r\n * validators.onChange + onSubmit 上(错误随 field.state.meta.errors 展示;输对即时消错)。\r\n */\r\n\r\n/** 任意带 safeParse 的 schema(如 zod)——避免硬依赖 zod 包,用结构类型描述。 */\r\nexport interface SafeParseSchema {\r\n safeParse: (v: unknown) => {\r\n success: boolean;\r\n error?: { issues?: Array<{ message?: string }> };\r\n };\r\n}\r\n\r\n/** fieldy 遗留的 validateSchema 形状(仅覆盖仓库实际用到的键)。 */\r\nexport interface LegacyValidateSchema {\r\n type?: string;\r\n required?: boolean | string;\r\n rules?: {\r\n max?: { value: number; message?: string };\r\n min?: { value: number; message?: string };\r\n email?: boolean | { message?: string };\r\n url?: boolean | { message?: string };\r\n };\r\n}\r\n\r\nexport interface FieldValidateProps {\r\n /** 必填(true 用默认文案,或直接传消息文案)。 */\r\n required?: boolean | string;\r\n /** schema 校验(如 z.string().email(...))。空值时跳过(配合 required 用)。 */\r\n zodSchema?: SafeParseSchema;\r\n /** 旧版 fieldy 校验声明(兼容层,逐步淘汰)。 */\r\n validateSchema?: LegacyValidateSchema;\r\n}\r\n\r\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\nconst URL_RE = /^https?:\\/\\/[^\\s]+$/i;\r\n\r\nfunction isEmpty(v: unknown): boolean {\r\n if (v === undefined || v === null || v === \"\") return true;\r\n if (Array.isArray(v) && v.length === 0) return true;\r\n return false;\r\n}\r\n\r\n/** 组装 TanStack Field validators;无校验需求返回 undefined(零开销)。 */\r\nexport function buildFieldValidators(props: FieldValidateProps, label?: string) {\r\n const { validateSchema, zodSchema } = props;\r\n // required 可来自新 prop 或旧 validateSchema.required。\r\n const required = props.required ?? validateSchema?.required;\r\n const rules = validateSchema?.rules;\r\n\r\n if (!required && !zodSchema && !rules) return undefined;\r\n\r\n const requiredMessage =\r\n typeof required === \"string\"\r\n ? required\r\n : `请输入${typeof label === \"string\" ? label : \"\"}`;\r\n\r\n const validate = ({ value }: { value: any }) => {\r\n if (required && isEmpty(value)) return requiredMessage;\r\n if (!isEmpty(value)) {\r\n const s = typeof value === \"string\" ? value : String(value ?? \"\");\r\n if (rules?.max && s.length > rules.max.value) {\r\n return rules.max.message || `长度不能超过 ${rules.max.value} 个字符`;\r\n }\r\n if (rules?.min && s.length < rules.min.value) {\r\n return rules.min.message || `长度不能少于 ${rules.min.value} 个字符`;\r\n }\r\n if (rules?.email && !EMAIL_RE.test(s)) {\r\n return (typeof rules.email === \"object\" && rules.email.message) || \"请输入合法的邮箱\";\r\n }\r\n if (rules?.url && !URL_RE.test(s)) {\r\n return (typeof rules.url === \"object\" && rules.url.message) || \"请输入合法的网址\";\r\n }\r\n if (zodSchema) {\r\n const r = zodSchema.safeParse(value);\r\n if (!r.success) return r.error?.issues?.[0]?.message || \"格式不正确\";\r\n }\r\n }\r\n return undefined;\r\n };\r\n // onChange 与 onSubmit 挂同一函数:输入即时重校验(错误输对即消,对齐旧版\"输入清错\"体验)。\r\n return { onChange: validate, onSubmit: validate };\r\n}\r\n\r\n/** 从 field.state.meta.errors 取首条可展示消息(string 或 {message} 兼容)。 */\r\nexport function firstErrorMessage(errors: unknown[] | undefined): string | undefined {\r\n const e = errors?.[0];\r\n if (!e) return undefined;\r\n if (typeof e === \"string\") return e;\r\n if (typeof e === \"object\" && e && \"message\" in e)\r\n return String((e as { message: unknown }).message);\r\n return String(e);\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport React, { useEffect, useId } from \"react\";\r\nimport {\r\n useAppFormContext,\r\n useFieldNamePrefix,\r\n joinFieldName,\r\n} from \"./context\";\r\nimport {\r\n buildFieldValidators,\r\n firstErrorMessage,\r\n type FieldValidateProps,\r\n} from \"./validators\";\r\n\r\n/**\r\n * bindField —— fieldy 的 toField 的 TanStack 等价 HOC:\r\n * 把「受控展示组件(value/onValueChange/isInvalid/errorMessage)」绑定到 TanStack Field。\r\n *\r\n * 关键约定:**显示层转换不污染 store**——组件渲染用 value ?? displayDefault(如 ''),\r\n * 但 store 里保持原始值(DB 的 null 不会被规范化写值弄脏,脏判定 isDefaultValue 因此可靠)。\r\n */\r\nexport type ControlProps = {\r\n id?: string;\r\n name?: string;\r\n label?: React.ReactNode;\r\n placeholder?: string;\r\n value?: any;\r\n isInvalid?: boolean;\r\n errorMessage?: React.ReactNode;\r\n onValueChange?: (value: any) => void;\r\n};\r\n\r\nexport type BoundFieldProps = FieldValidateProps & {\r\n /** 字段路径(XxxFields.* 常量)。可选:无 name 时不绑定,直接渲染展示组件(对齐 fieldy)。 */\r\n name?: string;\r\n /** 值写回前的转换(如 number 字段把输入串转数字)。 */\r\n coerce?: (raw: any) => any;\r\n /** 以下为 fieldy 遗留 props:类型上接受、运行时忽略(不写回 store、不透传 DOM)。 */\r\n initialValue?: unknown;\r\n defaultValue?: unknown;\r\n value?: unknown;\r\n valueComputer?: unknown;\r\n};\r\n\r\nexport type BindFieldOptions = {\r\n /** 渲染层空值兜底(不写回 store)。 */\r\n displayDefault?: unknown;\r\n /** 登记到字段元数据表的控件类型。 */\r\n controlType?: string;\r\n};\r\n\r\n/** 这些是 fieldy 遗留 / 校验声明 props,绝不能透传到底层展示组件(会漏到 DOM)。 */\r\nconst LEGACY_KEYS = [\r\n \"required\",\r\n \"zodSchema\",\r\n \"validateSchema\",\r\n \"coerce\",\r\n \"valueComputer\",\r\n \"initialValue\",\r\n \"defaultValue\",\r\n] as const;\r\n\r\nexport function bindField<P extends ControlProps = ControlProps>(\r\n Component: React.ComponentType<P>,\r\n options?: BindFieldOptions\r\n) {\r\n const { displayDefault = \"\", controlType } = options || {};\r\n return function BoundField(\r\n props: BoundFieldProps &\r\n Omit<P, \"value\" | \"onValueChange\" | \"isInvalid\" | \"errorMessage\">\r\n ) {\r\n const all = props as BoundFieldProps & Record<string, any>;\r\n const { name, required, coerce } = all;\r\n const { form, registerFieldMeta } = useAppFormContext();\r\n const prefix = useFieldNamePrefix();\r\n const fullName = name ? joinFieldName(prefix, name) : \"\";\r\n const id = useId();\r\n\r\n // 剥离遗留 / 校验 props,剩下的才透传给展示组件。\r\n const rest: Record<string, any> = {};\r\n for (const key of Object.keys(all)) {\r\n if (key === \"name\") continue;\r\n if ((LEGACY_KEYS as readonly string[]).includes(key)) continue;\r\n rest[key] = all[key];\r\n }\r\n\r\n const labelText = typeof rest.label === \"string\" ? rest.label : undefined;\r\n useEffect(() => {\r\n if (!name) return;\r\n return registerFieldMeta({ name: fullName, label: labelText, type: controlType });\r\n }, [name, fullName, labelText, registerFieldMeta]);\r\n\r\n const validators = buildFieldValidators(\r\n { required, zodSchema: all.zodSchema, validateSchema: all.validateSchema },\r\n labelText\r\n );\r\n\r\n // 无 name:不绑定 store,直接渲染展示组件(对齐 fieldy toField 的可选 name 行为)。\r\n if (!name) {\r\n return (\r\n <Component\r\n id={id}\r\n {...(required ? ({ requried: true } as unknown as Partial<P>) : undefined)}\r\n {...(rest as unknown as P)}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <form.Field name={fullName} validators={validators}>\r\n {(field: any) => {\r\n const raw = field.state.value;\r\n const errorMessage = firstErrorMessage(field.state.meta.errors);\r\n return (\r\n <Component\r\n id={id}\r\n // 必填星号展示位(校验本身走 validators)。\r\n {...(required ? ({ requried: true } as unknown as Partial<P>) : undefined)}\r\n {...(rest as unknown as P)}\r\n value={raw === undefined || raw === null ? displayDefault : raw}\r\n onValueChange={(v: any) => {\r\n field.handleChange(coerce ? coerce(v) : v);\r\n }}\r\n isInvalid={!!errorMessage}\r\n errorMessage={errorMessage}\r\n />\r\n );\r\n }}\r\n </form.Field>\r\n );\r\n };\r\n}\r\n","import * as React from \"react\";\r\n\r\nimport {\r\n InputGroup,\r\n InputGroupAddon,\r\n InputGroupInput,\r\n Label,\r\n cn,\r\n} from \"@rxdrag/shadcn\";\r\n\r\ntype ShadcnInputSize = \"sm\" | \"md\" | \"lg\";\r\ntype ShadcnInputVariant = \"default\" | \"filled\" | \"flat\";\r\n\r\ntype BaseInputProps = Omit<React.ComponentProps<\"input\">, \"size\"> & {\r\n size?: ShadcnInputSize;\r\n variant?: ShadcnInputVariant;\r\n};\r\n\r\nexport type InputProps = BaseInputProps & {\r\n label?: React.ReactNode;\r\n labelPlacement?: \"outside\" | \"inside\" | \"outside-left\";\r\n description?: React.ReactNode;\r\n isInvalid?: boolean;\r\n errorMessage?: React.ReactNode;\r\n onValueChange?: (value: string) => void;\r\n startContent?: React.ReactNode;\r\n endContent?: React.ReactNode;\r\n required?: boolean;\r\n requried?: boolean;\r\n classNames?: Partial<{\r\n base: string;\r\n label: string;\r\n inputWrapper: string;\r\n input: string;\r\n description: string;\r\n errorMessage: string;\r\n }>;\r\n};\r\n\r\nexport function Input(props: InputProps) {\r\n const {\r\n id: idProp,\r\n label,\r\n labelPlacement,\r\n description,\r\n isInvalid,\r\n errorMessage,\r\n onValueChange,\r\n startContent,\r\n endContent,\r\n className,\r\n classNames,\r\n size,\r\n variant,\r\n required,\r\n requried,\r\n onChange,\r\n \"aria-invalid\": ariaInvalid,\r\n ...rest\r\n } = props;\r\n\r\n const reactId = React.useId();\r\n const id = idProp ?? reactId;\r\n const requiredFlag = required ?? requried;\r\n const invalid = Boolean(isInvalid || errorMessage);\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n onChange?.(e);\r\n onValueChange?.(e.target.value);\r\n };\r\n\r\n return (\r\n <div className={cn(\"grid w-full gap-2\", className, classNames?.base)}>\r\n {label && labelPlacement !== \"inside\" ? (\r\n <Label className={cn(\"text-sm\", classNames?.label)} htmlFor={id}>\r\n {label}\r\n {requiredFlag ? (\r\n <span className=\"ml-1 text-destructive\">*</span>\r\n ) : null}\r\n </Label>\r\n ) : null}\r\n\r\n <InputGroup\r\n className={cn(\"overflow-hidden\", classNames?.inputWrapper)}\r\n data-disabled={rest.disabled ? true : undefined}\r\n size={size}\r\n variant={variant}\r\n >\r\n {startContent ? (\r\n <InputGroupAddon align=\"inline-start\">{startContent}</InputGroupAddon>\r\n ) : null}\r\n\r\n <InputGroupInput\r\n aria-invalid={ariaInvalid ?? invalid}\r\n className={classNames?.input}\r\n id={id}\r\n onChange={handleChange}\r\n required={requiredFlag}\r\n size={size}\r\n {...rest}\r\n />\r\n\r\n {endContent ? (\r\n <InputGroupAddon align=\"inline-end\">{endContent}</InputGroupAddon>\r\n ) : null}\r\n </InputGroup>\r\n\r\n {invalid ? (\r\n <div className={cn(\"text-xs text-destructive\", classNames?.errorMessage)}>\r\n {errorMessage}\r\n </div>\r\n ) : description ? (\r\n <div\r\n className={cn(\"text-xs text-muted-foreground\", classNames?.description)}\r\n >\r\n {description}\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","import * as React from \"react\";\r\n\r\nimport { Label, Textarea as ShadcnTextarea, cn } from \"@rxdrag/shadcn\";\r\n\r\nexport type TextareaProps = React.ComponentProps<\"textarea\"> & {\r\n id?: string;\r\n label?: React.ReactNode;\r\n labelPlacement?: \"outside\" | \"inside\" | \"outside-left\";\r\n description?: React.ReactNode;\r\n isInvalid?: boolean;\r\n errorMessage?: React.ReactNode;\r\n onValueChange?: (value: string) => void;\r\n required?: boolean;\r\n requried?: boolean;\r\n minRows?: number;\r\n classNames?: Partial<{\r\n base: string;\r\n label: string;\r\n textarea: string;\r\n description: string;\r\n errorMessage: string;\r\n }>;\r\n};\r\n\r\nexport function Textarea(props: TextareaProps) {\r\n const {\r\n id: idProp,\r\n label,\r\n labelPlacement,\r\n description,\r\n isInvalid,\r\n errorMessage,\r\n onValueChange,\r\n required,\r\n requried,\r\n minRows,\r\n rows,\r\n className,\r\n classNames,\r\n onChange,\r\n \"aria-invalid\": ariaInvalid,\r\n ...rest\r\n } = props;\r\n\r\n const rowsValue = rows ?? minRows;\r\n\r\n const reactId = React.useId();\r\n const id = idProp ?? reactId;\r\n const invalid = Boolean(isInvalid || errorMessage);\r\n const requiredFlag = required ?? requried;\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n onChange?.(e);\r\n onValueChange?.(e.target.value);\r\n };\r\n\r\n return (\r\n <div className={cn(\"grid w-full gap-2\", className, classNames?.base)}>\r\n {label && labelPlacement !== \"inside\" ? (\r\n <Label className={cn(\"text-sm\", classNames?.label)} htmlFor={id}>\r\n {label}\r\n </Label>\r\n ) : null}\r\n\r\n <ShadcnTextarea\r\n aria-invalid={ariaInvalid ?? invalid}\r\n className={classNames?.textarea}\r\n id={id}\r\n onChange={handleChange}\r\n required={requiredFlag}\r\n rows={rowsValue}\r\n {...rest}\r\n />\r\n\r\n {invalid ? (\r\n <div className={cn(\"text-xs text-destructive\", classNames?.errorMessage)}>\r\n {errorMessage}\r\n </div>\r\n ) : description ? (\r\n <div className={cn(\"text-xs text-muted-foreground\", classNames?.description)}>\r\n {description}\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","import * as React from \"react\";\r\n\r\nimport {\r\n Label,\r\n Select as ShadcnSelect,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n cn,\r\n} from \"@rxdrag/shadcn\";\r\n\r\nexport type SelectProps = {\r\n id?: string;\r\n label?: React.ReactNode;\r\n labelPlacement?: \"outside\" | \"inside\" | \"outside-left\";\r\n placeholder?: string;\r\n description?: React.ReactNode;\r\n isInvalid?: boolean;\r\n errorMessage?: React.ReactNode;\r\n value?: string | number;\r\n onValueChange?: (value?: string | number) => void;\r\n disabled?: boolean;\r\n className?: string;\r\n classNames?: Partial<{\r\n base: string;\r\n label: string;\r\n trigger: string;\r\n content: string;\r\n description: string;\r\n errorMessage: string;\r\n }>;\r\n children?: React.ReactNode;\r\n};\r\n\r\nexport function Select(props: SelectProps) {\r\n const {\r\n id: idProp,\r\n label,\r\n labelPlacement,\r\n placeholder,\r\n description,\r\n isInvalid,\r\n errorMessage,\r\n value,\r\n onValueChange,\r\n disabled,\r\n className,\r\n classNames,\r\n children,\r\n } = props;\r\n\r\n const reactId = React.useId();\r\n const id = idProp ?? reactId;\r\n const invalid = Boolean(isInvalid || errorMessage);\r\n\r\n const valueString = value === undefined || value === null ? undefined : String(value);\r\n\r\n const items = React.useMemo(() => {\r\n return React.Children.toArray(children)\r\n .map((child) => {\r\n if (!React.isValidElement(child)) {\r\n return null;\r\n }\r\n\r\n const optionValue = (child.props as { value?: unknown }).value ?? child.key;\n if (optionValue === null || optionValue === undefined) {\n return null;\n }\n\r\n const disabledFromChild = Boolean(\r\n (child.props as { isDisabled?: boolean; disabled?: boolean }).isDisabled ||\r\n (child.props as { disabled?: boolean }).disabled\r\n );\r\n\r\n return {\n value: String(optionValue),\n label: (child.props as { children?: React.ReactNode }).children,\r\n disabled: disabledFromChild,\r\n };\r\n })\r\n .filter(Boolean) as Array<{ value: string; label: React.ReactNode; disabled: boolean }>;\r\n }, [children]);\r\n\r\n return (\r\n <div className={cn(\"grid w-full gap-2\", classNames?.base)}>\r\n {label && labelPlacement !== \"inside\" ? (\r\n <Label className={cn(\"text-sm\", classNames?.label)} htmlFor={id}>\r\n {label}\r\n </Label>\r\n ) : null}\r\n\r\n <ShadcnSelect\r\n value={valueString}\r\n onValueChange={(v) => {\r\n onValueChange?.(v);\r\n }}\r\n >\r\n <SelectTrigger\r\n aria-invalid={invalid}\r\n className={cn(className, classNames?.trigger)}\r\n disabled={disabled}\r\n id={id}\r\n >\r\n <SelectValue placeholder={placeholder} />\r\n </SelectTrigger>\r\n\r\n <SelectContent className={cn(classNames?.content)}>\r\n {items.map((item) => (\r\n <SelectItem disabled={item.disabled} key={item.value} value={item.value}>\r\n {item.label}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </ShadcnSelect>\r\n\r\n {invalid ? (\r\n <div className={cn(\"text-xs text-destructive\", classNames?.errorMessage)}>\r\n {errorMessage}\r\n </div>\r\n ) : description ? (\r\n <div className={cn(\"text-xs text-muted-foreground\", classNames?.description)}>\r\n {description}\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","import { Select, type SelectProps } from \"./Select\";\r\n\r\nexport type SingleSelectProps = Omit<SelectProps, \"value\" | \"onValueChange\"> & {\r\n value?: string;\r\n onValueChange?: (value?: string) => void;\r\n};\r\n\r\nexport function SingleSelect(props: SingleSelectProps) {\r\n const { value, onValueChange, ...rest } = props;\r\n return (\r\n <Select\r\n {...rest}\r\n onValueChange={(v) => onValueChange?.(v as string)}\r\n value={value}\r\n />\r\n );\r\n}\r\n","import * as React from \"react\";\r\n\r\nimport { cn } from \"@rxdrag/shadcn\";\r\n\r\nexport type SwitchProps = Omit<\r\n React.ButtonHTMLAttributes<HTMLButtonElement>,\r\n \"onChange\" | \"value\"\r\n> & {\r\n value?: boolean;\r\n onValueChange?: (value: boolean) => void;\r\n size?: \"sm\" | \"md\" | \"lg\";\r\n children?: React.ReactNode;\r\n disabled?: boolean;\r\n};\r\n\r\nexport function Switch(props: SwitchProps) {\r\n const { value, onValueChange, size = \"md\", className, children, ...rest } =\r\n props;\r\n\r\n const checked = Boolean(value);\r\n const disabled = Boolean(rest.disabled);\r\n const toggle = () => onValueChange?.(!checked);\r\n\r\n const trackClass = cn(\r\n \"relative inline-flex shrink-0 cursor-pointer items-center rounded-full border border-border transition-colors\",\r\n checked ? \"bg-primary\" : \"bg-muted\",\r\n disabled && \"cursor-not-allowed opacity-50\",\r\n size === \"sm\" && \"h-5 w-9\",\r\n size === \"md\" && \"h-6 w-11\",\r\n size === \"lg\" && \"h-7 w-14\"\r\n );\r\n\r\n const thumbClass = cn(\r\n \"pointer-events-none inline-block rounded-full bg-background shadow transition-transform\",\r\n size === \"sm\" && \"ml-0.5 size-4\",\r\n size === \"md\" && \"ml-0.5 size-5\",\r\n size === \"lg\" && \"ml-0.5 size-6\",\r\n checked && size === \"sm\" && \"translate-x-4\",\r\n checked && size === \"md\" && \"translate-x-5\",\r\n checked && size === \"lg\" && \"translate-x-7\"\r\n );\r\n\r\n return (\r\n <label className={cn(\"inline-flex items-center gap-2\", className)}>\r\n <button\r\n aria-checked={checked}\r\n onClick={(e) => {\r\n e.preventDefault();\r\n if (disabled) {\r\n return;\r\n }\r\n toggle();\r\n }}\r\n role=\"switch\"\r\n type=\"button\"\r\n {...rest}\r\n className={trackClass}\r\n >\r\n <span className={thumbClass} />\r\n </button>\r\n {children ? <span className=\"text-sm cursor-pointer\">{children}</span> : null}\r\n </label>\r\n );\r\n}\r\n","import * as React from \"react\";\r\n\r\nimport { Checkbox as ShadcnCheckbox, Label } from \"@rxdrag/shadcn\";\r\n\r\nexport type CheckboxProps = {\r\n id?: string;\r\n children?: React.ReactNode;\r\n value?: boolean;\r\n onValueChange?: (value: boolean) => void;\r\n isInvalid?: boolean;\r\n errorMessage?: React.ReactNode;\r\n};\r\n\r\nexport function Checkbox(props: CheckboxProps) {\r\n const { id: idProp, value, onValueChange, isInvalid, errorMessage, children } =\r\n props;\r\n\r\n const reactId = React.useId();\r\n const id = idProp ?? reactId;\r\n\r\n return (\r\n <div className=\"grid gap-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <ShadcnCheckbox\r\n aria-invalid={isInvalid}\r\n checked={!!value}\r\n id={id}\r\n onCheckedChange={(checked: unknown) => {\r\n onValueChange?.(checked === true);\r\n }}\r\n />\r\n {children ? (\r\n <Label className=\"text-sm\" htmlFor={id}>\r\n {children}\r\n </Label>\r\n ) : null}\r\n </div>\r\n {isInvalid && errorMessage ? (\r\n <div className=\"text-xs text-destructive\">{errorMessage}</div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","export type ColorInputProps = {\r\n value?: string;\r\n onValueChange?: (value?: string) => void;\r\n};\r\nexport function ColorInput(props: ColorInputProps) {\r\n const { value, onValueChange } = props;\r\n\r\n return (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"color\"\r\n value={value}\r\n onChange={(e) => onValueChange?.(e.target.value)}\r\n className=\"w-10 h-10 rounded border border-border cursor-pointer\"\r\n />\r\n <input\r\n type=\"text\"\r\n value={value}\r\n onChange={(e) => onValueChange?.(e.target.value)}\r\n className=\"border border-input rounded-md px-3 py-1.5 w-32\"\r\n />\r\n </div>\r\n );\r\n}\r\n","import { EyeClosedIcon, EyeIcon } from \"@rxdrag/rxcms-common\";\r\nimport * as React from \"react\";\r\n\r\nimport { Input, type InputProps } from \"./Input\";\r\n\r\nexport type PasswordProps = Omit<InputProps, \"type\" | \"endContent\"> & {\r\n endContent?: React.ReactNode;\r\n};\r\n\r\nexport function Password(props: PasswordProps) {\r\n const { endContent, ...rest } = props;\r\n const [isVisible, setIsVisible] = React.useState(false);\r\n\r\n const toggleVisibility = () => setIsVisible(!isVisible);\r\n\r\n return (\r\n <Input\r\n endContent={\r\n <>\r\n {endContent}\r\n <button\r\n aria-label={isVisible ? \"Hide password\" : \"Show password\"}\r\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:text-foreground\"\r\n onClick={toggleVisibility}\r\n type=\"button\"\r\n >\r\n {isVisible ? (\r\n <EyeClosedIcon className=\"size-5\" />\r\n ) : (\r\n <EyeIcon className=\"size-5\" />\r\n )}\r\n </button>\r\n </>\r\n }\r\n type={isVisible ? \"text\" : \"password\"}\r\n {...rest}\r\n />\r\n );\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport type React from \"react\";\r\nimport { bindField, type BindFieldOptions, type ControlProps } from \"./bindField\";\r\nimport { Input, type InputProps } from \"./components/Input\";\r\nimport { Textarea, type TextareaProps } from \"./components/Textarea\";\r\nimport { Select, type SelectProps } from \"./components/Select\";\r\nimport { SingleSelect, type SingleSelectProps } from \"./components/SingleSelect\";\r\nimport { Switch, type SwitchProps } from \"./components/Switch\";\r\nimport { Checkbox, type CheckboxProps } from \"./components/Checkbox\";\r\nimport { ColorInput, type ColorInputProps } from \"./components/ColorInput\";\r\nimport { Password, type PasswordProps } from \"./components/Password\";\r\n\r\n/**\r\n * 业务字段组件(TanStack 版)——沿用 fieldy-ui 的同名 props 心智,功能对齐。\r\n * name 用 codegen 出的 XxxFields.* 常量;校验支持 required / zodSchema / 旧版 validateSchema。\r\n */\r\n\r\nconst BaseInputField = bindField<InputProps>(Input, {\r\n controlType: \"text\",\r\n displayDefault: \"\",\r\n});\r\n\r\n/** 文本/数字输入。type=\"number\" 时写回 store 的是 number(空串→undefined)。 */\r\nexport function InputField(\r\n props: Parameters<typeof BaseInputField>[0] & { type?: string }\r\n) {\r\n const coerce =\r\n props.type === \"number\"\r\n ? (raw: any) => {\r\n const s = String(raw ?? \"\").trim();\r\n if (s === \"\") return undefined;\r\n const n = Number(s);\r\n return Number.isNaN(n) ? raw : n;\r\n }\r\n : undefined;\r\n return <BaseInputField coerce={coerce} {...props} />;\r\n}\r\n\r\nexport const TextareaField = bindField<TextareaProps>(Textarea, {\r\n controlType: \"textarea\",\r\n displayDefault: \"\",\r\n});\r\nexport const SelectField = bindField<SelectProps>(Select, {\r\n controlType: \"select\",\r\n displayDefault: \"\",\r\n});\r\nexport const SingleSelectField = bindField<SingleSelectProps>(\r\n SingleSelect as unknown as React.ComponentType<SingleSelectProps>,\r\n { controlType: \"select\", displayDefault: \"\" }\r\n);\r\nexport const SwitchField = bindField<SwitchProps>(Switch, {\r\n controlType: \"switch\",\r\n displayDefault: false,\r\n});\r\nexport const CheckboxField = bindField<CheckboxProps>(Checkbox, {\r\n controlType: \"checkbox\",\r\n displayDefault: false,\r\n});\r\nexport const PasswordField = bindField<PasswordProps>(Password, {\r\n controlType: \"password\",\r\n displayDefault: \"\",\r\n});\r\nexport const ColorField = bindField<ColorInputProps>(ColorInput, {\r\n controlType: \"color\",\r\n displayDefault: \"\",\r\n});\r\n\r\n/**\r\n * toField —— fieldy-ui 同名 API 的兼容别名(供 glue 字段沿用)。\r\n * 旧签名是 toField(Component, { defaultValue }),这里把 defaultValue 映射为 displayDefault。\r\n * 保留「显式传 undefined」语义(如 select 存对象/undefined 而非 \"\")。\r\n */\r\nexport function toField<P extends ControlProps = ControlProps>(\r\n Component: React.ComponentType<P>,\r\n options?: { defaultValue?: unknown } & BindFieldOptions\r\n) {\r\n const displayDefault =\r\n options && \"defaultValue\" in options\r\n ? options.defaultValue\r\n : options?.displayDefault ?? \"\";\r\n return bindField<P>(Component, {\r\n displayDefault,\r\n controlType: options?.controlType,\r\n });\r\n}\r\n\r\n/**\r\n * fieldy-ui 的 FieldProps 兼容类型:字段包装组件的公共 props(供 glue 字段手写签名沿用)。\r\n */\r\nexport type FieldProps = {\r\n name?: string;\r\n label?: React.ReactNode;\r\n defaultValue?: unknown;\r\n initialValue?: unknown;\r\n value?: unknown;\r\n required?: boolean | string;\r\n validateSchema?: import(\"./validators\").LegacyValidateSchema;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n valueComputer?: any;\r\n};\r\n","import type { ReactNode } from \"react\";\r\nimport {\r\n FieldNamePrefixContext,\r\n useFieldNamePrefix,\r\n joinFieldName,\r\n} from \"./context\";\r\n\r\n/**\r\n * 嵌套对象字段:把 name 作为前缀下发给子字段(TanStack Form 用点号路径表达嵌套)。\r\n * 例如 <ObjectField name=\"meta\"><InputField name=\"title\" /></ObjectField>\r\n * 内部字段实际绑定到 \"meta.title\"。可多层嵌套。\r\n */\r\nexport function ObjectField(props: { name: string; children?: ReactNode }) {\r\n const parentPrefix = useFieldNamePrefix();\r\n const prefix = joinFieldName(parentPrefix, props.name);\r\n return (\r\n <FieldNamePrefixContext.Provider value={prefix}>\r\n {props.children}\r\n </FieldNamePrefixContext.Provider>\r\n );\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { useCallback } from \"react\";\r\nimport { useStore } from \"@tanstack/react-form\";\r\nimport {\r\n useAppFormContext,\r\n useFieldNamePrefix,\r\n joinFieldName,\r\n type AnyAppForm,\r\n} from \"./context\";\r\nimport { commitForm } from \"./AppForm\";\r\n\r\n/** 按点号路径读对象值(如 \"meta.title\")。 */\r\nfunction getByPath(obj: any, path: string): any {\r\n if (!path) return obj;\r\n return path.split(\".\").reduce((acc, key) => (acc == null ? acc : acc[key]), obj);\r\n}\r\n\r\n/** 订阅整表单当前值(TanStack store 切片)。 */\r\nexport function useFormValues<T = any>(): T {\r\n const { form } = useAppFormContext();\r\n return useStore(form.store, (s: any) => s.values) as T;\r\n}\r\n\r\n/** fieldy useFormValue 兼容别名(无参,返回整表单值)。 */\r\nexport const useFormValue = useFormValues;\r\n\r\n/** 订阅某字段当前值(尊重 ObjectField 前缀)。 */\r\nexport function useFieldValue<T = any>(name: string): T {\r\n const { form } = useAppFormContext();\r\n const prefix = useFieldNamePrefix();\r\n const full = joinFieldName(prefix, name);\r\n return useStore(form.store, (s: any) => getByPath(s.values, full)) as T;\r\n}\r\n\r\n/**\r\n * fieldy useFormModified 兼容:脏 = !isDefaultValue。\r\n * setModified(false):以当前值为新基线(保存成功后调用 → 变“未修改”,禁用保存按钮)。\r\n * setModified(true):无需处理(TanStack 由值变化自动置脏)。\r\n */\r\nexport function useFormModified(): {\r\n modified: boolean;\r\n setModified: (v: boolean) => void;\r\n} {\r\n const { form } = useAppFormContext();\r\n const isDefaultValue = useStore(form.store, (s: any) => s.isDefaultValue);\r\n const setModified = useCallback(\r\n (v: boolean) => {\r\n if (!v) {\r\n // 以当前值为新基线(= reset(当前值) + 记账同步)→ isDefaultValue 变 true 且关闭覆写通道。\r\n // 直接 form.reset 会触发 useAppForm 病灶:reset 清 touched 后下一渲染 update 用宿主旧\r\n // defaultValues 整表回滚(\"保存成功却回退\")。走 commitForm 让真身/appOptions 引用恒相等。\r\n commitForm(form);\r\n }\r\n },\r\n [form]\r\n );\r\n return { modified: !isDefaultValue, setModified };\r\n}\r\n\r\n/**\r\n * 命令式校验整表单并取值(替代 fieldy 的 form.validate())。\r\n * 返回 { ok, value }:ok=全字段校验通过;value=当前表单值(重组出的 entity 形状)。\r\n */\r\nexport async function validateForm<T = any>(\r\n form: AnyAppForm\r\n): Promise<{ ok: boolean; value: T }> {\r\n await form.validateAllFields(\"submit\");\r\n return { ok: !!form.state.isValid, value: form.state.values as T };\r\n}\r\n\r\n/**\r\n * 命令式设置某字段值(供加载后回填等场景,尊重 ObjectField 前缀)。\r\n * 用法:const setField = useSetFieldValue(); setField(\"schemaJson\", text)\r\n */\r\nexport function useSetFieldValue() {\r\n const { form } = useAppFormContext();\r\n const prefix = useFieldNamePrefix();\r\n return (name: string, value: unknown) =>\r\n form.setFieldValue(joinFieldName(prefix, name), value);\r\n}\r\n"],"names":["React","require$$0","jsxRuntimeModule","require$$1","jsx","jsxs","ShadcnTextarea","ShadcnSelect","ShadcnCheckbox","Fragment"],"mappings":";;;;;;AA6BO,MAAM,iBAAiB;AAAA,EAC5B;AACF;AAEO,SAAS,oBAAyC;AACjD,QAAA,MAAM,WAAW,cAAc;AACrC,MAAI,CAAC;AAAW,UAAA,IAAI,MAAM,qCAAqC;AACxD,SAAA;AACT;AAGO,SAAS,yBAA0D;AACxE,SAAO,WAAW,cAAc;AAClC;AAMa,MAAA,yBAAyB,cAAsB,EAAE;AAEvD,SAAS,qBAA6B;AAC3C,SAAO,WAAW,sBAAsB;AAC1C;AAGgB,SAAA,cAAc,QAAgB,MAAsB;AAClE,MAAI,CAAC;AAAe,WAAA;AACpB,MAAI,CAAC;AAAa,WAAA;AACX,SAAA,GAAG,MAAM,IAAI,IAAI;AAC1B;;;;;;;;;;;;;;;;;AChDA,MAAI,qBAAqB,OAAO,IAAI,4BAA4B,GAC9D,sBAAsB,OAAO,IAAI,gBAAgB;AACnD,WAAS,QAAQ,MAAM,QAAQ,UAAU;AACvC,QAAI,MAAM;AACV,eAAW,aAAa,MAAM,KAAK;AACnC,eAAW,OAAO,QAAQ,MAAM,KAAK,OAAO;AAC5C,QAAI,SAAS,QAAQ;AACnB,iBAAW,CAAA;AACX,eAAS,YAAY;AACnB,kBAAU,aAAa,SAAS,QAAQ,IAAI,OAAO,QAAQ;AAAA,IACjE;AAAS,iBAAW;AAClB,aAAS,SAAS;AAClB,WAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,KAAK,WAAW,SAAS,SAAS;AAAA,MAClC,OAAO;AAAA,IACX;AAAA,EACC;AACe,6BAAA,WAAG;AACR,6BAAA,MAAG;AACd,6BAAA,OAAe;;;;;;;;;;;;;;;;;;ACtBf,mBAAiB,QAAQ,IAAI,YAC1B,WAAY;AACX,aAAS,yBAAyB,MAAM;AACtC,UAAI,QAAQ;AAAM,eAAO;AACzB,UAAI,eAAe,OAAO;AACxB,eAAO,KAAK,aAAa,yBACrB,OACA,KAAK,eAAe,KAAK,QAAQ;AACvC,UAAI,aAAa,OAAO;AAAM,eAAO;AACrC,cAAQ,MAAI;AAAA,QACV,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,MACV;AACD,UAAI,aAAa,OAAO;AACtB,gBACG,aAAa,OAAO,KAAK,OACxB,QAAQ;AAAA,UACN;AAAA,QACD,GACH,KAAK,UACf;AAAA,UACU,KAAK;AACH,mBAAO;AAAA,UACT,KAAK;AACH,mBAAO,KAAK,eAAe;AAAA,UAC7B,KAAK;AACH,oBAAQ,KAAK,SAAS,eAAe,aAAa;AAAA,UACpD,KAAK;AACH,gBAAI,YAAY,KAAK;AACrB,mBAAO,KAAK;AACZ,qBACI,OAAO,UAAU,eAAe,UAAU,QAAQ,IACnD,OAAO,OAAO,OAAO,gBAAgB,OAAO,MAAM;AACrD,mBAAO;AAAA,UACT,KAAK;AACH,mBACG,YAAY,KAAK,eAAe,MACjC,SAAS,YACL,YACA,yBAAyB,KAAK,IAAI,KAAK;AAAA,UAE/C,KAAK;AACH,wBAAY,KAAK;AACjB,mBAAO,KAAK;AACZ,gBAAI;AACF,qBAAO,yBAAyB,KAAK,SAAS,CAAC;AAAA,YAC7D,SAAqB,GAAG;AAAA,YAAE;AAAA,QACjB;AACH,aAAO;AAAA,IACR;AACD,aAAS,mBAAmB,OAAO;AACjC,aAAO,KAAK;AAAA,IACb;AACD,aAAS,uBAAuB,OAAO;AACrC,UAAI;AACF,2BAAmB,KAAK;AACxB,YAAI,2BAA2B;AAAA,MAChC,SAAQ,GAAG;AACV,mCAA2B;AAAA,MAC5B;AACD,UAAI,0BAA0B;AAC5B,mCAA2B;AAC3B,YAAI,wBAAwB,yBAAyB;AACrD,YAAI,oCACD,eAAe,OAAO,UACrB,OAAO,eACP,MAAM,OAAO,WAAW,KAC1B,MAAM,YAAY,QAClB;AACF,8BAAsB;AAAA,UACpB;AAAA,UACA;AAAA,UACA;AAAA,QACV;AACQ,eAAO,mBAAmB,KAAK;AAAA,MAChC;AAAA,IACF;AACD,aAAS,YAAY,MAAM;AACzB,UAAI,SAAS;AAAqB,eAAO;AACzC,UACE,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa;AAElB,eAAO;AACT,UAAI;AACF,YAAI,OAAO,yBAAyB,IAAI;AACxC,eAAO,OAAO,MAAM,OAAO,MAAM;AAAA,MAClC,SAAQ,GAAG;AACV,eAAO;AAAA,MACR;AAAA,IACF;AACD,aAAS,WAAW;AAClB,UAAI,aAAa,qBAAqB;AACtC,aAAO,SAAS,aAAa,OAAO,WAAW,SAAQ;AAAA,IACxD;AACD,aAAS,eAAe;AACtB,aAAO,MAAM,uBAAuB;AAAA,IACrC;AACD,aAAS,YAAY,QAAQ;AAC3B,UAAI,eAAe,KAAK,QAAQ,KAAK,GAAG;AACtC,YAAI,SAAS,OAAO,yBAAyB,QAAQ,KAAK,EAAE;AAC5D,YAAI,UAAU,OAAO;AAAgB,iBAAO;AAAA,MAC7C;AACD,aAAO,WAAW,OAAO;AAAA,IAC1B;AACD,aAAS,2BAA2B,OAAO,aAAa;AACtD,eAAS,wBAAwB;AAC/B,uCACI,6BAA6B,MAC/B,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACZ;AAAA,MACO;AACD,4BAAsB,iBAAiB;AACvC,aAAO,eAAe,OAAO,OAAO;AAAA,QAClC,KAAK;AAAA,QACL,cAAc;AAAA,MACtB,CAAO;AAAA,IACF;AACD,aAAS,yCAAyC;AAChD,UAAI,gBAAgB,yBAAyB,KAAK,IAAI;AACtD,6BAAuB,aAAa,MAChC,uBAAuB,aAAa,IAAI,MAC1C,QAAQ;AAAA,QACN;AAAA,MACV;AACM,sBAAgB,KAAK,MAAM;AAC3B,aAAO,WAAW,gBAAgB,gBAAgB;AAAA,IACnD;AACD,aAAS,aAAa,MAAM,KAAK,OAAO,OAAO,YAAY,WAAW;AACpE,UAAI,UAAU,MAAM;AACpB,aAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MAChB;AACM,gBAAU,WAAW,UAAU,UAAU,QACrC,OAAO,eAAe,MAAM,OAAO;AAAA,QACjC,YAAY;AAAA,QACZ,KAAK;AAAA,MACjB,CAAW,IACD,OAAO,eAAe,MAAM,OAAO,EAAE,YAAY,OAAI,OAAO,KAAI,CAAE;AACtE,WAAK,SAAS;AACd,aAAO,eAAe,KAAK,QAAQ,aAAa;AAAA,QAC9C,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,OAAO;AAAA,MACf,CAAO;AACD,aAAO,eAAe,MAAM,cAAc;AAAA,QACxC,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,OAAO;AAAA,MACf,CAAO;AACD,aAAO,eAAe,MAAM,eAAe;AAAA,QACzC,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,OAAO;AAAA,MACf,CAAO;AACD,aAAO,eAAe,MAAM,cAAc;AAAA,QACxC,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,OAAO;AAAA,MACf,CAAO;AACD,aAAO,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG,OAAO,OAAO,IAAI;AAC/D,aAAO;AAAA,IACR;AACD,aAAS,WACP,MACA,QACA,UACA,kBACA,YACA,WACA;AACA,UAAI,WAAW,OAAO;AACtB,UAAI,WAAW;AACb,YAAI;AACF,cAAI,YAAY,QAAQ,GAAG;AACzB,iBACE,mBAAmB,GACnB,mBAAmB,SAAS,QAC5B;AAEA,gCAAkB,SAAS,gBAAgB,CAAC;AAC9C,mBAAO,UAAU,OAAO,OAAO,QAAQ;AAAA,UACxC;AACC,oBAAQ;AAAA,cACN;AAAA,YACd;AAAA;AACa,4BAAkB,QAAQ;AACjC,UAAI,eAAe,KAAK,QAAQ,KAAK,GAAG;AACtC,mBAAW,yBAAyB,IAAI;AACxC,YAAI,OAAO,OAAO,KAAK,MAAM,EAAE,OAAO,SAAU,GAAG;AACjD,iBAAO,UAAU;AAAA,QAC3B,CAAS;AACD,2BACE,IAAI,KAAK,SACL,oBAAoB,KAAK,KAAK,SAAS,IAAI,WAC3C;AACN,8BAAsB,WAAW,gBAAgB,MAC7C,OACA,IAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,IAAI,WAAW,MAC5D,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD,GACA,sBAAsB,WAAW,gBAAgB,IAAI;AAAA,MACzD;AACD,iBAAW;AACX,iBAAW,aACR,uBAAuB,QAAQ,GAAI,WAAW,KAAK;AACtD,kBAAY,MAAM,MACf,uBAAuB,OAAO,GAAG,GAAI,WAAW,KAAK,OAAO;AAC/D,UAAI,SAAS,QAAQ;AACnB,mBAAW,CAAA;AACX,iBAAS,YAAY;AACnB,oBAAU,aAAa,SAAS,QAAQ,IAAI,OAAO,QAAQ;AAAA,MACrE;AAAa,mBAAW;AAClB,kBACE;AAAA,QACE;AAAA,QACA,eAAe,OAAO,OAClB,KAAK,eAAe,KAAK,QAAQ,YACjC;AAAA,MACd;AACM,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAU;AAAA,QACV;AAAA,QACA;AAAA,MACR;AAAA,IACK;AACD,aAAS,kBAAkB,MAAM;AAC/B,qBAAe,IAAI,IACf,KAAK,WAAW,KAAK,OAAO,YAAY,KACxC,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa,oBACjB,gBAAgB,KAAK,SAAS,SAC3B,eAAe,KAAK,SAAS,KAAK,KAClC,KAAK,SAAS,MAAM,WACnB,KAAK,SAAS,MAAM,OAAO,YAAY,KACxC,KAAK,WAAW,KAAK,OAAO,YAAY;AAAA,IACjD;AACD,aAAS,eAAe,QAAQ;AAC9B,aACE,aAAa,OAAO,UACpB,SAAS,UACT,OAAO,aAAa;AAAA,IAEvB;AACD,QAAIA,SAAQC,gBACV,qBAAqB,OAAO,IAAI,4BAA4B,GAC5D,oBAAoB,OAAO,IAAI,cAAc,GAC7C,sBAAsB,OAAO,IAAI,gBAAgB,GACjD,yBAAyB,OAAO,IAAI,mBAAmB,GACvD,sBAAsB,OAAO,IAAI,gBAAgB,GACjD,sBAAsB,OAAO,IAAI,gBAAgB,GACjD,qBAAqB,OAAO,IAAI,eAAe,GAC/C,yBAAyB,OAAO,IAAI,mBAAmB,GACvD,sBAAsB,OAAO,IAAI,gBAAgB,GACjD,2BAA2B,OAAO,IAAI,qBAAqB,GAC3D,kBAAkB,OAAO,IAAI,YAAY,GACzC,kBAAkB,OAAO,IAAI,YAAY,GACzC,sBAAsB,OAAO,IAAI,gBAAgB,GACjD,yBAAyB,OAAO,IAAI,wBAAwB,GAC5D,uBACED,OAAM,iEACR,iBAAiB,OAAO,UAAU,gBAClC,cAAc,MAAM,SACpB,aAAa,QAAQ,aACjB,QAAQ,aACR,WAAY;AACV,aAAO;AAAA,IACnB;AACI,IAAAA,SAAQ;AAAA,MACN,0BAA0B,SAAU,mBAAmB;AACrD,eAAO,kBAAiB;AAAA,MACzB;AAAA,IACP;AACI,QAAI;AACJ,QAAI,yBAAyB,CAAA;AAC7B,QAAI,yBAAyBA,OAAM,yBAAyB;AAAA,MAC1DA;AAAA,MACA;AAAA,IACN;AACI,QAAI,wBAAwB,WAAW,YAAY,YAAY,CAAC;AAChE,QAAI,wBAAwB,CAAA;AAC5B,gCAAA,WAAmB;AACnB,gCAAA,MAAc,SAAU,MAAM,QAAQ,UAAU;AAC9C,UAAI,mBACF,MAAM,qBAAqB;AAC7B,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBACI,MAAM,uBAAuB,IAC7B;AAAA,QACJ,mBAAmB,WAAW,YAAY,IAAI,CAAC,IAAI;AAAA,MAC3D;AAAA,IACA;AACI,gCAAA,OAAe,SAAU,MAAM,QAAQ,UAAU;AAC/C,UAAI,mBACF,MAAM,qBAAqB;AAC7B,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBACI,MAAM,uBAAuB,IAC7B;AAAA,QACJ,mBAAmB,WAAW,YAAY,IAAI,CAAC,IAAI;AAAA,MAC3D;AAAA,IACA;AAAA,EACA;;;AC7VA,IAAI,QAAQ,IAAI,aAAa,cAAc;AACzCE,aAAA,UAAiBD;AACnB,OAAO;AACLC,aAAA,UAAiBC;AACnB;;ACoBO,SAAS,WAA6B,MAAwC;AAE7E,QAAA,YAAY,OAAO,KAAK,QAAQ;AACtC,YAAU,UAAU,KAAK;AAYnB,QAAA,gBAAgB,OAGZ,IAAI;AACV,MAAA,CAAC,cAAc,SAAS;AAC1B,kBAAc,UAAU;AAAA,MACtB,eAAe,KAAK;AAAA,MACpB,UAAU,OAAO,EAAE,YAAgC;;AAC3C,gBAAA,eAAU,YAAV,mCAAoB;AAAA,MAC5B;AAAA,IAAA;AAAA,EAEJ;AACM,QAAA,OAAO,QAAQ,cAAc,OAAc;AAEhD,OAA4C,eAAe,cAAc;AACnE,SAAA;AACT;AAGA,SAAS,gBAAgB,MAAkB,MAAqB;AAC9D,QAAM,aAAc,KAA4C;AAG5D,MAAA;AAAY,eAAW,gBAAgB;AAC7C;AAQgB,SAAA,WAA6B,MAAkB,MAAe;AAC3E,OAA8C,MAAM,IAAI;AAGzD,kBAAgB,MAAM,IAAI;AAC5B;AAOgB,SAAA,WAA6B,MAAkB,OAA0B;AACjF,QAAA,UAAW,KAA6C,MAAM;AACpE,aAAW,MAAM,EAAE,GAAI,SAAoB,GAAI,MAAmC,CAAA;AACpF;AAaO,SAAS,QAAQ,OAAqB;AAC3C,QAAM,EAAE,MAAM,UAAU,WAAW,OAAO,cAAkB,IAAA;AAGtD,QAAA,WAAW,OAA8B,CAAA,CAAE;AAC3C,QAAA,oBAAoB,YAAY,CAAC,SAA8B;AACnE,aAAS,UAAU,CAAC,GAAG,SAAS,SAAS,IAAI;AAC7C,WAAO,MAAM;AACX,eAAS,UAAU,SAAS,QAAQ,OAAO,CAAC,MAAM,MAAM,IAAI;AAAA,IAAA;AAAA,EAEhE,GAAG,CAAE,CAAA;AACL,QAAM,gBAAgB,YAAY,MAAM,SAAS,SAAS,CAAE,CAAA;AAE5D,QAAM,MAAM;AAAA,IACV,OAAO,EAAE,MAAM,mBAAmB,eAAe,MAAM,MAAM;IAC7D,CAAC,MAAM,mBAAmB,eAAe,MAAM,IAAI;AAAA,EAAA;AAIrD,QAAM,iBAAiB,SAAS,KAAK,OAAO,CAAC,MAAW,EAAE,cAAc;AACxE,YAAU,MAAM;AACd,mDAAgB,CAAC;AAAA,EAAc,GAC9B,CAAC,gBAAgB,aAAa,CAAC;AAElC,SACGC,kCAAAA,IAAA,eAAe,UAAf,EAAwB,OAAO,KAC9B,UAAAA,kCAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,UAAU,CAAC,MAAM;AACf,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,aAAK,KAAK;MACZ;AAAA,MAEC;AAAA,IAAA;AAAA,EAEL,EAAA,CAAA;AAEJ;AAGO,SAAS,aAAa,OAAoB;AACzC,QAAA,EAAE,SAAS;AACjB,QAAM,eAAe,SAAS,KAAK,OAAO,CAAC,MAAW,EAAE,YAAY;AAElE,SAAAA,kCAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU,gBAAgB,MAAM;AAAA,MAC/B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;ACjHA,MAAM,WAAW;AACjB,MAAM,SAAS;AAEf,SAAS,QAAQ,GAAqB;AACpC,MAAI,MAAM,UAAa,MAAM,QAAQ,MAAM;AAAW,WAAA;AACtD,MAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW;AAAU,WAAA;AACxC,SAAA;AACT;AAGgB,SAAA,qBAAqB,OAA2B,OAAgB;AACxE,QAAA,EAAE,gBAAgB,UAAc,IAAA;AAEhC,QAAA,WAAW,MAAM,aAAY,iDAAgB;AACnD,QAAM,QAAQ,iDAAgB;AAE9B,MAAI,CAAC,YAAY,CAAC,aAAa,CAAC;AAAc,WAAA;AAExC,QAAA,kBACJ,OAAO,aAAa,WAChB,WACA,MAAM,OAAO,UAAU,WAAW,QAAQ,EAAE;AAElD,QAAM,WAAW,CAAC,EAAE,YAA4B;;AAC1C,QAAA,YAAY,QAAQ,KAAK;AAAU,aAAA;AACnC,QAAA,CAAC,QAAQ,KAAK,GAAG;AACnB,YAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,SAAS,EAAE;AAChE,WAAI,+BAAO,QAAO,EAAE,SAAS,MAAM,IAAI,OAAO;AAC5C,eAAO,MAAM,IAAI,WAAW,UAAU,MAAM,IAAI,KAAK;AAAA,MACvD;AACA,WAAI,+BAAO,QAAO,EAAE,SAAS,MAAM,IAAI,OAAO;AAC5C,eAAO,MAAM,IAAI,WAAW,UAAU,MAAM,IAAI,KAAK;AAAA,MACvD;AACA,WAAI,+BAAO,UAAS,CAAC,SAAS,KAAK,CAAC,GAAG;AACrC,eAAQ,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAY;AAAA,MACrE;AACA,WAAI,+BAAO,QAAO,CAAC,OAAO,KAAK,CAAC,GAAG;AACjC,eAAQ,OAAO,MAAM,QAAQ,YAAY,MAAM,IAAI,WAAY;AAAA,MACjE;AACA,UAAI,WAAW;AACP,cAAA,IAAI,UAAU,UAAU,KAAK;AACnC,YAAI,CAAC,EAAE;AAAS,mBAAO,mBAAE,UAAF,mBAAS,WAAT,mBAAkB,OAAlB,mBAAsB,YAAW;AAAA,MAC1D;AAAA,IACF;AACO,WAAA;AAAA,EAAA;AAGT,SAAO,EAAE,UAAU,UAAU,UAAU,SAAS;AAClD;AAGO,SAAS,kBAAkB,QAAmD;AAC7E,QAAA,IAAI,iCAAS;AACnB,MAAI,CAAC;AAAU,WAAA;AACf,MAAI,OAAO,MAAM;AAAiB,WAAA;AAClC,MAAI,OAAO,MAAM,YAAY,KAAK,aAAa;AACtC,WAAA,OAAQ,EAA2B,OAAO;AACnD,SAAO,OAAO,CAAC;AACjB;ACjDA,MAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEgB,SAAA,UACd,WACA,SACA;AACA,QAAM,EAAE,iBAAiB,IAAI,YAAY,IAAI,WAAW,CAAA;AACjD,SAAA,SAAS,WACd,OAEA;AACA,UAAM,MAAM;AACZ,UAAM,EAAE,MAAM,UAAU,OAAA,IAAW;AACnC,UAAM,EAAE,MAAM,kBAAkB,IAAI,kBAAkB;AACtD,UAAM,SAAS;AACf,UAAM,WAAW,OAAO,cAAc,QAAQ,IAAI,IAAI;AACtD,UAAM,KAAK;AAGX,UAAM,OAA4B,CAAA;AAClC,eAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,UAAI,QAAQ;AAAQ;AACf,UAAA,YAAkC,SAAS,GAAG;AAAG;AACjD,WAAA,GAAG,IAAI,IAAI,GAAG;AAAA,IACrB;AAEA,UAAM,YAAY,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAChE,cAAU,MAAM;AACd,UAAI,CAAC;AAAM;AACJ,aAAA,kBAAkB,EAAE,MAAM,UAAU,OAAO,WAAW,MAAM,aAAa;AAAA,OAC/E,CAAC,MAAM,UAAU,WAAW,iBAAiB,CAAC;AAEjD,UAAM,aAAa;AAAA,MACjB,EAAE,UAAU,WAAW,IAAI,WAAW,gBAAgB,IAAI,eAAe;AAAA,MACzE;AAAA,IAAA;AAIF,QAAI,CAAC,MAAM;AAEP,aAAAA,kCAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACC,GAAI,WAAY,EAAE,UAAU,SAAmC;AAAA,UAC/D,GAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAGX;AAGE,WAAAA,kCAAA,IAAC,KAAK,OAAL,EAAW,MAAM,UAAU,YACzB,WAAC,UAAe;AACT,YAAA,MAAM,MAAM,MAAM;AACxB,YAAM,eAAe,kBAAkB,MAAM,MAAM,KAAK,MAAM;AAE5D,aAAAA,kCAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UAEC,GAAI,WAAY,EAAE,UAAU,SAAmC;AAAA,UAC/D,GAAI;AAAA,UACL,OAAO,QAAQ,UAAa,QAAQ,OAAO,iBAAiB;AAAA,UAC5D,eAAe,CAAC,MAAW;AACzB,kBAAM,aAAa,SAAS,OAAO,CAAC,IAAI,CAAC;AAAA,UAC3C;AAAA,UACA,WAAW,CAAC,CAAC;AAAA,UACb;AAAA,QAAA;AAAA,MAAA;AAAA,IAIR,EAAA,CAAA;AAAA,EAAA;AAGN;AC3FO,SAAS,MAAM,OAAmB;AACjC,QAAA;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACD,IAAA;AAEE,QAAA,UAAU,MAAM;AACtB,QAAM,KAAK,UAAU;AACrB,QAAM,eAAe,YAAY;AAC3B,QAAA,UAAU,QAAQ,aAAa,YAAY;AAE3C,QAAA,eAAe,CAAC,MAA2C;AAC/D,yCAAW;AACK,mDAAA,EAAE,OAAO;AAAA,EAAK;AAI9B,SAAAC,uCAAC,SAAI,WAAW,GAAG,qBAAqB,WAAW,yCAAY,IAAI,GAChE,UAAA;AAAA,IAAS,SAAA,mBAAmB,WAC3BA,kCAAAA,KAAC,OAAM,EAAA,WAAW,GAAG,WAAW,yCAAY,KAAK,GAAG,SAAS,IAC1D,UAAA;AAAA,MAAA;AAAA,MACA,eACED,kCAAAA,IAAA,QAAA,EAAK,WAAU,yBAAwB,cAAC,CAAA,IACvC;AAAA,IAAA,EAAA,CACN,IACE;AAAA,IAEJC,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,GAAG,mBAAmB,yCAAY,YAAY;AAAA,QACzD,iBAAe,KAAK,WAAW,OAAO;AAAA,QACtC;AAAA,QACA;AAAA,QAEC,UAAA;AAAA,UAAA,eACED,kCAAAA,IAAA,iBAAA,EAAgB,OAAM,gBAAgB,uBAAa,CAAA,IAClD;AAAA,UAEJA,kCAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,gBAAc,eAAe;AAAA,cAC7B,WAAW,yCAAY;AAAA,cACvB;AAAA,cACA,UAAU;AAAA,cACV,UAAU;AAAA,cACV;AAAA,cACC,GAAG;AAAA,YAAA;AAAA,UACN;AAAA,UAEC,aACEA,kCAAAA,IAAA,iBAAA,EAAgB,OAAM,cAAc,qBAAW,CAAA,IAC9C;AAAA,QAAA;AAAA,MAAA;AAAA,IACN;AAAA,IAEC,UACEA,kCAAAA,IAAA,OAAA,EAAI,WAAW,GAAG,4BAA4B,yCAAY,YAAY,GACpE,UACH,aAAA,CAAA,IACE,cACFA,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,GAAG,iCAAiC,yCAAY,WAAW;AAAA,QAErE,UAAA;AAAA,MAAA;AAAA,IAAA,IAED;AAAA,EACN,EAAA,CAAA;AAEJ;AChGO,SAAS,SAAS,OAAsB;AACvC,QAAA;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACD,IAAA;AAEJ,QAAM,YAAY,QAAQ;AAEpB,QAAA,UAAU,MAAM;AACtB,QAAM,KAAK,UAAU;AACf,QAAA,UAAU,QAAQ,aAAa,YAAY;AACjD,QAAM,eAAe,YAAY;AAE3B,QAAA,eAAe,CAAC,MAA8C;AAClE,yCAAW;AACK,mDAAA,EAAE,OAAO;AAAA,EAAK;AAI9B,SAAAC,uCAAC,SAAI,WAAW,GAAG,qBAAqB,WAAW,yCAAY,IAAI,GAChE,UAAA;AAAA,IAAA,SAAS,mBAAmB,WAC1BD,kCAAAA,IAAA,OAAA,EAAM,WAAW,GAAG,WAAW,yCAAY,KAAK,GAAG,SAAS,IAC1D,gBACH,CAAA,IACE;AAAA,IAEJA,kCAAA;AAAA,MAACE;AAAAA,MAAA;AAAA,QACC,gBAAc,eAAe;AAAA,QAC7B,WAAW,yCAAY;AAAA,QACvB;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACL,GAAG;AAAA,MAAA;AAAA,IACN;AAAA,IAEC,gDACE,OAAI,EAAA,WAAW,GAAG,4BAA4B,yCAAY,YAAY,GACpE,UAAA,aAAA,CACH,IACE,cACFF,kCAAAA,IAAC,SAAI,WAAW,GAAG,iCAAiC,yCAAY,WAAW,GACxE,UAAA,YAAA,CACH,IACE;AAAA,EACN,EAAA,CAAA;AAEJ;AClDO,SAAS,OAAO,OAAoB;AACnC,QAAA;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACE,IAAA;AAEE,QAAA,UAAU,MAAM;AACtB,QAAM,KAAK,UAAU;AACf,QAAA,UAAU,QAAQ,aAAa,YAAY;AAEjD,QAAM,cAAc,UAAU,UAAa,UAAU,OAAO,SAAY,OAAO,KAAK;AAE9E,QAAA,QAAQ,MAAM,QAAQ,MAAM;AAChC,WAAO,MAAM,SAAS,QAAQ,QAAQ,EACnC,IAAI,CAAC,UAAU;AACd,UAAI,CAAC,MAAM,eAAe,KAAK,GAAG;AACzB,eAAA;AAAA,MACT;AAEA,YAAM,cAAe,MAAM,MAA8B,SAAS,MAAM;AACpE,UAAA,gBAAgB,QAAQ,gBAAgB,QAAW;AAC9C,eAAA;AAAA,MACT;AAEA,YAAM,oBAAoB;AAAA,QACvB,MAAM,MAAuD,cAC3D,MAAM,MAAiC;AAAA,MAAA;AAGrC,aAAA;AAAA,QACL,OAAO,OAAO,WAAW;AAAA,QACzB,OAAQ,MAAM,MAAyC;AAAA,QACvD,UAAU;AAAA,MAAA;AAAA,IACZ,CACD,EACA,OAAO,OAAO;AAAA,EAAA,GAChB,CAAC,QAAQ,CAAC;AAEb,gDACG,OAAI,EAAA,WAAW,GAAG,qBAAqB,yCAAY,IAAI,GACrD,UAAA;AAAA,IAAA,SAAS,mBAAmB,WAC1BA,kCAAAA,IAAA,OAAA,EAAM,WAAW,GAAG,WAAW,yCAAY,KAAK,GAAG,SAAS,IAC1D,gBACH,CAAA,IACE;AAAA,IAEJC,kCAAA;AAAA,MAACE;AAAAA,MAAA;AAAA,QACC,OAAO;AAAA,QACP,eAAe,CAAC,MAAM;AACpB,yDAAgB;AAAA,QAClB;AAAA,QAEA,UAAA;AAAA,UAAAH,kCAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,gBAAc;AAAA,cACd,WAAW,GAAG,WAAW,yCAAY,OAAO;AAAA,cAC5C;AAAA,cACA;AAAA,cAEA,UAAAA,kCAAA,IAAC,eAAY,YAA0B,CAAA;AAAA,YAAA;AAAA,UACzC;AAAA,UAEAA,kCAAAA,IAAC,eAAc,EAAA,WAAW,GAAG,yCAAY,OAAO,GAC7C,UAAA,MAAM,IAAI,CAAC,SACVA,kCAAAA,IAAC,cAAW,UAAU,KAAK,UAA2B,OAAO,KAAK,OAC/D,eAAK,MADkC,GAAA,KAAK,KAE/C,CACD,EACH,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF;AAAA,IAEC,gDACE,OAAI,EAAA,WAAW,GAAG,4BAA4B,yCAAY,YAAY,GACpE,UAAA,aAAA,CACH,IACE,cACFA,kCAAAA,IAAC,SAAI,WAAW,GAAG,iCAAiC,yCAAY,WAAW,GACxE,UAAA,YAAA,CACH,IACE;AAAA,EACN,EAAA,CAAA;AAEJ;ACxHO,SAAS,aAAa,OAA0B;AACrD,QAAM,EAAE,OAAO,eAAe,GAAG,SAAS;AAExC,SAAAA,kCAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ,eAAe,CAAC,MAAM,+CAAgB;AAAA,MACtC;AAAA,IAAA;AAAA,EAAA;AAGN;ACDO,SAAS,OAAO,OAAoB;AACnC,QAAA,EAAE,OAAO,eAAe,OAAO,MAAM,WAAW,UAAU,GAAG,KACjE,IAAA;AAEI,QAAA,UAAU,QAAQ,KAAK;AACvB,QAAA,WAAW,QAAQ,KAAK,QAAQ;AACtC,QAAM,SAAS,MAAM,+CAAgB,CAAC;AAEtC,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,UAAU,eAAe;AAAA,IACzB,YAAY;AAAA,IACZ,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,EAAA;AAGnB,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,IACjB,WAAW,SAAS,QAAQ;AAAA,IAC5B,WAAW,SAAS,QAAQ;AAAA,IAC5B,WAAW,SAAS,QAAQ;AAAA,EAAA;AAG9B,gDACG,SAAM,EAAA,WAAW,GAAG,kCAAkC,SAAS,GAC9D,UAAA;AAAA,IAAAA,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,gBAAc;AAAA,QACd,SAAS,CAAC,MAAM;AACd,YAAE,eAAe;AACjB,cAAI,UAAU;AACZ;AAAA,UACF;AACO;QACT;AAAA,QACA,MAAK;AAAA,QACL,MAAK;AAAA,QACJ,GAAG;AAAA,QACJ,WAAW;AAAA,QAEX,UAAAA,kCAAAA,IAAC,QAAK,EAAA,WAAW,WAAY,CAAA;AAAA,MAAA;AAAA,IAC/B;AAAA,IACC,WAAYA,kCAAA,IAAA,QAAA,EAAK,WAAU,0BAA0B,SAAS,CAAA,IAAU;AAAA,EAC3E,EAAA,CAAA;AAEJ;AClDO,SAAS,SAAS,OAAsB;AACvC,QAAA,EAAE,IAAI,QAAQ,OAAO,eAAe,WAAW,cAAc,SACjE,IAAA;AAEI,QAAA,UAAU,MAAM;AACtB,QAAM,KAAK,UAAU;AAGnB,SAAAC,kCAAA,KAAC,OAAI,EAAA,WAAU,cACb,UAAA;AAAA,IAACA,kCAAAA,KAAA,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAAD,kCAAA;AAAA,QAACI;AAAAA,QAAA;AAAA,UACC,gBAAc;AAAA,UACd,SAAS,CAAC,CAAC;AAAA,UACX;AAAA,UACA,iBAAiB,CAAC,YAAqB;AACrC,2DAAgB,YAAY;AAAA,UAC9B;AAAA,QAAA;AAAA,MACF;AAAA,MACC,iDACE,OAAM,EAAA,WAAU,WAAU,SAAS,IACjC,SACH,CAAA,IACE;AAAA,IAAA,GACN;AAAA,IACC,aAAa,eACZJ,kCAAA,IAAC,SAAI,WAAU,4BAA4B,uBAAa,CAAA,IACtD;AAAA,EACN,EAAA,CAAA;AAEJ;ACtCO,SAAS,WAAW,OAAwB;AAC3C,QAAA,EAAE,OAAO,cAAkB,IAAA;AAG/B,SAAAC,kCAAA,KAAC,OAAI,EAAA,WAAU,2BACb,UAAA;AAAA,IAAAD,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,UAAU,CAAC,MAAM,+CAAgB,EAAE,OAAO;AAAA,QAC1C,WAAU;AAAA,MAAA;AAAA,IACZ;AAAA,IACAA,kCAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,UAAU,CAAC,MAAM,+CAAgB,EAAE,OAAO;AAAA,QAC1C,WAAU;AAAA,MAAA;AAAA,IACZ;AAAA,EACF,EAAA,CAAA;AAEJ;ACdO,SAAS,SAAS,OAAsB;AAC7C,QAAM,EAAE,YAAY,GAAG,KAAA,IAAS;AAChC,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AAEtD,QAAM,mBAAmB,MAAM,aAAa,CAAC,SAAS;AAGpD,SAAAA,kCAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,YAEKC,kCAAA,KAAAI,4BAAA,EAAA,UAAA;AAAA,QAAA;AAAA,QACDL,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAY,YAAY,kBAAkB;AAAA,YAC1C,WAAU;AAAA,YACV,SAAS;AAAA,YACT,MAAK;AAAA,YAEJ,UAAA,kDACE,eAAc,EAAA,WAAU,UAAS,IAElCA,kCAAA,IAAC,SAAQ,EAAA,WAAU,SAAS,CAAA;AAAA,UAAA;AAAA,QAEhC;AAAA,MAAA,GACF;AAAA,MAEF,MAAM,YAAY,SAAS;AAAA,MAC1B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;ACrBA,MAAM,iBAAiB,UAAsB,OAAO;AAAA,EAClD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AAGM,SAAS,WACd,OACA;AACA,QAAM,SACJ,MAAM,SAAS,WACX,CAAC,QAAa;AACZ,UAAM,IAAI,OAAO,OAAO,EAAE,EAAE,KAAK;AACjC,QAAI,MAAM;AAAW,aAAA;AACf,UAAA,IAAI,OAAO,CAAC;AAClB,WAAO,OAAO,MAAM,CAAC,IAAI,MAAM;AAAA,EAEjC,IAAA;AACN,SAAQA,kCAAAA,IAAA,gBAAA,EAAe,QAAiB,GAAG,MAAO,CAAA;AACpD;AAEa,MAAA,gBAAgB,UAAyB,UAAU;AAAA,EAC9D,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AACY,MAAA,cAAc,UAAuB,QAAQ;AAAA,EACxD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AACM,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA,EAAE,aAAa,UAAU,gBAAgB,GAAG;AAC9C;AACa,MAAA,cAAc,UAAuB,QAAQ;AAAA,EACxD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AACY,MAAA,gBAAgB,UAAyB,UAAU;AAAA,EAC9D,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AACY,MAAA,gBAAgB,UAAyB,UAAU;AAAA,EAC9D,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AACY,MAAA,aAAa,UAA2B,YAAY;AAAA,EAC/D,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AAOe,SAAA,QACd,WACA,SACA;AACA,QAAM,iBACJ,WAAW,kBAAkB,UACzB,QAAQ,gBACR,mCAAS,mBAAkB;AACjC,SAAO,UAAa,WAAW;AAAA,IAC7B;AAAA,IACA,aAAa,mCAAS;AAAA,EAAA,CACvB;AACH;ACxEO,SAAS,YAAY,OAA+C;AACzE,QAAM,eAAe;AACrB,QAAM,SAAS,cAAc,cAAc,MAAM,IAAI;AACrD,+CACG,uBAAuB,UAAvB,EAAgC,OAAO,QACrC,gBAAM,SACT,CAAA;AAEJ;ACRA,SAAS,UAAU,KAAU,MAAmB;AAC9C,MAAI,CAAC;AAAa,WAAA;AAClB,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,KAAK,QAAS,OAAO,OAAO,MAAM,IAAI,GAAG,GAAI,GAAG;AACjF;AAGO,SAAS,gBAA4B;AACpC,QAAA,EAAE,SAAS;AACjB,SAAO,SAAS,KAAK,OAAO,CAAC,MAAW,EAAE,MAAM;AAClD;AAGO,MAAM,eAAe;AAGrB,SAAS,cAAuB,MAAiB;AAChD,QAAA,EAAE,SAAS;AACjB,QAAM,SAAS;AACT,QAAA,OAAO,cAAc,QAAQ,IAAI;AAChC,SAAA,SAAS,KAAK,OAAO,CAAC,MAAW,UAAU,EAAE,QAAQ,IAAI,CAAC;AACnE;AAOO,SAAS,kBAGd;AACM,QAAA,EAAE,SAAS;AACjB,QAAM,iBAAiB,SAAS,KAAK,OAAO,CAAC,MAAW,EAAE,cAAc;AACxE,QAAM,cAAc;AAAA,IAClB,CAAC,MAAe;AACd,UAAI,CAAC,GAAG;AAIN,mBAAW,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,IACA,CAAC,IAAI;AAAA,EAAA;AAEP,SAAO,EAAE,UAAU,CAAC,gBAAgB,YAAY;AAClD;AAMA,eAAsB,aACpB,MACoC;AAC9B,QAAA,KAAK,kBAAkB,QAAQ;AAC9B,SAAA,EAAE,IAAI,CAAC,CAAC,KAAK,MAAM,SAAS,OAAO,KAAK,MAAM;AACvD;AAMO,SAAS,mBAAmB;AAC3B,QAAA,EAAE,SAAS;AACjB,QAAM,SAAS;AACR,SAAA,CAAC,MAAc,UACpB,KAAK,cAAc,cAAc,QAAQ,IAAI,GAAG,KAAK;AACzD;","x_google_ignoreList":[1,2,3]}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * 字段校验(提交/输入时执行)。
3
+ *
4
+ * 支持两条写法:
5
+ * 1) 新写法(对齐 deepclaw):`required`(bool/文案)+ `zodSchema`(任何带 safeParse 的 schema,可选)。
6
+ * 2) 旧兼容写法(fieldy 遗留):`validateSchema={{ type, required, rules: { max/min/email/url } }}`。
7
+ *
8
+ * validator 统一是「值 → 错误消息 | undefined」的纯函数,挂到 TanStack Field 的
9
+ * validators.onChange + onSubmit 上(错误随 field.state.meta.errors 展示;输对即时消错)。
10
+ */
11
+ /** 任意带 safeParse 的 schema(如 zod)——避免硬依赖 zod 包,用结构类型描述。 */
12
+ export interface SafeParseSchema {
13
+ safeParse: (v: unknown) => {
14
+ success: boolean;
15
+ error?: {
16
+ issues?: Array<{
17
+ message?: string;
18
+ }>;
19
+ };
20
+ };
21
+ }
22
+ /** fieldy 遗留的 validateSchema 形状(仅覆盖仓库实际用到的键)。 */
23
+ export interface LegacyValidateSchema {
24
+ type?: string;
25
+ required?: boolean | string;
26
+ rules?: {
27
+ max?: {
28
+ value: number;
29
+ message?: string;
30
+ };
31
+ min?: {
32
+ value: number;
33
+ message?: string;
34
+ };
35
+ email?: boolean | {
36
+ message?: string;
37
+ };
38
+ url?: boolean | {
39
+ message?: string;
40
+ };
41
+ };
42
+ }
43
+ export interface FieldValidateProps {
44
+ /** 必填(true 用默认文案,或直接传消息文案)。 */
45
+ required?: boolean | string;
46
+ /** schema 校验(如 z.string().email(...))。空值时跳过(配合 required 用)。 */
47
+ zodSchema?: SafeParseSchema;
48
+ /** 旧版 fieldy 校验声明(兼容层,逐步淘汰)。 */
49
+ validateSchema?: LegacyValidateSchema;
50
+ }
51
+ /** 组装 TanStack Field validators;无校验需求返回 undefined(零开销)。 */
52
+ export declare function buildFieldValidators(props: FieldValidateProps, label?: string): {
53
+ onChange: ({ value }: {
54
+ value: any;
55
+ }) => string | undefined;
56
+ onSubmit: ({ value }: {
57
+ value: any;
58
+ }) => string | undefined;
59
+ } | undefined;
60
+ /** 从 field.state.meta.errors 取首条可展示消息(string 或 {message} 兼容)。 */
61
+ export declare function firstErrorMessage(errors: unknown[] | undefined): string | undefined;
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@rxdrag/form",
3
+ "version": "0.1.0",
4
+ "module": "dist/index.mjs",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "devDependencies": {
12
+ "@types/react": "^19.1.0",
13
+ "@types/react-dom": "^19.1.0",
14
+ "eslint": "^9.39.2",
15
+ "react": "^19.1.0",
16
+ "react-dom": "^19.1.0",
17
+ "typescript": "^5",
18
+ "@rxdrag/tsconfig": "0.3.0",
19
+ "@rxdrag/eslint-config-custom": "0.3.0"
20
+ },
21
+ "peerDependencies": {
22
+ "react": "^19.1.0",
23
+ "react-dom": "^19.1.0"
24
+ },
25
+ "dependencies": {
26
+ "@tanstack/react-form": "^1.23.6",
27
+ "@rxdrag/shadcn": "0.2.0",
28
+ "@rxdrag/rxcms-common": "0.3.0"
29
+ },
30
+ "scripts": {
31
+ "lint": "eslint . --ext .ts,tsx",
32
+ "clean": "rimraf -rf .turbo && rimraf -rf node_modules && rimraf -rf dist",
33
+ "build": "vite build"
34
+ },
35
+ "typings": "dist/index.d.ts"
36
+ }