@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
@@ -1,15 +1,17 @@
1
1
  /**表单项*/
2
2
 
3
- import { MObject } from 'interface';
3
+ import { MObject } from 'common/interface';
4
4
  import React, { useEffect, useMemo } from 'react';
5
5
  import clsx from 'clsx';
6
- import { useFairysValtioFormInstanceContextState, FairysValtioFormInstance } from './instance';
6
+ import { useFairysValtioFormInstanceContextState, FairysValtioFormInstance } from 'common/instance';
7
7
  import { useFairysValtioFormLayoutContext, FairysValtioFormLayoutContextOptions } from './layout';
8
- import { FairysValtioFormParentAttrs, useFairysValtioFormAttrsName } from './hooks';
9
- import { get } from './utils';
8
+ import { FairysValtioFormParentAttrs, useFairysValtioFormAttrsName, useId } from 'common/hooks';
9
+ import { formatePath, get } from 'common/utils';
10
10
  import { RuleItem } from 'async-validator';
11
11
 
12
12
  export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
13
+ /**平台*/
14
+ platform?: 'pc' | 'rn' | 'taro';
13
15
  /**
14
16
  * 表单项名称 ,字段需要和存储的字段路径一致
15
17
  *
@@ -26,6 +28,8 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
26
28
  label?: string;
27
29
  /**传递组件字段*/
28
30
  valuePropName?: string;
31
+ /**取值字段(默认 valuePropName字段值)*/
32
+ getValuePath?: string;
29
33
  /**自定义获取值*/
30
34
  getValueFromEvent?: (event: any, form: FairysValtioFormInstance<T>) => any;
31
35
  /**值格式化*/
@@ -138,10 +142,12 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
138
142
  const parent_isInvalidBorderRed = layoutAttrs.isInvalidBorderRed;
139
143
  const parent_isInvalidTextRed = layoutAttrs.isInvalidTextRed;
140
144
  const parent_showColon = layoutAttrs.showColon;
145
+ const parent_platform = layoutAttrs.platform;
141
146
 
142
147
  const {
143
148
  name,
144
149
  valuePropName = 'value',
150
+ getValuePath = valuePropName,
145
151
  getValueFromEvent,
146
152
  formatValue,
147
153
  onAfterUpdate,
@@ -166,6 +172,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
166
172
  isInvalidTextRed = parent_isInvalidTextRed,
167
173
  isJoinParentField = true,
168
174
  rules,
175
+ platform = parent_platform,
169
176
  } = props;
170
177
 
171
178
  const {
@@ -179,32 +186,34 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
179
186
  const error = errorState[_name];
180
187
  // 使用从 Form 中设置的规则
181
188
  const _formItemRules = formInstance.rules?.[_name];
182
-
189
+ const id = useId(_name);
183
190
  formInstance.nameToPaths[_name] = paths;
184
- /**挂载校验规则*/
185
- if (Array.isArray(rules) && rules.length) {
186
- formInstance.mountRules[_name] = rules;
187
- }
188
191
  useEffect(() => {
192
+ if (Array.isArray(rules) && rules.length) {
193
+ formInstance.mountRules[_name] = rules;
194
+ }
189
195
  return () => {
190
196
  formInstance.removeRules(_name);
191
197
  };
192
- }, [_name]);
198
+ }, [_name, rules]);
193
199
 
194
200
  const onValueChange = (event: any) => {
195
- let value = event;
201
+ let _value = event;
196
202
  const target = event?.detail || event?.target;
197
203
  if (typeof getValueFromEvent === 'function') {
198
- value = getValueFromEvent(event, formInstance);
199
- } else if (event && target && typeof target === 'object' && valuePropName in target) {
200
- value = target.valuePropName;
204
+ _value = getValueFromEvent(event, formInstance);
205
+ } else if (event && target && typeof target === 'object' && getValuePath in target) {
206
+ _value = get(target, formatePath(getValuePath));
201
207
  }
202
208
  if (typeof formatValue === 'function') {
203
- value = formatValue(value, formInstance, event);
209
+ _value = formatValue(_value, formInstance, event);
204
210
  }
205
- formInstance.updatedValueByPaths(_name, value);
211
+ // 校验值是否有变化
212
+ if (value === _value) return;
213
+
214
+ formInstance.updatedValueByPaths(_name, _value);
206
215
  if (typeof onAfterUpdate === 'function') {
207
- onAfterUpdate(value, formInstance, event);
216
+ onAfterUpdate(_value, formInstance, event);
208
217
  }
209
218
  };
