@fairys/valtio-form-basic 0.0.12 → 0.0.13

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 (48) hide show
  1. package/esm/{form → common}/hooks/index.d.ts +1 -0
  2. package/esm/{form → common}/hooks/index.js +9 -1
  3. package/esm/common/index.d.ts +4 -0
  4. package/esm/common/index.js +4 -0
  5. package/esm/{form → common}/instance/index.d.ts +9 -2
  6. package/esm/{form → common}/instance/index.js +19 -5
  7. package/esm/{form → common}/utils/index.d.ts +1 -0
  8. package/esm/{form → common}/utils/index.js +2 -1
  9. package/esm/form/form.d.ts +7 -7
  10. package/esm/form/form.item.d.ts +10 -3
  11. package/esm/form/form.item.js +50 -32
  12. package/esm/form/form.js +5 -3
  13. package/esm/form/layout.d.ts +4 -2591
  14. package/esm/form/layout.js +7 -4
  15. package/esm/index.d.ts +1 -2
  16. package/esm/index.js +1 -2
  17. package/esm/styles/index.css +20 -4
  18. package/lib/common/hooks/index.d.ts +35 -0
  19. package/lib/common/hooks/index.js +117 -0
  20. package/lib/common/index.d.ts +4 -0
  21. package/lib/common/index.js +87 -0
  22. package/lib/common/instance/index.d.ts +88 -0
  23. package/lib/common/instance/index.js +243 -0
  24. package/lib/common/interface.d.ts +4 -0
  25. package/lib/common/interface.js +18 -0
  26. package/lib/common/utils/index.d.ts +25 -0
  27. package/lib/common/utils/index.js +107 -0
  28. package/lib/form/form.d.ts +76 -0
  29. package/lib/form/form.item.d.ts +224 -0
  30. package/lib/form/form.item.js +321 -0
  31. package/lib/form/form.js +53 -0
  32. package/lib/form/layout.d.ts +153 -0
  33. package/lib/form/layout.js +196 -0
  34. package/lib/index.d.ts +4 -0
  35. package/lib/index.js +18 -27
  36. package/lib/styles/index.css +308 -0
  37. package/package.json +5 -5
  38. package/src/{form → common}/hooks/index.tsx +9 -1
  39. package/src/common/index.ts +4 -0
  40. package/src/{form → common}/instance/index.ts +51 -13
  41. package/src/{form → common}/utils/index.ts +2 -0
  42. package/src/form/form.item.tsx +59 -36
  43. package/src/form/form.tsx +12 -7
  44. package/src/form/layout.tsx +9 -3
  45. package/src/index.tsx +4 -5
  46. /package/esm/{interface.d.ts → common/interface.d.ts} +0 -0
  47. /package/esm/{interface.js → common/interface.js} +0 -0
  48. /package/src/{interface.ts → common/interface.ts} +0 -0
@@ -32,3 +32,4 @@ export declare const useFairysValtioFormAttrsName: (options?: FairysValtioFormAt
32
32
  name: string;
33
33
  paths: (number | symbol)[] | (string | number)[];
34
34
  };
35
+ export declare const useId: (suffix?: string) => string;
@@ -54,4 +54,12 @@ const useFairysValtioFormAttrsName = (options = {})=>{
54
54
  paths: _paths
55
55
  };
56
56
  };
57
- export { FairysValtioFormParentAttrs, FairysValtioFormParentAttrsContext, useFairysValtioFormAttrsName, useFairysValtioFormParentAttrs, useFairysValtioFormParentAttrsContext, useFairysValtioFormParentAttrsState };
57
+ let localId = 0;
58
+ const useId = (suffix = 'form-item-input')=>{
59
+ const count = useRef(localId++);
60
+ return useMemo(()=>`fairys-valtio-form_${count.current.toString(32)}_${suffix}`, [
61
+ count.current,
62
+ suffix
63
+ ]);
64
+ };
65
+ export { FairysValtioFormParentAttrs, FairysValtioFormParentAttrsContext, useFairysValtioFormAttrsName, useFairysValtioFormParentAttrs, useFairysValtioFormParentAttrsContext, useFairysValtioFormParentAttrsState, useId };
@@ -0,0 +1,4 @@
1
+ export * from './hooks';
2
+ export * from './instance';
3
+ export * from './utils';
4
+ export * from './interface';
@@ -0,0 +1,4 @@
1
+ export * from "./hooks/index.js";
2
+ export * from "./instance/index.js";
3
+ export * from "./utils/index.js";
4
+ export * from "./interface.js";
@@ -1,7 +1,14 @@
1
- import { MObject } from '../../interface';
1
+ import { MObject } from '../interface';
2
2
  import { RuleItem, ValidateFieldsError, Values } from 'async-validator';
