@os-design/form 1.0.3 → 1.0.5
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.
- package/README.md +21 -0
- package/dist/cjs/index.js +28 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -325,6 +325,27 @@ const Form: React.FC = () => {
|
|
|
325
325
|
};
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
+
To reset the entire form (e.g. when the modal with the form is closed), call `form.reset()`.
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
const Form: React.FC = () => {
|
|
332
|
+
const { Field, form } = useForm<FormData>({
|
|
333
|
+
title: 'Title',
|
|
334
|
+
content: 'Content',
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
const onReset = useCallback(() => form.reset(), [form]);
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<Form>
|
|
341
|
+
<Field name='title' render={(props) => <Input {...props} />} />
|
|
342
|
+
<Field name='content' render={(props) => <TextArea {...props} />} />
|
|
343
|
+
<Button onClick={onReset}>Reset</Button>
|
|
344
|
+
</Form>
|
|
345
|
+
);
|
|
346
|
+
};
|
|
347
|
+
```
|
|
348
|
+
|
|
328
349
|
## 🎚️ Transforming field values
|
|
329
350
|
|
|
330
351
|
There are few cases where this is necessary:
|
package/dist/cjs/index.js
CHANGED
|
@@ -42,18 +42,36 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
42
42
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
43
43
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
44
44
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
45
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
45
46
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
46
47
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
48
|
+
var Form = /*#__PURE__*/function () {
|
|
49
|
+
function Form(initValues) {
|
|
50
|
+
_classCallCheck(this, Form);
|
|
51
|
+
this.initValues = void 0;
|
|
52
|
+
this.values = void 0;
|
|
53
|
+
this.errors = void 0;
|
|
54
|
+
this.initValues = initValues;
|
|
55
|
+
this.values = new _SubscribableData["default"]((0, _clone["default"])(initValues));
|
|
56
|
+
this.errors = new _SubscribableData["default"]({});
|
|
57
|
+
}
|
|
58
|
+
_createClass(Form, [{
|
|
59
|
+
key: "reset",
|
|
60
|
+
value: function reset() {
|
|
61
|
+
var _this = this;
|
|
62
|
+
// Reset values
|
|
63
|
+
Object.keys(this.values.getAll()).forEach(function (name) {
|
|
64
|
+
_this.values.set(name, _this.initValues[name]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Reset errors
|
|
68
|
+
Object.keys(this.errors.getAll()).forEach(function (name) {
|
|
69
|
+
_this.errors.set(name, undefined);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}]);
|
|
73
|
+
return Form;
|
|
74
|
+
}();
|
|
57
75
|
var FormContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
58
76
|
// eslint-disable-next-line react/function-component-definition
|
|
59
77
|
function FormProvider(_ref) {
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Form","initValues","values","errors","SubscribableData","clone","FormContext","createContext","FormProvider","form","children","createUseValueHook","name","useState","get","value","setValue","useEffect","subscription","subscribeToField","v","unsubscribe","useError","currentForm","useContext","Error","createUseTransformerHook","useValue","transformer","transformerRef","useRef","current","partialValues","Object","entries","forEach","n","set","createFieldComponent","props","toValue","fromValue","render","transformedValue","useMemo","error","modified","isEqual","reset","useCallback","fromValueRef","onChange","undefined","renderRef","inputProps","fieldState","useModifiedFields","modifiedFields","setModifiedFields","modifiedFieldsRef","initValuesRef","subscribeToAllFields","isInitValue","fields","includes","filter","field","useFormResponse","useTransformer","Field","length","useForm","memoizedInitValues","useDeepEqualMemo","useExistingForm"],"sources":["../../src/index.tsx"],"sourcesContent":["import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport SubscribableData from './SubscribableData';\nimport clone from './utils/clone';\nimport isEqual from './utils/isEqual';\nimport useDeepEqualMemo from './utils/useDeepEqualMemo';\n\nexport * from './SubscriptionManager';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype Values = Record<string, any>;\ntype Errors<TValues extends Values> = Record<keyof TValues, string | undefined>;\n\nclass Form<\n TValues extends Values,\n TErrors extends Errors<TValues> = Errors<TValues>\n> {\n public readonly initValues: TValues;\n\n public readonly values: SubscribableData<TValues>;\n\n public readonly errors: SubscribableData<TErrors>;\n\n public constructor(initValues: TValues) {\n this.initValues = initValues;\n this.values = new SubscribableData(clone(initValues));\n this.errors = new SubscribableData({} as TErrors);\n }\n}\n\nconst FormContext = createContext<any>(null);\n\ninterface FormProviderProps<TValues extends Values> {\n form: Form<TValues>;\n children?: ReactNode;\n}\n\n// eslint-disable-next-line react/function-component-definition\nexport function FormProvider<TValues extends Values>({\n form,\n children,\n}: FormProviderProps<TValues>) {\n return <FormContext.Provider value={form}>{children}</FormContext.Provider>;\n}\n\nconst createUseValueHook =\n <TValues extends Values>(form: Form<TValues>) =>\n <TName extends keyof TValues>(name: TName) => {\n const [value, setValue] = useState<TValues[TName]>(form.values.get(name));\n\n useEffect(() => {\n const subscription = form.values.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [name]);\n\n return value;\n };\n\nexport const useError = <\n TValues extends Values = Values,\n TName extends keyof TValues = keyof TValues\n>(\n name: TName,\n form?: Form<TValues>\n) => {\n const currentForm = useContext(FormContext) || form;\n if (!currentForm) throw new Error('Specify the form');\n const [value, setValue] = useState<string | undefined>(\n currentForm.errors.get(name)\n );\n\n useEffect(() => {\n const subscription = currentForm.errors.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [currentForm.errors, name]);\n\n return value;\n};\n\nexport type Transformer<TValues extends Values, TName extends keyof TValues> = (\n value: TValues[TName]\n) => Partial<TValues>;\n\nconst createUseTransformerHook = <TValues extends Values>(\n form: Form<TValues>\n) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n name: TName,\n transformer: Transformer<TValues, TName>\n ) => {\n const value = useValue(name);\n\n const transformerRef = useRef(transformer);\n useEffect(() => {\n transformerRef.current = transformer;\n }, [transformer]);\n\n useEffect(() => {\n const partialValues = transformerRef.current(value);\n Object.entries(partialValues).forEach(([n, v]) => {\n form.values.set(n, v);\n });\n }, [value]);\n };\n};\n\ninterface InputProps<T> {\n value: T;\n onChange: (value: T) => void;\n}\ninterface FieldState {\n error?: string;\n modified: boolean;\n reset: () => void;\n}\ninterface FieldPropsWithoutTransformers<TName, TStateValue> {\n name: TName;\n toValue?: never;\n fromValue?: never;\n render: (\n inputProps: InputProps<TStateValue>,\n fieldState: FieldState\n ) => ReactElement;\n}\ninterface FieldPropsWithTransformers<TName, TStateValue, TInputValue> {\n name: TName;\n toValue: (value: TStateValue) => TInputValue;\n fromValue?: (value: TInputValue) => TStateValue;\n render: (\n inputProps: InputProps<TInputValue>,\n fieldState: FieldState\n ) => ReactElement;\n}\ntype FieldProps<TName, TStateValue, TInputValue> =\n | FieldPropsWithoutTransformers<TName, TStateValue>\n | FieldPropsWithTransformers<TName, TStateValue, TInputValue>;\n\nconst createFieldComponent = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n props: FieldProps<TName, TValues[TName], any>\n ) => {\n const { name, toValue, fromValue, render } = props;\n\n const value = useValue(name);\n const transformedValue = useMemo<any>(\n () => (toValue ? toValue(value) : value),\n [toValue, value]\n );\n const error = useError<TValues>(name, form);\n\n const modified = useMemo(\n () => !isEqual(value, form.initValues[name]),\n [name, value]\n );\n const reset = useCallback(\n () => form.values.set(name, form.initValues[name]),\n [name]\n );\n\n const fromValueRef = useRef(fromValue);\n useEffect(() => {\n fromValueRef.current = fromValue;\n }, [fromValue]);\n\n const onChange = useCallback(\n (v: any) => {\n form.values.set(\n name,\n fromValueRef.current ? fromValueRef.current(v) : (v as TValues[TName])\n );\n form.errors.set(name, undefined);\n },\n [name]\n );\n\n const renderRef = useRef(render);\n useEffect(() => {\n renderRef.current = render;\n }, [render]);\n\n const inputProps = useMemo(\n () => ({ value: transformedValue, onChange }),\n [onChange, transformedValue]\n );\n const fieldState = useMemo(\n () => ({ error, modified, reset }),\n [error, modified, reset]\n );\n\n return useMemo(\n () => renderRef.current(inputProps, fieldState),\n [fieldState, inputProps]\n );\n };\n};\n\nconst useModifiedFields = <TValues extends Values>(form: Form<TValues>) => {\n const [modifiedFields, setModifiedFields] = useState<Array<keyof TValues>>(\n []\n );\n\n const modifiedFieldsRef = useRef(modifiedFields);\n useEffect(() => {\n modifiedFieldsRef.current = modifiedFields;\n }, [modifiedFields]);\n\n const initValuesRef = useRef(form.initValues);\n useEffect(() => {\n initValuesRef.current = form.initValues;\n }, [form.initValues]);\n\n useEffect(() => {\n const subscription = form.values.subscribeToAllFields((name, value) => {\n const isInitValue = isEqual(value, initValuesRef.current[name]);\n const fields = modifiedFieldsRef.current;\n\n if (fields.includes(name)) {\n if (isInitValue) {\n setModifiedFields(fields.filter((field) => field !== name));\n }\n } else if (!isInitValue) {\n setModifiedFields([...fields, name]);\n }\n });\n return () => subscription.unsubscribe();\n }, [form.values]);\n\n return modifiedFields;\n};\n\nconst useFormResponse = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = useMemo(() => createUseValueHook(form), [form]);\n const useTransformer = useMemo(() => createUseTransformerHook(form), [form]);\n const Field = useMemo(() => createFieldComponent(form), [form]);\n\n const modifiedFields = useModifiedFields(form);\n const modified = useMemo(\n () => modifiedFields.length > 0,\n [modifiedFields.length]\n );\n\n return useMemo(\n () => ({\n form,\n Field,\n useValue,\n useTransformer,\n modifiedFields,\n modified,\n }),\n [Field, form, modified, modifiedFields, useTransformer, useValue]\n );\n};\n\nexport const useForm = <TValues extends Values = Values>(\n initValues: TValues\n) => {\n const memoizedInitValues = useDeepEqualMemo<TValues>(\n () => initValues,\n [initValues]\n );\n const form = useMemo(\n () => new Form<TValues>(memoizedInitValues),\n [memoizedInitValues]\n );\n return useFormResponse(form);\n};\n\nexport const useExistingForm = <TValues extends Values = Values>() => {\n const form = useContext<Form<TValues> | null>(FormContext);\n if (!form) throw new Error('Wrap your form in a FormProvider');\n return useFormResponse(form);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Form","initValues","values","errors","SubscribableData","clone","Object","keys","getAll","forEach","name","set","undefined","FormContext","createContext","FormProvider","form","children","createUseValueHook","useState","get","value","setValue","useEffect","subscription","subscribeToField","v","unsubscribe","useError","currentForm","useContext","Error","createUseTransformerHook","useValue","transformer","transformerRef","useRef","current","partialValues","entries","n","createFieldComponent","props","toValue","fromValue","render","transformedValue","useMemo","error","modified","isEqual","reset","useCallback","fromValueRef","onChange","renderRef","inputProps","fieldState","useModifiedFields","modifiedFields","setModifiedFields","modifiedFieldsRef","initValuesRef","subscribeToAllFields","isInitValue","fields","includes","filter","field","useFormResponse","useTransformer","Field","length","useForm","memoizedInitValues","useDeepEqualMemo","useExistingForm"],"sources":["../../src/index.tsx"],"sourcesContent":["import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport SubscribableData from './SubscribableData';\nimport clone from './utils/clone';\nimport isEqual from './utils/isEqual';\nimport useDeepEqualMemo from './utils/useDeepEqualMemo';\n\nexport * from './SubscriptionManager';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype Values = Record<string, any>;\ntype Errors<TValues extends Values> = Record<keyof TValues, string | undefined>;\n\nclass Form<\n TValues extends Values,\n TErrors extends Errors<TValues> = Errors<TValues>\n> {\n public readonly initValues: TValues;\n\n public readonly values: SubscribableData<TValues>;\n\n public readonly errors: SubscribableData<TErrors>;\n\n public constructor(initValues: TValues) {\n this.initValues = initValues;\n this.values = new SubscribableData(clone(initValues));\n this.errors = new SubscribableData({} as TErrors);\n }\n\n public reset() {\n // Reset values\n Object.keys(this.values.getAll()).forEach((name) => {\n this.values.set(name, this.initValues[name]);\n });\n\n // Reset errors\n Object.keys(this.errors.getAll()).forEach((name) => {\n this.errors.set(name, undefined as any);\n });\n }\n}\n\nconst FormContext = createContext<any>(null);\n\ninterface FormProviderProps<TValues extends Values> {\n form: Form<TValues>;\n children?: ReactNode;\n}\n\n// eslint-disable-next-line react/function-component-definition\nexport function FormProvider<TValues extends Values>({\n form,\n children,\n}: FormProviderProps<TValues>) {\n return <FormContext.Provider value={form}>{children}</FormContext.Provider>;\n}\n\nconst createUseValueHook =\n <TValues extends Values>(form: Form<TValues>) =>\n <TName extends keyof TValues>(name: TName) => {\n const [value, setValue] = useState<TValues[TName]>(form.values.get(name));\n\n useEffect(() => {\n const subscription = form.values.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [name]);\n\n return value;\n };\n\nexport const useError = <\n TValues extends Values = Values,\n TName extends keyof TValues = keyof TValues\n>(\n name: TName,\n form?: Form<TValues>\n) => {\n const currentForm = useContext(FormContext) || form;\n if (!currentForm) throw new Error('Specify the form');\n const [value, setValue] = useState<string | undefined>(\n currentForm.errors.get(name)\n );\n\n useEffect(() => {\n const subscription = currentForm.errors.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [currentForm.errors, name]);\n\n return value;\n};\n\nexport type Transformer<TValues extends Values, TName extends keyof TValues> = (\n value: TValues[TName]\n) => Partial<TValues>;\n\nconst createUseTransformerHook = <TValues extends Values>(\n form: Form<TValues>\n) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n name: TName,\n transformer: Transformer<TValues, TName>\n ) => {\n const value = useValue(name);\n\n const transformerRef = useRef(transformer);\n useEffect(() => {\n transformerRef.current = transformer;\n }, [transformer]);\n\n useEffect(() => {\n const partialValues = transformerRef.current(value);\n Object.entries(partialValues).forEach(([n, v]) => {\n form.values.set(n, v);\n });\n }, [value]);\n };\n};\n\ninterface InputProps<T> {\n value: T;\n onChange: (value: T) => void;\n}\ninterface FieldState {\n error?: string;\n modified: boolean;\n reset: () => void;\n}\ninterface FieldPropsWithoutTransformers<TName, TStateValue> {\n name: TName;\n toValue?: never;\n fromValue?: never;\n render: (\n inputProps: InputProps<TStateValue>,\n fieldState: FieldState\n ) => ReactElement | null;\n}\ninterface FieldPropsWithTransformers<TName, TStateValue, TInputValue> {\n name: TName;\n toValue: (value: TStateValue) => TInputValue;\n fromValue?: (value: TInputValue) => TStateValue;\n render: (\n inputProps: InputProps<TInputValue>,\n fieldState: FieldState\n ) => ReactElement | null;\n}\ntype FieldProps<TName, TStateValue, TInputValue> =\n | FieldPropsWithoutTransformers<TName, TStateValue>\n | FieldPropsWithTransformers<TName, TStateValue, TInputValue>;\n\nconst createFieldComponent = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n props: FieldProps<TName, TValues[TName], any>\n ) => {\n const { name, toValue, fromValue, render } = props;\n\n const value = useValue(name);\n const transformedValue = useMemo<any>(\n () => (toValue ? toValue(value) : value),\n [toValue, value]\n );\n const error = useError<TValues>(name, form);\n\n const modified = useMemo(\n () => !isEqual(value, form.initValues[name]),\n [name, value]\n );\n const reset = useCallback(\n () => form.values.set(name, form.initValues[name]),\n [name]\n );\n\n const fromValueRef = useRef(fromValue);\n useEffect(() => {\n fromValueRef.current = fromValue;\n }, [fromValue]);\n\n const onChange = useCallback(\n (v: any) => {\n form.values.set(\n name,\n fromValueRef.current ? fromValueRef.current(v) : (v as TValues[TName])\n );\n form.errors.set(name, undefined);\n },\n [name]\n );\n\n const renderRef = useRef(render);\n useEffect(() => {\n renderRef.current = render;\n }, [render]);\n\n const inputProps = useMemo(\n () => ({ value: transformedValue, onChange }),\n [onChange, transformedValue]\n );\n const fieldState = useMemo(\n () => ({ error, modified, reset }),\n [error, modified, reset]\n );\n\n return useMemo(\n () => renderRef.current(inputProps, fieldState),\n [fieldState, inputProps]\n );\n };\n};\n\nconst useModifiedFields = <TValues extends Values>(form: Form<TValues>) => {\n const [modifiedFields, setModifiedFields] = useState<Array<keyof TValues>>(\n []\n );\n\n const modifiedFieldsRef = useRef(modifiedFields);\n useEffect(() => {\n modifiedFieldsRef.current = modifiedFields;\n }, [modifiedFields]);\n\n const initValuesRef = useRef(form.initValues);\n useEffect(() => {\n initValuesRef.current = form.initValues;\n }, [form.initValues]);\n\n useEffect(() => {\n const subscription = form.values.subscribeToAllFields((name, value) => {\n const isInitValue = isEqual(value, initValuesRef.current[name]);\n const fields = modifiedFieldsRef.current;\n\n if (fields.includes(name)) {\n if (isInitValue) {\n setModifiedFields(fields.filter((field) => field !== name));\n }\n } else if (!isInitValue) {\n setModifiedFields([...fields, name]);\n }\n });\n return () => subscription.unsubscribe();\n }, [form.values]);\n\n return modifiedFields;\n};\n\nconst useFormResponse = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = useMemo(() => createUseValueHook(form), [form]);\n const useTransformer = useMemo(() => createUseTransformerHook(form), [form]);\n const Field = useMemo(() => createFieldComponent(form), [form]);\n\n const modifiedFields = useModifiedFields(form);\n const modified = useMemo(\n () => modifiedFields.length > 0,\n [modifiedFields.length]\n );\n\n return useMemo(\n () => ({\n form,\n Field,\n useValue,\n useTransformer,\n modifiedFields,\n modified,\n }),\n [Field, form, modified, modifiedFields, useTransformer, useValue]\n );\n};\n\nexport const useForm = <TValues extends Values = Values>(\n initValues: TValues\n) => {\n const memoizedInitValues = useDeepEqualMemo<TValues>(\n () => initValues,\n [initValues]\n );\n const form = useMemo(\n () => new Form<TValues>(memoizedInitValues),\n [memoizedInitValues]\n );\n return useFormResponse(form);\n};\n\nexport const useExistingForm = <TValues extends Values = Values>() => {\n const form = useContext<Form<TValues> | null>(FormContext);\n if (!form) throw new Error('Wrap your form in a FormProvider');\n return useFormResponse(form);\n};\n"],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -16,6 +16,17 @@ class Form {
|
|
|
16
16
|
this.values = new SubscribableData(clone(initValues));
|
|
17
17
|
this.errors = new SubscribableData({});
|
|
18
18
|
}
|
|
19
|
+
reset() {
|
|
20
|
+
// Reset values
|
|
21
|
+
Object.keys(this.values.getAll()).forEach(name => {
|
|
22
|
+
this.values.set(name, this.initValues[name]);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Reset errors
|
|
26
|
+
Object.keys(this.errors.getAll()).forEach(name => {
|
|
27
|
+
this.errors.set(name, undefined);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
19
30
|
}
|
|
20
31
|
const FormContext = /*#__PURE__*/createContext(null);
|
|
21
32
|
// eslint-disable-next-line react/function-component-definition
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","SubscribableData","clone","isEqual","useDeepEqualMemo","Form","constructor","initValues","values","errors","FormContext","FormProvider","form","children","createUseValueHook","name","value","setValue","get","subscription","subscribeToField","v","unsubscribe","useError","currentForm","Error","createUseTransformerHook","useValue","transformer","transformerRef","current","partialValues","Object","entries","forEach","n","set","createFieldComponent","props","toValue","fromValue","render","transformedValue","error","modified","reset","fromValueRef","onChange","undefined","renderRef","inputProps","fieldState","useModifiedFields","modifiedFields","setModifiedFields","modifiedFieldsRef","initValuesRef","subscribeToAllFields","isInitValue","fields","includes","filter","field","useFormResponse","useTransformer","Field","length","useForm","memoizedInitValues","useExistingForm"],"sources":["../../src/index.tsx"],"sourcesContent":["import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport SubscribableData from './SubscribableData';\nimport clone from './utils/clone';\nimport isEqual from './utils/isEqual';\nimport useDeepEqualMemo from './utils/useDeepEqualMemo';\n\nexport * from './SubscriptionManager';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype Values = Record<string, any>;\ntype Errors<TValues extends Values> = Record<keyof TValues, string | undefined>;\n\nclass Form<\n TValues extends Values,\n TErrors extends Errors<TValues> = Errors<TValues>\n> {\n public readonly initValues: TValues;\n\n public readonly values: SubscribableData<TValues>;\n\n public readonly errors: SubscribableData<TErrors>;\n\n public constructor(initValues: TValues) {\n this.initValues = initValues;\n this.values = new SubscribableData(clone(initValues));\n this.errors = new SubscribableData({} as TErrors);\n }\n}\n\nconst FormContext = createContext<any>(null);\n\ninterface FormProviderProps<TValues extends Values> {\n form: Form<TValues>;\n children?: ReactNode;\n}\n\n// eslint-disable-next-line react/function-component-definition\nexport function FormProvider<TValues extends Values>({\n form,\n children,\n}: FormProviderProps<TValues>) {\n return <FormContext.Provider value={form}>{children}</FormContext.Provider>;\n}\n\nconst createUseValueHook =\n <TValues extends Values>(form: Form<TValues>) =>\n <TName extends keyof TValues>(name: TName) => {\n const [value, setValue] = useState<TValues[TName]>(form.values.get(name));\n\n useEffect(() => {\n const subscription = form.values.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [name]);\n\n return value;\n };\n\nexport const useError = <\n TValues extends Values = Values,\n TName extends keyof TValues = keyof TValues\n>(\n name: TName,\n form?: Form<TValues>\n) => {\n const currentForm = useContext(FormContext) || form;\n if (!currentForm) throw new Error('Specify the form');\n const [value, setValue] = useState<string | undefined>(\n currentForm.errors.get(name)\n );\n\n useEffect(() => {\n const subscription = currentForm.errors.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [currentForm.errors, name]);\n\n return value;\n};\n\nexport type Transformer<TValues extends Values, TName extends keyof TValues> = (\n value: TValues[TName]\n) => Partial<TValues>;\n\nconst createUseTransformerHook = <TValues extends Values>(\n form: Form<TValues>\n) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n name: TName,\n transformer: Transformer<TValues, TName>\n ) => {\n const value = useValue(name);\n\n const transformerRef = useRef(transformer);\n useEffect(() => {\n transformerRef.current = transformer;\n }, [transformer]);\n\n useEffect(() => {\n const partialValues = transformerRef.current(value);\n Object.entries(partialValues).forEach(([n, v]) => {\n form.values.set(n, v);\n });\n }, [value]);\n };\n};\n\ninterface InputProps<T> {\n value: T;\n onChange: (value: T) => void;\n}\ninterface FieldState {\n error?: string;\n modified: boolean;\n reset: () => void;\n}\ninterface FieldPropsWithoutTransformers<TName, TStateValue> {\n name: TName;\n toValue?: never;\n fromValue?: never;\n render: (\n inputProps: InputProps<TStateValue>,\n fieldState: FieldState\n ) => ReactElement;\n}\ninterface FieldPropsWithTransformers<TName, TStateValue, TInputValue> {\n name: TName;\n toValue: (value: TStateValue) => TInputValue;\n fromValue?: (value: TInputValue) => TStateValue;\n render: (\n inputProps: InputProps<TInputValue>,\n fieldState: FieldState\n ) => ReactElement;\n}\ntype FieldProps<TName, TStateValue, TInputValue> =\n | FieldPropsWithoutTransformers<TName, TStateValue>\n | FieldPropsWithTransformers<TName, TStateValue, TInputValue>;\n\nconst createFieldComponent = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n props: FieldProps<TName, TValues[TName], any>\n ) => {\n const { name, toValue, fromValue, render } = props;\n\n const value = useValue(name);\n const transformedValue = useMemo<any>(\n () => (toValue ? toValue(value) : value),\n [toValue, value]\n );\n const error = useError<TValues>(name, form);\n\n const modified = useMemo(\n () => !isEqual(value, form.initValues[name]),\n [name, value]\n );\n const reset = useCallback(\n () => form.values.set(name, form.initValues[name]),\n [name]\n );\n\n const fromValueRef = useRef(fromValue);\n useEffect(() => {\n fromValueRef.current = fromValue;\n }, [fromValue]);\n\n const onChange = useCallback(\n (v: any) => {\n form.values.set(\n name,\n fromValueRef.current ? fromValueRef.current(v) : (v as TValues[TName])\n );\n form.errors.set(name, undefined);\n },\n [name]\n );\n\n const renderRef = useRef(render);\n useEffect(() => {\n renderRef.current = render;\n }, [render]);\n\n const inputProps = useMemo(\n () => ({ value: transformedValue, onChange }),\n [onChange, transformedValue]\n );\n const fieldState = useMemo(\n () => ({ error, modified, reset }),\n [error, modified, reset]\n );\n\n return useMemo(\n () => renderRef.current(inputProps, fieldState),\n [fieldState, inputProps]\n );\n };\n};\n\nconst useModifiedFields = <TValues extends Values>(form: Form<TValues>) => {\n const [modifiedFields, setModifiedFields] = useState<Array<keyof TValues>>(\n []\n );\n\n const modifiedFieldsRef = useRef(modifiedFields);\n useEffect(() => {\n modifiedFieldsRef.current = modifiedFields;\n }, [modifiedFields]);\n\n const initValuesRef = useRef(form.initValues);\n useEffect(() => {\n initValuesRef.current = form.initValues;\n }, [form.initValues]);\n\n useEffect(() => {\n const subscription = form.values.subscribeToAllFields((name, value) => {\n const isInitValue = isEqual(value, initValuesRef.current[name]);\n const fields = modifiedFieldsRef.current;\n\n if (fields.includes(name)) {\n if (isInitValue) {\n setModifiedFields(fields.filter((field) => field !== name));\n }\n } else if (!isInitValue) {\n setModifiedFields([...fields, name]);\n }\n });\n return () => subscription.unsubscribe();\n }, [form.values]);\n\n return modifiedFields;\n};\n\nconst useFormResponse = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = useMemo(() => createUseValueHook(form), [form]);\n const useTransformer = useMemo(() => createUseTransformerHook(form), [form]);\n const Field = useMemo(() => createFieldComponent(form), [form]);\n\n const modifiedFields = useModifiedFields(form);\n const modified = useMemo(\n () => modifiedFields.length > 0,\n [modifiedFields.length]\n );\n\n return useMemo(\n () => ({\n form,\n Field,\n useValue,\n useTransformer,\n modifiedFields,\n modified,\n }),\n [Field, form, modified, modifiedFields, useTransformer, useValue]\n );\n};\n\nexport const useForm = <TValues extends Values = Values>(\n initValues: TValues\n) => {\n const memoizedInitValues = useDeepEqualMemo<TValues>(\n () => initValues,\n [initValues]\n );\n const form = useMemo(\n () => new Form<TValues>(memoizedInitValues),\n [memoizedInitValues]\n );\n return useFormResponse(form);\n};\n\nexport const useExistingForm = <TValues extends Values = Values>() => {\n const form = useContext<Form<TValues> | null>(FormContext);\n if (!form) throw new Error('Wrap your form in a FormProvider');\n return useFormResponse(form);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","SubscribableData","clone","isEqual","useDeepEqualMemo","Form","constructor","initValues","values","errors","reset","Object","keys","getAll","forEach","name","set","undefined","FormContext","FormProvider","form","children","createUseValueHook","value","setValue","get","subscription","subscribeToField","v","unsubscribe","useError","currentForm","Error","createUseTransformerHook","useValue","transformer","transformerRef","current","partialValues","entries","n","createFieldComponent","props","toValue","fromValue","render","transformedValue","error","modified","fromValueRef","onChange","renderRef","inputProps","fieldState","useModifiedFields","modifiedFields","setModifiedFields","modifiedFieldsRef","initValuesRef","subscribeToAllFields","isInitValue","fields","includes","filter","field","useFormResponse","useTransformer","Field","length","useForm","memoizedInitValues","useExistingForm"],"sources":["../../src/index.tsx"],"sourcesContent":["import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport SubscribableData from './SubscribableData';\nimport clone from './utils/clone';\nimport isEqual from './utils/isEqual';\nimport useDeepEqualMemo from './utils/useDeepEqualMemo';\n\nexport * from './SubscriptionManager';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype Values = Record<string, any>;\ntype Errors<TValues extends Values> = Record<keyof TValues, string | undefined>;\n\nclass Form<\n TValues extends Values,\n TErrors extends Errors<TValues> = Errors<TValues>\n> {\n public readonly initValues: TValues;\n\n public readonly values: SubscribableData<TValues>;\n\n public readonly errors: SubscribableData<TErrors>;\n\n public constructor(initValues: TValues) {\n this.initValues = initValues;\n this.values = new SubscribableData(clone(initValues));\n this.errors = new SubscribableData({} as TErrors);\n }\n\n public reset() {\n // Reset values\n Object.keys(this.values.getAll()).forEach((name) => {\n this.values.set(name, this.initValues[name]);\n });\n\n // Reset errors\n Object.keys(this.errors.getAll()).forEach((name) => {\n this.errors.set(name, undefined as any);\n });\n }\n}\n\nconst FormContext = createContext<any>(null);\n\ninterface FormProviderProps<TValues extends Values> {\n form: Form<TValues>;\n children?: ReactNode;\n}\n\n// eslint-disable-next-line react/function-component-definition\nexport function FormProvider<TValues extends Values>({\n form,\n children,\n}: FormProviderProps<TValues>) {\n return <FormContext.Provider value={form}>{children}</FormContext.Provider>;\n}\n\nconst createUseValueHook =\n <TValues extends Values>(form: Form<TValues>) =>\n <TName extends keyof TValues>(name: TName) => {\n const [value, setValue] = useState<TValues[TName]>(form.values.get(name));\n\n useEffect(() => {\n const subscription = form.values.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [name]);\n\n return value;\n };\n\nexport const useError = <\n TValues extends Values = Values,\n TName extends keyof TValues = keyof TValues\n>(\n name: TName,\n form?: Form<TValues>\n) => {\n const currentForm = useContext(FormContext) || form;\n if (!currentForm) throw new Error('Specify the form');\n const [value, setValue] = useState<string | undefined>(\n currentForm.errors.get(name)\n );\n\n useEffect(() => {\n const subscription = currentForm.errors.subscribeToField(name, (v) => {\n setValue(v);\n });\n return () => subscription.unsubscribe();\n }, [currentForm.errors, name]);\n\n return value;\n};\n\nexport type Transformer<TValues extends Values, TName extends keyof TValues> = (\n value: TValues[TName]\n) => Partial<TValues>;\n\nconst createUseTransformerHook = <TValues extends Values>(\n form: Form<TValues>\n) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n name: TName,\n transformer: Transformer<TValues, TName>\n ) => {\n const value = useValue(name);\n\n const transformerRef = useRef(transformer);\n useEffect(() => {\n transformerRef.current = transformer;\n }, [transformer]);\n\n useEffect(() => {\n const partialValues = transformerRef.current(value);\n Object.entries(partialValues).forEach(([n, v]) => {\n form.values.set(n, v);\n });\n }, [value]);\n };\n};\n\ninterface InputProps<T> {\n value: T;\n onChange: (value: T) => void;\n}\ninterface FieldState {\n error?: string;\n modified: boolean;\n reset: () => void;\n}\ninterface FieldPropsWithoutTransformers<TName, TStateValue> {\n name: TName;\n toValue?: never;\n fromValue?: never;\n render: (\n inputProps: InputProps<TStateValue>,\n fieldState: FieldState\n ) => ReactElement | null;\n}\ninterface FieldPropsWithTransformers<TName, TStateValue, TInputValue> {\n name: TName;\n toValue: (value: TStateValue) => TInputValue;\n fromValue?: (value: TInputValue) => TStateValue;\n render: (\n inputProps: InputProps<TInputValue>,\n fieldState: FieldState\n ) => ReactElement | null;\n}\ntype FieldProps<TName, TStateValue, TInputValue> =\n | FieldPropsWithoutTransformers<TName, TStateValue>\n | FieldPropsWithTransformers<TName, TStateValue, TInputValue>;\n\nconst createFieldComponent = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = createUseValueHook(form);\n return <TName extends keyof TValues>(\n props: FieldProps<TName, TValues[TName], any>\n ) => {\n const { name, toValue, fromValue, render } = props;\n\n const value = useValue(name);\n const transformedValue = useMemo<any>(\n () => (toValue ? toValue(value) : value),\n [toValue, value]\n );\n const error = useError<TValues>(name, form);\n\n const modified = useMemo(\n () => !isEqual(value, form.initValues[name]),\n [name, value]\n );\n const reset = useCallback(\n () => form.values.set(name, form.initValues[name]),\n [name]\n );\n\n const fromValueRef = useRef(fromValue);\n useEffect(() => {\n fromValueRef.current = fromValue;\n }, [fromValue]);\n\n const onChange = useCallback(\n (v: any) => {\n form.values.set(\n name,\n fromValueRef.current ? fromValueRef.current(v) : (v as TValues[TName])\n );\n form.errors.set(name, undefined);\n },\n [name]\n );\n\n const renderRef = useRef(render);\n useEffect(() => {\n renderRef.current = render;\n }, [render]);\n\n const inputProps = useMemo(\n () => ({ value: transformedValue, onChange }),\n [onChange, transformedValue]\n );\n const fieldState = useMemo(\n () => ({ error, modified, reset }),\n [error, modified, reset]\n );\n\n return useMemo(\n () => renderRef.current(inputProps, fieldState),\n [fieldState, inputProps]\n );\n };\n};\n\nconst useModifiedFields = <TValues extends Values>(form: Form<TValues>) => {\n const [modifiedFields, setModifiedFields] = useState<Array<keyof TValues>>(\n []\n );\n\n const modifiedFieldsRef = useRef(modifiedFields);\n useEffect(() => {\n modifiedFieldsRef.current = modifiedFields;\n }, [modifiedFields]);\n\n const initValuesRef = useRef(form.initValues);\n useEffect(() => {\n initValuesRef.current = form.initValues;\n }, [form.initValues]);\n\n useEffect(() => {\n const subscription = form.values.subscribeToAllFields((name, value) => {\n const isInitValue = isEqual(value, initValuesRef.current[name]);\n const fields = modifiedFieldsRef.current;\n\n if (fields.includes(name)) {\n if (isInitValue) {\n setModifiedFields(fields.filter((field) => field !== name));\n }\n } else if (!isInitValue) {\n setModifiedFields([...fields, name]);\n }\n });\n return () => subscription.unsubscribe();\n }, [form.values]);\n\n return modifiedFields;\n};\n\nconst useFormResponse = <TValues extends Values>(form: Form<TValues>) => {\n const useValue = useMemo(() => createUseValueHook(form), [form]);\n const useTransformer = useMemo(() => createUseTransformerHook(form), [form]);\n const Field = useMemo(() => createFieldComponent(form), [form]);\n\n const modifiedFields = useModifiedFields(form);\n const modified = useMemo(\n () => modifiedFields.length > 0,\n [modifiedFields.length]\n );\n\n return useMemo(\n () => ({\n form,\n Field,\n useValue,\n useTransformer,\n modifiedFields,\n modified,\n }),\n [Field, form, modified, modifiedFields, useTransformer, useValue]\n );\n};\n\nexport const useForm = <TValues extends Values = Values>(\n initValues: TValues\n) => {\n const memoizedInitValues = useDeepEqualMemo<TValues>(\n () => initValues,\n [initValues]\n );\n const form = useMemo(\n () => new Form<TValues>(memoizedInitValues),\n [memoizedInitValues]\n );\n return useFormResponse(form);\n};\n\nexport const useExistingForm = <TValues extends Values = Values>() => {\n const form = useContext<Form<TValues> | null>(FormContext);\n if (!form) throw new Error('Wrap your form in a FormProvider');\n return useFormResponse(form);\n};\n"],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ declare class Form<TValues extends Values, TErrors extends Errors<TValues> = Err
|
|
|
8
8
|
readonly values: SubscribableData<TValues>;
|
|
9
9
|
readonly errors: SubscribableData<TErrors>;
|
|
10
10
|
constructor(initValues: TValues);
|
|
11
|
+
reset(): void;
|
|
11
12
|
}
|
|
12
13
|
interface FormProviderProps<TValues extends Values> {
|
|
13
14
|
form: Form<TValues>;
|
|
@@ -29,18 +30,18 @@ interface FieldPropsWithoutTransformers<TName, TStateValue> {
|
|
|
29
30
|
name: TName;
|
|
30
31
|
toValue?: never;
|
|
31
32
|
fromValue?: never;
|
|
32
|
-
render: (inputProps: InputProps<TStateValue>, fieldState: FieldState) => ReactElement;
|
|
33
|
+
render: (inputProps: InputProps<TStateValue>, fieldState: FieldState) => ReactElement | null;
|
|
33
34
|
}
|
|
34
35
|
interface FieldPropsWithTransformers<TName, TStateValue, TInputValue> {
|
|
35
36
|
name: TName;
|
|
36
37
|
toValue: (value: TStateValue) => TInputValue;
|
|
37
38
|
fromValue?: (value: TInputValue) => TStateValue;
|
|
38
|
-
render: (inputProps: InputProps<TInputValue>, fieldState: FieldState) => ReactElement;
|
|
39
|
+
render: (inputProps: InputProps<TInputValue>, fieldState: FieldState) => ReactElement | null;
|
|
39
40
|
}
|
|
40
41
|
type FieldProps<TName, TStateValue, TInputValue> = FieldPropsWithoutTransformers<TName, TStateValue> | FieldPropsWithTransformers<TName, TStateValue, TInputValue>;
|
|
41
42
|
export declare const useForm: <TValues extends Values = Values>(initValues: TValues) => {
|
|
42
43
|
form: Form<TValues, Errors<TValues>>;
|
|
43
|
-
Field: <TName extends keyof TValues>(props: FieldProps<TName, TValues[TName], any>) => React.ReactElement<any, string | React.JSXElementConstructor<any
|
|
44
|
+
Field: <TName extends keyof TValues>(props: FieldProps<TName, TValues[TName], any>) => React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
44
45
|
useValue: <TName_1 extends keyof TValues>(name: TName_1) => TValues[TName_1];
|
|
45
46
|
useTransformer: <TName_2 extends keyof TValues>(name: TName_2, transformer: Transformer<TValues, TName_2>) => void;
|
|
46
47
|
modifiedFields: (keyof TValues)[];
|
|
@@ -48,7 +49,7 @@ export declare const useForm: <TValues extends Values = Values>(initValues: TVal
|
|
|
48
49
|
};
|
|
49
50
|
export declare const useExistingForm: <TValues extends Values = Values>() => {
|
|
50
51
|
form: Form<TValues, Errors<TValues>>;
|
|
51
|
-
Field: <TName extends keyof TValues>(props: FieldProps<TName, TValues[TName], any>) => React.ReactElement<any, string | React.JSXElementConstructor<any
|
|
52
|
+
Field: <TName extends keyof TValues>(props: FieldProps<TName, TValues[TName], any>) => React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
52
53
|
useValue: <TName_1 extends keyof TValues>(name: TName_1) => TValues[TName_1];
|
|
53
54
|
useTransformer: <TName_2 extends keyof TValues>(name: TName_2, transformer: Transformer<TValues, TName_2>) => void;
|
|
54
55
|
modifiedFields: (keyof TValues)[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,YAAY,EACZ,SAAS,EAOV,MAAM,OAAO,CAAC;AACf,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAKlD,cAAc,uBAAuB,CAAC;AAItC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAClC,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,CAAC,MAAM,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEhF,cAAM,IAAI,CACR,OAAO,SAAS,MAAM,EACtB,OAAO,SAAS,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;IAEjD,SAAgB,UAAU,EAAE,OAAO,CAAC;IAEpC,SAAgB,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAElD,SAAgB,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBAE/B,UAAU,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,YAAY,EACZ,SAAS,EAOV,MAAM,OAAO,CAAC;AACf,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAKlD,cAAc,uBAAuB,CAAC;AAItC,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAClC,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,CAAC,MAAM,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEhF,cAAM,IAAI,CACR,OAAO,SAAS,MAAM,EACtB,OAAO,SAAS,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;IAEjD,SAAgB,UAAU,EAAE,OAAO,CAAC;IAEpC,SAAgB,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAElD,SAAgB,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBAE/B,UAAU,EAAE,OAAO;IAM/B,KAAK;CAWb;AAID,UAAU,iBAAiB,CAAC,OAAO,SAAS,MAAM;IAChD,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAGD,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,EAAE,EACnD,IAAI,EACJ,QAAQ,GACT,EAAE,iBAAiB,CAAC,OAAO,CAAC,eAE5B;AAiBD,eAAO,MAAM,QAAQ,sKAqBpB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,EAAE,KAAK,SAAS,MAAM,OAAO,IAAI,CAC7E,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAClB,OAAO,CAAC,OAAO,CAAC,CAAC;AA0BtB,UAAU,UAAU,CAAC,CAAC;IACpB,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC9B;AACD,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AACD,UAAU,6BAA6B,CAAC,KAAK,EAAE,WAAW;IACxD,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,MAAM,EAAE,CACN,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,EACnC,UAAU,EAAE,UAAU,KACnB,YAAY,GAAG,IAAI,CAAC;CAC1B;AACD,UAAU,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW;IAClE,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,WAAW,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,WAAW,CAAC;IAChD,MAAM,EAAE,CACN,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,EACnC,UAAU,EAAE,UAAU,KACnB,YAAY,GAAG,IAAI,CAAC;CAC1B;AACD,KAAK,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,IAC3C,6BAA6B,CAAC,KAAK,EAAE,WAAW,CAAC,GACjD,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AAwHhE,eAAO,MAAM,OAAO;;;;;;;CAYnB,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;CAI3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@os-design/form",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": "git@gitlab.com:os-team/libs/os-design.git",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=18"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "fa9d0a3ced0b15668def80990adceea92379239b"
|
|
38
38
|
}
|