210
219
 
@@ -212,6 +221,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
212
221
  const baseControl = {
213
222
  ...attrs,
214
223
  name,
224
+ id,
215
225
  [valuePropName]: value,
216
226
  [trigger]: onValueChange,
217
227
  };
@@ -288,11 +298,10 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
288
298
  const itemBody_cls = useMemo(() => {
289
299
  // 默认两端显示
290
300
  return clsx(
291
- 'fairys-valtio-form-item-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border',
301
+ 'fairys-valtio-form-item-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border fairystaroform__items-start',
292
302
  {
293
303
  'fairystaroform__flex-row fairystaroform__justify-start': labelMode === 'left',
294
304
  'fairystaroform__flex-row fairystaroform__justify-end': labelMode === 'between' || labelMode === 'top',
295
- 'fairystaroform__flex-row': labelMode === 'top',
296
305
  'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 ':
297
306
  itemBorderType === 'body',
298
307
  'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && itemBorderType === 'body',
@@ -333,20 +342,25 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
333
342
  '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-[10px] fairystaroform__z-10',
334
343
  {
335
344
  'fairystaroform__bottom-[-14px] fairystaroform__left-0 fairystaroform__justify-start':
336
- errorLayout === 'bottom-left',
345
+ errorLayout === 'bottom-left' && platform !== 'pc',
346
+ 'fairystaroform__bottom-[-10px] fairystaroform__left-0 fairystaroform__justify-start':
347
+ errorLayout === 'bottom-left' && platform === 'pc',
337
348
  'fairystaroform__bottom-[-14px] fairystaroform__right-0 fairystaroform__justify-end':
338
- errorLayout === 'bottom-right',
349
+ errorLayout === 'bottom-right' && platform !== 'pc',
350
+ 'fairystaroform__bottom-[-10px] fairystaroform__right-0 fairystaroform__justify-end':
351
+ errorLayout === 'bottom-right' && platform === 'pc',
339
352
  'fairystaroform__top-[-4px] fairystaroform__right-0 fairystaroform__justify-end': errorLayout === 'top-right',
340
353
  'fairystaroform__top-[-4px] fairystaroform__left-0 fairystaroform__justify-start': errorLayout === 'top-left',
341
354
  /**边框底部提示*/
342
- 'fairystaroform__left-0 fairystaroform__bottom-[-2px] fairystaroform__justify-start':
355
+ 'fairystaroform__left-0 fairystaroform__bottom-[-2px] fairystaroform__justify-start':
343
356
  errorLayout === 'left-border-top',
344
357
  /**边框顶部提示*/
345
- 'fairystaroform__right-0 fairystaroform__bottom-[-2px] fairystaroform__justify-end':
358
+ 'fairystaroform__right-0 fairystaroform__bottom-[-2px] fairystaroform__justify-end':
346
359
  errorLayout === 'right-border-top',
360
+ 'fairystaroform__px-[4px]': platform === 'pc',
347
361
  },
348
362
  );
349
- }, [errorLayout]);
363
+ }, [errorLayout, platform]);
350
364
 
351
365
  const styleBase = useMemo(() => {
352
366
  const css: React.CSSProperties = {};
@@ -377,6 +391,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
377
391
  error,
378
392
  _name,
379
393
  name,
394
+ id,
380
395
  paths,
381
396
  parentName,
382
397
  formAttrsNameInstance,
@@ -438,6 +453,8 @@ export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = object>
438
453
  _name?: string;
439
454
  /**表单项名称*/
440
455
  name?: string;
456
+ /**表单项ID*/
457
+ id?: string;
441
458
  /**表单项路径*/
442
459
  paths?: (string | number)[];
443
460
  /**父级字段名*/
@@ -496,6 +513,7 @@ export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = objec
496
513
  const {
497
514
  name,
498
515
  valuePropName = 'value',
516
+ getValuePath = valuePropName,
499
517
  getValueFromEvent,
500
518
  formatValue,
501
519
  onAfterUpdate,
@@ -512,40 +530,44 @@ export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = objec
512
530
  parentName,
513
531
  formAttrsNameInstance,
514
532
  } = useFairysValtioFormAttrsName({ name, isJoinParentField });
533
+ const id = useId(_name);
515
534
  const value = useMemo(() => get(state, paths), [state, paths]);
516
535
  const error = errorState[_name];
517
536
  formInstance.nameToPaths[_name] = paths;
518
- /**挂载校验规则*/
519
- if (Array.isArray(rules) && rules.length) {
520
- formInstance.mountRules[_name] = rules;
521
- }
522
537
 
523
538
  useEffect(() => {
539
+ if (Array.isArray(rules) && rules.length) {
540
+ formInstance.mountRules[_name] = rules;
541
+ }
524
542
  return () => {
525
543
  formInstance.removeRules(_name);
526
544
  };
527
- }, [_name]);
545
+ }, [_name, rules]);
528
546
 