3
+ import { FairysValtioFormAttrsProps } from '../../form/form';
3
4
  /**表单实例*/
4
5
  export declare class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>> {
6
+ /***
7
+ * 判断值是否为代理对象
8
+ * @param value 值
9
+ * @returns 是否为代理对象
10
+ */
11
+ isValtioProxy: (value: any) => boolean;
5
12
  /**状态*/
6
13
  state: T;
7
14
  /**
@@ -14,7 +21,7 @@ export declare class FairysValtioFormInstance<T extends MObject<T> = Record<stri
14
21
  ctor: (options?: {
15
22
  formData?: Partial<T>;
16
23
  hideState?: Record<PropertyKey, boolean>;
17
- initFormDataType?: "deepCopy" | "proxy" | "immutable";
24
+ initFormDataType?: FairysValtioFormAttrsProps["initFormDataType"];
18
25
  }) => void;
19
26
  /**
20
27
  * 更新数据
@@ -1,19 +1,30 @@
1
1
  import { createContext, useContext, useRef } from "react";
2
- import { proxy, ref as external_valtio_ref, snapshot, useSnapshot } from "valtio";
2
+ import { proxy, ref as external_valtio_ref, snapshot, unstable_getInternalStates, useSnapshot } from "valtio";
3
3
  import async_validator from "async-validator";
4
4
  import { copy } from "fast-copy";
5
- import { formatePath, get, set } from "../utils/index.js";
5
+ import { formatePath, get, isObject, set } from "../utils/index.js";
6
6
  class FairysValtioFormInstance {
7
+ isValtioProxy = (value)=>{
8
+ const { refSet } = unstable_getInternalStates();
9
+ const canProxyDefault = (x)=>isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer) && !(x instanceof Promise);
10
+ return canProxyDefault(value);
11
+ };
7
12
  state = proxy({});
8
13
  errorState = proxy({});
9
14
  hideState = proxy({});
10
15
  ctor = (options)=>{
11
16
  const { formData, hideState, initFormDataType = 'deepCopy' } = options || {};
17
+ this.mountRules = {};
18
+ this.nameToPaths = {};
12
19
  this.errorState = proxy({});
13
20
  this.hideState = proxy(hideState ? copy(hideState) : {});
14
- if ('deepCopy' === initFormDataType) this.state = proxy(formData ? copy(formData) : {});
15
- else if ('proxy' === initFormDataType) this.state = proxy(formData);
16
- else if ('immutable' === initFormDataType) this.state = formData;
21
+ const isValtioProxy = this.isValtioProxy(formData);
22
+ if (isValtioProxy) if ('deepCopy' === initFormDataType) this.state = proxy(copy(snapshot(formData)));
23
+ else this.state = formData;
24
+ else {
25
+ if ('deepCopy' === initFormDataType) this.state = proxy(copy(formData || {}));
26
+ this.state = proxy(formData || {});
27
+ }
17
28
  };
18
29
  updated = (state, isValidate = true)=>{
19
30
  const keys = Object.keys(state);
@@ -67,6 +78,9 @@ class FairysValtioFormInstance {
67
78
  this.state = proxy({});
68
79
  this.errorState = proxy({});
69
80
  this.hideState = proxy({});
81
+ this.mountRules = {};
82
+ this.rules = {};
83
+ this.nameToPaths = {};
70
84
  };
71
85
  mountRules = {};
72
86
  removeRules = (name)=>{
@@ -22,3 +22,4 @@ export declare function get<TDefault = unknown>(value: any, segments: PropertyKe
22
22
  export declare function formatePath(path: PropertyKey): (number | symbol)[] | (string | number)[];
23
23
  /**格式化属性名*/
24
24
  export declare function formateName(name?: string, parentName?: string): string;
25
+ export declare const isObject: (x: unknown) => x is object;
@@ -57,4 +57,5 @@ function formateName(name, parentName) {
57
57
  if (name) return name;
58
58
  return '';
59
59
  }
60
- export { formateName, formatePath, get, set };
60
+ const isObject = (x)=>'object' == typeof x && null !== x;
61
+ export { formateName, formatePath, get, isObject, set };
@@ -1,5 +1,5 @@
1
- import { MObject } from '../interface';
2
- import { FairysValtioFormInstance } from './instance';
1
+ import { MObject } from '../common/interface';
2
+ import { FairysValtioFormInstance } from '../common/instance';
3
3
  import { type ReactNode } from 'react';
4
4
  import { FairysValtioFormLayoutAttrsProps } from './layout';
5
5
  import { RuleItem } from 'async-validator';
@@ -17,10 +17,9 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
17
17
  /**
18
18
  * 初始化表单数据类型,默认值为 deepCopy
19
19
  * - deepCopy:使用深度拷贝初始化表单数据
20
- * - proxy:使用代理对象初始化表单数据
21
- * - immutable:直接使用对象,不进行任何处理,注意,这个使用必须是`valtio`中的`proxy`声明的对象数据,否则表单项更新数据不会同步
20
+ * - immutable:直接使用对象(注意:当传递的不是`valtio`的`proxy`对象时,会使用`valtio`中的`proxy`声明)
22
21
  */
23
- initFormDataType?: 'deepCopy' | 'proxy' | 'immutable';
22
+ initFormDataType?: 'deepCopy' | 'immutable';
24
23
  }
