@homecode/ui 4.25.3 → 4.26.1

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.
@@ -17,7 +17,7 @@ function dropFocusFromSubmit() {
17
17
  function getInitialTouched(initialValues) {
18
18
  return Object.keys(initialValues).reduce((acc, name) => ({ ...acc, [name]: false }), {});
19
19
  }
20
- function getNotEmpty(_defaultValues, values) {
20
+ function getChanged(_defaultValues, values) {
21
21
  const defaultValues = _defaultValues || values;
22
22
  return Object.entries(values).reduce((acc, [field, val]) => compare(defaultValues[field], val) ? acc : { ...acc, [field]: true }, {});
23
23
  }
@@ -39,4 +39,4 @@ function cloneValues(values) {
39
39
  return Object.entries(values).reduce((acc, [name, val]) => ({ ...acc, [name]: cloneValue(val) }), {});
40
40
  }
41
41
 
42
- export { cloneValues, dropFocusFromSubmit, getInitialTouched, getNotEmpty, getVal, patchWithCustomMessages };
42
+ export { cloneValues, dropFocusFromSubmit, getChanged, getInitialTouched, getVal, patchWithCustomMessages };
@@ -1,30 +1,16 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { Component } from 'react';
3
- import { createStore } from 'justorm/react';
2
+ import { useRef, useState, useCallback, useEffect } from 'react';
4
3
  import cn from 'classnames';
5
4
  import compare from 'compareq';
6
- import pick from 'lodash.pick';
7
- import omit from 'lodash.omit';
8
5
  import { Input } from '../Input/Input.js';
9
6
  import S from './Form.styl.js';
10
- import { cloneValues, getNotEmpty, getInitialTouched, patchWithCustomMessages, dropFocusFromSubmit, getVal } from './Form.helpers.js';
7
+ import { cloneValues, getInitialTouched, getChanged, patchWithCustomMessages, dropFocusFromSubmit, getVal } from './Form.helpers.js';
11
8
  import { Validator } from './Validator.js';
12
9
  import '../Spinner/Spinner.styl.js';
13
10
  import '../Button/Button.styl.js';
14
11
  import './SubmitButtons/SubmitButtons.styl.js';
15
12
 
16
- const STORE_FIELDS_EXPOSED = [
17
- 'isDirty',
18
- 'isEmpty',
19
- 'isValid',
20
- 'isLoading',
21
- 'values',
22
- 'errors',
23
- 'touched',
24
- 'changed',
25
- 'disabled',
26
- ];
27
- function Field(props) {
13
+ const Field = function Field(props) {
28
14
  const { value, error, markEdited, isChanged, isTouched, clearMargins, component: Control = Input, className, onChange, onBlur, handleChange, handleBlur, children, ...controlProps } = props;
29
15
  const { name, isHidden } = controlProps;
30
16
  const valField = typeof value === 'boolean' ? 'checked' : 'value';
@@ -48,239 +34,246 @@ function Field(props) {
48
34
  error: isTouched && error?.message,
49
35
  });
50
36
  return (jsxs("div", { className: classes, children: [jsx(Control, { ...controlProps }), children] }));
51
- }
52
- class Form extends Component {
53
- store;
54
- validationSchema;
55
- defaultValues = {};
56
- constructor(props) {
57
- super(props);
58
- const { initialValues, validationSchema, defaultDisabled } = props;
59
- this.updateDefaultValues();
60
- this.validationSchema = validationSchema;
61
- const values = cloneValues(initialValues);
62
- const notEmpty = getNotEmpty(this.defaultValues, initialValues);
63
- const disabled = Object(defaultDisabled);
64
- this.store = createStore(this, {
65
- values,
66
- touched: getInitialTouched(initialValues),
67
- changed: {},
68
- notEmpty,
69
- disabled,
70
- isLoading: false,
71
- isDirty: false,
72
- // TODO: do not validate here (only when Field is mounted)
73
- ...this.getValidationState({ values, disabled }),
74
- isEmpty: Object.keys(notEmpty).length === 0,
75
- });
76
- }
77
- componentDidMount() {
78
- this.calcChangedAll();
79
- this.validate();
80
- this.onInit();
81
- }
82
- shouldComponentUpdate({ defaultValues, initialValues, validationSchema, }) {
83
- const validationChanged = !compare(validationSchema, this.props.validationSchema);
84
- const initialValsChanged = !compare(initialValues, this.props.initialValues);
85
- const defaultValsChanged = !compare(defaultValues, this.props.defaultValues);
86
- this.validationSchema = validationSchema;
87
- if (initialValsChanged) {
88
- this.setInitialVals(initialValues);
89
- }
90
- if (defaultValsChanged)
91
- this.updateDefaultValues();
92
- if (initialValsChanged || defaultValsChanged) {
93
- this.calcChangedAll(initialValues);
94
- }
95
- if (initialValsChanged || validationChanged) {
96
- this.validate();
97
- }
98
- return true;
99
- }
100
- updateDefaultValues(props = this.props) {
101
- const { defaultValues, initialValues } = props;
102
- return defaultValues || cloneValues(initialValues);
103
- }
104
- setInitialVals(initialValues = {}) {
105
- this.store.values = cloneValues(initialValues);
106
- this.validate();
107
- this.onInit();
108
- }
109
- setValue = (field, val) => {
110
- const { values } = this.store;
111
- values[field] = val;
112
- this.calcChanged(field, val);
113
- this.validate();
37
+ };
38
+ function Form(props) {
39
+ const { className, children, initialValues = {}, validationSchema, defaultDisabled = {}, defaultValues, markEdited, onInit, onChange, onSubmit, ...restProps } = props;
40
+ const validationSchemaRef = useRef(validationSchema);
41
+ const defaultValuesRef = useRef({});
42
+ // Update default values helper
43
+ const updateDefaultValues = (propsToUse = props) => {
44
+ const { defaultValues: dv, initialValues: iv } = propsToUse;
45
+ return dv || cloneValues(iv);
114
46
  };
115
- setValues = vals => {
116
- const { values } = this.store;
117
- Object.assign(values, vals);
118
- this.calcChangedAll();
119
- this.validate();
120
- return values;
47
+ // Initialize default values
48
+ defaultValuesRef.current = updateDefaultValues();
49
+ // Separate states
50
+ const [values, _setValues] = useState(() => cloneValues(initialValues));
51
+ const [touched, _setTouched] = useState(() => getInitialTouched(initialValues));
52
+ const [changed, _setChanged] = useState({});
53
+ const [disabled, setDisabled] = useState(() => ({ ...defaultDisabled }));
54
+ const [isLoading, setIsLoading] = useState(false);
55
+ const [isDirty, setIsDirty] = useState(false);
56
+ const [isValid, setIsValid] = useState(true);
57
+ const [errors, _setErrors] = useState({});
58
+ const [isEmpty, setIsEmpty] = useState(() => Object.keys(getChanged(defaultValuesRef.current, initialValues))
59
+ .length === 0);
60
+ // Refs for stable handlers
61
+ const valuesRef = useRef(values);
62
+ const changedRef = useRef(changed);
63
+ const touchedRef = useRef(touched);
64
+ const errorsRef = useRef(errors);
65
+ const onChangeRef = useRef(onChange);
66
+ const setValues = (newValues) => {
67
+ _setValues(newValues);
68
+ valuesRef.current = newValues;
121
69
  };
122
- setDisabled = (name, isDisabled) => {
123
- const { disabled } = this.store;
124
- if (typeof name === 'object') {
125
- Object.assign(disabled, name);
126
- return;
127
- }
128
- if (isDisabled) {
129
- disabled[name] = true;
130
- }
131
- else {
132
- delete disabled[name];
133
- }
70
+ const setValue = (field, val) => {
71
+ setValues({ ...valuesRef.current, [field]: val });
134
72
  };
135
- reset = () => {
136
- const { initialValues } = this.props;
137
- this.setValues(initialValues);
138
- this.store.touched = getInitialTouched(initialValues);
73
+ const setErrors = (newErrors) => {
74
+ _setErrors(newErrors);
75
+ errorsRef.current = newErrors;
139
76
  };
140
- field = (props) => jsx(Field, { ...this.getFieldProps(props) });
141
- getFieldProps(props) {
142
- const { markEdited } = this.props;
143
- const { name } = props;
144
- const { values, changed, touched, errors } = this.store.originalObject;
145
- const fieldProps = {
146
- ...props,
147
- value: values[name],
148
- markEdited,
149
- isChanged: changed[name],
150
- isTouched: touched[name],
151
- error: errors?.[name],
152
- handleChange: this.onChange,
153
- handleBlur: this.onBlur,
154
- };
155
- if (this.validationSchema?.[name].empty === false)
156
- fieldProps.required = true;
157
- return fieldProps;
158
- }
159
- getFormAPI() {
160
- return {
161
- ...pick(this.store.originalObject, STORE_FIELDS_EXPOSED),
162
- Field: this.field,
163
- setValue: this.setValue,
164
- setValues: this.setValues,
165
- setDisabled: this.setDisabled,
166
- reset: this.reset,
167
- submit: this.onSubmit,
168
- };
169
- }
170
- getValidationState(store) {
171
- const errors = this.getValidationErrors(store);
172
- const isValid = Object.keys(errors).length === 0;
173
- return { isValid, errors };
174
- }
175
- getValidationErrors(store = this.store.originalObject) {
176
- const { values, disabled } = store;
177
- if (!this.validationSchema)
77
+ const setTouched = (newTouched) => {
78
+ _setTouched(newTouched);
79
+ touchedRef.current = newTouched;
80
+ };
81
+ const setFieldTouched = (field, isTouched) => {
82
+ setTouched({ ...touchedRef.current, [field]: isTouched });
83
+ };
84
+ const setChanged = (newChanged) => {
85
+ _setChanged(newChanged);
86
+ changedRef.current = newChanged;
87
+ };
88
+ // Update refs
89
+ onChangeRef.current = onChange;
90
+ const updateIsDirty = () => {
91
+ const newIsDirty = Object.keys(changedRef.current).length > 0;
92
+ setIsDirty(newIsDirty);
93
+ };
94
+ const updateIsEmpty = () => {
95
+ const newNotEmpty = getChanged(defaultValuesRef.current, valuesRef.current);
96
+ setIsEmpty(Object.keys(newNotEmpty).length === 0);
97
+ };
98
+ // Validation functions
99
+ const getValidationErrors = useCallback((valuesData = valuesRef.current, disabledData = disabled) => {
100
+ if (!validationSchemaRef.current)
178
101
  return {};
179
- // @ts-ignore
180
- const schema = Object.entries(this.validationSchema).reduce((acc, [field, { ...rule }]) => {
102
+ const schema = Object.entries(validationSchemaRef.current).reduce((acc, [field, { ...rule }]) => {
181
103
  const { type, check } = rule;
182
- if (disabled[field])
104
+ if (disabledData[field])
183
105
  return acc;
184
106
  if (type === 'custom') {
185
- // NOTE: pass all `values` to custom checker function
186
- // to allow create validator for dependent fields
187
- // @ts-ignore
188
107
  rule.check = function checkWrap(...args) {
189
- // @ts-ignore
190
- return check.call(this, ...args, values);
108
+ return check.call(this, ...args, valuesData);
191
109
  };
192
110
  }
193
111
  return { ...acc, [field]: rule };
194
112
  }, {});
195
- const res = Validator.validate(values, schema);
113
+ const res = Validator.validate(valuesData, schema);
196
114
  if (typeof res === 'object')
197
115
  return patchWithCustomMessages(res, schema);
198
116
  return {};
199
- }
200
- calcChanged(field, val) {
201
- const { initialValues } = this.props;
202
- const { changed, notEmpty } = this.store;
117
+ }, [values, disabled]);
118
+ const validate = useCallback(() => {
119
+ const newErrors = getValidationErrors();
120
+ const newIsValid = Object.keys(newErrors).length === 0;
121
+ setErrors(newErrors);
122
+ setIsValid(newIsValid);
123
+ }, [getValidationErrors]);
124
+ const calcChanged = useCallback((field, val) => {
125
+ const newChanged = { ...changedRef.current };
203
126
  if (compare(val, initialValues[field])) {
204
- delete changed[field];
205
- }
206
- else {
207
- changed[field] = true;
208
- }
209
- if (compare(val, this.defaultValues[field])) {
210
- delete notEmpty[field];
127
+ delete newChanged[field];
211
128
  }
212
129
  else {
213
- notEmpty[field] = true;
130
+ newChanged[field] = true;
214
131
  }
215
- Object.assign(this.store, {
216
- isDirty: Object.keys(changed).length > 0,
217
- isEmpty: Object.keys(notEmpty).length === 0,
218
- });
219
- }
220
- calcChangedAll(initialValues = this.props.initialValues) {
221
- const { values } = this.store.originalObject;
222
- const notEmpty = getNotEmpty(this.defaultValues, values);
223
- const changed = Object.entries(values).reduce((acc, [field, val]) => compare(initialValues[field], val) ? acc : { ...acc, [field]: true }, {});
224
- Object.assign(this.store, {
225
- changed,
226
- isDirty: Object.keys(changed).length > 0,
227
- isEmpty: Object.keys(notEmpty).length === 0,
132
+ setChanged(newChanged);
133
+ updateIsDirty();
134
+ updateIsEmpty();
135
+ }, [initialValues]);
136
+ const calcChangedAll = (initValues = initialValues) => {
137
+ const newChanged = Object.entries(values).reduce((acc, [field, val]) => compare(initValues[field], val) ? acc : { ...acc, [field]: true }, {});
138
+ setChanged(newChanged);
139
+ updateIsDirty();
140
+ updateIsEmpty();
141
+ };
142
+ // Form API methods
143
+ const setValueAPI = (field, val) => {
144
+ setValue(field, val);
145
+ calcChanged(field, val);
146
+ validate();
147
+ };
148
+ const setValuesAPI = vals => {
149
+ const newValues = { ...valuesRef.current, ...vals };
150
+ setValues(newValues);
151
+ calcChangedAll();
152
+ validate();
153
+ return values;
154
+ };
155
+ const setDisabledAPI = useCallback((name, isDisabledFlag) => {
156
+ setDisabled(prev => {
157
+ const newDisabled = { ...prev };
158
+ if (typeof name === 'object') {
159
+ Object.assign(newDisabled, name);
160
+ }
161
+ else if (isDisabledFlag) {
162
+ newDisabled[name] = true;
163
+ }
164
+ else {
165
+ delete newDisabled[name];
166
+ }
167
+ return newDisabled;
228
168
  });
229
- }
230
- validate() {
231
- Object.assign(this.store, this.getValidationState());
232
- }
233
- onInit() {
234
- const { onInit } = this.props;
235
- if (onInit)
236
- onInit(this.getFormAPI());
237
- }
238
- onSubmit = async (e) => {
239
- const { onSubmit } = this.props;
240
- const { values } = this.store.originalObject;
169
+ }, []);
170
+ const reset = useCallback(() => {
171
+ setValues(cloneValues(initialValues));
172
+ setTouched({});
173
+ setChanged({});
174
+ updateIsDirty();
175
+ updateIsEmpty();
176
+ validate();
177
+ }, [initialValues]);
178
+ // Event handlers - memoized to prevent field recreation
179
+ const onChangeHandler = useCallback((field, val) => {
180
+ if (valuesRef.current[field] === val)
181
+ return;
182
+ const newValues = { ...valuesRef.current, [field]: val };
183
+ if (onChangeRef.current && !onChangeRef.current(newValues))
184
+ return;
185
+ setValue(field, val);
186
+ setFieldTouched(field, true);
187
+ calcChanged(field, val);
188
+ validate();
189
+ }, [calcChanged, validate]);
190
+ const onBlurHandler = useCallback((name) => {
191
+ setFieldTouched(name, true);
192
+ }, []);
193
+ const onSubmitHandler = async (e) => {
241
194
  e?.preventDefault();
242
195
  dropFocusFromSubmit();
243
196
  if (!onSubmit)
244
197
  return;
245
- this.store.isLoading = true;
198
+ setIsLoading(true);
246
199
  await onSubmit({ ...values });
247
- this.store.isLoading = false;
248
- };
249
- onChange = (field, val) => {
250
- const { onChange } = this.props;
251
- const { values, touched } = this.store;
252
- if (values[field] === val)
253
- return;
254
- const newValues = { ...values.originalObject, [field]: val };
255
- // @ts-ignore
256
- if (onChange && onChange(newValues) === false)
257
- return;
258
- values[field] = val;
259
- touched[field] = true;
260
- this.handleChange(field, val);
200
+ setIsLoading(false);
261
201
  };
262
- onBlur = (name) => {
263
- this.store.touched[name] = true;
202
+ // Simple field component - let memo on Field handle optimization
203
+ const FieldComponent = useRef((fieldProps) => {
204
+ const { name } = fieldProps;
205
+ const fullProps = {
206
+ ...fieldProps,
207
+ value: valuesRef.current[name],
208
+ error: errorsRef.current[name],
209
+ markEdited,
210
+ isChanged: changedRef.current[name],
211
+ isTouched: touchedRef.current[name],
212
+ handleChange: onChangeHandler,
213
+ handleBlur: onBlurHandler,
214
+ };
215
+ if (validationSchemaRef.current?.[name]?.empty === false) {
216
+ fullProps.required = true;
217
+ }
218
+ return jsx(Field, { ...fullProps });
219
+ });
220
+ const formAPI = {
221
+ values,
222
+ touched,
223
+ changed,
224
+ disabled,
225
+ isLoading,
226
+ isDirty,
227
+ isValid,
228
+ isEmpty,
229
+ errors,
230
+ Field: FieldComponent.current,
231
+ setValue: setValueAPI,
232
+ setValues: setValuesAPI,
233
+ setDisabled: setDisabledAPI,
234
+ reset,
235
+ submit: onSubmitHandler,
264
236
  };
265
- handleChange(field, val) {
266
- this.calcChanged(field, val);
267
- this.validate();
268
- }
269
- render() {
270
- const { className, children, ...rest } = this.props;
271
- const { isLoading } = this.store;
272
- const classes = cn(S.root, className, isLoading && S.isLoading);
273
- const formProps = omit(rest, [
274
- 'defaultValues',
275
- 'defaultDisabled',
276
- 'initialValues',
277
- 'validationSchema',
278
- 'onInit',
279
- 'onChange',
280
- 'onSubmit',
281
- ]);
282
- return (jsx("form", { className: classes, ...formProps, onSubmit: this.onSubmit, children: children(this.getFormAPI()) }));
283
- }
237
+ // Effects
238
+ useEffect(() => {
239
+ validationSchemaRef.current = validationSchema;
240
+ }, [validationSchema]);
241
+ useEffect(() => {
242
+ calcChangedAll();
243
+ validate();
244
+ if (onInit)
245
+ onInit(formAPI);
246
+ }, []);
247
+ useEffect(() => {
248
+ const validationChanged = !compare(validationSchema, validationSchemaRef.current);
249
+ const initialValsChanged = !compare(initialValues, props.initialValues);
250
+ const defaultValsChanged = !compare(defaultValues, props.defaultValues);
251
+ if (initialValsChanged) {
252
+ setValues(cloneValues(initialValues));
253
+ validate();
254
+ if (onInit)
255
+ onInit(formAPI);
256
+ }
257
+ if (defaultValsChanged) {
258
+ defaultValuesRef.current = updateDefaultValues();
259
+ }
260
+ if (initialValsChanged || defaultValsChanged) {
261
+ calcChangedAll(initialValues);
262
+ }
263
+ if (initialValsChanged || validationChanged) {
264
+ validate();
265
+ }
266
+ }, [
267
+ initialValues,
268
+ validationSchema,
269
+ defaultValues,
270
+ onInit,
271
+ formAPI,
272
+ calcChangedAll,
273
+ validate,
274
+ ]);
275
+ const classes = cn(S.root, className, isLoading && S.isLoading);
276
+ return (jsx("form", { className: classes, ...restProps, onSubmit: onSubmitHandler, children: children(formAPI) }));
284
277
  }
285
278
 
286
279
  export { Form };
@@ -51,7 +51,7 @@ const Input = forwardRef((props, ref) => {
51
51
  const [inputValue, setInputValue] = useState((value ?? defaultValue ?? ''));
52
52
  const [labelClipPath, setLabelClipPath] = useState('');
53
53
  const [autoComplete, setAutoComplete] = useState('');
54
- const uid = generateUID();
54
+ const uid = useRef(generateUID());
55
55
  const isTextArea = type === 'textarea';
56
56
  const isNumber = type === 'number';
57
57
  const hasValue = isNumber || Boolean(value || inputValue || defaultValue);
@@ -171,7 +171,7 @@ const Input = forwardRef((props, ref) => {
171
171
  }
172
172
  if (!autoComplete) {
173
173
  controlProps.suppressHydrationWarning = true;
174
- controlProps.autoComplete = uid;
174
+ controlProps.autoComplete = uid.current;
175
175
  delete controlProps.name;
176
176
  }
177
177
  if (controlProps.value === undefined)
@@ -196,7 +196,6 @@ const Input = forwardRef((props, ref) => {
196
196
  label,
197
197
  isLabelOnTop,
198
198
  autoComplete,
199
- uid,
200
199
  ]);
201
200
  const wrapControl = control => {
202
201
  if (isTextArea) {
@@ -254,7 +253,7 @@ const Input = forwardRef((props, ref) => {
254
253
  }, []);
255
254
  const Control = isTextArea ? 'span' : 'input';
256
255
  const classes = cn(S.root, isTextArea && S.isTextArea, S[`size-${size}`], S[`variant-${variant}`], isFocused && S.isFocused, error && S.hasError, hasClear && S.hasClear, disabled && S.isDisabled, round && S.round, className);
257
- return (jsxs("div", { className: classes, title: String(value), children: [jsxs("label", { className: cn(S.main, clearPaddingLeft && S.clearPaddingLeft, clearPaddingRight && S.clearPaddingRight), children: [jsx("div", { className: S.border, suppressHydrationWarning: true, style: { clipPath: labelClipPath } }, "border"), renderAddon('left'), wrapControl(jsxs(Fragment, { children: [createElement(Control, { ...controlProps, className: cn(S.control, controlProps?.className), ref: setRef, key: "control" }), isTextArea &&
256
+ return (jsxs("div", { className: classes, children: [jsxs("label", { className: cn(S.main, clearPaddingLeft && S.clearPaddingLeft, clearPaddingRight && S.clearPaddingRight), children: [jsx("div", { className: S.border, suppressHydrationWarning: true, style: { clipPath: labelClipPath } }, "border"), renderAddon('left'), wrapControl(jsxs(Fragment, { children: [createElement(Control, { ...controlProps, className: cn(S.control, controlProps?.className), ref: setRef, key: "control" }), isTextArea &&
258
257
  controlProps.placeholder &&
259
258
  !controlProps.value && (jsx("span", { className: S.placeholder, spellCheck: false, children: controlProps.placeholder }))] })), isNumber && (jsxs("div", { className: S.numberArrows, children: [jsx(Button, { variant: "clear", onClick: () => onNumberWheel(1), tabIndex: -1, children: jsx(Icon, { type: "chevronUp", size: size }) }), jsx(Button, { variant: "clear", onClick: () => onNumberWheel(-1), tabIndex: -1, children: jsx(Icon, { type: "chevronDown", size: size }) })] })), jsx(Label, { className: S.label, size: size, isOnTop: isLabelOnTop, isError: Boolean(error), onClipPathChange: onLabelClipPathChange, children: label }, "label"), hasClear && !disabled && hasValue && (jsx(Button, { className: S.clearButton, variant: "clear", size: size, square: true, round: round, onClick: onClearPress, title: "", children: jsx(Icon, { className: S.clearIcon, size: size, type: "close" }) }, "clear")), renderAddon('right'), required && !hideRequiredStar && (jsx(RequiredStar, { size: size }, "required-star"))] }, "main"), !disabled && typeof error === 'string' && (jsx(AssistiveText, { variant: "danger", size: size, children: error }, "assistive-text"))] }));
260
259
  });
@@ -1,32 +1,4 @@
1
- import { Component } from 'react';
2
1
  import * as T from './Form.types';
3
- export declare class Form extends Component<T.Props> {
4
- store: any;
5
- validationSchema: T.FormValidationSchema;
6
- defaultValues: T.FormValues;
7
- constructor(props: T.Props);
8
- componentDidMount(): void;
9
- shouldComponentUpdate({ defaultValues, initialValues, validationSchema, }: T.Props): boolean;
10
- updateDefaultValues(props?: Readonly<T.Props>): T.FormValues;
11
- setInitialVals(initialValues?: {}): void;
12
- setValue: (field: any, val: any) => void;
13
- setValues: (vals: any) => any;
14
- setDisabled: (name: string | object, isDisabled?: any) => void;
15
- reset: () => void;
16
- field: (props: T.FieldProps) => JSX.Element;
17
- getFieldProps(props: any): T.FormFieldProps;
18
- getFormAPI(): T.FormAPI;
19
- getValidationState(store?: any): T.ValidationState;
20
- getValidationErrors(store?: T.ValidationStateParams): any;
21
- calcChanged(field: string, val: any): void;
22
- calcChangedAll(initialValues?: T.FormValues): void;
23
- validate(): void;
24
- onInit(): void;
25
- onSubmit: (e: any) => Promise<void>;
26
- onChange: (field: string, val: any) => void;
27
- onBlur: (name: string) => void;
28
- handleChange(field: string, val: any): void;
29
- render(): JSX.Element;
30
- }
2
+ export declare function Form(props: T.Props): JSX.Element;
31
3
  export * from './SubmitButtons/SubmitButtons';
32
4
  export * as FormTypes from './Form.types';
@@ -1,6 +1,6 @@
1
1
  export declare function patchWithCustomMessages(checkRes: any, validationSchema: any): any;
2
2
  export declare function dropFocusFromSubmit(): void;
3
3
  export declare function getInitialTouched(initialValues: any): {};
4
- export declare function getNotEmpty(_defaultValues: any, values: any): {};
4
+ export declare function getChanged(_defaultValues: any, values: any): {};
5
5
  export declare function getVal(e: any, val: any, valField: any): any;
6
6
  export declare function cloneValues(values: any): {};
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -45,7 +45,7 @@ export type Props = ComponentType & {
45
45
  markEdited?: boolean;
46
46
  children: (api: FormAPI) => ReactNode | ReactNode[];
47
47
  onInit?: (api: FormAPI) => boolean | void;
48
- onChange?: (values: FormValues) => void;
48
+ onChange?: (values: FormValues) => void | boolean;
49
49
  onSubmit?: (values: FormValues) => Promise<void>;
50
50
  };
51
51
  export type FieldProps = {
@@ -76,6 +76,7 @@ export declare const icons: {
76
76
  soundWave: () => Promise<any>;
77
77
  sparks: () => Promise<any>;
78
78
  star: () => Promise<any>;
79
+ stopInCircle: () => Promise<any>;
79
80
  syncArrows: () => Promise<any>;
80
81
  table: () => Promise<any>;
81
82
  telegram: () => Promise<any>;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "4.25.3",
3
+ "version": "4.26.1",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
- "test": "jest",
6
+ "tests": "jest",
7
+ "tests:watch": "jest --watch",
7
8
  "ts": "tsc --noUnusedLocals",
8
9
  "dev": "NODE_OPTIONS='--loader ts-node/esm' NODE_ENV=development webpack-dev-server --mode=development --config ./src/docs/config/webpack.config.js --progress",
9
10
  "build": "rollup -c rollup.config.ts --configPlugin @rollup/plugin-typescript",