529
547
  const onValueChange = (event: any) => {
530
- let value = event;
548
+ let _value = event;
531
549
  const target = event?.detail || event?.target;
532
550
  if (typeof getValueFromEvent === 'function') {
533
- value = getValueFromEvent(event, formInstance);
534
- } else if (event && target && typeof target === 'object' && valuePropName in target) {
535
- value = target.valuePropName;
551
+ _value = getValueFromEvent(event, formInstance);
552
+ } else if (event && target && typeof target === 'object' && getValuePath in target) {
553
+ _value = get(target, formatePath(getValuePath));
536
554
  }
537
555
  if (typeof formatValue === 'function') {
538
- value = formatValue(value, formInstance, event);
556
+ _value = formatValue(_value, formInstance, event);
539
557
  }
540
- formInstance.updatedValueByPaths(_name, value);
558
+ // 校验值是否有变化
559
+ if (value === _value) return;
560
+
561
+ formInstance.updatedValueByPaths(_name, _value);
541
562
  if (typeof onAfterUpdate === 'function') {
542
- onAfterUpdate(value, formInstance, event);
563
+ onAfterUpdate(_value, formInstance, event);
543
564
  }
544
565
  };
545
566
  /**基础组件参数*/
546
567
  const baseControl = {
547
568
  ...attrs,
548
569
  name,
570
+ id,
549
571
  [valuePropName]: value,
550
572
  [trigger]: onValueChange,
551
573
  };
@@ -558,6 +580,7 @@ export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = objec
558
580
  formInstance,
559
581
  _name,
560
582
  name,
583
+ id,
561
584
  paths,
562
585
  parentName,
563
586
  formAttrsNameInstance,
package/src/form/form.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import { MObject } from 'interface';
2
- import { FairysValtioFormInstance, useFairysValtioFormInstance } from './instance';
3
- import { useMemo, type ReactNode } from 'react';
1
+ import { MObject } from 'common/interface';
2
+ import { FairysValtioFormInstance, useFairysValtioFormInstance } from 'common/instance';
3
+ import { useImperativeHandle, useMemo, type ReactNode, useEffect } from 'react';
4
4
  import { FairysValtioFormLayoutAttrsProps } from './layout';
5
5
  import { RuleItem } from 'async-validator';
6
6
 
@@ -18,10 +18,9 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
18
18
  /**
19
19
  * 初始化表单数据类型,默认值为 deepCopy
20
20
  * - deepCopy:使用深度拷贝初始化表单数据
21
- * - proxy:使用代理对象初始化表单数据
22
- * - immutable:直接使用对象,不进行任何处理,注意,这个使用必须是`valtio`中的`proxy`声明的对象数据,否则表单项更新数据不会同步
21
+ * - immutable:直接使用对象(注意:当传递的不是`valtio`的`proxy`对象时,会使用`valtio`中的`proxy`声明)
23
22
  */
24
- initFormDataType?: 'deepCopy' | 'proxy' | 'immutable';
23
+ initFormDataType?: 'deepCopy' | 'immutable';
25
24
  }
26
25
 
27
26
  /**
@@ -44,13 +43,19 @@ export const Form = (props: FormProps) => {
44
43
  }
45
44
  * ```
46
45
  */