25
24
  /**
26
25
  * 表单属性处理
@@ -42,7 +41,7 @@ export const Form = (props: FormProps) => {
42
41
  }
43
42
  * ```
44
43
  */
45
- export declare function useFairysValtioForm<T extends MObject<T> = object>(props: FairysValtioFormAttrsProps<T>): {
44
+ export declare function useFairysValtioForm<T extends MObject<T> = object>(props: FairysValtioFormAttrsProps<T>, ref: React.Ref<FairysValtioFormInstance<T>>): {
46
45
  formInstance: FairysValtioFormInstance<T>;
47
46
  /**子元素*/
48
47
  children: ReactNode;
@@ -59,6 +58,7 @@ export declare function useFairysValtioForm<T extends MObject<T> = object>(props
59
58
  bordered?: boolean;
60
59
  boxShadow?: boolean;
61
60
  lastItemBordered?: boolean;
61
+ platform?: "pc" | "rn" | "taro";
62
62
  colCount?: number;
63
63
  errorLayout?: "bottom-left" | "bottom-right" | "top-right" | "top-left" | "left-border-top" | "right-border-top";
64
64
  labelMode?: "left" | "top" | "between";
@@ -68,7 +68,7 @@ export declare function useFairysValtioForm<T extends MObject<T> = object>(props
68
68
  formItemLabelStyle?: React.CSSProperties;
69
69
  formItemBodyClassName?: string;
70
70
  formItemBodyStyle?: React.CSSProperties;
71
- itemBorderType?: "bottom" | "body";
71
+ itemBorderType?: "bottom" | "body" | "none";
72
72
  itemBorderColor?: React.CSSProperties["borderColor"];
73
73
  isInvalidBorderRed?: boolean;
74
74
  isInvalidTextRed?: boolean;
@@ -1,11 +1,13 @@
1
1
  /**表单项*/
2
- import { MObject } from '../interface';
2
+ import { MObject } from '../common/interface';
3
3
  import React from 'react';
4
- import { FairysValtioFormInstance } from './instance';
4
+ import { FairysValtioFormInstance } from '../common/instance';
5
5
  import { FairysValtioFormLayoutContextOptions } from './layout';
6
- import { FairysValtioFormParentAttrs } from './hooks';
6
+ import { FairysValtioFormParentAttrs } from '../common/hooks';
7
7
  import { RuleItem } from 'async-validator';
8
8
  export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
9
+ /**平台*/
10
+ platform?: 'pc' | 'rn' | 'taro';
9
11
  /**
10
12
  * 表单项名称 ,字段需要和存储的字段路径一致
11
13
  *
@@ -22,6 +24,8 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
22
24
  label?: string;
23
25
  /**传递组件字段*/
24
26
  valuePropName?: string;
27
+ /**取值字段(默认 valuePropName字段值)*/
28
+ getValuePath?: string;
25
29
  /**自定义获取值*/
26
30
  getValueFromEvent?: (event: any, form: FairysValtioFormInstance<T>) => any;
27
31
  /**值格式化*/
@@ -151,6 +155,8 @@ export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = object>
151
155
  _name?: string;
152
156
  /**表单项名称*/
153
157
  name?: string;
158
+ /**表单项ID*/
159
+ id?: string;
154
160
  /**表单项路径*/
155
161
  paths?: (string | number)[];
156
162
  /**父级字段名*/
@@ -210,6 +216,7 @@ export declare function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T>
210
216
  formInstance: FairysValtioFormInstance<T>;
211
217
  _name: string;
212
218
  name: string;
219
+ id: string;
213
220
  paths: (number | symbol)[] | (string | number)[];
214
221
  parentName: string;
215
222
  formAttrsNameInstance: FairysValtioFormParentAttrs;
@@ -1,9 +1,9 @@
1
1
  import react, { useEffect, useMemo } from "react";
2
2
  import clsx from "clsx";
3
- import { useFairysValtioFormInstanceContextState } from "./instance/index.js";
3
+ import { useFairysValtioFormInstanceContextState } from "../common/instance/index.js";
4
4
  import { useFairysValtioFormLayoutContext } from "./layout.js";
5
- import { useFairysValtioFormAttrsName } from "./hooks/index.js";
6
- import { get } from "./utils/index.js";
5
+ import { useFairysValtioFormAttrsName, useId } from "../common/hooks/index.js";
6
+ import { formatePath, get } from "../common/utils/index.js";
7
7
  function useFairysValtioFormItemAttrs(props) {
8
8
  const [layoutAttrs] = useFairysValtioFormLayoutContext();
9
9
  const colCount = layoutAttrs.colCount || 1;
@@ -20,7 +20,8 @@ function useFairysValtioFormItemAttrs(props) {
20
20
  const parent_isInvalidBorderRed = layoutAttrs.isInvalidBorderRed;
21
21
  const parent_isInvalidTextRed = layoutAttrs.isInvalidTextRed;
22
22
  const parent_showColon = layoutAttrs.showColon;
23
- const { name, valuePropName = 'value', getValueFromEvent, formatValue, onAfterUpdate, trigger = 'onChange', className, style, labelClassName, labelStyle, bodyClassName, bodyStyle, children, labelMode = parent_labelMode, errorLayout = parent_errorLayout, colSpan = 1, rowSpan = 1, isRequired: _isRequired, itemBorderType = parent_borderedType, attrs = {}, showColon = parent_showColon, itemBorderColor = parent_itemBorderColor, isInvalidBorderRed = parent_isInvalidBorderRed, isInvalidTextRed = parent_isInvalidTextRed, isJoinParentField = true, rules } = props;
23
+ const parent_platform = layoutAttrs.platform;
24
+ const { name, valuePropName = 'value', getValuePath = valuePropName, getValueFromEvent, formatValue, onAfterUpdate, trigger = 'onChange', className, style, labelClassName, labelStyle, bodyClassName, bodyStyle, children, labelMode = parent_labelMode, errorLayout = parent_errorLayout, colSpan = 1, rowSpan = 1, isRequired: _isRequired, itemBorderType = parent_borderedType, attrs = {}, showColon = parent_showColon, itemBorderColor = parent_itemBorderColor, isInvalidBorderRed = parent_isInvalidBorderRed, isInvalidTextRed = parent_isInvalidTextRed, isJoinParentField = true, rules, platform = parent_platform } = props;
24
25
  const { name: _name, paths, parentName, formAttrsNameInstance } = useFairysValtioFormAttrsName({
25
26
  name,
26
27
  isJoinParentField
@@ -32,25 +33,31 @@ function useFairysValtioFormItemAttrs(props) {
32
33
  ]);
33
34
  const error = errorState[_name];
34
35
  const _formItemRules = formInstance.rules?.[_name];
36
+ const id = useId(_name);
35
37
  formInstance.nameToPaths[_name] = paths;
36
- if (Array.isArray(rules) && rules.length) formInstance.mountRules[_name] = rules;
37
- useEffect(()=>()=>{
38
+ useEffect(()=>{
39
+ if (Array.isArray(rules) && rules.length) formInstance.mountRules[_name] = rules;
40
+ return ()=>{
38
41
  formInstance.removeRules(_name);
39
- }, [
40
- _name
42
+ };
43
+ }, [
44
+ _name,
45
+ rules
41
46
  ]);
42
47
  const onValueChange = (event)=>{
43
- let value = event;
48
+ let _value = event;
44
49
  const target = event?.detail || event?.target;
45
- if ('function' == typeof getValueFromEvent) value = getValueFromEvent(event, formInstance);
46
- else if (event && target && 'object' == typeof target && valuePropName in target) value = target.valuePropName;
47
- if ('function' == typeof formatValue) value = formatValue(value, formInstance, event);
48
- formInstance.updatedValueByPaths(_name, value);
49
- if ('function' == typeof onAfterUpdate) onAfterUpdate(value, formInstance, event);
50
+ if ('function' == typeof getValueFromEvent) _value = getValueFromEvent(event, formInstance);
51
+ else if (event && target && 'object' == typeof target && getValuePath in target) _value = get(target, formatePath(getValuePath));
52
+ if ('function' == typeof formatValue) _value = formatValue(_value, formInstance, event);
53
+ if (value === _value) return;
54
+ formInstance.updatedValueByPaths(_name, _value);
55
+ if ('function' == typeof onAfterUpdate) onAfterUpdate(_value, formInstance, event);
50
56
  };
51
57
  const baseControl = {
52
58
  ...attrs,
53
59
  name,
60
+ id,
54
61
  [valuePropName]: value,
55
62
  [trigger]: onValueChange
56
63
  };
@@ -104,10 +111,9 @@ function useFairysValtioFormItemAttrs(props) {
104
111
  isRequired,
105
112
  showColon
106
113
  ]);
107
- const itemBody_cls = useMemo(()=>clsx('fairys-valtio-form-item-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border', {
114
+ const itemBody_cls = useMemo(()=>clsx('fairys-valtio-form-item-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border fairystaroform__items-start', {
108
115
  'fairystaroform__flex-row fairystaroform__justify-start': 'left' === labelMode,
109
116
  'fairystaroform__flex-row fairystaroform__justify-end': 'between' === labelMode || 'top' === labelMode,
110
- 'fairystaroform__flex-row': 'top' === labelMode,
111
117
  'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 ': 'body' === itemBorderType,
112
118
  'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && 'body' === itemBorderType
113
119
  }, parent_formItemBodyClassName, bodyClassName), [
@@ -127,14 +133,18 @@ function useFairysValtioFormItemAttrs(props) {
127
133
  const itemExtra_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-extra fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__box-border fairystaroform__flex fairystaroform__items-center fairystaroform__justify-center'), []);
128
134
  const itemHelp_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-help fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-_zkh1_10px_zhk2_ fairystaroform__w-full fairystaroform__box-border'), []);
129
135
  const itemError_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-error fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__w-full fairystaroform__flex fairystaroform__flex-row fairystaroform__box-border fairystaroform__text-red fairystaroform__absolute fairystaroform__text-_zkh1_10px_zhk2_ fairystaroform__z-10', {
130
- 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'bottom-left' === errorLayout,
131
- 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'bottom-right' === errorLayout,
136
+ 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'bottom-left' === errorLayout && 'pc' !== platform,
137
+ 'fairystaroform__bottom-_zkh1_-10px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'bottom-left' === errorLayout && 'pc' === platform,
138
+ 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'bottom-right' === errorLayout && 'pc' !== platform,
139
+ 'fairystaroform__bottom-_zkh1_-10px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'bottom-right' === errorLayout && 'pc' === platform,
132
140
  'fairystaroform__top-_zkh1_-4px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'top-right' === errorLayout,
133
141
  'fairystaroform__top-_zkh1_-4px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'top-left' === errorLayout,
134
- 'fairystaroform__left-0 fairystaroform__bottom-_zkh1_-2px_zhk2_ fairystaroform__justify-start': 'left-border-top' === errorLayout,
135
- 'fairystaroform__right-0 fairystaroform__bottom-_zkh1_-2px_zhk2_ fairystaroform__justify-end': 'right-border-top' === errorLayout
142
+ 'fairystaroform__left-0 fairystaroform__bottom-_zkh1_-2px_zhk2_ fairystaroform__justify-start': 'left-border-top' === errorLayout,
143
+ 'fairystaroform__right-0 fairystaroform__bottom-_zkh1_-2px_zhk2_ fairystaroform__justify-end': 'right-border-top' === errorLayout,
144
+ 'fairystaroform__px-_zkh1_4px_zhk2_': 'pc' === platform
136
145
  }), [
137
- errorLayout
146
+ errorLayout,
147
+ platform
138
148
  ]);
139
149
  const styleBase = useMemo(()=>{
140
150
  const css = {};
@@ -166,6 +176,7 @@ function useFairysValtioFormItemAttrs(props) {
166
176
  error,
167
177
  _name,
168
178
  name,
179
+ id,
169
180
  paths,
170
181
  parentName,
171
182
  formAttrsNameInstance,
@@ -202,36 +213,42 @@ function useFairysValtioFormItemAttrs(props) {
202
213
  };
203
214
  }
204
215
  function useFairysValtioFormItemNoStyleAttrs(props) {
205
- const { name, valuePropName = 'value', getValueFromEvent, formatValue, onAfterUpdate, trigger = 'onChange', children, attrs = {}, isJoinParentField = true, rules } = props;
216
+ const { name, valuePropName = 'value', getValuePath = valuePropName, getValueFromEvent, formatValue, onAfterUpdate, trigger = 'onChange', children, attrs = {}, isJoinParentField = true, rules } = props;
206
217
  const [state, errorState, formInstance] = useFairysValtioFormInstanceContextState();
207
218
  const { name: _name, paths, parentName, formAttrsNameInstance } = useFairysValtioFormAttrsName({
208
219
  name,
209
220
  isJoinParentField
210
221
  });
222
+ const id = useId(_name);
211
223
  const value = useMemo(()=>get(state, paths), [
212
224
  state,
213
225
  paths
214
226
  ]);
215
227
  const error = errorState[_name];
216
228
  formInstance.nameToPaths[_name] = paths;
217
- if (Array.isArray(rules) && rules.length) formInstance.mountRules[_name] = rules;
218
- useEffect(()=>()=>{
229
+ useEffect(()=>{
230
+ if (Array.isArray(rules) && rules.length) formInstance.mountRules[_name] = rules;
231
+ return ()=>{
219
232
  formInstance.removeRules(_name);
220
- }, [
221
- _name
233
+ };
234
+ }, [
235
+ _name,
236
+ rules
222
237
  ]);
223
238
  const onValueChange = (event)=>{
224
- let value = event;
239
+ let _value = event;
225
240
  const target = event?.detail || event?.target;
226
- if ('function' == typeof getValueFromEvent) value = getValueFromEvent(event, formInstance);
227
- else if (event && target && 'object' == typeof target && valuePropName in target) value = target.valuePropName;
228
- if ('function' == typeof formatValue) value = formatValue(value, formInstance, event);
229
- formInstance.updatedValueByPaths(_name, value);
230
- if ('function' == typeof onAfterUpdate) onAfterUpdate(value, formInstance, event);
241
+ if ('function' == typeof getValueFromEvent) _value = getValueFromEvent(event, formInstance);
242
+ else if (event && target && 'object' == typeof target && getValuePath in target) _value = get(target, formatePath(getValuePath));
243
+ if ('function' == typeof formatValue) _value = formatValue(_value, formInstance, event);
244
+ if (value === _value) return;
245
+ formInstance.updatedValueByPaths(_name, _value);
246
+ if ('function' == typeof onAfterUpdate) onAfterUpdate(_value, formInstance, event);
231
247
  };
232
248
  const baseControl = {
233
249
  ...attrs,
234
250
  name,
251
+ id,
235
252
  [valuePropName]: value,
236
253
  [trigger]: onValueChange
237
254
  };
@@ -244,6 +261,7 @@ function useFairysValtioFormItemNoStyleAttrs(props) {
244
261
  formInstance,
245
262
  _name,
246
263
  name,
264
+ id,
247
265
  paths,
248
266
  parentName,
249
267
  formAttrsNameInstance,
package/esm/form/form.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useFairysValtioFormInstance } from "./instance/index.js";
2
- import { useMemo } from "react";
3
- function useFairysValtioForm(props) {
1
+ import { useFairysValtioFormInstance } from "../common/instance/index.js";
2
+ import { useEffect, useImperativeHandle, useMemo } from "react";
3
+ function useFairysValtioForm(props, ref) {
4
4
  const { form, rules, formData, hideState, initFormDataType = 'deepCopy', ...rest } = props;
5
5
  const formInstance = useFairysValtioFormInstance(form);
6
6
  formInstance.rules = rules;
@@ -9,6 +9,8 @@ function useFairysValtioForm(props) {
9
9
  hideState,
10
10
  initFormDataType
11
11
  }), []);
12
+ useImperativeHandle(ref, ()=>formInstance);
13
+ useEffect(()=>()=>formInstance.clear(), []);
12
14
  return {
13
15
  ...rest,
14
16
  formInstance