@fairys/valtio-form-basic 0.0.9 → 0.0.11

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.
@@ -8,7 +8,7 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
8
8
  form?: FairysValtioFormInstance<T>;
9
9
  /**子元素*/
10
10
  children: ReactNode;
11
- /**表单项规则*/
11
+ /**表单项规则(如果表单项没有指定规则,则使用全局规则,如果表单项指定规则,则使用表单项规则)*/
12
12
  rules?: Record<PropertyKey, RuleItem[]>;
13
13
  /**表单初始值*/
14
14
  formData?: FairysValtioFormInstance<T>['state'];
@@ -55,7 +55,7 @@ export declare function useFairysValtioForm<T extends MObject<T> = object>(props
55
55
  boxShadow?: boolean;
56
56
  lastItemBordered?: boolean;
57
57
  colCount?: number;
58
- errorLayout?: "left-bottom" | "right-bottom" | "top-right" | "top-left";
58
+ errorLayout?: "bottom-left" | "bottom-right" | "top-right" | "top-left" | "left-border-top" | "right-border-top";
59
59
  labelMode?: "left" | "top" | "between";
60
60
  formItemClassName?: string;
61
61
  formItemStyle?: React.CSSProperties;
@@ -66,5 +66,6 @@ export declare function useFairysValtioForm<T extends MObject<T> = object>(props
66
66
  itemBorderType?: "bottom" | "body";
67
67
  itemBorderColor?: React.CSSProperties["borderColor"];
68
68
  isInvalidBorderRed?: boolean;
69
+ isInvalidTextRed?: boolean;
69
70
  showColon?: boolean;
70
71
  };
@@ -38,9 +38,9 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
38
38
  bodyStyle?: React.CSSProperties;
39
39
  children?: React.ReactNode;
40
40
  /**规则校验失败错误提示位置*/
41
- errorLayout?: 'left-bottom' | 'right-bottom' | 'top-right' | 'top-left';
41
+ errorLayout?: FairysValtioFormLayoutContextOptions['errorLayout'];
42
42
  /**label显示模式*/
43
- labelMode?: 'left' | 'top' | 'between';
43
+ labelMode?: FairysValtioFormLayoutContextOptions['labelMode'];
44
44
  /**额外内容*/
45
45
  extra?: React.ReactNode;
46
46
  /**底部提示内容*/
@@ -65,6 +65,8 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
65
65
  itemBorderColor?: React.CSSProperties['borderColor'];
66
66
  /**是否校验失败时显示红色边框*/
67
67
  isInvalidBorderRed?: boolean;
68
+ /**是否校验失败时显示红色文本*/
69
+ isInvalidTextRed?: boolean;
68
70
  /**输入框属性*/
69
71
  attrs?: any;
70
72
  /**是否拼接父级字段名*/
@@ -8,7 +8,7 @@ function useFairysValtioFormItemAttrs(props) {
8
8
  const [layoutAttrs] = useFairysValtioFormLayoutContext();
9
9
  const colCount = layoutAttrs.colCount || 1;
10
10
  const parent_borderedType = layoutAttrs.itemBorderType || 'bottom';
11
- const parent_errorLayout = layoutAttrs.errorLayout || 'right-bottom';
11
+ const parent_errorLayout = layoutAttrs.errorLayout || 'bottom-right';
12
12
  const parent_formItemClassName = layoutAttrs.formItemClassName;
13
13
  const parent_formItemLabelClassName = layoutAttrs.formItemLabelClassName;
14
14
  const parent_formItemLabelStyle = layoutAttrs.formItemLabelStyle;
@@ -18,8 +18,9 @@ function useFairysValtioFormItemAttrs(props) {
18
18
  const parent_labelMode = layoutAttrs.labelMode || 'between';
19
19
  const parent_itemBorderColor = layoutAttrs.itemBorderColor;
20
20
  const parent_isInvalidBorderRed = layoutAttrs.isInvalidBorderRed;
21
+ const parent_isInvalidTextRed = layoutAttrs.isInvalidTextRed;
21
22
  const parent_showColon = layoutAttrs.showColon;
22
- 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, isJoinParentField = true, rules } = props;
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
24
  const { name: _name, paths, parentName, formAttrsNameInstance } = useFairysValtioFormAttrsName({
24
25
  name,
25
26
  isJoinParentField
@@ -30,6 +31,7 @@ function useFairysValtioFormItemAttrs(props) {
30
31
  paths
31
32
  ]);
32
33
  const error = errorState[_name];
34
+ const _formItemRules = formInstance.rules?.[_name];
33
35
  formInstance.nameToPaths[_name] = paths;
34
36
  if (Array.isArray(rules) && rules.length) formInstance.mountRules[_name] = rules;
35
37
  useEffect(()=>()=>{
@@ -55,10 +57,12 @@ function useFairysValtioFormItemAttrs(props) {
55
57
  const isRequired = useMemo(()=>{
56
58
  if (_isRequired) return _isRequired;
57
59
  if (Array.isArray(rules) && rules.length) return rules.some((rule)=>rule.required);
60
+ if (_formItemRules && Array.isArray(_formItemRules) && _formItemRules.length) return _formItemRules.some((rule)=>rule.required);
58
61
  return false;
59
62
  }, [
60
63
  rules,
61
- formInstance
64
+ formInstance,
65
+ _formItemRules
62
66
  ]);
63
67
  const isInvalid = useMemo(()=>{
64
68
  if (Array.isArray(error) && error.length) return true;
@@ -66,8 +70,9 @@ function useFairysValtioFormItemAttrs(props) {
66
70
  }, [
67
71
  error
68
72
  ]);
69
- const item_cls = useMemo(()=>clsx('fairys-valtio-form-item fairystaroform__p-_zkh1_4px_zhk2_ fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__relative fairystaroform__flex fairystaroform__flex-col fairystaroform__box-border fairystaroform__break-all', {
73
+ const item_cls = useMemo(()=>clsx('fairys-valtio-form-item fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__p-_zkh1_4px_zhk2_ fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__relative fairystaroform__flex fairystaroform__flex-col fairystaroform__box-border fairystaroform__break-all', {
70
74
  'fairys-valtio-form-item-invalid': isInvalid,
75
+ 'fairys-valtio-form-item-invalid-text-red': isInvalid && isInvalidTextRed,
71
76
  'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && 'bottom' === itemBorderType,
72
77
  'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200': 'bottom' === itemBorderType,
73
78
  [labelMode]: labelMode
@@ -79,7 +84,7 @@ function useFairysValtioFormItemAttrs(props) {
79
84
  isInvalid,
80
85
  isInvalidBorderRed
81
86
  ]);
82
- const itemContainer_cls = useMemo(()=>clsx('fairys-valtio-form-item-container fairystaroform__flex-1 fairystaroform__h-full fairystaroform__flex fairystaroform__box-border', {
87
+ const itemContainer_cls = useMemo(()=>clsx('fairys-valtio-form-item-container fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__flex-1 fairystaroform__h-full fairystaroform__flex fairystaroform__box-border', {
83
88
  'fairystaroform__flex-row fairystaroform__items-center fairystaroform__justify-between fairystaroform__gap-_zkh1_8px_zhk2_': 'between' === labelMode,
84
89
  'fairystaroform__flex-col fairystaroform__gap-_zkh1_4px_zhk2_': 'top' === labelMode,
85
90
  'fairystaroform__flex-row fairystaroform__gap-_zkh1_8px_zhk2_': 'left' === labelMode
@@ -87,7 +92,7 @@ function useFairysValtioFormItemAttrs(props) {
87
92
  labelClassName,
88
93
  labelMode
89
94
  ]);
90
- const itemLabel_cls = useMemo(()=>clsx('fairys-valtio-form-item-label fairystaroform__text-gray-800 fairystaroform__flex fairystaroform__items-center fairystaroform__relative fairystaroform__box-border', {
95
+ const itemLabel_cls = useMemo(()=>clsx('fairys-valtio-form-item-label fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-gray-800 fairystaroform__flex fairystaroform__items-center fairystaroform__relative fairystaroform__box-border', {
91
96
  'fairystaroform__justify-start': 'left' !== labelMode,
92
97
  'fairystaroform__justify-end': 'left' === labelMode,
93
98
  required: isRequired,
@@ -99,7 +104,7 @@ function useFairysValtioFormItemAttrs(props) {
99
104
  isRequired,
100
105
  showColon
101
106
  ]);
102
- const itemBody_cls = useMemo(()=>clsx('fairys-valtio-form-item-body fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border', {
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', {
103
108
  'fairystaroform__flex-row fairystaroform__justify-start': 'left' === labelMode,
104
109
  'fairystaroform__flex-row fairystaroform__justify-end': 'between' === labelMode || 'top' === labelMode,
105
110
  'fairystaroform__flex-row': 'top' === labelMode,
@@ -113,19 +118,21 @@ function useFairysValtioFormItemAttrs(props) {
113
118
  isInvalid,
114
119
  isInvalidBorderRed
115
120
  ]);
116
- const itemInput_cls = useMemo(()=>clsx('fairys-valtio-form-item-body fairystaroform__flex fairystaroform__flex-row fairystaroform__flex-1 fairystaroform__box-border', {
121
+ const itemInput_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-input fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__min-h-_zkh1_32px_zhk2_ fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-1 fairystaroform__box-border', {
117
122
  'fairystaroform__justify-end fairystaroform__text-right': 'between' === labelMode,
118
123
  'fairystaroform__justify-start fairystaroform__text-left fairystaroform__items-center': 'between' !== labelMode
119
124
  }), [
120
125
  labelMode
121
126
  ]);
122
- const itemExtra_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-extra fairystaroform__box-border fairystaroform__flex fairystaroform__items-center fairystaroform__justify-center'), []);
123
- const itemHelp_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-help fairystaroform__text-_zkh1_10px_zhk2_ fairystaroform__w-full fairystaroform__box-border'), []);
124
- const itemError_cls = useMemo(()=>clsx('fairys-valtio-form-item-body-error fairystaroform__px-_zkh1_4px_zhk2_ fairystaroform__w-full fairystaroform__flex fairystaroform__flex-row fairystaroform__box-border fairystaroform__text-red fairystaroform__absolute fairystaroform__text-_zkh1_10px_zhk2_ fairystaroform__z-10', {
125
- 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'left-bottom' === errorLayout,
126
- 'fairystaroform__bottom-_zkh1_-14px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'right-bottom' === errorLayout,
127
- 'fairystaroform__top-_zkh1_-14px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'top-right' === errorLayout,
128
- 'fairystaroform__top-_zkh1_-14px_zhk2_ fairystaroform__left-0 fairystaroform__justify-start': 'top-left' === errorLayout
127
+ 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
+ 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
+ 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,
132
+ 'fairystaroform__top-_zkh1_-4px_zhk2_ fairystaroform__right-0 fairystaroform__justify-end': 'top-right' === errorLayout,
133
+ '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
129
136
  }), [
130
137
  errorLayout
131
138
  ]);
@@ -57,8 +57,17 @@ export declare class FairysValtioFormInstance<T extends MObject<T> = Record<stri
57
57
  rules: Record<PropertyKey, RuleItem[]>;
58
58
  /**表单项名称到路径映射*/
59
59
  nameToPaths: Record<PropertyKey, PropertyKey[]>;
60
- /**验证表单项规则*/
60
+ /**验证表单项规则
61
+ * @param fields 要验证的字段(可选)
62
+ * @param isReturn 是否返回验证结果(可选)
63
+ */
61
64
  validate: (fields?: PropertyKey[], isReturn?: boolean) => Promise<ValidateFieldsError | Values>;
65
+ /**
66
+ * 验证某些前缀的字段
67
+ * @param prefix 前缀字段数组
68
+ * @param isReturn 是否返回验证结果(可选)
69
+ */
70
+ validatePrefixFields: (prefix: string[], isReturn?: boolean) => Promise<ValidateFieldsError | Values>;
62
71
  }
63
72
  /**声明实例*/
64
73
  export declare function useFairysValtioFormInstance<T extends MObject<T> = object>(instance?: FairysValtioFormInstance<T>): FairysValtioFormInstance<T>;
@@ -129,6 +129,11 @@ class FairysValtioFormInstance {
129
129
  });
130
130
  });
131
131
  };
132
+ validatePrefixFields = async (prefix, isReturn = true)=>{
133
+ const fields = Object.keys(this.rules);
134
+ const _fields = fields.filter((item)=>prefix.some((p)=>item.toString().startsWith(p)));
135
+ return this.validate(_fields, isReturn);
136
+ };
132
137
  }
133
138
  function useFairysValtioFormInstance(instance) {
134
139
  const ref = useRef();
@@ -2,7 +2,7 @@ export interface FairysValtioFormLayoutContextOptions {
2
2
  /**列数据*/
3
3
  colCount?: number;
4
4
  /**规则校验失败错误提示位置*/
5
- errorLayout?: 'left-bottom' | 'right-bottom' | 'top-right' | 'top-left';
5
+ errorLayout?: 'bottom-left' | 'bottom-right' | 'top-right' | 'top-left' | 'left-border-top' | 'right-border-top';
6
6
  /**
7
7
  * label显示模式
8
8
  * @platform taro 支持 between
@@ -28,6 +28,8 @@ export interface FairysValtioFormLayoutContextOptions {
28
28
  itemBorderColor?: React.CSSProperties['borderColor'];
29
29
  /**是否校验失败时显示红色边框*/
30
30
  isInvalidBorderRed?: boolean;
31
+ /**是否校验失败时显示红色文本*/
32
+ isInvalidTextRed?: boolean;
31
33
  /**是否显示冒号*/
32
34
  showColon?: boolean;
33
35
  }
@@ -69,7 +71,7 @@ export declare const useFairysValtioFormLayoutInstance: (instance?: FairysValtio
69
71
  export declare const FairysValtioFormLayoutContext: import("react").Context<FairysValtioFormLayoutInstance>;
70
72
  export declare const useFairysValtioFormLayoutContext: () => readonly [{
71
73
  readonly colCount?: number;
72
- readonly errorLayout?: "left-bottom" | "right-bottom" | "top-right" | "top-left";
74
+ readonly errorLayout?: "bottom-left" | "bottom-right" | "top-right" | "top-left" | "left-border-top" | "right-border-top";
73
75
  readonly labelMode?: "left" | "top" | "between";
74
76
  readonly formItemClassName?: string;
75
77
  readonly formItemStyle?: {
@@ -2654,6 +2656,7 @@ export declare const useFairysValtioFormLayoutContext: () => readonly [{
2654
2656
  readonly itemBorderType?: "bottom" | "body";
2655
2657
  readonly itemBorderColor?: React.CSSProperties["borderColor"];
2656
2658
  readonly isInvalidBorderRed?: boolean;
2659
+ readonly isInvalidTextRed?: boolean;
2657
2660
  readonly showColon?: boolean;
2658
2661
  }, FairysValtioFormLayoutInstance];
2659
2662
  /**
@@ -4,7 +4,7 @@ import { proxy, useSnapshot } from "valtio";
4
4
  class FairysValtioFormLayoutInstance {
5
5
  state = proxy({
6
6
  colCount: 1,
7
- errorLayout: 'right-bottom',
7
+ errorLayout: 'bottom-right',
8
8
  labelMode: 'between',
9
9
  itemBorderType: 'bottom'
10
10
  });
@@ -35,7 +35,7 @@ function useFairysValtioFormLayoutAttrs(props) {
35
35
  const formLayoutInstance = useFairysValtioFormLayoutInstance();
36
36
  const [state] = useFairysValtioFormLayoutContext();
37
37
  const parent_colCount = state.colCount || 1;
38
- const parent_errorLayout = state.errorLayout || 'right-bottom';
38
+ const parent_errorLayout = state.errorLayout || 'bottom-right';
39
39
  const parent_labelMode = state.labelMode || 'between';
40
40
  const parent_formItemClassName = state.formItemClassName;
41
41
  const parent_formItemStyle = state.formItemStyle;
@@ -46,8 +46,9 @@ function useFairysValtioFormLayoutAttrs(props) {
46
46
  const parent_borderedType = state.itemBorderType || 'bottom';
47
47
  const parent_itemBorderColor = state.itemBorderColor;
48
48
  const parent_isInvalidBorderRed = state.isInvalidBorderRed;
49
+ const parent_isInvalidTextRed = state.isInvalidTextRed;
49
50
  const parent_showColon = state.showColon;
50
- const { colCount = parent_colCount, errorLayout = parent_errorLayout, labelMode = parent_labelMode, formItemClassName = parent_formItemClassName, formItemStyle = parent_formItemStyle, formItemLabelClassName = parent_formItemLabelClassName, formItemLabelStyle = parent_formItemLabelStyle, formItemBodyClassName = parent_formItemBodyClassName, formItemBodyStyle = parent_formItemBodyStyle, itemBorderType = parent_borderedType, itemBorderColor = parent_itemBorderColor, lastItemBordered = true, isInvalidBorderRed = parent_isInvalidBorderRed, showColon = parent_showColon, gap, isAllColSpan = false, className, style, headerClassName, headerStyle, bodyClassName, bodyStyle, bordered, boxShadow } = props;
51
+ const { colCount = parent_colCount, errorLayout = parent_errorLayout, labelMode = parent_labelMode, formItemClassName = parent_formItemClassName, formItemStyle = parent_formItemStyle, formItemLabelClassName = parent_formItemLabelClassName, formItemLabelStyle = parent_formItemLabelStyle, formItemBodyClassName = parent_formItemBodyClassName, formItemBodyStyle = parent_formItemBodyStyle, itemBorderType = parent_borderedType, itemBorderColor = parent_itemBorderColor, lastItemBordered = true, isInvalidBorderRed = parent_isInvalidBorderRed, isInvalidTextRed = parent_isInvalidTextRed, showColon = parent_showColon, gap, isAllColSpan = false, className, style, headerClassName, headerStyle, bodyClassName, bodyStyle, bordered, boxShadow } = props;
51
52
  useMemo(()=>formLayoutInstance.updated({
52
53
  colCount,
53
54
  errorLayout,
@@ -61,6 +62,7 @@ function useFairysValtioFormLayoutAttrs(props) {
61
62
  itemBorderType,
62
63
  itemBorderColor,
63
64
  isInvalidBorderRed,
65
+ isInvalidTextRed,
64
66
  showColon
65
67
  }), [
66
68
  colCount,
@@ -75,9 +77,10 @@ function useFairysValtioFormLayoutAttrs(props) {
75
77
  itemBorderType,
76
78
  itemBorderColor,
77
79
  isInvalidBorderRed,
80
+ isInvalidTextRed,
78
81
  showColon
79
82
  ]);
80
- const layoutCls = useMemo(()=>clsx("fairys-valtio-form-layout fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-_zkh1_4px_zhk2_", {
83
+ const layoutCls = useMemo(()=>clsx("fairys-valtio-form-layout fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-_zkh1_8px_zhk2_", {
81
84
  'fairys-valtio-form-layout-all-col-span': isAllColSpan,
82
85
  'fairys-valtio-form-layout-box-shadow': boxShadow,
83
86
  'fairystaroform__border fairystaroform__border-solid fairystaroform__border-gray-200': bordered,
@@ -89,7 +92,7 @@ function useFairysValtioFormLayoutAttrs(props) {
89
92
  boxShadow,
90
93
  lastItemBordered
91
94
  ]);
92
- const headerCls = useMemo(()=>clsx("fairys-valtio-form-layout-header fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-_zkh1_12px_zhk2_ fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border", {
95
+ const headerCls = useMemo(()=>clsx("fairys-valtio-form-layout-header fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-_zkh1_10px_zhk2_ fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border", {
93
96
  'fairystaroform__px-_zkh1_8px_zhk2_': bordered || boxShadow,
94
97
  'fairystaroform__px-_zkh1_4px_zhk2_': !bordered && !boxShadow
95
98
  }, headerClassName), [
@@ -97,9 +100,9 @@ function useFairysValtioFormLayoutAttrs(props) {
97
100
  bordered,
98
101
  boxShadow
99
102
  ]);
100
- const headerTitleCls = useMemo(()=>clsx("fairys-valtio-form-layout-header-title fairystaroform__text-_zkh1_14px_zhk2_ fairystaroform__font-bold fairystaroform__box-border"), []);
101
- const headerExtraCls = useMemo(()=>clsx("fairys-valtio-form-layout-header-extra fairystaroform__box-border"), []);
102
- const body_base = useMemo(()=>clsx('fairys-valtio-form-layout-body fairystaroform__px-_zkh1_8px_zhk2_ fairystaroform__w-full fairystaroform__grid fairystaroform__gap-_zkh1_2px_zhk2_ fairystaroform__box-border', bodyClassName), [
103
+ const headerTitleCls = useMemo(()=>clsx("fairys-valtio-form-layout-header-title fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-_zkh1_14px_zhk2_ fairystaroform__font-bold fairystaroform__box-border"), []);
104
+ const headerExtraCls = useMemo(()=>clsx("fairys-valtio-form-layout-header-extra fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__box-border"), []);
105
+ const body_base = useMemo(()=>clsx('fairys-valtio-form-layout-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__px-_zkh1_8px_zhk2_ fairystaroform__w-full fairystaroform__grid fairystaroform__gap-_zkh1_2px_zhk2_ fairystaroform__box-border', bodyClassName), [
103
106
  bodyClassName
104
107
  ]);
105
108
  const styleBase = useMemo(()=>{
@@ -63,6 +63,10 @@
63
63
  bottom: -14px;
64
64
  }
65
65
 
66
+ .fairystaroform__bottom-_zkh1_-2px_zhk2_ {
67
+ bottom: -2px;
68
+ }
69
+
66
70
  .fairystaroform__left-0 {
67
71
  left: 0;
68
72
  }
@@ -71,8 +75,8 @@
71
75
  right: 0;
72
76
  }
73
77
 
74
- .fairystaroform__top-_zkh1_-14px_zhk2_ {
75
- top: -14px;
78
+ .fairystaroform__top-_zkh1_-4px_zhk2_ {
79
+ top: -4px;
76
80
  }
77
81
 
78
82
  .fairystaroform__z-10 {
@@ -91,6 +95,10 @@
91
95
  height: 100%;
92
96
  }
93
97
 
98
+ .fairystaroform__min-h-_zkh1_32px_zhk2_ {
99
+ min-height: 32px;
100
+ }
101
+
94
102
  .fairystaroform__w-full {
95
103
  width: 100%;
96
104
  }
@@ -166,8 +174,8 @@
166
174
  border-bottom-color: rgb(229 231 235 / var(--un-border-bottom-opacity));
167
175
  }
168
176
 
169
- .fairystaroform__rounded-_zkh1_4px_zhk2_ {
170
- border-radius: 4px;
177
+ .fairystaroform__rounded-_zkh1_8px_zhk2_ {
178
+ border-radius: 8px;
171
179
  }
172
180
 
173
181
  .fairystaroform__border-solid {
@@ -192,9 +200,9 @@
192
200
  padding-right: 8px;
193
201
  }
194
202
 
195
- .fairystaroform__py-_zkh1_12px_zhk2_ {
196
- padding-top: 12px;
197
- padding-bottom: 12px;
203
+ .fairystaroform__py-_zkh1_10px_zhk2_ {
204
+ padding-top: 10px;
205
+ padding-bottom: 10px;
198
206
  }
199
207
 
200
208
  .fairystaroform__text-left {
@@ -231,6 +239,16 @@
231
239
  font-weight: 700;
232
240
  }
233
241
 
242
+ .fairystaroform__transition-all {
243
+ transition-property: all;
244
+ transition-duration: .15s;
245
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
246
+ }
247
+
248
+ .fairystaroform__duration-300 {
249
+ transition-duration: .3s;
250
+ }
251
+
234
252
  .fairys-valtio-form-item-label.show-colon:after {
235
253
  content: ":";
236
254
  text-align: center;
@@ -268,3 +286,7 @@
268
286
  border-bottom-color: red !important;
269
287
  }
270
288
 
289
+ .fairys-valtio-form-item-invalid-text-red > .fairys-valtio-form-item-container > .fairys-valtio-form-item-label, .fairys-valtio-form-item-invalid-text-red > .fairys-valtio-form-item-container > .fairys-valtio-form-item-body > .fairys-valtio-form-item-body-input {
290
+ color: red !important;
291
+ }
292
+
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "SunLxy <1011771396@qq.com>",
4
4
  "description": "使用 valtio 实现的表单基础库, 使其更加便捷,同时支持`PC`、`H5`、`Taro`,同时也更加灵活。",
5
5
  "homepage": "https://github.com/autumn-fairy-tales/fairys-taro-react",
6
- "version": "0.0.9",
6
+ "version": "0.0.11",
7
7
  "main": "lib/index.js",
8
8
  "types": "esm/index.d.ts",
9
9
  "module": "esm/index.js",
@@ -42,9 +42,9 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
42
42
  bodyStyle?: React.CSSProperties;
43
43
  children?: React.ReactNode;
44
44
  /**规则校验失败错误提示位置*/
45
- errorLayout?: 'left-bottom' | 'right-bottom' | 'top-right' | 'top-left';
45
+ errorLayout?: FairysValtioFormLayoutContextOptions['errorLayout'];
46
46
  /**label显示模式*/
47
- labelMode?: 'left' | 'top' | 'between';
47
+ labelMode?: FairysValtioFormLayoutContextOptions['labelMode'];
48
48
  /**额外内容*/
49
49
  extra?: React.ReactNode;
50
50
  /**底部提示内容*/
@@ -69,6 +69,8 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
69
69
  itemBorderColor?: React.CSSProperties['borderColor'];
70
70
  /**是否校验失败时显示红色边框*/
71
71
  isInvalidBorderRed?: boolean;
72
+ /**是否校验失败时显示红色文本*/
73
+ isInvalidTextRed?: boolean;
72
74
  /**输入框属性*/
73
75
  attrs?: any;
74
76
  /**是否拼接父级字段名*/
@@ -124,7 +126,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
124
126
  const [layoutAttrs] = useFairysValtioFormLayoutContext();
125
127
  const colCount = layoutAttrs.colCount || 1;
126
128
  const parent_borderedType = layoutAttrs.itemBorderType || 'bottom';
127
- const parent_errorLayout = layoutAttrs.errorLayout || 'right-bottom';
129
+ const parent_errorLayout = layoutAttrs.errorLayout || 'bottom-right';
128
130
  const parent_formItemClassName = layoutAttrs.formItemClassName;
129
131
  const parent_formItemLabelClassName = layoutAttrs.formItemLabelClassName;
130
132
  const parent_formItemLabelStyle = layoutAttrs.formItemLabelStyle;
@@ -134,6 +136,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
134
136
  const parent_labelMode = layoutAttrs.labelMode || 'between';
135
137
  const parent_itemBorderColor = layoutAttrs.itemBorderColor;
136
138
  const parent_isInvalidBorderRed = layoutAttrs.isInvalidBorderRed;
139
+ const parent_isInvalidTextRed = layoutAttrs.isInvalidTextRed;
137
140
  const parent_showColon = layoutAttrs.showColon;
138
141
 
139
142
  const {
@@ -160,6 +163,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
160
163
  showColon = parent_showColon,
161
164
  itemBorderColor = parent_itemBorderColor,
162
165
  isInvalidBorderRed = parent_isInvalidBorderRed,
166
+ isInvalidTextRed = parent_isInvalidTextRed,
163
167
  isJoinParentField = true,
164
168
  rules,
165
169
  } = props;
@@ -173,6 +177,9 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
173
177
  const [state, errorState, formInstance] = useFairysValtioFormInstanceContextState<T>();
174
178
  const value = useMemo(() => get(state, paths), [state, paths]);
175
179
  const error = errorState[_name];
180
+ // 使用从 Form 中设置的规则
181
+ const _formItemRules = formInstance.rules?.[_name];
182
+
176
183
  formInstance.nameToPaths[_name] = paths;
177
184
  /**挂载校验规则*/
178
185
  if (Array.isArray(rules) && rules.length) {
@@ -215,9 +222,11 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
215
222
  return _isRequired;
216
223
  } else if (Array.isArray(rules) && rules.length) {
217
224
  return rules.some((rule) => rule.required);
225
+ } else if (_formItemRules && Array.isArray(_formItemRules) && _formItemRules.length) {
226
+ return _formItemRules.some((rule) => rule.required);
218
227
  }
219
228
  return false;
220
- }, [rules, formInstance]);
229
+ }, [rules, formInstance, _formItemRules]);
221
230
 
222
231
  /**校验是否存在错误信息*/
223
232
  const isInvalid = useMemo(() => {
@@ -230,9 +239,10 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
230
239
  /**表单项类名*/
231
240
  const item_cls = useMemo(() => {
232
241
  return clsx(
233
- 'fairys-valtio-form-item fairystaroform__p-[4px] fairystaroform__text-[12px] fairystaroform__relative fairystaroform__flex fairystaroform__flex-col fairystaroform__box-border fairystaroform__break-all',
242
+ 'fairys-valtio-form-item fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__p-[4px] fairystaroform__text-[12px] fairystaroform__relative fairystaroform__flex fairystaroform__flex-col fairystaroform__box-border fairystaroform__break-all',
234
243
  {
235
244
  'fairys-valtio-form-item-invalid': isInvalid,
245
+ 'fairys-valtio-form-item-invalid-text-red': isInvalid && isInvalidTextRed,
236
246
  'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && itemBorderType === 'bottom',
237
247
  'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200':
238
248
  itemBorderType === 'bottom',
@@ -247,7 +257,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
247
257
  const itemContainer_cls = useMemo(() => {
248
258
  // 默认两端显示
249
259
  return clsx(
250
- 'fairys-valtio-form-item-container fairystaroform__flex-1 fairystaroform__h-full fairystaroform__flex fairystaroform__box-border',
260
+ 'fairys-valtio-form-item-container fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__flex-1 fairystaroform__h-full fairystaroform__flex fairystaroform__box-border',
251
261
  {
252
262
  'fairystaroform__flex-row fairystaroform__items-center fairystaroform__justify-between fairystaroform__gap-[8px]':
253
263
  labelMode === 'between',
@@ -262,7 +272,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
262
272
  const itemLabel_cls = useMemo(() => {
263
273
  // 默认两端显示
264
274
  return clsx(
265
- 'fairys-valtio-form-item-label fairystaroform__text-gray-800 fairystaroform__flex fairystaroform__items-center fairystaroform__relative fairystaroform__box-border',
275
+ 'fairys-valtio-form-item-label fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-gray-800 fairystaroform__flex fairystaroform__items-center fairystaroform__relative fairystaroform__box-border',
266
276
  {
267
277
  'fairystaroform__justify-start': labelMode !== 'left',
268
278
  'fairystaroform__justify-end': labelMode === 'left',
@@ -278,7 +288,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
278
288
  const itemBody_cls = useMemo(() => {
279
289
  // 默认两端显示
280
290
  return clsx(
281
- 'fairys-valtio-form-item-body fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border',
291
+ 'fairys-valtio-form-item-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__relative fairystaroform__flex-1 fairystaroform__flex fairystaroform__box-border',
282
292
  {
283
293
  'fairystaroform__flex-row fairystaroform__justify-start': labelMode === 'left',
284
294
  'fairystaroform__flex-row fairystaroform__justify-end': labelMode === 'between' || labelMode === 'top',
@@ -295,7 +305,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
295
305
  // 表单项输入类名
296
306
  const itemInput_cls = useMemo(() => {
297
307
  return clsx(
298
- 'fairys-valtio-form-item-body fairystaroform__flex fairystaroform__flex-row fairystaroform__flex-1 fairystaroform__box-border',
308
+ 'fairys-valtio-form-item-body-input fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__min-h-[32px] fairystaroform__flex fairystaroform__flex-row fairystaroform__items-center fairystaroform__flex-1 fairystaroform__box-border',
299
309
  {
300
310
  'fairystaroform__justify-end fairystaroform__text-right': labelMode === 'between',
301
311
  'fairystaroform__justify-start fairystaroform__text-left fairystaroform__items-center': labelMode !== 'between',
@@ -306,28 +316,34 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
306
316
  /**表单项额外内容类名*/
307
317
  const itemExtra_cls = useMemo(() => {
308
318
  return clsx(
309
- 'fairys-valtio-form-item-body-extra fairystaroform__box-border fairystaroform__flex fairystaroform__items-center fairystaroform__justify-center',
319
+ 'fairys-valtio-form-item-body-extra fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__box-border fairystaroform__flex fairystaroform__items-center fairystaroform__justify-center',
310
320
  );
311
321
  }, []);
312
322
 
313
323
  /**表单项底部提示内容类名*/
314
324
  const itemHelp_cls = useMemo(() => {
315
325
  return clsx(
316
- 'fairys-valtio-form-item-body-help fairystaroform__text-[10px] fairystaroform__w-full fairystaroform__box-border',
326
+ 'fairys-valtio-form-item-body-help fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-[10px] fairystaroform__w-full fairystaroform__box-border',
317
327
  );
318
328
  }, []);
319
329
 
320
330
  /**表单项错误提示类名*/
321
331
  const itemError_cls = useMemo(() => {
322
332
  return clsx(
323
- 'fairys-valtio-form-item-body-error fairystaroform__px-[4px] fairystaroform__w-full fairystaroform__flex fairystaroform__flex-row fairystaroform__box-border fairystaroform__text-red fairystaroform__absolute fairystaroform__text-[10px] fairystaroform__z-10',
333
+ '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',
324
334
  {
325
335
  'fairystaroform__bottom-[-14px] fairystaroform__left-0 fairystaroform__justify-start':
326
- errorLayout === 'left-bottom',
336
+ errorLayout === 'bottom-left',
327
337
  'fairystaroform__bottom-[-14px] fairystaroform__right-0 fairystaroform__justify-end':
328
- errorLayout === 'right-bottom',
329
- 'fairystaroform__top-[-14px] fairystaroform__right-0 fairystaroform__justify-end': errorLayout === 'top-right',
330
- 'fairystaroform__top-[-14px] fairystaroform__left-0 fairystaroform__justify-start': errorLayout === 'top-left',
338
+ errorLayout === 'bottom-right',
339
+ 'fairystaroform__top-[-4px] fairystaroform__right-0 fairystaroform__justify-end': errorLayout === 'top-right',
340
+ 'fairystaroform__top-[-4px] fairystaroform__left-0 fairystaroform__justify-start': errorLayout === 'top-left',
341
+ /**边框底部提示*/
342
+ 'fairystaroform__left-0 fairystaroform__bottom-[-2px] fairystaroform__justify-start':
343
+ errorLayout === 'left-border-top',
344
+ /**边框顶部提示*/
345
+ 'fairystaroform__right-0 fairystaroform__bottom-[-2px] fairystaroform__justify-end':
346
+ errorLayout === 'right-border-top',
331
347
  },
332
348
  );
333
349
  }, [errorLayout]);
package/src/form/form.tsx CHANGED
@@ -9,7 +9,7 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
9
9
  form?: FairysValtioFormInstance<T>;
10
10
  /**子元素*/
11
11
  children: ReactNode;
12
- /**表单项规则*/
12
+ /**表单项规则(如果表单项没有指定规则,则使用全局规则,如果表单项指定规则,则使用表单项规则)*/
13
13
  rules?: Record<PropertyKey, RuleItem[]>;
14
14
  /**表单初始值*/
15
15
  formData?: FairysValtioFormInstance<T>['state'];
@@ -129,7 +129,10 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
129
129
  rules: Record<PropertyKey, RuleItem[]> = {};
130
130
  /**表单项名称到路径映射*/
131
131
  nameToPaths: Record<PropertyKey, PropertyKey[]> = {};
132
- /**验证表单项规则*/
132
+ /**验证表单项规则
133
+ * @param fields 要验证的字段(可选)
134
+ * @param isReturn 是否返回验证结果(可选)
135
+ */
133
136
  validate = async (fields?: PropertyKey[], isReturn: boolean = true): Promise<ValidateFieldsError | Values> => {
134
137
  const rules = {
135
138
  ...this.rules,
@@ -190,6 +193,17 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
190
193
  });
191
194
  });
192
195
  };
196
+
197
+ /**
198
+ * 验证某些前缀的字段
199
+ * @param prefix 前缀字段数组
200
+ * @param isReturn 是否返回验证结果(可选)
201
+ */
202
+ validatePrefixFields = async (prefix: string[], isReturn: boolean = true): Promise<ValidateFieldsError | Values> => {
203
+ const fields = Object.keys(this.rules) as PropertyKey[];
204
+ const _fields = fields.filter((item) => prefix.some((p) => item.toString().startsWith(p)));
205
+ return this.validate(_fields, isReturn);
206
+ };
193
207
  }
194
208
 
195
209
  /**声明实例*/
@@ -6,7 +6,7 @@ export interface FairysValtioFormLayoutContextOptions {
6
6
  /**列数据*/
7
7
  colCount?: number;
8
8
  /**规则校验失败错误提示位置*/
9
- errorLayout?: 'left-bottom' | 'right-bottom' | 'top-right' | 'top-left';
9
+ errorLayout?: 'bottom-left' | 'bottom-right' | 'top-right' | 'top-left' | 'left-border-top' | 'right-border-top';
10
10
  /**
11
11
  * label显示模式
12
12
  * @platform taro 支持 between
@@ -32,6 +32,8 @@ export interface FairysValtioFormLayoutContextOptions {
32
32
  itemBorderColor?: React.CSSProperties['borderColor'];
33
33
  /**是否校验失败时显示红色边框*/
34
34
  isInvalidBorderRed?: boolean;
35
+ /**是否校验失败时显示红色文本*/
36
+ isInvalidTextRed?: boolean;
35
37
  /**是否显示冒号*/
36
38
  showColon?: boolean;
37
39
  }
@@ -70,7 +72,7 @@ export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayout
70
72
  export class FairysValtioFormLayoutInstance {
71
73
  state = proxy<FairysValtioFormLayoutContextOptions>({
72
74
  colCount: 1,
73
- errorLayout: 'right-bottom',
75
+ errorLayout: 'bottom-right',
74
76
  labelMode: 'between',
75
77
  itemBorderType: 'bottom',
76
78
  });
@@ -154,7 +156,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
154
156
  const formLayoutInstance = useFairysValtioFormLayoutInstance();
155
157
  const [state] = useFairysValtioFormLayoutContext();
156
158
  const parent_colCount = state.colCount || 1;
157
- const parent_errorLayout = state.errorLayout || 'right-bottom';
159
+ const parent_errorLayout = state.errorLayout || 'bottom-right';
158
160
  const parent_labelMode = state.labelMode || 'between';
159
161
  const parent_formItemClassName = state.formItemClassName;
160
162
  const parent_formItemStyle = state.formItemStyle;
@@ -165,6 +167,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
165
167
  const parent_borderedType = state.itemBorderType || 'bottom';
166
168
  const parent_itemBorderColor = state.itemBorderColor;
167
169
  const parent_isInvalidBorderRed = state.isInvalidBorderRed;
170
+ const parent_isInvalidTextRed = state.isInvalidTextRed;
168
171
  const parent_showColon = state.showColon;
169
172
 
170
173
  const {
@@ -181,6 +184,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
181
184
  itemBorderColor = parent_itemBorderColor,
182
185
  lastItemBordered = true,
183
186
  isInvalidBorderRed = parent_isInvalidBorderRed,
187
+ isInvalidTextRed = parent_isInvalidTextRed,
184
188
  showColon = parent_showColon,
185
189
  gap,
186
190
  isAllColSpan = false,
@@ -209,6 +213,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
209
213
  itemBorderType,
210
214
  itemBorderColor,
211
215
  isInvalidBorderRed,
216
+ isInvalidTextRed,
212
217
  showColon,
213
218
  }),
214
219
  [
@@ -224,6 +229,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
224
229
  itemBorderType,
225
230
  itemBorderColor,
226
231
  isInvalidBorderRed,
232
+ isInvalidTextRed,
227
233
  showColon,
228
234
  ],
229
235
  );
@@ -231,7 +237,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
231
237
  const layoutCls = useMemo(
232
238
  () =>
233
239
  clsx(
234
- `fairys-valtio-form-layout fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-[4px]`,
240
+ `fairys-valtio-form-layout fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-[8px]`,
235
241
  {
236
242
  'fairys-valtio-form-layout-all-col-span': isAllColSpan,
237
243
  'fairys-valtio-form-layout-box-shadow': boxShadow,
@@ -245,7 +251,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
245
251
  const headerCls = useMemo(
246
252
  () =>
247
253
  clsx(
248
- `fairys-valtio-form-layout-header fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-[12px] fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border`,
254
+ `fairys-valtio-form-layout-header fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-[10px] fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border`,
249
255
  {
250
256
  'fairystaroform__px-[8px]': bordered || boxShadow,
251
257
  'fairystaroform__px-[4px]': !bordered && !boxShadow,
@@ -257,15 +263,21 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
257
263
  const headerTitleCls = useMemo(
258
264
  () =>
259
265
  clsx(
260
- `fairys-valtio-form-layout-header-title fairystaroform__text-[14px] fairystaroform__font-bold fairystaroform__box-border`,
266
+ `fairys-valtio-form-layout-header-title fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-[14px] fairystaroform__font-bold fairystaroform__box-border`,
267
+ ),
268
+ [],
269
+ );
270
+ const headerExtraCls = useMemo(
271
+ () =>
272
+ clsx(
273
+ `fairys-valtio-form-layout-header-extra fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__box-border`,
261
274
  ),
262
275
  [],
263
276
  );
264
- const headerExtraCls = useMemo(() => clsx(`fairys-valtio-form-layout-header-extra fairystaroform__box-border`), []);
265
277
 
266
278
  const body_base = useMemo(() => {
267
279
  return clsx(
268
- 'fairys-valtio-form-layout-body fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__gap-[2px] fairystaroform__box-border',
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',
269
281
  bodyClassName,
270
282
  );
271
283
  }, [bodyClassName]);
@@ -45,3 +45,11 @@
45
45
  .fairys-valtio-form-item-invalid-border-red {
46
46
  border-bottom-color: red !important;
47
47
  }
48
+
49
+ .fairys-valtio-form-item-invalid-text-red > .fairys-valtio-form-item-container > .fairys-valtio-form-item-label,
50
+ .fairys-valtio-form-item-invalid-text-red
51
+ > .fairys-valtio-form-item-container
52
+ > .fairys-valtio-form-item-body
53
+ > .fairys-valtio-form-item-body-input {
54
+ color: red !important;
55
+ }