47
- export function useFairysValtioForm<T extends MObject<T> = object>(props: FairysValtioFormAttrsProps<T>) {
46
+ export function useFairysValtioForm<T extends MObject<T> = object>(
47
+ props: FairysValtioFormAttrsProps<T>,
48
+ ref: React.Ref<FairysValtioFormInstance<T>>,
49
+ ) {
48
50
  const { form, rules, formData, hideState, initFormDataType = 'deepCopy', ...rest } = props;
49
51
  const formInstance = useFairysValtioFormInstance(form);
50
52
  /**表单规则*/
51
53
  formInstance.rules = rules;
52
54
  /**初始化表单值*/
53
55
  useMemo(() => formInstance.ctor({ formData, hideState, initFormDataType }), []);
56
+ useImperativeHandle(ref, () => formInstance);
57
+ /**卸载清空所有数据*/
58
+ useEffect(() => () => formInstance.clear(), []);
54
59
  return {
55
60
  ...rest,
56
61
  formInstance,
@@ -3,6 +3,8 @@ import clsx from 'clsx';
3
3
  import { proxy, useSnapshot } from 'valtio';
4
4
 
5
5
  export interface FairysValtioFormLayoutContextOptions {
6
+ /**平台*/
7
+ platform?: 'pc' | 'rn' | 'taro';
6
8
  /**列数据*/
7
9
  colCount?: number;
8
10
  /**规则校验失败错误提示位置*/
@@ -27,7 +29,7 @@ export interface FairysValtioFormLayoutContextOptions {
27
29
  /**
28
30
  * 底部边框类型
29
31
  */
30
- itemBorderType?: 'bottom' | 'body';
32
+ itemBorderType?: 'bottom' | 'body' | 'none';
31
33
  /**边框颜色*/
32
34
  itemBorderColor?: React.CSSProperties['borderColor'];
33
35
  /**是否校验失败时显示红色边框*/
@@ -104,7 +106,7 @@ export const FairysValtioFormLayoutContext = createContext<FairysValtioFormLayou
104
106
  export const useFairysValtioFormLayoutContext = () => {
105
107
  const instance = useContext(FairysValtioFormLayoutContext);
106
108
  const state = useSnapshot(instance.state);
107
- return [state, instance] as const;
109
+ return [state, instance] as [FairysValtioFormLayoutContextOptions, FairysValtioFormLayoutInstance];
108
110
  };
109
111
 
110
112
  /**
@@ -169,6 +171,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
169
171
  const parent_isInvalidBorderRed = state.isInvalidBorderRed;
170
172
  const parent_isInvalidTextRed = state.isInvalidTextRed;
171
173
  const parent_showColon = state.showColon;
174
+ const parent_platform = state.platform;
172
175
 
173
176
  const {
174
177
  colCount = parent_colCount,
@@ -186,6 +189,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
186
189
  isInvalidBorderRed = parent_isInvalidBorderRed,
187
190
  isInvalidTextRed = parent_isInvalidTextRed,
188
191
  showColon = parent_showColon,
192
+ platform = parent_platform,
189
193
  gap,
190
194
  isAllColSpan = false,
191
195
  className,
@@ -215,6 +219,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
215
219
  isInvalidBorderRed,
216
220
  isInvalidTextRed,
217
221
  showColon,
222
+ platform,
218
223
  }),
219
224
  [
220
225
  colCount,
@@ -231,6 +236,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
231
236
  isInvalidBorderRed,
232
237
  isInvalidTextRed,
233
238
  showColon,
239
+ platform,
234
240
  ],
235
241
  );
236
242
 
@@ -277,7 +283,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
277
283
 
278
284
  const body_base = useMemo(() => {
279
285
  return clsx(
280
- 'fairys-valtio-form-layout-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__gap-[2px] fairystaroform__box-border',
286
+ 'fairys-valtio-form-layout-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__box-border fairystaroform__pt-[8px] fairystaroform__pb-[12px] fairystaroform__gap-[6px]',
281
287
  bodyClassName,
282
288
  );
283
289
  }, [bodyClassName]);
package/src/index.tsx CHANGED
@@ -1,5 +1,4 @@
1
- export * from './form/hooks';
2
- export * from './form/instance';
3
- export * from './form/layout';
4
- export * from './form/form';
5
- export * from './form/form.item';
1
+ export * from 'common';
2
+ export * from 'form/layout';
3
+ export * from 'form/form';
4
+ export * from 'form/form.item';
File without changes
File without changes
File without changes